Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -405,12 +405,14 @@ CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_) : Context(Outer.Context), Out(Out_), NullOut(false), Structor(Outer.Structor), StructorType(Outer.StructorType), - SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags), + Substitutions(Outer.Substitutions) {} CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_) : Context(Outer.Context), Out(Out_), NullOut(true), Structor(Outer.Structor), StructorType(Outer.StructorType), - SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags), + Substitutions(Outer.Substitutions) {} #if MANGLE_CHECKER ~CXXNameMangler() { @@ -458,6 +460,8 @@ void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); + // Destructive copy substitutions from other mangler. + void extendSubstitutions(CXXNameMangler* Other); void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, bool recursive = false); @@ -685,6 +689,10 @@ // Output name with implicit tags and function encoding from temporary buffer. mangleNameWithAbiTags(FD, &AdditionalAbiTags); Out << FunctionEncodingStream.str().substr(EncodingPositionStart); + + // Function encoding could create new substitutions so we have to add + // temp mangled substitutions to main mangler. + extendSubstitutions(&FunctionEncodingMangler); } void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { @@ -4426,6 +4434,14 @@ Substitutions[Ptr] = SeqID++; } +void CXXNameMangler::extendSubstitutions(CXXNameMangler* Other) { + assert(Other->SeqID >= SeqID && "Must be superset of substitutions!"); + if (Other->SeqID > SeqID) { + Substitutions.swap(Other->Substitutions); + SeqID = Other->SeqID; + } +} + CXXNameMangler::AbiTagList CXXNameMangler::makeFunctionReturnTypeTags(const FunctionDecl *FD) { // When derived abi tags are disabled there is no need to make any list. Index: test/CodeGenCXX/mangle-abi-tag.cpp =================================================================== --- test/CodeGenCXX/mangle-abi-tag.cpp +++ test/CodeGenCXX/mangle-abi-tag.cpp @@ -203,3 +203,19 @@ } // A18::operator A[abi:A][abi:B]() but GCC adds the same tags twice! // CHECK-DAG: define linkonce_odr {{.+}} @_ZN3A18cv1AB1AB1BEv( + +namespace N19 { + class A {}; + class __attribute__((abi_tag("B"))) B {}; + class D {}; + class F {}; + + template + class C {}; + + B foo(A, D); +} +void f19_test(N19::C, N19::F, N19::D) { +} +// f19_test(N19::C, N19::F, N19::D) +// CHECK-DAG: define void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_(