Correctly mangle address of member in template arguments. Fixes PR6460
llvm-svn: 98254
This commit is contained in:
parent
45d878b0f0
commit
4d5c3d99e5
|
@ -172,10 +172,12 @@ private:
|
||||||
void mangleCXXCtorType(CXXCtorType T);
|
void mangleCXXCtorType(CXXCtorType T);
|
||||||
void mangleCXXDtorType(CXXDtorType T);
|
void mangleCXXDtorType(CXXDtorType T);
|
||||||
|
|
||||||
void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
|
void mangleTemplateArgs(const TemplateParameterList &PL,
|
||||||
|
const TemplateArgument *TemplateArgs,
|
||||||
unsigned NumTemplateArgs);
|
unsigned NumTemplateArgs);
|
||||||
void mangleTemplateArgs(const TemplateArgumentList &L);
|
void mangleTemplateArgs(const TemplateParameterList &PL,
|
||||||
void mangleTemplateArg(const TemplateArgument &A);
|
const TemplateArgumentList &AL);
|
||||||
|
void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A);
|
||||||
|
|
||||||
void mangleTemplateParameter(unsigned Index);
|
void mangleTemplateParameter(unsigned Index);
|
||||||
};
|
};
|
||||||
|
@ -248,8 +250,10 @@ void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) {
|
||||||
Out << Prefix;
|
Out << Prefix;
|
||||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
|
||||||
mangleFunctionEncoding(FD);
|
mangleFunctionEncoding(FD);
|
||||||
|
else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
|
||||||
|
mangleName(VD);
|
||||||
else
|
else
|
||||||
mangleName(cast<VarDecl>(D));
|
mangleName(cast<FieldDecl>(D));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
|
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
|
||||||
|
@ -369,7 +373,8 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
|
||||||
const TemplateArgumentList *TemplateArgs = 0;
|
const TemplateArgumentList *TemplateArgs = 0;
|
||||||
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
|
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
|
||||||
mangleUnscopedTemplateName(TD);
|
mangleUnscopedTemplateName(TD);
|
||||||
mangleTemplateArgs(*TemplateArgs);
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +396,8 @@ void CXXNameMangler::mangleName(const TemplateDecl *TD,
|
||||||
|
|
||||||
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
|
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
|
||||||
mangleUnscopedTemplateName(TD);
|
mangleUnscopedTemplateName(TD);
|
||||||
mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
|
||||||
} else {
|
} else {
|
||||||
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
|
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
|
||||||
}
|
}
|
||||||
|
@ -628,7 +634,8 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
|
||||||
const TemplateArgumentList *TemplateArgs = 0;
|
const TemplateArgumentList *TemplateArgs = 0;
|
||||||
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
|
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
|
||||||
mangleTemplatePrefix(TD);
|
mangleTemplatePrefix(TD);
|
||||||
mangleTemplateArgs(*TemplateArgs);
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
manglePrefix(DC, NoFunction);
|
manglePrefix(DC, NoFunction);
|
||||||
|
@ -645,7 +652,8 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,
|
||||||
Out << 'N';
|
Out << 'N';
|
||||||
|
|
||||||
mangleTemplatePrefix(TD);
|
mangleTemplatePrefix(TD);
|
||||||
mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
|
||||||
|
|
||||||
Out << 'E';
|
Out << 'E';
|
||||||
}
|
}
|
||||||
|
@ -702,7 +710,8 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
|
||||||
const TemplateArgumentList *TemplateArgs = 0;
|
const TemplateArgumentList *TemplateArgs = 0;
|
||||||
if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
|
if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
|
||||||
mangleTemplatePrefix(TD);
|
mangleTemplatePrefix(TD);
|
||||||
mangleTemplateArgs(*TemplateArgs);
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
|
||||||
}
|
}
|
||||||
else if(NoFunction && isa<FunctionDecl>(DC))
|
else if(NoFunction && isa<FunctionDecl>(DC))
|
||||||
return;
|
return;
|
||||||
|
@ -1143,7 +1152,9 @@ void CXXNameMangler::mangleType(const TypenameType *T) {
|
||||||
TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
|
TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
|
||||||
assert(TD && "FIXME: Support dependent template names");
|
assert(TD && "FIXME: Support dependent template names");
|
||||||
mangleTemplatePrefix(TD);
|
mangleTemplatePrefix(TD);
|
||||||
mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
|
TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
|
||||||
|
mangleTemplateArgs(*TemplateParameters, TST->getArgs(),
|
||||||
|
TST->getNumArgs());
|
||||||
addSubstitution(QualType(TST, 0));
|
addSubstitution(QualType(TST, 0));
|
||||||
}
|
}
|
||||||
} else if (const TemplateTypeParmType *TTPT =
|
} else if (const TemplateTypeParmType *TTPT =
|
||||||
|
@ -1521,24 +1532,27 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &L) {
|
void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
|
||||||
|
const TemplateArgumentList &AL) {
|
||||||
// <template-args> ::= I <template-arg>+ E
|
// <template-args> ::= I <template-arg>+ E
|
||||||
Out << "I";
|
Out << "I";
|
||||||
for (unsigned i = 0, e = L.size(); i != e; ++i)
|
for (unsigned i = 0, e = AL.size(); i != e; ++i)
|
||||||
mangleTemplateArg(L[i]);
|
mangleTemplateArg(PL.getParam(i), AL[i]);
|
||||||
Out << "E";
|
Out << "E";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
|
void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
|
||||||
|
const TemplateArgument *TemplateArgs,
|
||||||
unsigned NumTemplateArgs) {
|
unsigned NumTemplateArgs) {
|
||||||
// <template-args> ::= I <template-arg>+ E
|
// <template-args> ::= I <template-arg>+ E
|
||||||
Out << "I";
|
Out << "I";
|
||||||
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
||||||
mangleTemplateArg(TemplateArgs[i]);
|
mangleTemplateArg(PL.getParam(i), TemplateArgs[i]);
|
||||||
Out << "E";
|
Out << "E";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) {
|
void CXXNameMangler::mangleTemplateArg(const NamedDecl *P,
|
||||||
|
const TemplateArgument &A) {
|
||||||
// <template-arg> ::= <type> # type or template
|
// <template-arg> ::= <type> # type or template
|
||||||
// ::= X <expression> E # expression
|
// ::= X <expression> E # expression
|
||||||
// ::= <expr-primary> # simple expressions
|
// ::= <expr-primary> # simple expressions
|
||||||
|
@ -1566,18 +1580,33 @@ void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) {
|
||||||
case TemplateArgument::Declaration: {
|
case TemplateArgument::Declaration: {
|
||||||
// <expr-primary> ::= L <mangled-name> E # external name
|
// <expr-primary> ::= L <mangled-name> E # external name
|
||||||
|
|
||||||
// FIXME: Clang produces AST's where pointer-to-member-function expressions
|
// Clang produces AST's where pointer-to-member-function expressions
|
||||||
// and pointer-to-function expressions are represented as a declaration not
|
// and pointer-to-function expressions are represented as a declaration not
|
||||||
// an expression; this is not how gcc represents them and this changes the
|
// an expression. We compensate for it here to produce the correct mangling.
|
||||||
// mangling.
|
NamedDecl *D = cast<NamedDecl>(A.getAsDecl());
|
||||||
|
const NonTypeTemplateParmDecl *Parameter = cast<NonTypeTemplateParmDecl>(P);
|
||||||
|
bool compensateMangling = D->isCXXClassMember() &&
|
||||||
|
!Parameter->getType()->isReferenceType();
|
||||||
|
if (compensateMangling) {
|
||||||
|
Out << 'X';
|
||||||
|
mangleOperatorName(OO_Amp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
Out << 'L';
|
Out << 'L';
|
||||||
// References to external entities use the mangled name; if the name would
|
// References to external entities use the mangled name; if the name would
|
||||||
// not normally be manged then mangle it as unqualified.
|
// not normally be manged then mangle it as unqualified.
|
||||||
//
|
//
|
||||||
// FIXME: The ABI specifies that external names here should have _Z, but
|
// FIXME: The ABI specifies that external names here should have _Z, but
|
||||||
// gcc leaves this off.
|
// gcc leaves this off.
|
||||||
mangle(cast<NamedDecl>(A.getAsDecl()), "Z");
|
if (compensateMangling)
|
||||||
|
mangle(D, "_Z");
|
||||||
|
else
|
||||||
|
mangle(D, "Z");
|
||||||
Out << 'E';
|
Out << 'E';
|
||||||
|
|
||||||
|
if (compensateMangling)
|
||||||
|
Out << 'E';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,3 +414,42 @@ namespace test3 {
|
||||||
get_p_2(obj);
|
get_p_2(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CHECK: define void @_ZN5test41gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
|
||||||
|
namespace test4 {
|
||||||
|
struct foo { int bar; };
|
||||||
|
template <int (foo::*)>
|
||||||
|
struct zed {};
|
||||||
|
void g(zed<&foo::bar>*)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
// CHECK: define void @_ZN5test51gEPNS_3zedIXadL_ZNS_3foo3barEEEEE
|
||||||
|
namespace test5 {
|
||||||
|
struct foo { static int bar; };
|
||||||
|
template <int *>
|
||||||
|
struct zed {};
|
||||||
|
void g(zed<&foo::bar>*)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
// CHECK: define void @_ZN5test61gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
|
||||||
|
namespace test6 {
|
||||||
|
struct foo { int bar(); };
|
||||||
|
template <int (foo::*)()>
|
||||||
|
struct zed {};
|
||||||
|
void g(zed<&foo::bar>*)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
// CHECK: define void @_ZN5test71gEPNS_3zedIXadL_ZNS_3foo3barEvEEEE
|
||||||
|
namespace test7 {
|
||||||
|
struct foo { static int bar(); };
|
||||||
|
template <int (*f)()>
|
||||||
|
struct zed {};
|
||||||
|
void g(zed<&foo::bar>*)
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
// CHECK: define void @_ZN5test81AILZNS_1B5valueEEE3incEv
|
||||||
|
namespace test8 {
|
||||||
|
template <int &counter> class A { void inc() { counter++; } };
|
||||||
|
class B { static int value; };
|
||||||
|
template class A<B::value>;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue