diff options
author | Francois Pichet <pichet2000@gmail.com> | 2010-12-27 01:32:00 +0000 |
---|---|---|
committer | Francois Pichet <pichet2000@gmail.com> | 2010-12-27 01:32:00 +0000 |
commit | b7577657cdf30199a091d3f71d63ff9ab25846f0 (patch) | |
tree | 0b248aedbb3409f249ae8a2a160c468e81bfb0b6 /clang | |
parent | 2ac8355ecd187bcf86aeae9ae0c8a92b37daf8b1 (diff) | |
download | bcm5719-llvm-b7577657cdf30199a091d3f71d63ff9ab25846f0.tar.gz bcm5719-llvm-b7577657cdf30199a091d3f71d63ff9ab25846f0.zip |
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
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 41 | ||||
-rw-r--r-- | clang/test/Parser/MicrosoftExtensions.cpp | 16 |
2 files changed, 39 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 4ac162a9f9d..d08d26ffb69 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -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))); diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp index ef4a3f6d784..bc8e88d64bb 100644 --- a/clang/test/Parser/MicrosoftExtensions.cpp +++ b/clang/test/Parser/MicrosoftExtensions.cpp @@ -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); +} |