DmitryPolukhin created this revision. DmitryPolukhin added a reviewer: rsmith. DmitryPolukhin added subscribers: cfe-commits, andreybokhanko.
Recursive mangling should use all existing substitutions and newly created substitutions should be copied outer mangler. This patch should fix PR30401 and related cases but unfortunately it is ABI breaking change for Clang backward compatibility (I hope it is rare case in practice). Perhaps this patch will have to be back ported to 3.9. https://reviews.llvm.org/D24704 Files: lib/AST/ItaniumMangle.cpp test/CodeGenCXX/mangle-abi-tag.cpp 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<typename T, B F(T, D)> + class C {}; + + B foo(A, D); +} +void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) { +} +// f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D) +// CHECK-DAG: define void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_( 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,7 @@ void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); + void extendSubstitutions(const CXXNameMangler& Other); void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, bool recursive = false); @@ -685,6 +688,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 +4433,14 @@ Substitutions[Ptr] = SeqID++; } +void CXXNameMangler::extendSubstitutions(const CXXNameMangler& Other) { + assert(Other.SeqID >= SeqID && "Must be superset of substitutions!"); + if (Other.SeqID > SeqID) { + Substitutions = 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<typename T, B F(T, D)> + class C {}; + + B foo(A, D); +} +void f19_test(N19::C<N19::A, &N19::foo>, N19::F, N19::D) { +} +// f19_test(N19::C<N19::A, &N19::foo[abi:B]>, N19::F, N19::D) +// CHECK-DAG: define void @_Z8f19_testN3N191CINS_1AEXadL_ZNS_3fooB1BES1_NS_1DEEEEENS_1FES2_( 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,7 @@ void addSubstitution(QualType T); void addSubstitution(TemplateName Template); void addSubstitution(uintptr_t Ptr); + void extendSubstitutions(const CXXNameMangler& Other); void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier, bool recursive = false); @@ -685,6 +688,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 +4433,14 @@ Substitutions[Ptr] = SeqID++; } +void CXXNameMangler::extendSubstitutions(const CXXNameMangler& Other) { + assert(Other.SeqID >= SeqID && "Must be superset of substitutions!"); + if (Other.SeqID > SeqID) { + Substitutions = 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits