summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/Mangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/Mangle.cpp')
-rw-r--r--lib/CodeGen/Mangle.cpp173
1 files changed, 101 insertions, 72 deletions
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index 2e0580f..32555ab 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -53,19 +53,19 @@ static const DeclContext *GetLocalClassFunctionDeclContext(
static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) {
assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
"Passed in decl is not a ctor or dtor!");
-
+
if (const TemplateDecl *TD = MD->getPrimaryTemplate()) {
MD = cast<CXXMethodDecl>(TD->getTemplatedDecl());
assert((isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) &&
"Templated decl is not a ctor or dtor!");
}
-
+
return MD;
}
static const unsigned UnknownArity = ~0U;
-
+
/// CXXNameMangler - Manage the mangling of a single name.
class CXXNameMangler {
MangleContext &Context;
@@ -73,7 +73,7 @@ class CXXNameMangler {
const CXXMethodDecl *Structor;
unsigned StructorType;
-
+
llvm::DenseMap<uintptr_t, unsigned> Substitutions;
ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -92,7 +92,7 @@ public:
~CXXNameMangler() {
if (Out.str()[0] == '\01')
return;
-
+
int status = 0;
char *result = abi::__cxa_demangle(Out.str().str().c_str(), 0, 0, &status);
assert(status == 0 && "Could not demangle mangled name!");
@@ -151,7 +151,7 @@ private:
void mangleQualifiers(Qualifiers Quals);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
-
+
// Declare manglers for every type class.
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT)
@@ -172,10 +172,12 @@ private:
void mangleCXXCtorType(CXXCtorType T);
void mangleCXXDtorType(CXXDtorType T);
- void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
+ void mangleTemplateArgs(const TemplateParameterList &PL,
+ const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
- void mangleTemplateArgs(const TemplateArgumentList &L);
- void mangleTemplateArg(const TemplateArgument &A);
+ void mangleTemplateArgs(const TemplateParameterList &PL,
+ const TemplateArgumentList &AL);
+ void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A);
void mangleTemplateParameter(unsigned Index);
};
@@ -248,8 +250,10 @@ void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) {
Out << Prefix;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
mangleFunctionEncoding(FD);
+ else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+ mangleName(VD);
else
- mangleName(cast<VarDecl>(D));
+ mangleName(cast<FieldDecl>(D));
}
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
@@ -306,7 +310,7 @@ static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
LinkageSpecDecl::lang_cxx && "Unexpected linkage decl!");
DC = DC->getParent();
}
-
+
return DC;
}
@@ -315,10 +319,10 @@ static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
static bool isStdNamespace(const DeclContext *DC) {
if (!DC->isNamespace())
return false;
-
+
if (!IgnoreLinkageSpecDecls(DC->getParent())->isTranslationUnit())
return false;
-
+
return isStd(cast<NamespaceDecl>(DC));
}
@@ -349,12 +353,12 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
// ::= <local-name>
//
const DeclContext *DC = ND->getDeclContext();
-
+
if (GetLocalClassFunctionDeclContext(DC)) {
mangleLocalName(ND);
return;
}
-
+
// If this is an extern variable declared locally, the relevant DeclContext
// is that of the containing namespace, or the translation unit.
if (isa<FunctionDecl>(DC) && ND->hasLinkage())
@@ -369,7 +373,8 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleUnscopedTemplateName(TD);
- mangleTemplateArgs(*TemplateArgs);
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
return;
}
@@ -391,7 +396,8 @@ void CXXNameMangler::mangleName(const TemplateDecl *TD,
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
mangleUnscopedTemplateName(TD);
- mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
} else {
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
}
@@ -417,7 +423,7 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
= dyn_cast<TemplateTemplateParmDecl>(ND)) {
mangleTemplateParameter(TTP->getIndex());
return;
- }
+ }
mangleUnscopedName(ND->getTemplatedDecl());
addSubstitution(ND);
@@ -429,7 +435,7 @@ void CXXNameMangler::mangleNumber(int64_t Number) {
Out << 'n';
Number = -Number;
}
-
+
Out << Number;
}
@@ -445,7 +451,7 @@ void CXXNameMangler::mangleCallOffset(const ThunkAdjustment &Adjustment) {
Out << '_';
return;
}
-
+
Out << 'v';
mangleNumber(Adjustment.NonVirtual);
Out << '_';
@@ -496,7 +502,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
case DeclarationName::Identifier: {
if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
// We must avoid conflicts between internally- and externally-
- // linked variable declaration names in the same TU.
+ // linked variable declaration names in the same TU.
// This naming convention is the same as that followed by GCC, though it
// shouldn't actually matter.
if (ND && isa<VarDecl>(ND) && ND->getLinkage() == InternalLinkage &&
@@ -582,7 +588,7 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
unsigned Arity;
if (ND) {
Arity = cast<FunctionDecl>(ND)->getNumParams();
-
+
// If we have a C++ member function, we need to include the 'this' pointer.
// FIXME: This does not make sense for operators that are static, but their
// names stay the same regardless of the arity (operator new for instance).
@@ -628,7 +634,8 @@ void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
- mangleTemplateArgs(*TemplateArgs);
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
}
else {
manglePrefix(DC, NoFunction);
@@ -645,7 +652,8 @@ void CXXNameMangler::mangleNestedName(const TemplateDecl *TD,
Out << 'N';
mangleTemplatePrefix(TD);
- mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, TemplateArgs, NumTemplateArgs);
Out << 'E';
}
@@ -656,26 +664,26 @@ void CXXNameMangler::mangleLocalName(const NamedDecl *ND) {
// <discriminator> := _ <non-negative number>
const DeclContext *DC = ND->getDeclContext();
Out << 'Z';
-
+
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
mangleObjCMethodName(MD);
else if (const DeclContext *CDC = GetLocalClassFunctionDeclContext(DC)) {
mangleFunctionEncoding(cast<FunctionDecl>(CDC));
Out << 'E';
mangleNestedName(ND, DC, true /*NoFunction*/);
-
+
// FIXME. This still does not cover all cases.
unsigned disc;
if (Context.getNextDiscriminator(ND, disc)) {
if (disc < 10)
Out << '_' << disc;
- else
+ else
Out << "__" << disc << '_';
}
return;
}
- else
+ else
mangleFunctionEncoding(cast<FunctionDecl>(DC));
Out << 'E';
@@ -702,7 +710,8 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(cast<NamedDecl>(DC), TemplateArgs)) {
mangleTemplatePrefix(TD);
- mangleTemplateArgs(*TemplateArgs);
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, *TemplateArgs);
}
else if(NoFunction && isa<FunctionDecl>(DC))
return;
@@ -729,7 +738,7 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
= dyn_cast<TemplateTemplateParmDecl>(ND)) {
mangleTemplateParameter(TTP->getIndex());
return;
- }
+ }
manglePrefix(ND->getDeclContext());
mangleUnqualifiedName(ND->getTemplatedDecl());
@@ -749,22 +758,22 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
case OO_Array_Delete: Out << "da"; break;
// ::= ps # + (unary)
// ::= pl # +
- case OO_Plus:
+ case OO_Plus:
assert((Arity == 1 || Arity == 2) && "Invalid arity!");
Out << (Arity == 1? "ps" : "pl"); break;
// ::= ng # - (unary)
// ::= mi # -
- case OO_Minus:
+ case OO_Minus:
assert((Arity == 1 || Arity == 2) && "Invalid arity!");
Out << (Arity == 1? "ng" : "mi"); break;
// ::= ad # & (unary)
// ::= an # &
- case OO_Amp:
+ case OO_Amp:
assert((Arity == 1 || Arity == 2) && "Invalid arity!");
Out << (Arity == 1? "ad" : "an"); break;
// ::= de # * (unary)
// ::= ml # *
- case OO_Star:
+ case OO_Star:
assert((Arity == 1 || Arity == 2) && "Invalid arity!");
Out << (Arity == 1? "de" : "ml"); break;
// ::= co # ~
@@ -863,15 +872,15 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
llvm::SmallString<64> Name;
llvm::raw_svector_ostream OS(Name);
-
- const ObjCContainerDecl *CD =
+
+ const ObjCContainerDecl *CD =
dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
assert (CD && "Missing container decl in GetNameForMethod");
OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
OS << '(' << CID->getNameAsString() << ')';
OS << ' ' << MD->getSelector().getAsString() << ']';
-
+
Out << OS.str().size() << OS.str();
}
@@ -1143,7 +1152,9 @@ void CXXNameMangler::mangleType(const TypenameType *T) {
TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl();
assert(TD && "FIXME: Support dependent template names");
mangleTemplatePrefix(TD);
- mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
+ TemplateParameterList *TemplateParameters = TD->getTemplateParameters();
+ mangleTemplateArgs(*TemplateParameters, TST->getArgs(),
+ TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
} else if (const TemplateTypeParmType *TTPT =
@@ -1173,7 +1184,7 @@ void CXXNameMangler::mangleType(const TypeOfExprType *T) {
void CXXNameMangler::mangleType(const DecltypeType *T) {
Expr *E = T->getUnderlyingExpr();
-
+
// type ::= Dt <expression> E # decltype of an id-expression
// # or class member access
// ::= DT <expression> E # decltype of an expression
@@ -1195,11 +1206,11 @@ void CXXNameMangler::mangleType(const DecltypeType *T) {
Out << 'E';
}
-void CXXNameMangler::mangleIntegerLiteral(QualType T,
+void CXXNameMangler::mangleIntegerLiteral(QualType T,
const llvm::APSInt &Value) {
// <expr-primary> ::= L <type> <value number> E # integer literal
Out << 'L';
-
+
mangleType(T);
if (T->isBooleanType()) {
// Boolean values are encoded as 0/1.
@@ -1210,7 +1221,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T,
Value.abs().print(Out, false);
}
Out << 'E';
-
+
}
void CXXNameMangler::mangleCalledExpression(const Expr *E, unsigned Arity) {
@@ -1314,7 +1325,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
break;
}
- case Expr::CXXUnresolvedConstructExprClass: {
+ case Expr::CXXUnresolvedConstructExprClass: {
const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
unsigned N = CE->arg_size();
@@ -1323,7 +1334,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
if (N != 1) Out << "_";
for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
if (N != 1) Out << "E";
- break;
+ break;
}
case Expr::CXXTemporaryObjectExprClass:
@@ -1355,18 +1366,18 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
case Expr::UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(E);
- mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
+ mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
/*Arity=*/1);
mangleExpression(UO->getSubExpr());
break;
}
-
+
case Expr::BinaryOperatorClass: {
const BinaryOperator *BO = cast<BinaryOperator>(E);
- mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
+ mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
/*Arity=*/2);
mangleExpression(BO->getLHS());
- mangleExpression(BO->getRHS());
+ mangleExpression(BO->getRHS());
break;
}
@@ -1396,7 +1407,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
mangleExpression(ECE->getSubExpr());
break;
}
-
+
case Expr::CXXOperatorCallExprClass: {
const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);
unsigned NumArgs = CE->getNumArgs();
@@ -1406,7 +1417,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
mangleExpression(CE->getArg(i));
break;
}
-
+
case Expr::ParenExprClass:
mangleExpression(cast<ParenExpr>(E)->getSubExpr());
break;
@@ -1415,7 +1426,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
const NamedDecl *D = cast<DeclRefExpr>(E)->getDecl();
switch (D->getKind()) {
- default:
+ default:
// <expr-primary> ::= L <mangled-name> E # external name
Out << 'L';
mangle(D, "_Z");
@@ -1466,7 +1477,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
mangleType(FL->getType());
// TODO: avoid this copy with careful stream management.
- llvm::SmallVector<char,20> Buffer;
+ llvm::SmallString<20> Buffer;
FL->getValue().bitcastToAPInt().toString(Buffer, 16, false);
Out.write(Buffer.data(), Buffer.size());
@@ -1475,7 +1486,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
}
case Expr::IntegerLiteralClass:
- mangleIntegerLiteral(E->getType(),
+ mangleIntegerLiteral(E->getType(),
llvm::APSInt(cast<IntegerLiteral>(E)->getValue()));
break;
@@ -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
Out << "I";
- for (unsigned i = 0, e = L.size(); i != e; ++i)
- mangleTemplateArg(L[i]);
+ for (unsigned i = 0, e = AL.size(); i != e; ++i)
+ mangleTemplateArg(PL.getParam(i), AL[i]);
Out << "E";
}
-void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
+void CXXNameMangler::mangleTemplateArgs(const TemplateParameterList &PL,
+ const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << "I";
for (unsigned i = 0; i != NumTemplateArgs; ++i)
- mangleTemplateArg(TemplateArgs[i]);
+ mangleTemplateArg(PL.getParam(i), TemplateArgs[i]);
Out << "E";
}
-void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) {
+void CXXNameMangler::mangleTemplateArg(const NamedDecl *P,
+ const TemplateArgument &A) {
// <template-arg> ::= <type> # type or template
// ::= X <expression> E # expression
// ::= <expr-primary> # simple expressions
@@ -1554,7 +1568,7 @@ void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) {
assert(A.getAsTemplate().getAsTemplateDecl() &&
"FIXME: Support dependent template names");
mangleName(A.getAsTemplate().getAsTemplateDecl());
- break;
+ break;
case TemplateArgument::Expression:
Out << 'X';
mangleExpression(A.getAsExpr());
@@ -1566,18 +1580,33 @@ void CXXNameMangler::mangleTemplateArg(const TemplateArgument &A) {
case TemplateArgument::Declaration: {
// <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
- // an expression; this is not how gcc represents them and this changes the
- // mangling.
+ // an expression. We compensate for it here to produce the correct 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';
// References to external entities use the mangled name; if the name would
// not normally be manged then mangle it as unqualified.
//
// FIXME: The ABI specifies that external names here should have _Z, but
// gcc leaves this off.
- mangle(cast<NamedDecl>(A.getAsDecl()), "Z");
+ if (compensateMangling)
+ mangle(D, "_Z");
+ else
+ mangle(D, "Z");
Out << 'E';
+
+ if (compensateMangling)
+ Out << 'E';
+
break;
}
}
@@ -1689,20 +1718,20 @@ bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl *SD,
const char (&Str)[StrLen]) {
if (!SD->getIdentifier()->isStr(Str))
return false;
-
+
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
if (TemplateArgs.size() != 2)
return false;
-
+
if (!isCharType(TemplateArgs[0].getAsType()))
return false;
-
+
if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
return false;
-
+
return true;
}
-
+
bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
// <substitution> ::= St # ::std::
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
@@ -1769,7 +1798,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
Out << "So";
return true;
}
-
+
// <substitution> ::= Sd # ::std::basic_iostream<char,
// ::std::char_traits<char> >
if (isStreamCharSpecialization(SD, "basic_iostream")) {
@@ -1838,7 +1867,7 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
/// \brief Mangles the a thunk with the offset n for the declaration D and
/// emits that name to the given output stream.
-void MangleContext::mangleThunk(const FunctionDecl *FD,
+void MangleContext::mangleThunk(const FunctionDecl *FD,
const ThunkAdjustment &ThisAdjustment,
llvm::SmallVectorImpl<char> &Res) {
assert(!isa<CXXDestructorDecl>(FD) &&
@@ -1866,7 +1895,7 @@ void MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *D,
/// \brief Mangles the a covariant thunk for the declaration D and emits that
/// name to the given output stream.
-void
+void
MangleContext::mangleCovariantThunk(const FunctionDecl *FD,
const CovariantThunkAdjustment& Adjustment,
llvm::SmallVectorImpl<char> &Res) {
OpenPOWER on IntegriCloud