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 | 6915c529dbb43073dad148c2e83a1c56bfcc05c8 (patch) | |
tree | 0c2c87221a0ebf6664fab355e3c03fc22bc38f25 /lib/Sema/SemaExprCXX.cpp | |
parent | 8fac25d33b13e25f512dd921d4d5a4b565f5d175 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 4ac162a9f9..d08d26ffb6 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/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))); |