diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 27ba2bef6746..21548a0b161a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -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 + // ::= # non-dependent or dependent type name or + // # dependent elaborated type specifier using + // # ‘typename' + // ::= Ts # dependent elaborated type specifier using + // # ‘struct’ or ‘class' + // ::= Tu # dependent elaborated type specifier using + // # ‘union' + // ::= Te # 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'; } diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp index ffb66361fcba..24207dbce647 100644 --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -951,3 +951,43 @@ namespace test44 { } // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this) } + +namespace test45 { + struct S { + enum e {}; + }; + template + void f(enum T::e *) {} + template void f(S::e *); + // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPNTeT_1eE(i32*) +} + +namespace test46 { + struct S { + struct s {}; + }; + template + void f(struct T::s *) {} + template void f(S::s *); + // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPNTsT_1sE(%"struct.test46::S::s"*) +} + +namespace test47 { + struct S { + class c {}; + }; + template + void f(class T::c *) {} + template void f(S::c *); + // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPNTsT_1cE(%"class.test47::S::c"*) +} + +namespace test48 { + struct S { + union u {}; + }; + template + void f(union T::u *) {} + template void f(S::u *); + // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPNTuT_1uE(%"union.test48::S::u"*) +}