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.

llvm-svn: 205943
This commit is contained in:
David Majnemer 2014-04-10 00:49:24 +00:00
parent 4469138e98
commit 64e40c56fb
2 changed files with 68 additions and 1 deletions

View 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';
}

View 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"*)
}