]> granicus.if.org Git - clang/commitdiff
[-cxx-abi microsoft] Create backrefs for <unnamed-type-`id'>
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 25 Nov 2013 17:50:19 +0000 (17:50 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 25 Nov 2013 17:50:19 +0000 (17:50 +0000)
It wasn't possible for an anonymous type to show up inside of function arguments.
However, decltype (which MSVC added support for in 2010) makes this
possible.  Further, backrefs to these anonymous types can now be formed.

This fixes PR18022.

N.B. We do not, and very likely _will not_, support MSVC's bug where
subsequent typedefs of anonymous types leak into the linkage name; this
is a gross violation of the ABI.  A warning should be introduced to
inform our users of this particular shortcoming.

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

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms.cpp

index ed7168e3eb049eb6857bf399240a98b05251637d..868bc11244a73bd16cec28672b2a6e9bd4779447 100644 (file)
@@ -135,7 +135,7 @@ private:
     mangleUnqualifiedName(ND, ND->getDeclName());
   }
   void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
-  void mangleSourceName(const IdentifierInfo *II);
+  void mangleSourceName(StringRef Name);
   void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
   void mangleCXXDtorType(CXXDtorType T);
   void mangleQualifiers(Qualifiers Quals, bool IsMember);
@@ -510,7 +510,7 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
   switch (Name.getNameKind()) {
     case DeclarationName::Identifier: {
       if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-        mangleSourceName(II);
+        mangleSourceName(II->getName());
         break;
       }
       
@@ -531,19 +531,22 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
                "Typedef should not be in another decl context!");
         assert(D->getDeclName().getAsIdentifierInfo() &&
                "Typedef was not named!");
-        mangleSourceName(D->getDeclName().getAsIdentifierInfo());
+        mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());
         break;
       }
 
-      if (TD->hasDeclaratorForAnonDecl())
+      if (TD->hasDeclaratorForAnonDecl()) {
         // Anonymous types with no tag or typedef get the name of their
         // declarator mangled in.
-        Out << "<unnamed-type-" << TD->getDeclaratorForAnonDecl()->getName()
-            << ">@";
-      else
+        llvm::SmallString<64> Name("<unnamed-type-");
+        Name += TD->getDeclaratorForAnonDecl()->getName();
+        Name += ">";
+        mangleSourceName(Name.str());
+      } else {
         // Anonymous types with no tag, no typedef, or declarator get
-        // '<unnamed-tag>@'.
-        Out << "<unnamed-tag>@";
+        // '<unnamed-tag>'.
+        mangleSourceName("<unnamed-tag>");
+      }
       break;
     }
       
@@ -787,17 +790,16 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
   }
 }
 
-void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
+void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
   // <source name> ::= <identifier> @
-  std::string key = II->getNameStart();
   BackRefMap::iterator Found;
   if (UseNameBackReferences)
-    Found = NameBackReferences.find(key);
+    Found = NameBackReferences.find(Name);
   if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-    Out << II->getName() << '@';
+    Out << Name << '@';
     if (UseNameBackReferences && NameBackReferences.size() < 10) {
       size_t Size = NameBackReferences.size();
-      NameBackReferences[key] = Size;
+      NameBackReferences[Name] = Size;
     }
   } else {
     Out << Found->second;
index 42d574fa53e2ed2288eab33e90924b73e5f68e40..68ec2b3baf68b3c8d79e65847733a062c11a6459 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 -std=c++11| FileCheck -check-prefix X64 %s
 
 int a;
 // CHECK-DAG: @"\01?a@@3HA"
@@ -356,3 +356,11 @@ void TypedefNewDelete::operator delete[](void *) { }
 // CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
 // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
 // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
+
+namespace PR18022 {
+
+struct { } a;
+decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
+// CHECK-DAG: ?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z
+
+}