forked from OSchip/llvm-project
More __uuidof validation:
1. Do not validate for uuid attribute if the type is template dependent. 2. Search every class declaration and definition for the uuid attribute. llvm-svn: 122578
This commit is contained in:
parent
2ac8355ecd
commit
b7577657cd
|
@ -372,16 +372,23 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
|
|||
return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
|
||||
}
|
||||
|
||||
// Get the CXXRecordDecl associated with QT bypassing 1 level of pointer,
|
||||
// reference or array type.
|
||||
static CXXRecordDecl *GetCXXRecordOfUuidArg(QualType QT) {
|
||||
Type* Ty = QT.getTypePtr();;
|
||||
/// Retrieve the UuidAttr associated with QT.
|
||||
static UuidAttr *GetUuidAttrOfType(QualType QT) {
|
||||
// Optionally remove one level of pointer, reference or array indirection.
|
||||
Type *Ty = QT.getTypePtr();;
|
||||
if (QT->isPointerType() || QT->isReferenceType())
|
||||
Ty = QT->getPointeeType().getTypePtr();
|
||||
else if (QT->isArrayType())
|
||||
Ty = cast<ArrayType>(QT)->getElementType().getTypePtr();
|
||||
|
||||
return Ty->getAsCXXRecordDecl();
|
||||
// Loop all class definition and declaration looking for an uuid attribute.
|
||||
CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
|
||||
while (RD) {
|
||||
if (UuidAttr *Uuid = RD->getAttr<UuidAttr>())
|
||||
return Uuid;
|
||||
RD = RD->getPreviousDeclaration();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Build a Microsoft __uuidof expression with a type operand.
|
||||
|
@ -389,11 +396,11 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
|||
SourceLocation TypeidLoc,
|
||||
TypeSourceInfo *Operand,
|
||||
SourceLocation RParenLoc) {
|
||||
// Make sure Operand has an associated GUID.
|
||||
CXXRecordDecl* RD = GetCXXRecordOfUuidArg(Operand->getType());
|
||||
if (!RD || !RD->getAttr<UuidAttr>())
|
||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||
|
||||
if (!Operand->getType()->isDependentType()) {
|
||||
if (!GetUuidAttrOfType(Operand->getType()))
|
||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||
}
|
||||
|
||||
// FIXME: add __uuidof semantic analysis for type operand.
|
||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||
Operand,
|
||||
|
@ -405,14 +412,12 @@ ExprResult Sema::BuildCXXUuidof(QualType TypeInfoType,
|
|||
SourceLocation TypeidLoc,
|
||||
Expr *E,
|
||||
SourceLocation RParenLoc) {
|
||||
// Make sure E has an associated GUID.
|
||||
// 0 is fine also.
|
||||
CXXRecordDecl* RD = GetCXXRecordOfUuidArg(E->getType());
|
||||
if ((!RD || !RD->getAttr<UuidAttr>()) &&
|
||||
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
|
||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||
|
||||
// FIXME: add __uuidof semantic analysis for expr operand.
|
||||
if (!E->getType()->isDependentType()) {
|
||||
if (!GetUuidAttrOfType(E->getType()) &&
|
||||
!E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
|
||||
return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
|
||||
}
|
||||
// FIXME: add __uuidof semantic analysis for type operand.
|
||||
return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
|
||||
E,
|
||||
SourceRange(TypeidLoc, RParenLoc)));
|
||||
|
|
|
@ -48,6 +48,11 @@ struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
|
|||
struct_with_uuid { };
|
||||
struct struct_without_uuid { };
|
||||
|
||||
struct __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
|
||||
struct_with_uuid2;
|
||||
|
||||
struct
|
||||
struct_with_uuid2 {} ;
|
||||
|
||||
int uuid_sema_test()
|
||||
{
|
||||
|
@ -55,6 +60,7 @@ int uuid_sema_test()
|
|||
struct_without_uuid var_without_uuid[1];
|
||||
|
||||
__uuidof(struct_with_uuid);
|
||||
__uuidof(struct_with_uuid2);
|
||||
__uuidof(struct_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||
__uuidof(struct_with_uuid*);
|
||||
__uuidof(struct_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||
|
@ -69,3 +75,13 @@ int uuid_sema_test()
|
|||
__uuidof(0);
|
||||
__uuidof(1);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void template_uuid()
|
||||
{
|
||||
T expr;
|
||||
|
||||
__uuidof(T);
|
||||
__uuidof(expr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue