]> granicus.if.org Git - clang/commitdiff
Sema: Propagate the mangling number into instantiations
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 4 Dec 2013 09:01:55 +0000 (09:01 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 4 Dec 2013 09:01:55 +0000 (09:01 +0000)
We would lose track of the mangling number assigned to the original
declaration which would cause us to create manglings that didn't match
the Itanium C++ specification.

e.g. Two static fields with the same name inside of a function template
would receive the same mangling with LLVM fixing up the second field so
they wouldn't collide.  This would create an incompatibility with other
compilers following the Itanium ABI.

I've confirmed that the new mangling is identical to the ones generated
by icc and gcc.

N.B. This was uncovered while working on Microsoft mangler.

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

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CodeGenCXX/mangle-template.cpp

index 0e6e204e661080c55af406a0d8efe657743a44e8..b10cb397ffe2c89640fb84191db92ee2671851d8 100644 (file)
@@ -648,6 +648,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
 
   Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
   Enum->setAccess(D->getAccess());
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D));
   if (SubstQualifier(D, Enum)) return 0;
   Owner->addDecl(Enum);
 
@@ -1133,6 +1135,10 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
   if (D->isLocalClass())
     SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
 
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(Record,
+                                    SemaRef.Context.getManglingNumber(D));
+
   Owner->addDecl(Record);
 
   // DR1484 clarifies that the members of a local class are instantiated as part
@@ -3023,6 +3029,10 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
   if (Tmpl->isDeleted())
     New->setDeletedAsWritten();
 
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(New,
+                                    SemaRef.Context.getManglingNumber(Tmpl));
+
   // If we are performing substituting explicitly-specified template arguments
   // or deduced template arguments into a function template and we reach this
   // point, we are now past the point where SFINAE applies and have committed
@@ -3453,6 +3463,9 @@ void Sema::BuildVariableInstantiation(
     NewVar->setInstantiationOfStaticDataMember(OldVar,
                                                TSK_ImplicitInstantiation);
 
+  // Forward the mangling number from the template to the instantiated decl.
+  Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
+
   // Delay instantiation of the initializer for variable templates until a
   // definition of the variable is needed.
   if (!isa<VarTemplateSpecializationDecl>(NewVar) && !InstantiatingVarTemplate)
index 3b7f3027f6c244b2331cc79451eff6010deaefab..9bd74b54a5ba5f362656055ab0a69dec3c53d8d4 100644 (file)
@@ -182,3 +182,25 @@ namespace test13 {
   template short returnShort<-32768>();
   // CHECK: @_ZN6test1311returnShortILsn32768EEEsv()
 }
+
+namespace test14 {
+  template <typename> inline int inl(bool b) {
+    if (b) {
+      static struct {
+        int field;
+      } a;
+      // CHECK: @_ZZN6test143inlIvEEibE1a
+
+      return a.field;
+    } else {
+      static struct {
+        int field;
+      } a;
+      // CHECK: @_ZZN6test143inlIvEEibE1a_0
+
+      return a.field;
+    }
+  }
+
+  int call(bool b) { return inl<void>(b); }
+}