]> granicus.if.org Git - clang/commitdiff
AST: Implement proposal for dependent elaborated type specifiers
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 10 Apr 2014 00:49:24 +0000 (00:49 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 10 Apr 2014 00:49:24 +0000 (00:49 +0000)
cxx-abi-dev came up with a way to disambiguate between different
keywords used in elaborated type specifiers.

This resolves certain collisions during mangling.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205943 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/mangle.cpp

index 27ba2bef67468111dcb82e5fd2b508cbd48428bc..21548a0b161a59ead7a51f01320bbce6c113ccf3 100644 (file)
@@ -2361,8 +2361,35 @@ void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
 void CXXNameMangler::mangleType(const DependentNameType *T) {
   // Typename types are always nested
   Out << 'N';
+  // Proposal by cxx-abi-dev, 2014-03-26
+  // <class-enum-type> ::= <name>    # non-dependent or dependent type name or
+  //                                 # dependent elaborated type specifier using
+  //                                 # ‘typename'
+  //                   ::= Ts <name> # dependent elaborated type specifier using
+  //                                 # ‘struct’ or ‘class'
+  //                   ::= Tu <name> # dependent elaborated type specifier using
+  //                                 # ‘union'
+  //                   ::= Te <name> # dependent elaborated type specifier using
+  //                                 # ‘enum’
+  switch (T->getKeyword()) {
+    case ETK_Typename:
+      break;
+    case ETK_Struct:
+    case ETK_Class:
+    case ETK_Interface:
+      Out << "Ts";
+      break;
+    case ETK_Union:
+      Out << "Tu";
+      break;
+    case ETK_Enum:
+      Out << "Te";
+      break;
+    default:
+      llvm_unreachable("unexpected keyword for dependent type name");
+  }
   manglePrefix(T->getQualifier());
-  mangleSourceName(T->getIdentifier());    
+  mangleSourceName(T->getIdentifier());
   Out << 'E';
 }
 
index ffb66361fcba3ac5aa6b3b455b7e18cdce1a4699..24207dbce64720b2d9862bd22c02aa84174905d5 100644 (file)
@@ -951,3 +951,43 @@ namespace test44 {
   }
   // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this)
 }
+
+namespace test45 {
+  struct S {
+    enum e {};
+  };
+  template <typename T>
+  void f(enum T::e *) {}
+  template void f<S>(S::e *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPNTeT_1eE(i32*)
+}
+
+namespace test46 {
+  struct S {
+    struct s {};
+  };
+  template <typename T>
+  void f(struct T::s *) {}
+  template void f<S>(S::s *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPNTsT_1sE(%"struct.test46::S::s"*)
+}
+
+namespace test47 {
+  struct S {
+    class c {};
+  };
+  template <typename T>
+  void f(class T::c *) {}
+  template void f<S>(S::c *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPNTsT_1cE(%"class.test47::S::c"*)
+}
+
+namespace test48 {
+  struct S {
+    union u {};
+  };
+  template <typename T>
+  void f(union T::u *) {}
+  template void f<S>(S::u *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPNTuT_1uE(%"union.test48::S::u"*)
+}