]> granicus.if.org Git - clang/commitdiff
PR30401: Fix substitutions for functions with abi_tag
authorDmitry Polukhin <dmitry.polukhin@gmail.com>
Wed, 21 Sep 2016 08:27:03 +0000 (08:27 +0000)
committerDmitry Polukhin <dmitry.polukhin@gmail.com>
Wed, 21 Sep 2016 08:27:03 +0000 (08:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@282059 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/mangle-abi-tag.cpp

index 2f9123cc001929d88693bf037cb5d50cab2f049f..95d8af96485b96bebd82a6a3647c04b8876a331c 100644 (file)
@@ -405,12 +405,14 @@ public:
   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 @@ private:
   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 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
   // 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 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
   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 385a16f26a514b3d52b282c9088d01394271266b..990d2f94b5a5782fd5b9fa7144f7ede36511f6d4 100644 (file)
@@ -203,3 +203,19 @@ void f18_test() {
 }
 // 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_(