diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp | 218 |
1 files changed, 146 insertions, 72 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp index 5d5b83d..40f8730 100644 --- a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp +++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp @@ -13,6 +13,7 @@ #include "clang/AST/Mangle.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Attr.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -21,19 +22,31 @@ #include "clang/AST/ExprCXX.h" #include "clang/Basic/ABI.h" #include "clang/Basic/DiagnosticOptions.h" - #include <map> using namespace clang; namespace { +static const FunctionDecl *getStructor(const FunctionDecl *fn) { + if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate()) + return ftd->getTemplatedDecl(); + + return fn; +} + /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the /// Microsoft Visual C++ ABI. class MicrosoftCXXNameMangler { MangleContext &Context; raw_ostream &Out; + /// The "structor" is the top-level declaration being mangled, if + /// that's not a template specialization; otherwise it's the pattern + /// for that specialization. + const NamedDecl *Structor; + unsigned StructorType; + // FIXME: audit the performance of BackRefMap as it might do way too many // copying of strings. typedef std::map<std::string, unsigned> BackRefMap; @@ -47,7 +60,15 @@ class MicrosoftCXXNameMangler { public: MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_) - : Context(C), Out(Out_), UseNameBackReferences(true) { } + : Context(C), Out(Out_), + Structor(0), StructorType(-1), + UseNameBackReferences(true) { } + + MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_, + const CXXDestructorDecl *D, CXXDtorType Type) + : Context(C), Out(Out_), + Structor(getStructor(D)), StructorType(Type), + UseNameBackReferences(true) { } raw_ostream &getStream() const { return Out; } @@ -68,12 +89,13 @@ private: void mangleSourceName(const IdentifierInfo *II); void manglePostfix(const DeclContext *DC, bool NoFunction=false); void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); + void mangleCXXDtorType(CXXDtorType T); void mangleQualifiers(Qualifiers Quals, bool IsMember); void manglePointerQualifiers(Qualifiers Quals); void mangleUnscopedTemplateName(const TemplateDecl *ND); void mangleTemplateInstantiationName(const TemplateDecl *TD, - const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs); + const TemplateArgumentList &TemplateArgs); void mangleObjCMethodName(const ObjCMethodDecl *MD); void mangleLocalName(const FunctionDecl *FD); @@ -96,12 +118,12 @@ private: void mangleExtraDimensions(QualType T); void mangleFunctionClass(const FunctionDecl *FD); void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false); - void mangleIntegerLiteral(QualType T, const llvm::APSInt &Number); + void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean); void mangleExpression(const Expr *E); void mangleThrowSpecification(const FunctionProtoType *T); - void mangleTemplateArgs( - const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs); + void mangleTemplateArgs(const TemplateDecl *TD, + const TemplateArgumentList &TemplateArgs); }; @@ -345,47 +367,19 @@ void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) { } static const TemplateDecl * -isTemplate(const NamedDecl *ND, - SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { +isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) { // Check if we have a function template. if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){ if (const TemplateDecl *TD = FD->getPrimaryTemplate()) { - if (FD->getTemplateSpecializationArgsAsWritten()) { - const ASTTemplateArgumentListInfo *ArgList = - FD->getTemplateSpecializationArgsAsWritten(); - TemplateArgs.append(ArgList->getTemplateArgs(), - ArgList->getTemplateArgs() + - ArgList->NumTemplateArgs); - } else { - const TemplateArgumentList *ArgList = - FD->getTemplateSpecializationArgs(); - TemplateArgumentListInfo LI; - for (unsigned i = 0, e = ArgList->size(); i != e; ++i) - TemplateArgs.push_back(TemplateArgumentLoc(ArgList->get(i), - FD->getTypeSourceInfo())); - } + TemplateArgs = FD->getTemplateSpecializationArgs(); return TD; } } // Check if we have a class template. if (const ClassTemplateSpecializationDecl *Spec = - dyn_cast<ClassTemplateSpecializationDecl>(ND)) { - TypeSourceInfo *TSI = Spec->getTypeAsWritten(); - if (TSI) { - TemplateSpecializationTypeLoc TSTL = - cast<TemplateSpecializationTypeLoc>(TSI->getTypeLoc()); - TemplateArgumentListInfo LI(TSTL.getLAngleLoc(), TSTL.getRAngleLoc()); - for (unsigned i = 0, e = TSTL.getNumArgs(); i != e; ++i) - TemplateArgs.push_back(TSTL.getArgLoc(i)); - } else { - TemplateArgumentListInfo LI; - const TemplateArgumentList &ArgList = - Spec->getTemplateArgs(); - for (unsigned i = 0, e = ArgList.size(); i != e; ++i) - TemplateArgs.push_back(TemplateArgumentLoc(ArgList[i], - TemplateArgumentLocInfo())); - } + dyn_cast<ClassTemplateSpecializationDecl>(ND)) { + TemplateArgs = &Spec->getTemplateArgs(); return Spec->getSpecializedTemplate(); } @@ -399,8 +393,9 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // ::= <ctor-dtor-name> // ::= <source-name> // ::= <template-name> - SmallVector<TemplateArgumentLoc, 2> TemplateArgs; + // Check if we have a template. + const TemplateArgumentList *TemplateArgs = 0; if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { // We have a template. // Here comes the tricky thing: if we need to mangle something like @@ -430,7 +425,7 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, Found = NameBackReferences.find(BackReferenceKey); } if (!UseNameBackReferences || Found == NameBackReferences.end()) { - mangleTemplateInstantiationName(TD, TemplateArgs); + mangleTemplateInstantiationName(TD, *TemplateArgs); if (UseNameBackReferences && NameBackReferences.size() < 10) { size_t Size = NameBackReferences.size(); NameBackReferences[BackReferenceKey] = Size; @@ -453,7 +448,7 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) { if (NS->isAnonymousNamespace()) { - Out << "?A"; + Out << "?A@"; break; } } @@ -481,11 +476,22 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, llvm_unreachable("Can't mangle Objective-C selector names here!"); case DeclarationName::CXXConstructorName: + if (ND == Structor) { + assert(StructorType == Ctor_Complete && + "Should never be asked to mangle a ctor other than complete"); + } Out << "?0"; break; case DeclarationName::CXXDestructorName: - Out << "?1"; + if (ND == Structor) + // If the named decl is the C++ destructor we're mangling, + // use the type we were given. + mangleCXXDtorType(static_cast<CXXDtorType>(StructorType)); + else + // Otherwise, use the complete destructor name. This is relevant if a + // class with a destructor is declared within a destructor. + mangleCXXDtorType(Dtor_Complete); break; case DeclarationName::CXXConversionFunctionName: @@ -543,6 +549,23 @@ void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC, } } +void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) { + switch (T) { + case Dtor_Deleting: + Out << "?_G"; + return; + case Dtor_Base: + // FIXME: We should be asked to mangle base dtors. + // However, fixing this would require larger changes to the CodeGenModule. + // Please put llvm_unreachable here when CGM is changed. + // For now, just mangle a base dtor the same way as a complete dtor... + case Dtor_Complete: + Out << "?1"; + return; + } + llvm_unreachable("Unsupported dtor type?"); +} + void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc) { switch (OO) { @@ -736,19 +759,23 @@ void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) { void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( const TemplateDecl *TD, - const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { + const TemplateArgumentList &TemplateArgs) { // <template-name> ::= <unscoped-template-name> <template-args> // ::= <substitution> // Always start with the unqualified name. // Templates have their own context for back references. - BackRefMap TemplateContext; - NameBackReferences.swap(TemplateContext); + ArgBackRefMap OuterArgsContext; + BackRefMap OuterTemplateContext; + NameBackReferences.swap(OuterTemplateContext); + TypeBackReferences.swap(OuterArgsContext); mangleUnscopedTemplateName(TD); - mangleTemplateArgs(TemplateArgs); + mangleTemplateArgs(TD, TemplateArgs); - NameBackReferences.swap(TemplateContext); + // Restore the previous back reference contexts. + NameBackReferences.swap(OuterTemplateContext); + TypeBackReferences.swap(OuterArgsContext); } void @@ -759,13 +786,13 @@ MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) { } void -MicrosoftCXXNameMangler::mangleIntegerLiteral(QualType T, - const llvm::APSInt &Value) { +MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value, + bool IsBoolean) { // <integer-literal> ::= $0 <number> Out << "$0"; // Make sure booleans are encoded as 0/1. - if (T->isBooleanType()) - Out << (Value.getBoolValue() ? "0" : "A@"); + if (IsBoolean && Value.getBoolValue()) + mangleNumber(1); else mangleNumber(Value); } @@ -775,7 +802,7 @@ MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { // See if this is a constant expression. llvm::APSInt Value; if (E->isIntegerConstantExpr(Value, Context.getASTContext())) { - mangleIntegerLiteral(E->getType(), Value); + mangleIntegerLiteral(Value, E->getType()->isBooleanType()); return; } @@ -788,39 +815,42 @@ MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { } void -MicrosoftCXXNameMangler::mangleTemplateArgs( - const SmallVectorImpl<TemplateArgumentLoc> &TemplateArgs) { +MicrosoftCXXNameMangler::mangleTemplateArgs(const TemplateDecl *TD, + const TemplateArgumentList &TemplateArgs) { // <template-args> ::= {<type> | <integer-literal>}+ @ unsigned NumTemplateArgs = TemplateArgs.size(); for (unsigned i = 0; i < NumTemplateArgs; ++i) { - const TemplateArgumentLoc &TAL = TemplateArgs[i]; - const TemplateArgument &TA = TAL.getArgument(); + const TemplateArgument &TA = TemplateArgs[i]; switch (TA.getKind()) { case TemplateArgument::Null: llvm_unreachable("Can't mangle null template arguments!"); case TemplateArgument::Type: - mangleType(TA.getAsType(), TAL.getSourceRange()); + mangleType(TA.getAsType(), SourceRange()); + break; + case TemplateArgument::Declaration: + mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?"); break; case TemplateArgument::Integral: - mangleIntegerLiteral(TA.getIntegralType(), TA.getAsIntegral()); + mangleIntegerLiteral(TA.getAsIntegral(), + TA.getIntegralType()->isBooleanType()); break; case TemplateArgument::Expression: mangleExpression(TA.getAsExpr()); break; case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: - case TemplateArgument::Declaration: case TemplateArgument::NullPtr: case TemplateArgument::Pack: { // Issue a diagnostic. DiagnosticsEngine &Diags = Context.getDiags(); unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this %select{ERROR|ERROR|pointer/reference|nullptr|" - "integral|template|template pack expansion|ERROR|parameter pack}0 " - "template argument yet"); - Diags.Report(TAL.getLocation(), DiagID) + "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() - << TAL.getSourceRange(); + << TD->getSourceRange(); } } } @@ -1048,6 +1078,15 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break; case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break; case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break; + + case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break; + case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break; + case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break; + case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break; + case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break; + case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break; + case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break; + case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break; case BuiltinType::NullPtr: Out << "$$T"; break; @@ -1096,9 +1135,18 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, // <return-type> ::= <type> // ::= @ # structors (they have no declared return type) - if (IsStructor) + if (IsStructor) { + if (isa<CXXDestructorDecl>(D) && D == Structor && + StructorType == Dtor_Deleting) { + // The scalar deleting destructor takes an extra int argument. + // However, the FunctionType generated has 0 arguments. + // FIXME: This is a temporary hack. + // Maybe should fix the FunctionType creation instead? + Out << "PAXI@Z"; + return; + } Out << '@'; - else { + } else { QualType Result = Proto->getResultType(); const Type* RT = Result.getTypePtr(); if (!RT->isAnyPointerType() && !RT->isReferenceType()) { @@ -1471,12 +1519,38 @@ void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, void MicrosoftCXXNameMangler::mangleType(const VectorType *T, SourceRange Range) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle this vector type yet"); - Diags.Report(Range.getBegin(), DiagID) - << Range; + const BuiltinType *ET = T->getElementType()->getAs<BuiltinType>(); + assert(ET && "vectors with non-builtin elements are unsupported"); + uint64_t Width = getASTContext().getTypeSize(T); + // Pattern match exactly the typedefs in our intrinsic headers. Anything that + // doesn't match the Intel types uses a custom mangling below. + bool IntelVector = true; + if (Width == 64 && ET->getKind() == BuiltinType::LongLong) { + Out << "T__m64"; + } else if (Width == 128 || Width == 256) { + if (ET->getKind() == BuiltinType::Float) + Out << "T__m" << Width; + else if (ET->getKind() == BuiltinType::LongLong) + Out << "T__m" << Width << 'i'; + else if (ET->getKind() == BuiltinType::Double) + Out << "U__m" << Width << 'd'; + else + IntelVector = false; + } else { + IntelVector = false; + } + + if (!IntelVector) { + // The MS ABI doesn't have a special mangling for vector types, so we define + // our own mangling to handle uses of __vector_size__ on user-specified + // types, and for extensions like __v4sf. + Out << "T__clang_vec" << T->getNumElements() << '_'; + mangleType(ET, Range); + } + + Out << "@@"; } + void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T, SourceRange Range) { DiagnosticsEngine &Diags = Context.getDiags(); @@ -1697,7 +1771,7 @@ void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D, void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream & Out) { - MicrosoftCXXNameMangler mangler(*this, Out); + MicrosoftCXXNameMangler mangler(*this, Out, D, Type); mangler.mangle(D); } void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *VD, |