forked from OSchip/llvm-project
[ms-cxxabi] Mangle variadic template parameter packs
Unlike Itanium, there is no code to indicate the beginning of a parameter pack. I tested this with MSVC 2013, which is the only version that implements variadic templates so far. This is needed to compile APInt.cpp for the MS C++ ABI. Reviewers: timurrrr Differential Revision: http://llvm-reviews.chandlerc.com/D1077 llvm-svn: 185454
This commit is contained in:
parent
5001ec9190
commit
f0ae35b88c
|
@ -134,7 +134,8 @@ private:
|
|||
|
||||
void mangleTemplateArgs(const TemplateDecl *TD,
|
||||
const TemplateArgumentList &TemplateArgs);
|
||||
|
||||
void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,
|
||||
int ArgIndex);
|
||||
};
|
||||
|
||||
/// MicrosoftMangleContext - Overrides the default MangleContext for the
|
||||
|
@ -848,44 +849,57 @@ MicrosoftCXXNameMangler::mangleTemplateArgs(const TemplateDecl *TD,
|
|||
unsigned NumTemplateArgs = TemplateArgs.size();
|
||||
for (unsigned i = 0; i < NumTemplateArgs; ++i) {
|
||||
const TemplateArgument &TA = TemplateArgs[i];
|
||||
switch (TA.getKind()) {
|
||||
case TemplateArgument::Null:
|
||||
llvm_unreachable("Can't mangle null template arguments!");
|
||||
case TemplateArgument::Type: {
|
||||
QualType T = TA.getAsType();
|
||||
mangleType(T, SourceRange(), QMM_Escape);
|
||||
break;
|
||||
}
|
||||
case TemplateArgument::Declaration:
|
||||
mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
|
||||
break;
|
||||
case TemplateArgument::Integral:
|
||||
mangleIntegerLiteral(TA.getAsIntegral(),
|
||||
TA.getIntegralType()->isBooleanType());
|
||||
break;
|
||||
case TemplateArgument::Expression:
|
||||
mangleExpression(TA.getAsExpr());
|
||||
break;
|
||||
case TemplateArgument::Template:
|
||||
case TemplateArgument::TemplateExpansion:
|
||||
case TemplateArgument::NullPtr:
|
||||
case TemplateArgument::Pack: {
|
||||
// Issue a diagnostic.
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
||||
"cannot mangle template argument %0 of kind %select{ERROR|ERROR|"
|
||||
"pointer/reference|nullptr|integral|template|template pack expansion|"
|
||||
"ERROR|parameter pack}1 yet");
|
||||
Diags.Report(TD->getLocation(), DiagID)
|
||||
<< i + 1
|
||||
<< TA.getKind()
|
||||
<< TD->getSourceRange();
|
||||
}
|
||||
}
|
||||
mangleTemplateArg(TD, TA, i);
|
||||
}
|
||||
Out << '@';
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
|
||||
const TemplateArgument &TA,
|
||||
int ArgIndex) {
|
||||
switch (TA.getKind()) {
|
||||
case TemplateArgument::Null:
|
||||
llvm_unreachable("Can't mangle null template arguments!");
|
||||
case TemplateArgument::Type: {
|
||||
QualType T = TA.getAsType();
|
||||
mangleType(T, SourceRange(), QMM_Escape);
|
||||
break;
|
||||
}
|
||||
case TemplateArgument::Declaration:
|
||||
mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
|
||||
break;
|
||||
case TemplateArgument::Integral:
|
||||
mangleIntegerLiteral(TA.getAsIntegral(),
|
||||
TA.getIntegralType()->isBooleanType());
|
||||
break;
|
||||
case TemplateArgument::Expression:
|
||||
mangleExpression(TA.getAsExpr());
|
||||
break;
|
||||
case TemplateArgument::Pack:
|
||||
// Unlike Itanium, there is no character code to indicate an argument pack.
|
||||
// FIXME: ArgIndex will be off, but we only use if for diagnostics that
|
||||
// should ultimately be removed.
|
||||
for (TemplateArgument::pack_iterator I = TA.pack_begin(), E = TA.pack_end();
|
||||
I != E; ++I)
|
||||
mangleTemplateArg(TD, *I, ArgIndex);
|
||||
break;
|
||||
case TemplateArgument::Template:
|
||||
case TemplateArgument::TemplateExpansion:
|
||||
case TemplateArgument::NullPtr: {
|
||||
// Issue a diagnostic.
|
||||
DiagnosticsEngine &Diags = Context.getDiags();
|
||||
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
|
||||
"cannot mangle template argument %0 of kind %select{ERROR|ERROR|"
|
||||
"pointer/reference|nullptr|integral|template|template pack expansion|"
|
||||
"ERROR|parameter pack}1 yet");
|
||||
Diags.Report(TD->getLocation(), DiagID)
|
||||
<< ArgIndex + 1
|
||||
<< TA.getKind()
|
||||
<< TD->getSourceRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
|
||||
bool IsMember) {
|
||||
// <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
|
||||
|
|
|
@ -133,3 +133,26 @@ void spam() {
|
|||
// CHECK: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
|
||||
// X64: "\01??$FunctionPointerTemplate@$1?spam@@YAXXZ@@YAXXZ"
|
||||
}
|
||||
|
||||
// Unlike Itanium, there is no character code to indicate an argument pack.
|
||||
// Tested with MSVC 2013, the first version which supports variadic templates.
|
||||
|
||||
template <typename ...Ts> void variadic_fn_template(const Ts &...args) { }
|
||||
void variadic_fn_instantiate() {
|
||||
variadic_fn_template(0, 1, 3, 4);
|
||||
variadic_fn_template(0, 1, 'a', "b");
|
||||
}
|
||||
// CHECK: "\01??$variadic_fn_template@HHHH@@YAXABH000@Z"
|
||||
// CHECK: "\01??$variadic_fn_template@HHD$$BY01D@@YAXABH0ABDAAY01$$CBD@Z"
|
||||
|
||||
template <typename ...Ts>
|
||||
struct VariadicClass {
|
||||
VariadicClass() { }
|
||||
int x;
|
||||
};
|
||||
void variadic_class_instantiate() {
|
||||
VariadicClass<int, char, bool> a;
|
||||
VariadicClass<bool, char, int> b;
|
||||
}
|
||||
// CHECK: call {{.*}} @"\01??0?$VariadicClass@HD_N@@QAE@XZ"
|
||||
// CHECK: call {{.*}} @"\01??0?$VariadicClass@_NDH@@QAE@XZ"
|
||||
|
|
Loading…
Reference in New Issue