зеркало из https://github.com/microsoft/clang-1.git
Just mangle substituted template parameter types as unresolved types.
This is kindof questionable but seems to do more-or-less the right thing. This is not a particularly friendly part of the ABI. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134227 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
561f81243f
Коммит
35ee32e800
|
@ -818,28 +818,21 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
|
|||
case Type::Decltype:
|
||||
case Type::TemplateTypeParm:
|
||||
case Type::UnaryTransform:
|
||||
case Type::SubstTemplateTypeParm:
|
||||
unresolvedType:
|
||||
assert(!qualifier->getPrefix());
|
||||
|
||||
// We only get here recursively if we're followed by identifiers.
|
||||
if (recursive) Out << 'N';
|
||||
|
||||
// This seems to do everything we want.
|
||||
// This seems to do everything we want. It's not really
|
||||
// sanctioned for a substituted template parameter, though.
|
||||
mangleType(QualType(type, 0));
|
||||
|
||||
// We never want to print 'E' directly after an unresolved-type,
|
||||
// so we return directly.
|
||||
return;
|
||||
|
||||
// Substituted template type parameters should only come up with
|
||||
// enclosing templates.
|
||||
// <unresolved-type> ::= <existing-substitution> [ <template-args> ]
|
||||
case Type::SubstTemplateTypeParm: {
|
||||
if (recursive) Out << 'N';
|
||||
mangleExistingSubstitution(QualType(type, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
case Type::Typedef:
|
||||
mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());
|
||||
break;
|
||||
|
|
|
@ -770,3 +770,35 @@ namespace test31 { // instantiation-dependent mangling of decltype
|
|||
// CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
|
||||
template void f3(int);
|
||||
}
|
||||
|
||||
// PR10205
|
||||
namespace test32 {
|
||||
template<typename T, int=T::value> struct A {
|
||||
typedef int type;
|
||||
};
|
||||
struct B { enum { value = 4 }; };
|
||||
|
||||
template <class T> typename A<T>::type foo() { return 0; }
|
||||
void test() {
|
||||
foo<B>();
|
||||
// CHECK: call i32 @_ZN6test323fooINS_1BEEENS_1AIT_XsrS3_5valueEE4typeEv()
|
||||
}
|
||||
}
|
||||
|
||||
namespace test33 {
|
||||
template <class T> struct X {
|
||||
enum { value = T::value };
|
||||
};
|
||||
|
||||
template<typename T, int=X<T>::value> struct A {
|
||||
typedef int type;
|
||||
};
|
||||
struct B { enum { value = 4 }; };
|
||||
|
||||
template <class T> typename A<T>::type foo() { return 0; }
|
||||
|
||||
void test() {
|
||||
foo<B>();
|
||||
// CHECK: call i32 @_ZN6test333fooINS_1BEEENS_1AIT_Xsr1XIS3_EE5valueEE4typeEv()
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче