]> granicus.if.org Git - clang/commitdiff
AST: Fix __uuidof for template specializations
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 14 Jul 2014 23:40:24 +0000 (23:40 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 14 Jul 2014 23:40:24 +0000 (23:40 +0000)
While we previously supported __uuidof applied to a template
specialization, we would only find the uuid attribute if it was applied
to the template argument.  We would erroneously ignore the uuid
attribute on the specialization itself.

This is required to parse Windows Runtime C++ Template Library headers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213016 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprCXX.cpp
test/CodeGenCXX/microsoft-templ-uuidof.cpp [new file with mode: 0644]

index 31bf432cf9f9f0e0e7af9c5d84b91bb58cfec711..c127b4a1dc013ed926b211728578cd8d66f1861a 100644 (file)
@@ -68,6 +68,11 @@ const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
   if (!RD)
     return nullptr;
 
+  // Loop over all record redeclarations looking for a uuid attribute.
+  for (const TagDecl *I : RD->redecls())
+    if (const UuidAttr *Uuid = I->getAttr<UuidAttr>())
+      return Uuid;
+
   // __uuidof can grab UUIDs from template arguments.
   if (ClassTemplateSpecializationDecl *CTSD =
           dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
@@ -106,11 +111,6 @@ const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
     return UuidForRD;
   }
 
-  // Loop over all record redeclarations looking for a uuid attribute.
-  for (const TagDecl *I : RD->redecls())
-    if (const UuidAttr *Uuid = I->getAttr<UuidAttr>())
-      return Uuid;
-
   return nullptr;
 }
 
diff --git a/test/CodeGenCXX/microsoft-templ-uuidof.cpp b/test/CodeGenCXX/microsoft-templ-uuidof.cpp
new file mode 100644 (file)
index 0000000..0ee3908
--- /dev/null
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s --check-prefix=CHECK
+
+struct _GUID;
+
+template <typename>
+struct X {
+};
+
+struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) A {};
+
+struct B {};
+
+template <>
+struct __declspec(uuid("{BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB}")) X<B> {};
+
+struct __declspec(uuid("{CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC}")) C {};
+
+const _GUID &xa = __uuidof(X<A>);
+// CHECK-DAG:  @"\01?xa@@3ABU_GUID@@B" = {{.*}} @_GUID_aaaaaaaa_aaaa_aaaa_aaaa_aaaaaaaaaaaa
+
+const _GUID &xb = __uuidof(X<B>);
+// CHECK-DAG:  @"\01?xb@@3ABU_GUID@@B" = {{.*}} @_GUID_bbbbbbbb_bbbb_bbbb_bbbb_bbbbbbbbbbbb
+const _GUID &xc = __uuidof(X<C>);
+// CHECK-DAG:  @"\01?xc@@3ABU_GUID@@B" = {{.*}} @_GUID_cccccccc_cccc_cccc_cccc_cccccccccccc
+
+template <>
+struct __declspec(uuid("{DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD}")) X<C> {};
+
+template <typename>
+struct __declspec(uuid("{EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE}")) Y {
+};
+
+const _GUID &xd = __uuidof(X<C>);
+// CHECK-DAG:  @"\01?xd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd
+
+const _GUID &yd = __uuidof(Y<X<C> >);
+// CHECK-DAG:  @"\01?yd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd