]> granicus.if.org Git - clang/commitdiff
More __uuidof validation:
authorFrancois Pichet <pichet2000@gmail.com>
Mon, 27 Dec 2010 01:32:00 +0000 (01:32 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Mon, 27 Dec 2010 01:32:00 +0000 (01:32 +0000)
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

lib/Sema/SemaExprCXX.cpp
test/Parser/MicrosoftExtensions.cpp

index 4ac162a9f9d05c922d836c807d2e256946821ac3..d08d26ffb695d04149b567b96b66b703d1159c6e 100644 (file)
@@ -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) {
-  TypeTy = 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)));  
index ef4a3f6d78447ecab11fb0a7f9a7423ec3ba69d0..bc8e88d64bbe721559695a4d55a9bdff7adcae94 100644 (file)
@@ -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);
+}