diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.h | 36 | ||||
-rw-r--r-- | lib/CodeGen/CGCXXABI.h | 10 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGVTables.h | 89 | ||||
-rw-r--r-- | lib/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTBAA.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/GlobalDecl.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/ItaniumCXXABI.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 2615 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.h | 179 | ||||
-rw-r--r-- | lib/CodeGen/MicrosoftCXXABI.cpp | 1158 |
18 files changed, 39 insertions, 4104 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 36767711b4..daa9052fda 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -799,7 +799,7 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const BlockExpr *BExpr, const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic); MangleBuffer Name; - CGM.getMangledName(GD, Name, BD); + CGM.getBlockMangledName(GD, Name, BD); llvm::Function *Fn = llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage, Name.getString(), &CGM.getModule()); diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index b734e62205..bb217fbcc9 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -16,12 +16,12 @@ #include "CGCXXABI.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "Mangle.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Mangle.h" #include "clang/AST/StmtCXX.h" #include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/StringExtras.h" diff --git a/lib/CodeGen/CGCXX.h b/lib/CodeGen/CGCXX.h deleted file mode 100644 index 1e6adb05a0..0000000000 --- a/lib/CodeGen/CGCXX.h +++ /dev/null @@ -1,36 +0,0 @@ -//===----- CGCXX.h - C++ related code CodeGen declarations ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These classes wrap the information about a call or function -// definition used to handle ABI compliancy. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANG_CODEGEN_CGCXX_H -#define CLANG_CODEGEN_CGCXX_H - -namespace clang { - -/// CXXCtorType - C++ constructor types -enum CXXCtorType { - Ctor_Complete, // Complete object ctor - Ctor_Base, // Base object ctor - Ctor_CompleteAllocating // Complete object allocating ctor -}; - -/// CXXDtorType - C++ destructor types -enum CXXDtorType { - Dtor_Deleting, // Deleting dtor - Dtor_Complete, // Complete object dtor - Dtor_Base // Base object dtor -}; - -} // end namespace clang - -#endif // CLANG_CODEGEN_CGCXX_H diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h index 56c4ea98ae..8bc1385d7f 100644 --- a/lib/CodeGen/CGCXXABI.h +++ b/lib/CodeGen/CGCXXABI.h @@ -32,18 +32,20 @@ namespace clang { class CXXMethodDecl; class CXXRecordDecl; class FieldDecl; + class MangleContext; namespace CodeGen { class CodeGenFunction; class CodeGenModule; - class MangleContext; /// Implements C++ ABI-specific code generation functions. class CGCXXABI { protected: CodeGenModule &CGM; + llvm::OwningPtr<MangleContext> MangleCtx; - CGCXXABI(CodeGenModule &CGM) : CGM(CGM) {} + CGCXXABI(CodeGenModule &CGM) + : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {} protected: ImplicitParamDecl *&getThisDecl(CodeGenFunction &CGF) { @@ -74,7 +76,9 @@ public: virtual ~CGCXXABI(); /// Gets the mangle context. - virtual MangleContext &getMangleContext() = 0; + MangleContext &getMangleContext() { + return *MangleCtx; + } /// Find the LLVM type used to represent the given member pointer /// type. diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 77984b11cc..16a3a196bb 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -148,7 +148,7 @@ static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D, const DeclContext *DC = ND->getDeclContext(); if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) { MangleBuffer Name; - CGM.getMangledName(GlobalDecl(), Name, BD); + CGM.getBlockMangledName(GlobalDecl(), Name, BD); ContextName = Name.getString(); } else diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 3574ba2c18..c7e0837b3d 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -137,6 +137,8 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD, E = OMD->param_end(); PI != E; ++PI) Args.push_back(std::make_pair(*PI, (*PI)->getType())); + CurGD = OMD; + StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart()); } diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index 1d2e8c1e04..3e3cd4b165 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -16,6 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/GlobalVariable.h" +#include "clang/Basic/ABI.h" #include "GlobalDecl.h" namespace clang { @@ -24,94 +25,6 @@ namespace clang { namespace CodeGen { class CodeGenModule; -/// ReturnAdjustment - A return adjustment. -struct ReturnAdjustment { - /// NonVirtual - The non-virtual adjustment from the derived object to its - /// nearest virtual base. - int64_t NonVirtual; - - /// VBaseOffsetOffset - The offset (in bytes), relative to the address point - /// of the virtual base class offset. - int64_t VBaseOffsetOffset; - - ReturnAdjustment() : NonVirtual(0), VBaseOffsetOffset(0) { } - - bool isEmpty() const { return !NonVirtual && !VBaseOffsetOffset; } - - friend bool operator==(const ReturnAdjustment &LHS, - const ReturnAdjustment &RHS) { - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VBaseOffsetOffset == RHS.VBaseOffsetOffset; - } - - friend bool operator<(const ReturnAdjustment &LHS, - const ReturnAdjustment &RHS) { - if (LHS.NonVirtual < RHS.NonVirtual) - return true; - - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VBaseOffsetOffset < RHS.VBaseOffsetOffset; - } -}; - -/// ThisAdjustment - A 'this' pointer adjustment. -struct ThisAdjustment { - /// NonVirtual - The non-virtual adjustment from the derived object to its - /// nearest virtual base. - int64_t NonVirtual; - - /// VCallOffsetOffset - The offset (in bytes), relative to the address point, - /// of the virtual call offset. - int64_t VCallOffsetOffset; - - ThisAdjustment() : NonVirtual(0), VCallOffsetOffset(0) { } - - bool isEmpty() const { return !NonVirtual && !VCallOffsetOffset; } - - friend bool operator==(const ThisAdjustment &LHS, - const ThisAdjustment &RHS) { - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VCallOffsetOffset == RHS.VCallOffsetOffset; - } - - friend bool operator<(const ThisAdjustment &LHS, - const ThisAdjustment &RHS) { - if (LHS.NonVirtual < RHS.NonVirtual) - return true; - - return LHS.NonVirtual == RHS.NonVirtual && - LHS.VCallOffsetOffset < RHS.VCallOffsetOffset; - } -}; - -/// ThunkInfo - The 'this' pointer adjustment as well as an optional return -/// adjustment for a thunk. -struct ThunkInfo { - /// This - The 'this' pointer adjustment. - ThisAdjustment This; - - /// Return - The return adjustment. - ReturnAdjustment Return; - - ThunkInfo() { } - - ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return) - : This(This), Return(Return) { } - - friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) { - return LHS.This == RHS.This && LHS.Return == RHS.Return; - } - - friend bool operator<(const ThunkInfo &LHS, const ThunkInfo &RHS) { - if (LHS.This < RHS.This) - return true; - - return LHS.This == RHS.This && LHS.Return < RHS.Return; - } - - bool isEmpty() const { return This.isEmpty() && Return.isEmpty(); } -}; - // BaseSubobject - Uniquely identifies a direct or indirect base class. // Stores both the base class decl and the offset from the most derived class to // the base class. diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index b985d68504..1f33678993 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -35,7 +35,6 @@ add_clang_library(clangCodeGen CodeGenTBAA.cpp CodeGenTypes.cpp ItaniumCXXABI.cpp - Mangle.cpp MicrosoftCXXABI.cpp ModuleBuilder.cpp TargetInfo.cpp diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 7077b89ec2..5f21d9fa43 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -18,6 +18,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/CharUnits.h" +#include "clang/Basic/ABI.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -26,7 +27,6 @@ #include "CGBlocks.h" #include "CGBuilder.h" #include "CGCall.h" -#include "CGCXX.h" #include "CGValue.h" namespace llvm { diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 9ed3150ff5..df90011104 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -18,7 +18,6 @@ #include "CGCall.h" #include "CGCXXABI.h" #include "CGObjCRuntime.h" -#include "Mangle.h" #include "TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" #include "clang/AST/ASTContext.h" @@ -26,6 +25,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" @@ -275,7 +275,7 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer); else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND)) - getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer); + getCXXABI().getMangleContext().mangleBlock(BD, Buffer); else getCXXABI().getMangleContext().mangleName(ND, Buffer); @@ -289,9 +289,18 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { return Str; } -void CodeGenModule::getMangledName(GlobalDecl GD, MangleBuffer &Buffer, - const BlockDecl *BD) { - getCXXABI().getMangleContext().mangleBlock(GD, BD, Buffer.getBuffer()); +void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer, + const BlockDecl *BD) { + MangleContext &MangleCtx = getCXXABI().getMangleContext(); + const Decl *D = GD.getDecl(); + if (D == 0) + MangleCtx.mangleGlobalBlock(BD, Buffer.getBuffer()); + else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D)) + MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Buffer.getBuffer()); + else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) + MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Buffer.getBuffer()); + else + MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Buffer.getBuffer()); } llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) { @@ -1304,7 +1313,6 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); const llvm::FunctionType *Ty = getTypes().GetFunctionType(GD); - getCXXABI().getMangleContext().mangleInitDiscriminator(); // Get or create the prototype for the function. llvm::Constant *Entry = GetAddrOfFunction(GD, Ty); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 14a0e497a0..b1395be8c5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -14,17 +14,17 @@ #ifndef CLANG_CODEGEN_CODEGENMODULE_H #define CLANG_CODEGEN_CODEGENMODULE_H +#include "clang/Basic/ABI.h" #include "clang/Basic/LangOptions.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/Mangle.h" #include "CGBlocks.h" #include "CGCall.h" -#include "CGCXX.h" #include "CGVTables.h" #include "CodeGenTypes.h" #include "GlobalDecl.h" -#include "Mangle.h" #include "llvm/Module.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" @@ -66,6 +66,7 @@ namespace clang { class Diagnostic; class AnnotateAttr; class CXXDestructorDecl; + class MangleBuffer; namespace CodeGen { @@ -74,7 +75,6 @@ namespace CodeGen { class CGCXXABI; class CGDebugInfo; class CGObjCRuntime; - class MangleBuffer; struct OrderGlobalInits { unsigned int priority; @@ -480,7 +480,8 @@ public: unsigned &CallingConv); llvm::StringRef getMangledName(GlobalDecl GD); - void getMangledName(GlobalDecl GD, MangleBuffer &Buffer, const BlockDecl *BD); + void getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer, + const BlockDecl *BD); void EmitTentativeDefinition(const VarDecl *D); diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp index 61dc41ed45..71b43010e6 100644 --- a/lib/CodeGen/CodeGenTBAA.cpp +++ b/lib/CodeGen/CodeGenTBAA.cpp @@ -16,8 +16,8 @@ //===----------------------------------------------------------------------===// #include "CodeGenTBAA.h" -#include "Mangle.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/Mangle.h" #include "llvm/LLVMContext.h" #include "llvm/Metadata.h" #include "llvm/Constants.h" diff --git a/lib/CodeGen/CodeGenTBAA.h b/lib/CodeGen/CodeGenTBAA.h index 29f7f544d3..c4583473a0 100644 --- a/lib/CodeGen/CodeGenTBAA.h +++ b/lib/CodeGen/CodeGenTBAA.h @@ -26,11 +26,11 @@ namespace llvm { namespace clang { class ASTContext; class LangOptions; + class MangleContext; class QualType; class Type; namespace CodeGen { - class MangleContext; class CGRecordLayout; /// CodeGenTBAA - This class organizes the cross-module state that is used diff --git a/lib/CodeGen/GlobalDecl.h b/lib/CodeGen/GlobalDecl.h index 26dea402f4..ab3e2019a6 100644 --- a/lib/CodeGen/GlobalDecl.h +++ b/lib/CodeGen/GlobalDecl.h @@ -15,9 +15,9 @@ #ifndef CLANG_CODEGEN_GLOBALDECL_H #define CLANG_CODEGEN_GLOBALDECL_H -#include "CGCXX.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/ABI.h" namespace clang { diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 99575dfc8f..554d2403c0 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -22,7 +22,7 @@ #include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" -#include "Mangle.h" +#include <clang/AST/Mangle.h> #include <clang/AST/Type.h> #include <llvm/Target/TargetData.h> #include <llvm/Value.h> @@ -35,7 +35,6 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI { private: const llvm::IntegerType *PtrDiffTy; protected: - CodeGen::MangleContext MangleCtx; bool IsARM; // It's a little silly for us to cache this. @@ -52,12 +51,7 @@ protected: public: ItaniumCXXABI(CodeGen::CodeGenModule &CGM, bool IsARM = false) : - CGCXXABI(CGM), PtrDiffTy(0), MangleCtx(getContext(), CGM.getDiags()), - IsARM(IsARM) { } - - CodeGen::MangleContext &getMangleContext() { - return MangleCtx; - } + CGCXXABI(CGM), PtrDiffTy(0), IsARM(IsARM) { } bool isZeroInitializable(const MemberPointerType *MPT); diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp deleted file mode 100644 index b8ae1e7e41..0000000000 --- a/lib/CodeGen/Mangle.cpp +++ /dev/null @@ -1,2615 +0,0 @@ -//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Implements C++ name mangling according to the Itanium C++ ABI, -// which is used in GCC 3.2 and newer (and many compilers that are -// ABI-compatible with GCC): -// -// http://www.codesourcery.com/public/cxx-abi/abi.html -// -//===----------------------------------------------------------------------===// -#include "Mangle.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/ExprCXX.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/ErrorHandling.h" -#include "CGVTables.h" - -#define MANGLE_CHECKER 0 - -#if MANGLE_CHECKER -#include <cxxabi.h> -#endif - -using namespace clang; -using namespace CodeGen; - -MiscNameMangler::MiscNameMangler(MangleContext &C, - llvm::SmallVectorImpl<char> &Res) - : Context(C), Out(Res) { } - -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. - const DeclContext *DC = BD->getDeclContext(); - while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) - DC = DC->getParent(); - if (DC->isFunctionOrMethod()) { - Out << "__"; - if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) - mangleObjCMethodName(Method); - else { - 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 - // Itanium C++ ABI object. What should we do now? Right now, I'm just - // calling the mangleName() method on the MangleContext; is there a - // better way? - llvm::SmallString<64> Buffer; - Context.mangleName(ND, Buffer); - Out << Buffer; - } - } - Out << "_block_invoke_" << Context.getBlockId(BD, true); - } else { - Out << "__block_global_" << Context.getBlockId(BD, false); - } -} - -void MiscNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { - llvm::SmallString<64> Name; - llvm::raw_svector_ostream OS(Name); - - 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 << ')'; - OS << ' ' << MD->getSelector().getAsString() << ']'; - - Out << OS.str().size() << OS.str(); -} - -namespace { - -static const CXXRecordDecl *GetLocalClassDecl(const NamedDecl *ND) { - const DeclContext *DC = dyn_cast<DeclContext>(ND); - if (!DC) - DC = ND->getDeclContext(); - while (!DC->isNamespace() && !DC->isTranslationUnit()) { - if (isa<FunctionDecl>(DC->getParent())) - return dyn_cast<CXXRecordDecl>(DC); - DC = DC->getParent(); - } - return 0; -} - -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; - llvm::raw_svector_ostream Out; - - 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), SeqID(0) { } - CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res, - const CXXConstructorDecl *D, CXXCtorType 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), - SeqID(0) { } - -#if MANGLE_CHECKER - ~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!"); - free(result); - } -#endif - llvm::raw_svector_ostream &getStream() { return Out; } - - 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); - void mangleNameOrStandardSubstitution(const NamedDecl *ND); - -private: - bool mangleSubstitution(const NamedDecl *ND); - bool mangleSubstitution(QualType T); - bool mangleSubstitution(TemplateName Template); - bool mangleSubstitution(uintptr_t Ptr); - - bool mangleStandardSubstitution(const NamedDecl *ND); - - void addSubstitution(const NamedDecl *ND) { - ND = cast<NamedDecl>(ND->getCanonicalDecl()); - - addSubstitution(reinterpret_cast<uintptr_t>(ND)); - } - void addSubstitution(QualType T); - void addSubstitution(TemplateName Template); - void addSubstitution(uintptr_t Ptr); - - void mangleUnresolvedScope(NestedNameSpecifier *Qualifier); - void mangleUnresolvedName(NestedNameSpecifier *Qualifier, - DeclarationName Name, - unsigned KnownArity = UnknownArity); - - void mangleName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleUnqualifiedName(const NamedDecl *ND) { - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); - } - void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, - unsigned KnownArity); - void mangleUnscopedName(const NamedDecl *ND); - void mangleUnscopedTemplateName(const TemplateDecl *ND); - void mangleUnscopedTemplateName(TemplateName); - void mangleSourceName(const IdentifierInfo *II); - void mangleLocalName(const NamedDecl *ND); - void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, - bool NoFunction=false); - void mangleNestedName(const TemplateDecl *TD, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void manglePrefix(const DeclContext *DC, bool NoFunction=false); - void mangleTemplatePrefix(const TemplateDecl *ND); - void mangleTemplatePrefix(TemplateName Template); - void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity); - 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) -#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T); -#include "clang/AST/TypeNodes.def" - - void mangleType(const TagType*); - void mangleType(TemplateName); - void mangleBareFunctionType(const FunctionType *T, - bool MangleReturnType); - void mangleNeonVectorType(const VectorType *T); - - void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value); - void mangleMemberExpr(const Expr *Base, bool IsArrow, - NestedNameSpecifier *Qualifier, - DeclarationName Name, - unsigned KnownArity); - void mangleExpression(const Expr *E, unsigned Arity = UnknownArity); - void mangleCXXCtorType(CXXCtorType T); - void mangleCXXDtorType(CXXDtorType T); - - void mangleTemplateArgs(const ExplicitTemplateArgumentList &TemplateArgs); - void mangleTemplateArgs(TemplateName Template, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgument *TemplateArgs, - unsigned NumTemplateArgs); - void mangleTemplateArgs(const TemplateParameterList &PL, - const TemplateArgumentList &AL); - void mangleTemplateArg(const NamedDecl *P, const TemplateArgument &A); - - void mangleTemplateParameter(unsigned Index); -}; -} - -static bool isInCLinkageSpecification(const Decl *D) { - D = D->getCanonicalDecl(); - for (const DeclContext *DC = D->getDeclContext(); - !DC->isTranslationUnit(); DC = DC->getParent()) { - if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) - return Linkage->getLanguage() == LinkageSpecDecl::lang_c; - } - - return false; -} - -bool MangleContext::shouldMangleDeclName(const NamedDecl *D) { - // In C, functions with no attributes never need to be mangled. Fastpath them. - if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs()) - return false; - - // Any decl can be declared with __asm("foo") on it, and this takes precedence - // over all other naming in the .o file. - if (D->hasAttr<AsmLabelAttr>()) - return true; - - // Clang's "overloadable" attribute extension to C/C++ implies name mangling - // (always) as does passing a C++ member function and a function - // whose name is not a simple identifier. - const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (FD && (FD->hasAttr<OverloadableAttr>() || isa<CXXMethodDecl>(FD) || - !FD->getDeclName().isIdentifier())) - return true; - - // Otherwise, no mangling is done outside C++ mode. - if (!getASTContext().getLangOptions().CPlusPlus) - return false; - - // Variables at global scope with non-internal linkage are not mangled - if (!FD) { - const DeclContext *DC = D->getDeclContext(); - // Check for extern variable declared locally. - if (DC->isFunctionOrMethod() && D->hasLinkage()) - while (!DC->isNamespace() && !DC->isTranslationUnit()) - DC = DC->getParent(); - if (DC->isTranslationUnit() && D->getLinkage() != InternalLinkage) - return false; - } - - // Class members are always mangled. - if (D->getDeclContext()->isRecord()) - return true; - - // C functions and "main" are not mangled. - if ((FD && FD->isMain()) || isInCLinkageSpecification(D)) - return false; - - return true; -} - -void CXXNameMangler::mangle(const NamedDecl *D, llvm::StringRef Prefix) { - // Any decl can be declared with __asm("foo") on it, and this takes precedence - // over all other naming in the .o file. - if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) { - // If we have an asm name, then we use it as the mangling. - Out << '\01'; // LLVM IR Marker for __asm("foo") - Out << ALA->getLabel(); - return; - } - - // <mangled-name> ::= _Z <encoding> - // ::= <data name> - // ::= <special-name> - 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<FieldDecl>(D)); -} - -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { - // <encoding> ::= <function name> <bare-function-type> - mangleName(FD); - - // Don't mangle in the type if this isn't a decl we should typically mangle. - if (!Context.shouldMangleDeclName(FD)) - return; - - // Whether the mangling of a function type includes the return type depends on - // the context and the nature of the function. The rules for deciding whether - // the return type is included are: - // - // 1. Template functions (names or types) have return types encoded, with - // the exceptions listed below. - // 2. Function types not appearing as part of a function name mangling, - // e.g. parameters, pointer types, etc., have return type encoded, with the - // exceptions listed below. |