зеркало из 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::Decltype:
|
||||||
case Type::TemplateTypeParm:
|
case Type::TemplateTypeParm:
|
||||||
case Type::UnaryTransform:
|
case Type::UnaryTransform:
|
||||||
|
case Type::SubstTemplateTypeParm:
|
||||||
unresolvedType:
|
unresolvedType:
|
||||||
assert(!qualifier->getPrefix());
|
assert(!qualifier->getPrefix());
|
||||||
|
|
||||||
// We only get here recursively if we're followed by identifiers.
|
// We only get here recursively if we're followed by identifiers.
|
||||||
if (recursive) Out << 'N';
|
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));
|
mangleType(QualType(type, 0));
|
||||||
|
|
||||||
// We never want to print 'E' directly after an unresolved-type,
|
// We never want to print 'E' directly after an unresolved-type,
|
||||||
// so we return directly.
|
// so we return directly.
|
||||||
return;
|
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:
|
case Type::Typedef:
|
||||||
mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());
|
mangleSourceName(cast<TypedefType>(type)->getDecl()->getIdentifier());
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -770,3 +770,35 @@ namespace test31 { // instantiation-dependent mangling of decltype
|
||||||
// CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
|
// CHECK: define weak_odr void @_ZN6test312f3IiEEDTcl1gfp_EET_
|
||||||
template void f3(int);
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче