From: David Majnemer Date: Thu, 10 Apr 2014 00:49:24 +0000 (+0000) Subject: AST: Implement proposal for dependent elaborated type specifiers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fad0fcce426632c7788178f43018aae4a87d4b1;p=clang AST: Implement proposal for dependent elaborated type specifiers 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 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 27ba2bef67..21548a0b16 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/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/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index ffb66361fc..24207dbce6 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/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"*) +}