hvdijk created this revision.
hvdijk added a reviewer: rsmith.
hvdijk added a project: clang.
Herald added a project: All.
hvdijk requested review of this revision.
Herald added a subscriber: cfe-commits.

The Itanium C++ ABI says prefixes are substitutable. For most prefixes we 
already handle this: the manglePrefix(const DeclContext *, bool) and 
manglePrefix(QualType) overloads explicitly handles substitutions or defer to 
functions that handle substitutions on their behalf. The 
manglePrefix(NestedNameSpecifier *) overload, however, is different and handles 
some cases implicitly, but not all. The Identifier case was not handled; this 
change adds handling for it, as well as a test case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122663

Files:
  clang/lib/AST/ItaniumMangle.cpp
  clang/test/CodeGenCXX/mangle.cpp


Index: clang/test/CodeGenCXX/mangle.cpp
===================================================================
--- clang/test/CodeGenCXX/mangle.cpp
+++ clang/test/CodeGenCXX/mangle.cpp
@@ -1155,3 +1155,15 @@
   // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE
   template void f<int>(int);
 }
+
+namespace test61 {
+  struct X {
+    struct Y {
+      using a = int;
+      using b = int;
+    };
+  };
+  template <typename T> void f(typename T::Y::a, typename T::Y::b) {}
+  // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
+  template void f<X>(int, int);
+}
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -442,6 +442,7 @@
 private:
 
   bool mangleSubstitution(const NamedDecl *ND);
+  bool mangleSubstitution(NestedNameSpecifier *NNS);
   bool mangleSubstitution(QualType T);
   bool mangleSubstitution(TemplateName Template);
   bool mangleSubstitution(uintptr_t Ptr);
@@ -455,6 +456,11 @@
 
     addSubstitution(reinterpret_cast<uintptr_t>(ND));
   }
+  void addSubstitution(NestedNameSpecifier *NNS) {
+    NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
+
+    addSubstitution(reinterpret_cast<uintptr_t>(NNS));
+  }
   void addSubstitution(QualType T);
   void addSubstitution(TemplateName Template);
   void addSubstitution(uintptr_t Ptr);
@@ -2041,12 +2047,16 @@
     return;
 
   case NestedNameSpecifier::Identifier:
+    if (mangleSubstitution(qualifier))
+      return;
+
     // Member expressions can have these without prefixes, but that
     // should end up in mangleUnresolvedPrefix instead.
     assert(qualifier->getPrefix());
     manglePrefix(qualifier->getPrefix());
 
     mangleSourceName(qualifier->getAsIdentifier());
+    addSubstitution(qualifier);
     return;
   }
 
@@ -5962,6 +5972,11 @@
   return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
 }
 
+bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) {
+  NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
+  return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS));
+}
+
 /// Determine whether the given type has any qualifiers that are relevant for
 /// substitutions.
 static bool hasMangledSubstitutionQualifiers(QualType T) {


Index: clang/test/CodeGenCXX/mangle.cpp
===================================================================
--- clang/test/CodeGenCXX/mangle.cpp
+++ clang/test/CodeGenCXX/mangle.cpp
@@ -1155,3 +1155,15 @@
   // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE
   template void f<int>(int);
 }
+
+namespace test61 {
+  struct X {
+    struct Y {
+      using a = int;
+      using b = int;
+    };
+  };
+  template <typename T> void f(typename T::Y::a, typename T::Y::b) {}
+  // CHECK-LABEL: @_ZN6test611fINS_1XEEEvNT_1Y1aENS3_1bE
+  template void f<X>(int, int);
+}
Index: clang/lib/AST/ItaniumMangle.cpp
===================================================================
--- clang/lib/AST/ItaniumMangle.cpp
+++ clang/lib/AST/ItaniumMangle.cpp
@@ -442,6 +442,7 @@
 private:
 
   bool mangleSubstitution(const NamedDecl *ND);
+  bool mangleSubstitution(NestedNameSpecifier *NNS);
   bool mangleSubstitution(QualType T);
   bool mangleSubstitution(TemplateName Template);
   bool mangleSubstitution(uintptr_t Ptr);
@@ -455,6 +456,11 @@
 
     addSubstitution(reinterpret_cast<uintptr_t>(ND));
   }
+  void addSubstitution(NestedNameSpecifier *NNS) {
+    NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
+
+    addSubstitution(reinterpret_cast<uintptr_t>(NNS));
+  }
   void addSubstitution(QualType T);
   void addSubstitution(TemplateName Template);
   void addSubstitution(uintptr_t Ptr);
@@ -2041,12 +2047,16 @@
     return;
 
   case NestedNameSpecifier::Identifier:
+    if (mangleSubstitution(qualifier))
+      return;
+
     // Member expressions can have these without prefixes, but that
     // should end up in mangleUnresolvedPrefix instead.
     assert(qualifier->getPrefix());
     manglePrefix(qualifier->getPrefix());
 
     mangleSourceName(qualifier->getAsIdentifier());
+    addSubstitution(qualifier);
     return;
   }
 
@@ -5962,6 +5972,11 @@
   return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
 }
 
+bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) {
+  NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
+  return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS));
+}
+
 /// Determine whether the given type has any qualifiers that are relevant for
 /// substitutions.
 static bool hasMangledSubstitutionQualifiers(QualType T) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to