Hi rsmith, doug.gregor, rjmccall, 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. http://llvm-reviews.chandlerc.com/D2203 Files: lib/Sema/SemaTemplateInstantiateDecl.cpp test/CodeGenCXX/mangle-template.cpp Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -639,6 +639,8 @@ 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); @@ -1126,6 +1128,10 @@ 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); return Record; } @@ -1235,6 +1241,10 @@ if (D->isLocalExternDecl()) Function->setLocalExternDecl(); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Function, + SemaRef.Context.getManglingNumber(D)); + DeclContext *LexicalDC = Owner; if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) { assert(D->getDeclContext()->isFileContext()); @@ -1693,6 +1703,10 @@ if (D->isDeletedAsWritten()) SemaRef.SetDeclDeleted(Method, Method->getLocation()); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Method, + SemaRef.Context.getManglingNumber(D)); + // If there's a function template, let our caller handle it. if (FunctionTemplate) { // do nothing @@ -3435,6 +3449,9 @@ 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: test/CodeGenCXX/mangle-template.cpp =================================================================== --- test/CodeGenCXX/mangle-template.cpp +++ test/CodeGenCXX/mangle-template.cpp @@ -182,3 +182,24 @@ 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); } +}
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -639,6 +639,8 @@ 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); @@ -1126,6 +1128,10 @@ 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); return Record; } @@ -1235,6 +1241,10 @@ if (D->isLocalExternDecl()) Function->setLocalExternDecl(); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Function, + SemaRef.Context.getManglingNumber(D)); + DeclContext *LexicalDC = Owner; if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) { assert(D->getDeclContext()->isFileContext()); @@ -1693,6 +1703,10 @@ if (D->isDeletedAsWritten()) SemaRef.SetDeclDeleted(Method, Method->getLocation()); + // Forward the mangling number from the template to the instantiated decl. + SemaRef.Context.setManglingNumber(Method, + SemaRef.Context.getManglingNumber(D)); + // If there's a function template, let our caller handle it. if (FunctionTemplate) { // do nothing @@ -3435,6 +3449,9 @@ 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: test/CodeGenCXX/mangle-template.cpp =================================================================== --- test/CodeGenCXX/mangle-template.cpp +++ test/CodeGenCXX/mangle-template.cpp @@ -182,3 +182,24 @@ 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); } +}
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits