summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp442
1 files changed, 378 insertions, 64 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp b/contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp
index 6c2a648..30ee541 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/Mangle.cpp
@@ -40,7 +40,7 @@ MiscNameMangler::MiscNameMangler(MangleContext &C,
llvm::SmallVectorImpl<char> &Res)
: Context(C), Out(Res) { }
-void MiscNameMangler::mangleBlock(const BlockDecl *BD) {
+void MiscNameMangler::mangleBlock(GlobalDecl GD, const BlockDecl *BD) {
// Mangle the context of the block.
// FIXME: We currently mimic GCC's mangling scheme, which leaves much to be
// desired. Come up with a better mangling scheme.
@@ -55,6 +55,16 @@ void MiscNameMangler::mangleBlock(const BlockDecl *BD) {
const NamedDecl *ND = cast<NamedDecl>(DC);
if (IdentifierInfo *II = ND->getIdentifier())
Out << II->getName();
+ else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) {
+ llvm::SmallString<64> Buffer;
+ Context.mangleCXXDtor(D, GD.getDtorType(), Buffer);
+ Out << Buffer;
+ }
+ else if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND)) {
+ llvm::SmallString<64> Buffer;
+ Context.mangleCXXCtor(D, GD.getCtorType(), Buffer);
+ Out << Buffer;
+ }
else {
// FIXME: We were doing a mangleUnqualifiedName() before, but that's
// a private member of a class that will soon itself be private to the
@@ -125,19 +135,24 @@ class CXXNameMangler {
const CXXMethodDecl *Structor;
unsigned StructorType;
+ /// SeqID - The next subsitution sequence number.
+ unsigned SeqID;
+
llvm::DenseMap<uintptr_t, unsigned> Substitutions;
ASTContext &getASTContext() const { return Context.getASTContext(); }
public:
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
- : Context(C), Out(Res), Structor(0), StructorType(0) { }
+ : Context(C), Out(Res), Structor(0), StructorType(0), SeqID(0) { }
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
const CXXConstructorDecl *D, CXXCtorType Type)
- : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+ : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
+ SeqID(0) { }
CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res,
const CXXDestructorDecl *D, CXXDtorType Type)
- : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type) { }
+ : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type),
+ SeqID(0) { }
#if MANGLE_CHECKER
~CXXNameMangler() {
@@ -154,7 +169,9 @@ public:
void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
void mangleCallOffset(int64_t NonVirtual, int64_t Virtual);
+ void mangleNumber(const llvm::APSInt &I);
void mangleNumber(int64_t Number);
+ void mangleFloat(const llvm::APFloat &F);
void mangleFunctionEncoding(const FunctionDecl *FD);
void mangleName(const NamedDecl *ND);
void mangleType(QualType T);
@@ -215,6 +232,7 @@ private:
#include "clang/AST/TypeNodes.def"
void mangleType(const TagType*);
+ void mangleType(TemplateName);
void mangleBareFunctionType(const FunctionType *T,
bool MangleReturnType);
@@ -279,7 +297,7 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (!FD) {
const DeclContext *DC = D->getDeclContext();
// Check for extern variable declared locally.
- if (isa<FunctionDecl>(DC) && D->hasLinkage())
+ if (DC->isFunctionOrMethod() && D->hasLinkage())
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = DC->getParent();
if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage)
@@ -357,12 +375,6 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
mangleBareFunctionType(FT, MangleReturnType);
}
-/// isStd - Return whether a given namespace is the 'std' namespace.
-static bool isStd(const NamespaceDecl *NS) {
- const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
- return II && II->isStr("std");
-}
-
static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
while (isa<LinkageSpecDecl>(DC)) {
DC = DC->getParent();
@@ -371,15 +383,21 @@ static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
return DC;
}
+/// isStd - Return whether a given namespace is the 'std' namespace.
+static bool isStd(const NamespaceDecl *NS) {
+ if (!IgnoreLinkageSpecDecls(NS->getParent())->isTranslationUnit())
+ return false;
+
+ const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
+ return II && II->isStr("std");
+}
+
// isStdNamespace - Return whether a given decl context is a toplevel 'std'
// namespace.
static bool isStdNamespace(const DeclContext *DC) {
if (!DC->isNamespace())
return false;
- if (!IgnoreLinkageSpecDecls(DC->getParent())->isTranslationUnit())
- return false;
-
return isStd(cast<NamespaceDecl>(DC));
}
@@ -511,6 +529,21 @@ void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) {
addSubstitution(Template);
}
+void CXXNameMangler::mangleFloat(const llvm::APFloat &F) {
+ // TODO: avoid this copy with careful stream management.
+ llvm::SmallString<20> Buffer;
+ F.bitcastToAPInt().toString(Buffer, 16, false);
+ Out.write(Buffer.data(), Buffer.size());
+}
+
+void CXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
+ if (Value.isSigned() && Value.isNegative()) {
+ Out << 'n';
+ Value.abs().print(Out, true);
+ } else
+ Value.print(Out, Value.isSigned());
+}
+
void CXXNameMangler::mangleNumber(int64_t Number) {
// <number> ::= [n] <non-negative decimal integer>
if (Number < 0) {
@@ -593,6 +626,28 @@ void CXXNameMangler::mangleUnresolvedName(NestedNameSpecifier *Qualifier,
mangleUnqualifiedName(0, Name, KnownArity);
}
+static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
+ assert(RD->isAnonymousStructOrUnion() &&
+ "Expected anonymous struct or union!");
+
+ for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I) {
+ const FieldDecl *FD = *I;
+
+ if (FD->getIdentifier())
+ return FD;
+
+ if (const RecordType *RT = FD->getType()->getAs<RecordType>()) {
+ if (const FieldDecl *NamedDataMember =
+ FindFirstNamedDataMember(RT->getDecl()))
+ return NamedDataMember;
+ }
+ }
+
+ // We didn't find a named data member.
+ return 0;
+}
+
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
DeclarationName Name,
unsigned KnownArity) {
@@ -625,6 +680,28 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
}
+ if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ // We must have an anonymous union or struct declaration.
+ const RecordDecl *RD =
+ cast<RecordDecl>(VD->getType()->getAs<RecordType>()->getDecl());
+
+ // Itanium C++ ABI 5.1.2:
+ //
+ // For the purposes of mangling, the name of an anonymous union is
+ // considered to be the name of the first named data member found by a
+ // pre-order, depth-first, declaration-order walk of the data members of
+ // the anonymous union. If there is no such data member (i.e., if all of
+ // the data members in the union are unnamed), then there is no way for
+ // a program to refer to the anonymous union, and there is therefore no
+ // need to mangle its name.
+ const FieldDecl *FD = FindFirstNamedDataMember(RD);
+ assert(FD && "Didn't find a named data member!");
+ assert(FD->getIdentifier() && "Data member name isn't an identifier!");
+
+ mangleSourceName(FD->getIdentifier());
+ break;
+ }
+
// We must have an anonymous struct.
const TagDecl *TD = cast<TagDecl>(ND);
if (const TypedefDecl *D = TD->getTypedefForAnonDecl()) {
@@ -808,7 +885,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
manglePrefix(DC->getParent(), NoFunction);
llvm::SmallString<64> Name;
- Context.mangleBlock(Block, Name);
+ Context.mangleBlock(GlobalDecl(), Block, Name);
Out << Name.size() << Name;
return;
}
@@ -880,6 +957,53 @@ void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND) {
addSubstitution(ND);
}
+/// Mangles a template name under the production <type>. Required for
+/// template template arguments.
+/// <type> ::= <class-enum-type>
+/// ::= <template-param>
+/// ::= <substitution>
+void CXXNameMangler::mangleType(TemplateName TN) {
+ if (mangleSubstitution(TN))
+ return;
+
+ TemplateDecl *TD = 0;
+
+ switch (TN.getKind()) {
+ case TemplateName::QualifiedTemplate:
+ TD = TN.getAsQualifiedTemplateName()->getTemplateDecl();
+ goto HaveDecl;
+
+ case TemplateName::Template:
+ TD = TN.getAsTemplateDecl();
+ goto HaveDecl;
+
+ HaveDecl:
+ if (isa<TemplateTemplateParmDecl>(TD))
+ mangleTemplateParameter(cast<TemplateTemplateParmDecl>(TD)->getIndex());
+ else
+ mangleName(TD);
+ break;
+
+ case TemplateName::OverloadedTemplate:
+ llvm_unreachable("can't mangle an overloaded template name as a <type>");
+ break;
+
+ case TemplateName::DependentTemplate: {
+ const DependentTemplateName *Dependent = TN.getAsDependentTemplateName();
+ assert(Dependent->isIdentifier());
+
+ // <class-enum-type> ::= <name>
+ // <name> ::= <nested-name>
+ mangleUnresolvedScope(Dependent->getQualifier());
+ mangleSourceName(Dependent->getIdentifier());
+ break;
+ }
+
+ }
+
+ addSubstitution(TN);
+}
+
void
CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
switch (OO) {
@@ -1001,6 +1125,18 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
if (Quals.hasConst())
Out << 'K';
+ if (Quals.hasAddressSpace()) {
+ // Extension:
+ //
+ // <type> ::= U <address-space-number>
+ //
+ // where <address-space-number> is a source name consisting of 'AS'
+ // followed by the address space <number>.
+ llvm::SmallString<64> ASString;
+ ASString = "AS" + llvm::utostr_32(Quals.getAddressSpace());
+ Out << 'U' << ASString.size() << ASString;
+ }
+
// FIXME: For now, just drop all extension qualifiers on the floor.
}
@@ -1138,7 +1274,8 @@ void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
if (MangleReturnType)
mangleType(Proto->getResultType());
- if (Proto->getNumArgs() == 0) {
+ if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+ // <builtin-type> ::= v # void
Out << 'v';
return;
}
@@ -1204,6 +1341,22 @@ void CXXNameMangler::mangleType(const MemberPointerType *T) {
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
mangleQualifiers(Qualifiers::fromCVRMask(FPT->getTypeQuals()));
mangleType(FPT);
+
+ // Itanium C++ ABI 5.1.8:
+ //
+ // The type of a non-static member function is considered to be different,
+ // for the purposes of substitution, from the type of a namespace-scope or
+ // static member function whose type appears similar. The types of two
+ // non-static member functions are considered to be different, for the
+ // purposes of substitution, if the functions are members of different
+ // classes. In other words, for the purposes of substitution, the class of
+ // which the function is a member is considered part of the type of
+ // function.
+
+ // We increment the SeqID here to emulate adding an entry to the
+ // substitution table. We can't actually add it because we don't want this
+ // particular function type to be substituted.
+ ++SeqID;
} else
mangleType(PointeeType);
}
@@ -1213,8 +1366,6 @@ void CXXNameMangler::mangleType(const TemplateTypeParmType *T) {
mangleTemplateParameter(T->getIndex());
}
-// FIXME: <type> ::= <template-template-param> <template-args>
-
// <type> ::= P <type> # pointer-to
void CXXNameMangler::mangleType(const PointerType *T) {
Out << 'P';
@@ -1244,12 +1395,20 @@ void CXXNameMangler::mangleType(const ComplexType *T) {
}
// GNU extension: vector types
-// <type> ::= <vector-type>
-// <vector-type> ::= Dv <positive dimension number> _ <element type>
-// ::= Dv [<dimension expression>] _ <element type>
+// <type> ::= <vector-type>
+// <vector-type> ::= Dv <positive dimension number> _
+// <extended element type>
+// ::= Dv [<dimension expression>] _ <element type>
+// <extended element type> ::= <element type>
+// ::= p # AltiVec vector pixel
void CXXNameMangler::mangleType(const VectorType *T) {
Out << "Dv" << T->getNumElements() << '_';
- mangleType(T->getElementType());
+ if (T->getAltiVecSpecific() == VectorType::Pixel)
+ Out << 'p';
+ else if (T->getAltiVecSpecific() == VectorType::Bool)
+ Out << 'b';
+ else
+ mangleType(T->getElementType());
}
void CXXNameMangler::mangleType(const ExtVectorType *T) {
mangleType(static_cast<const VectorType*>(T));
@@ -1303,23 +1462,25 @@ void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
void CXXNameMangler::mangleType(const DependentNameType *T) {
// Typename types are always nested
Out << 'N';
- if (T->getIdentifier()) {
- mangleUnresolvedScope(T->getQualifier());
- mangleSourceName(T->getIdentifier());
- } else {
- const TemplateSpecializationType *TST = T->getTemplateId();
- if (!mangleSubstitution(QualType(TST, 0))) {
- mangleTemplatePrefix(TST->getTemplateName());
-
- // FIXME: GCC does not appear to mangle the template arguments when
- // the template in question is a dependent template name. Should we
- // emulate that badness?
- mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
- TST->getNumArgs());
- addSubstitution(QualType(TST, 0));
- }
- }
-
+ mangleUnresolvedScope(T->getQualifier());
+ mangleSourceName(T->getIdentifier());
+ Out << 'E';
+}
+
+void CXXNameMangler::mangleType(const DependentTemplateSpecializationType *T) {
+ // Dependently-scoped template types are always nested
+ Out << 'N';
+
+ // TODO: avoid making this TemplateName.
+ TemplateName Prefix =
+ getASTContext().getDependentTemplateName(T->getQualifier(),
+ T->getIdentifier());
+ mangleTemplatePrefix(Prefix);
+
+ // FIXME: GCC does not appear to mangle the template arguments when
+ // the template in question is a dependent template name. Should we
+ // emulate that badness?
+ mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs());
Out << 'E';
}
@@ -1369,9 +1530,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T,
// Boolean values are encoded as 0/1.
Out << (Value.getBoolValue() ? '1' : '0');
} else {
- if (Value.isNegative())
- Out << 'n';
- Value.abs().print(Out, false);
+ mangleNumber(Value);
}
Out << 'E';
@@ -1435,10 +1594,44 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
#define STMT(Type, Base) \
case Expr::Type##Class:
#include "clang/AST/StmtNodes.inc"
+ // fallthrough
+
+ // These all can only appear in local or variable-initialization
+ // contexts and so should never appear in a mangling.
+ case Expr::AddrLabelExprClass:
+ case Expr::BlockDeclRefExprClass:
+ case Expr::CXXThisExprClass:
+ case Expr::DesignatedInitExprClass:
+ case Expr::ImplicitValueInitExprClass:
+ case Expr::InitListExprClass:
+ case Expr::ParenListExprClass:
+ case Expr::CXXScalarValueInitExprClass:
llvm_unreachable("unexpected statement kind");
break;
- default: {
+ // FIXME: invent manglings for all these.
+ case Expr::BlockExprClass:
+ case Expr::CXXPseudoDestructorExprClass:
+ case Expr::ChooseExprClass:
+ case Expr::CompoundLiteralExprClass:
+ case Expr::ExtVectorElementExprClass:
+ case Expr::ObjCEncodeExprClass:
+ case Expr::ObjCImplicitSetterGetterRefExprClass:
+ case Expr::ObjCIsaExprClass:
+ case Expr::ObjCIvarRefExprClass:
+ case Expr::ObjCMessageExprClass:
+ case Expr::ObjCPropertyRefExprClass:
+ case Expr::ObjCProtocolExprClass:
+ case Expr::ObjCSelectorExprClass:
+ case Expr::ObjCStringLiteralClass:
+ case Expr::ObjCSuperExprClass:
+ case Expr::OffsetOfExprClass:
+ case Expr::PredefinedExprClass:
+ case Expr::ShuffleVectorExprClass:
+ case Expr::StmtExprClass:
+ case Expr::TypesCompatibleExprClass:
+ case Expr::UnaryTypeTraitExprClass:
+ case Expr::VAArgExprClass: {
// As bad as this diagnostic is, it's better than crashing.
Diagnostic &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
@@ -1450,6 +1643,11 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
break;
}
+ case Expr::CXXDefaultArgExprClass:
+ mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr());
+ break;
+
+ case Expr::CXXMemberCallExprClass: // fallthrough
case Expr::CallExprClass: {
const CallExpr *CE = cast<CallExpr>(E);
Out << "cl";
@@ -1460,6 +1658,26 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
break;
}
+ case Expr::CXXNewExprClass: {
+ // Proposal from David Vandervoorde, 2010.06.30
+ const CXXNewExpr *New = cast<CXXNewExpr>(E);
+ if (New->isGlobalNew()) Out << "gs";
+ Out << (New->isArray() ? "na" : "nw");
+ for (CXXNewExpr::const_arg_iterator I = New->placement_arg_begin(),
+ E = New->placement_arg_end(); I != E; ++I)
+ mangleExpression(*I);
+ Out << '_';
+ mangleType(New->getAllocatedType());
+ if (New->hasInitializer()) {
+ Out << "pi";
+ for (CXXNewExpr::const_arg_iterator I = New->constructor_arg_begin(),
+ E = New->constructor_arg_end(); I != E; ++I)
+ mangleExpression(*I);
+ }
+ Out << 'E';
+ break;
+ }
+
case Expr::MemberExprClass: {
const MemberExpr *ME = cast<MemberExpr>(E);
mangleMemberExpr(ME->getBase(), ME->isArrow(),
@@ -1533,6 +1751,43 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
break;
}
+ case Expr::CXXThrowExprClass: {
+ const CXXThrowExpr *TE = cast<CXXThrowExpr>(E);
+
+ // Proposal from David Vandervoorde, 2010.06.30
+ if (TE->getSubExpr()) {
+ Out << "tw";
+ mangleExpression(TE->getSubExpr());
+ } else {
+ Out << "tr";
+ }
+ break;
+ }
+
+ case Expr::CXXTypeidExprClass: {
+ const CXXTypeidExpr *TIE = cast<CXXTypeidExpr>(E);
+
+ // Proposal from David Vandervoorde, 2010.06.30
+ if (TIE->isTypeOperand()) {
+ Out << "ti";
+ mangleType(TIE->getTypeOperand());
+ } else {
+ Out << "te";
+ mangleExpression(TIE->getExprOperand());
+ }
+ break;
+ }
+
+ case Expr::CXXDeleteExprClass: {
+ const CXXDeleteExpr *DE = cast<CXXDeleteExpr>(E);
+
+ // Proposal from David Vandervoorde, 2010.06.30
+ if (DE->isGlobalDelete()) Out << "gs";
+ Out << (DE->isArrayForm() ? "da" : "dl");
+ mangleExpression(DE->getArgument());
+ break;
+ }
+
case Expr::UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(E);
mangleOperatorName(UnaryOperator::getOverloadedOperator(UO->getOpcode()),
@@ -1541,6 +1796,18 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
break;
}
+ case Expr::ArraySubscriptExprClass: {
+ const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(E);
+
+ // Array subscript is treated as a syntactically wierd form of
+ // binary operator.
+ Out << "ix";
+ mangleExpression(AE->getLHS());
+ mangleExpression(AE->getRHS());
+ break;
+ }
+
+ case Expr::CompoundAssignOperatorClass: // fallthrough
case Expr::BinaryOperatorClass: {
const BinaryOperator *BO = cast<BinaryOperator>(E);
mangleOperatorName(BinaryOperator::getOverloadedOperator(BO->getOpcode()),
@@ -1657,12 +1924,7 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
const FloatingLiteral *FL = cast<FloatingLiteral>(E);
Out << 'L';
mangleType(FL->getType());
-
- // TODO: avoid this copy with careful stream management.
- llvm::SmallString<20> Buffer;
- FL->getValue().bitcastToAPInt().toString(Buffer, 16, false);
- Out.write(Buffer.data(), Buffer.size());
-
+ mangleFloat(FL->getValue());
Out << 'E';
break;
}
@@ -1680,16 +1942,62 @@ void CXXNameMangler::mangleExpression(const Expr *E) {
Out << 'E';
break;
- case Expr::IntegerLiteralClass:
- mangleIntegerLiteral(E->getType(),
- llvm::APSInt(cast<IntegerLiteral>(E)->getValue()));
+ case Expr::IntegerLiteralClass: {
+ llvm::APSInt Value(cast<IntegerLiteral>(E)->getValue());
+ if (E->getType()->isSignedIntegerType())
+ Value.setIsSigned(true);
+ mangleIntegerLiteral(E->getType(), Value);
break;
+ }
+ case Expr::ImaginaryLiteralClass: {
+ const ImaginaryLiteral *IE = cast<ImaginaryLiteral>(E);
+ // Mangle as if a complex literal.
+ // Proposal from David Vandervoorde, 2010.06.30.
+ Out << 'L';
+ mangleType(E->getType());
+ if (const FloatingLiteral *Imag =
+ dyn_cast<FloatingLiteral>(IE->getSubExpr())) {
+ // Mangle a floating-point zero of the appropriate type.
+ mangleFloat(llvm::APFloat(Imag->getValue().getSemantics()));
+ Out << '_';
+ mangleFloat(Imag->getValue());
+ } else {
+ Out << '0' << '_';
+ llvm::APSInt Value(cast<IntegerLiteral>(IE->getSubExpr())->getValue());
+ if (IE->getSubExpr()->getType()->isSignedIntegerType())
+ Value.setIsSigned(true);
+ mangleNumber(Value);
+ }
+ Out << 'E';
+ break;
}
-}
-// FIXME: <type> ::= G <type> # imaginary (C 2000)
-// FIXME: <type> ::= U <source-name> <type> # vendor extended type qualifier
+ case Expr::StringLiteralClass: {
+ // Proposal from David Vandervoorde, 2010.06.30.
+ // I've sent a comment off asking whether this needs to also
+ // represent the length of the string.
+ Out << 'L';
+ const ConstantArrayType *T = cast<ConstantArrayType>(E->getType());
+ QualType CharTy = T->getElementType().getUnqualifiedType();
+ mangleType(CharTy);
+ Out << 'E';
+ break;
+ }
+
+ case Expr::GNUNullExprClass:
+ // FIXME: should this really be mangled the same as nullptr?
+ // fallthrough
+
+ case Expr::CXXNullPtrLiteralExprClass: {
+ // Proposal from David Vandervoorde, 2010.06.30, as
+ // modified by ABI list discussion.
+ Out << "LDnE";
+ break;
+ }
+
+ }
+}
void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) {
// <ctor-dtor-name> ::= C1 # complete object constructor
@@ -1774,9 +2082,8 @@ void CXXNameMangler::mangleTemplateArg(const NamedDecl *P,
mangleType(A.getAsType());
break;
case TemplateArgument::Template:
- assert(A.getAsTemplate().getAsTemplateDecl() &&
- "Can't get dependent template names here");
- mangleName(A.getAsTemplate().getAsTemplateDecl());
+ // This is mangled as <type>.
+ mangleType(A.getAsTemplate());
break;
case TemplateArgument::Expression:
Out << 'X';
@@ -1882,7 +2189,7 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
while (SeqID) {
assert(BufferPtr > Buffer && "Buffer overflow!");
- unsigned char c = static_cast<unsigned char>(SeqID) % 36;
+ char c = static_cast<char>(SeqID % 36);
*--BufferPtr = (c < 10 ? '0' + c : 'A' + c - 10);
SeqID /= 36;
@@ -2049,10 +2356,8 @@ void CXXNameMangler::addSubstitution(TemplateName Template) {
}
void CXXNameMangler::addSubstitution(uintptr_t Ptr) {
- unsigned SeqID = Substitutions.size();
-
assert(!Substitutions.count(Ptr) && "Substitution already exists!");
- Substitutions[Ptr] = SeqID;
+ Substitutions[Ptr] = SeqID++;
}
//
@@ -2092,10 +2397,10 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
Mangler.mangle(D);
}
-void MangleContext::mangleBlock(const BlockDecl *BD,
+void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD,
llvm::SmallVectorImpl<char> &Res) {
MiscNameMangler Mangler(*this, Res);
- Mangler.mangleBlock(BD);
+ Mangler.mangleBlock(GD, BD);
}
void MangleContext::mangleThunk(const CXXMethodDecl *MD,
@@ -2155,6 +2460,15 @@ void MangleContext::mangleGuardVariable(const VarDecl *D,
Mangler.mangleName(D);
}
+void MangleContext::mangleReferenceTemporary(const VarDecl *D,
+ llvm::SmallVectorImpl<char> &Res) {
+ // We match the GCC mangling here.
+ // <special-name> ::= GR <object name>
+ CXXNameMangler Mangler(*this, Res);
+ Mangler.getStream() << "_ZGR";
+ Mangler.mangleName(D);
+}
+
void MangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
llvm::SmallVectorImpl<char> &Res) {
// <special-name> ::= TV <type> # virtual table
OpenPOWER on IntegriCloud