aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorFrancois Pichet <pichet2000@gmail.com>2010-12-27 01:32:00 +0000
committerFrancois Pichet <pichet2000@gmail.com>2010-12-27 01:32:00 +0000
commit6915c529dbb43073dad148c2e83a1c56bfcc05c8 (patch)
tree0c2c87221a0ebf6664fab355e3c03fc22bc38f25 /lib/Sema/SemaExprCXX.cpp
parent8fac25d33b13e25f512dd921d4d5a4b565f5d175 (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.cpp41
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)));