From: David Majnemer Date: Wed, 4 Dec 2013 09:01:55 +0000 (+0000) Subject: Sema: Propagate the mangling number into instantiations X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=089cd19a554a9d37d89e674a65e095646104d768;p=clang Sema: Propagate the mangling number into instantiations 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 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 0e6e204e66..b10cb397ff 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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(NewVar) && !InstantiatingVarTemplate) diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 3b7f3027f6..9bd74b54a5 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -182,3 +182,25 @@ namespace test13 { template short returnShort<-32768>(); // CHECK: @_ZN6test1311returnShortILsn32768EEEsv() } + +namespace test14 { + template 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(b); } +}