diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2011-01-13 18:57:25 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-01-13 18:57:25 +0000 |
commit | 14110477887e3dc168ffc6c191e72d705051f99e (patch) | |
tree | dbb92d800ccd0adbb96c1d29c6d277c432648c11 | |
parent | c421f546e63b2f85caa1ca0d94d508f99bb871cb (diff) |
Move name mangling support from CodeGen to AST. In the
process, perform a number of refactorings:
- Move MiscNameMangler member functions to MangleContext
- Remove GlobalDecl dependency from MangleContext
- Make MangleContext abstract and move Itanium/Microsoft functionality
to their own classes/files
- Implement ASTContext::createMangleContext and have CodeGen use it
No (intended) functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123386 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 3 | ||||
-rw-r--r-- | include/clang/AST/Mangle.h (renamed from lib/CodeGen/Mangle.h) | 105 | ||||
-rw-r--r-- | include/clang/Basic/ABI.h | 126 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 13 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp (renamed from lib/CodeGen/Mangle.cpp) | 218 | ||||
-rw-r--r-- | lib/AST/Mangle.cpp | 132 | ||||
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 1184 | ||||
-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/MicrosoftCXXABI.cpp | 1158 |
24 files changed, 1652 insertions, 1481 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index e97f96972d..a0544ef8bd 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -57,6 +57,7 @@ namespace clang { class CXXRecordDecl; class Decl; class FieldDecl; + class MangleContext; class ObjCIvarDecl; class ObjCIvarRefExpr; class ObjCPropertyDecl; @@ -1058,6 +1059,8 @@ public: bool isNearlyEmpty(const CXXRecordDecl *RD) const; + MangleContext *createMangleContext(); + void ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI, llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) const; diff --git a/lib/CodeGen/Mangle.h b/include/clang/AST/Mangle.h index 402a9b8cc3..8dbca8daed 100644 --- a/lib/CodeGen/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -7,20 +7,15 @@ // //===----------------------------------------------------------------------===// // -// 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 +// Defines the C++ name mangling interface. // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_CODEGEN_MANGLE_H -#define LLVM_CLANG_CODEGEN_MANGLE_H +#ifndef LLVM_CLANG_AST_MANGLE_H +#define LLVM_CLANG_AST_MANGLE_H -#include "CGCXX.h" -#include "GlobalDecl.h" #include "clang/AST/Type.h" +#include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" @@ -36,8 +31,6 @@ namespace clang { class NamedDecl; class ObjCMethodDecl; class VarDecl; - -namespace CodeGen { struct ThisAdjustment; struct ThunkInfo; @@ -74,9 +67,6 @@ class MangleContext { ASTContext &Context; Diagnostic &Diags; - llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds; - unsigned Discriminator; - llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; @@ -91,15 +81,8 @@ public: Diagnostic &getDiags() const { return Diags; } - void startNewFunction() { LocalBlockIds.clear(); } + virtual void startNewFunction() { LocalBlockIds.clear(); } - uint64_t getAnonymousStructId(const TagDecl *TD) { - std::pair<llvm::DenseMap<const TagDecl *, - uint64_t>::iterator, bool> Result = - AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size())); - return Result.first->second; - } - unsigned getBlockId(const BlockDecl *BD, bool Local) { llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds = Local? LocalBlockIds : GlobalBlockIds; @@ -111,69 +94,57 @@ public: /// @name Mangler Entry Points /// @{ - virtual bool shouldMangleDeclName(const NamedDecl *D); - virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &); + virtual bool shouldMangleDeclName(const NamedDecl *D) = 0; + virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &)=0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, const ThisAdjustment &ThisAdjustment, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXVTable(const CXXRecordDecl *RD, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXVTT(const CXXRecordDecl *RD, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, - llvm::SmallVectorImpl<char> &); - virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &); - virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; + virtual void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &) = 0; + virtual void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - llvm::SmallVectorImpl<char> &); - void mangleBlock(GlobalDecl GD, - const BlockDecl *BD, llvm::SmallVectorImpl<char> &); + llvm::SmallVectorImpl<char> &) = 0; + + void mangleGlobalBlock(const BlockDecl *BD, + llvm::SmallVectorImpl<char> &Res); + void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, + const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res); + void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, + const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res); + void mangleBlock(const DeclContext *DC, const BlockDecl *BD, + llvm::SmallVectorImpl<char> &Res); + // Do the right thing. + void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &Res); + + void mangleObjCMethodName(const ObjCMethodDecl *MD, + llvm::SmallVectorImpl<char> &); // This is pretty lame. - void mangleItaniumGuardVariable(const VarDecl *D, - llvm::SmallVectorImpl<char> &); - - void mangleInitDiscriminator() { - Discriminator = 0; - } - - bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { - unsigned &discriminator = Uniquifier[ND]; - if (!discriminator) - discriminator = ++Discriminator; - if (discriminator == 1) - return false; - disc = discriminator-2; - return true; + virtual void mangleItaniumGuardVariable(const VarDecl *D, + llvm::SmallVectorImpl<char> &) { + assert(0 && "Target does not support mangling guard variables"); } /// @} }; -/// MiscNameMangler - Mangles Objective-C method names and blocks. -class MiscNameMangler { - MangleContext &Context; - llvm::raw_svector_ostream Out; - - ASTContext &getASTContext() const { return Context.getASTContext(); } - -public: - MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res); - - llvm::raw_svector_ostream &getStream() { return Out; } - - void mangleBlock(GlobalDecl GD, const BlockDecl *BD); - void mangleObjCMethodName(const ObjCMethodDecl *MD); -}; +MangleContext *createItaniumMangleContext(ASTContext &Context, + Diagnostic &Diags); +MangleContext *createMicrosoftMangleContext(ASTContext &Context, + Diagnostic &Diags); } -} #endif diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h new file mode 100644 index 0000000000..2a05958496 --- /dev/null +++ b/include/clang/Basic/ABI.h @@ -0,0 +1,126 @@ +//===----- ABI.h - ABI related declarations ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These enums/classes describe ABI related information about constructors, +// destructors and thunks. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_BASIC_ABI_H +#define CLANG_BASIC_ABI_H + +#include <stdint.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 +}; + +/// 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(); } +}; + +} // end namespace clang + +#endif // CLANG_BASIC_ABI_H diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 05e1973e61..3abfe22caa 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -22,6 +22,7 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/RecordLayout.h" +#include "clang/AST/Mangle.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -5835,4 +5836,16 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const { return ABI->isNearlyEmpty(RD); } +MangleContext *ASTContext::createMangleContext() { + switch (Target.getCXXABI()) { + case CXXABI_ARM: + case CXXABI_Itanium: + return createItaniumMangleContext(*this, getDiagnostics()); + case CXXABI_Microsoft: + return createMicrosoftMangleContext(*this, getDiagnostics()); + } + assert(0 && "Unsupported ABI"); + return 0; +} + CXXABI::~CXXABI() {} diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index e98a89646c..b49b89ed88 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -26,7 +26,10 @@ add_clang_library(clangAST ExprCXX.cpp InheritViz.cpp ItaniumCXXABI.cpp + ItaniumMangle.cpp + Mangle.cpp MicrosoftCXXABI.cpp + MicrosoftMangle.cpp NestedNameSpecifier.cpp ParentMap.cpp RecordLayout.cpp diff --git a/lib/CodeGen/Mangle.cpp b/lib/AST/ItaniumMangle.cpp index b8ae1e7e41..8daba88ea8 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1,4 +1,4 @@ -//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===// +//===--- ItaniumMangle.cpp - Itanium C++ Name Mangling ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,18 +14,18 @@ // http://www.codesourcery.com/public/cxx-abi/abi.html // //===----------------------------------------------------------------------===// -#include "Mangle.h" +#include "clang/AST/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/ABI.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 @@ -34,68 +34,6 @@ #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 { @@ -127,9 +65,77 @@ static const CXXMethodDecl *getStructor(const CXXMethodDecl *MD) { static const unsigned UnknownArity = ~0U; +class ItaniumMangleContext : public MangleContext { + llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds; + unsigned Discriminator; + llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier; + +public: + explicit ItaniumMangleContext(ASTContext &Context, + Diagnostic &Diags) + : MangleContext(Context, Diags) { } + + uint64_t getAnonymousStructId(const TagDecl *TD) { + std::pair<llvm::DenseMap<const TagDecl *, + uint64_t>::iterator, bool> Result = + AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size())); + return Result.first->second; + } + + void startNewFunction() { + MangleContext::startNewFunction(); + mangleInitDiscriminator(); + } + + /// @name Mangler Entry Points + /// @{ + + bool shouldMangleDeclName(const NamedDecl *D); + void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &); + void mangleThunk(const CXXMethodDecl *MD, + const ThunkInfo &Thunk, + llvm::SmallVectorImpl<char> &); + void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, + const ThisAdjustment &ThisAdjustment, + llvm::SmallVectorImpl<char> &); + void mangleReferenceTemporary(const VarDecl *D, + llvm::SmallVectorImpl<char> &); + void mangleCXXVTable(const CXXRecordDecl *RD, + llvm::SmallVectorImpl<char> &); + void mangleCXXVTT(const CXXRecordDecl *RD, + llvm::SmallVectorImpl<char> &); + void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, + const CXXRecordDecl *Type, + llvm::SmallVectorImpl<char> &); + void mangleCXXRTTI(QualType T, llvm::SmallVectorImpl<char> &); + void mangleCXXRTTIName(QualType T, llvm::SmallVectorImpl<char> &); + void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, + llvm::SmallVectorImpl<char> &); + void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, + llvm::SmallVectorImpl<char> &); + + void mangleItaniumGuardVariable(const VarDecl *D, + llvm::SmallVectorImpl<char> &); + + void mangleInitDiscriminator() { + Discriminator = 0; + } + + bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) { + unsigned &discriminator = Uniquifier[ND]; + if (!discriminator) + discriminator = ++Discriminator; + if (discriminator == 1) + return false; + disc = discriminator-2; + return true; + } + /// @} +}; + /// CXXNameMangler - Manage the mangling of a single name. class CXXNameMangler { - MangleContext &Context; + ItaniumMangleContext &Context; llvm::raw_svector_ostream Out; const CXXMethodDecl *Structor; @@ -143,13 +149,13 @@ class CXXNameMangler { ASTContext &getASTContext() const { return Context.getASTContext(); } public: - CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res) + CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res) : Context(C), Out(Res), Structor(0), StructorType(0), SeqID(0) { } - CXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res, + CXXNameMangler(ItaniumMangleContext &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, + CXXNameMangler(ItaniumMangleContext &C, llvm::SmallVectorImpl<char> &Res, const CXXDestructorDecl *D, CXXDtorType Type) : Context(C), Out(Res), Structor(getStructor(D)), StructorType(Type), SeqID(0) { } @@ -259,6 +265,7 @@ private: void mangleTemplateParameter(unsigned Index); }; + } static bool isInCLinkageSpecification(const Decl *D) { @@ -272,7 +279,7 @@ static bool isInCLinkageSpecification(const Decl *D) { return false; } -bool MangleContext::shouldMangleDeclName(const NamedDecl *D) { +bool ItaniumMangleContext::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; @@ -896,7 +903,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(GlobalDecl(), Block, Name); + Context.mangleBlock(Block, Name); Out << Name.size() << Name; return; } @@ -1150,7 +1157,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) { void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { llvm::SmallString<64> Buffer; - MiscNameMangler(Context, Buffer).mangleObjCMethodName(MD); + Context.mangleObjCMethodName(MD, Buffer); Out << Buffer; } @@ -2470,8 +2477,8 @@ void CXXNameMangler::addSubstitution(uintptr_t Ptr) { /// and this routine will return false. In this case, the caller should just /// emit the identifier of the declaration (\c D->getIdentifier()) as its /// name. -void MangleContext::mangleName(const NamedDecl *D, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleName(const NamedDecl *D, + llvm::SmallVectorImpl<char> &Res) { assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) && "Invalid mangleName() call, argument is not a variable or function!"); assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) && @@ -2485,27 +2492,23 @@ void MangleContext::mangleName(const NamedDecl *D, return Mangler.mangle(D); } -void MangleContext::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D, + CXXCtorType Type, + llvm::SmallVectorImpl<char> &Res) { CXXNameMangler Mangler(*this, Res, D, Type); Mangler.mangle(D); } -void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D, + CXXDtorType Type, + llvm::SmallVectorImpl<char> &Res) { CXXNameMangler Mangler(*this, Res, D, Type); Mangler.mangle(D); } -void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD, - llvm::SmallVectorImpl<char> &Res) { - MiscNameMangler Mangler(*this, Res); - Mangler.mangleBlock(GD, BD); -} - -void MangleContext::mangleThunk(const CXXMethodDecl *MD, - const ThunkInfo &Thunk, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD, + const ThunkInfo &Thunk, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= T <call-offset> <base encoding> // # base is the nominal target function of thunk // <special-name> ::= Tc <call-offset> <call-offset> <base encoding> @@ -2533,9 +2536,10 @@ void MangleContext::mangleThunk(const CXXMethodDecl *MD, } void -MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, - const ThisAdjustment &ThisAdjustment, - llvm::SmallVectorImpl<char> &Res) { +ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, + CXXDtorType Type, + const ThisAdjustment &ThisAdjustment, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= T <call-offset> <base encoding> // # base is the nominal target function of thunk @@ -2551,8 +2555,8 @@ MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, /// mangleGuardVariable - Returns the mangled name for a guard variable /// for the passed in VarDecl. -void MangleContext::mangleItaniumGuardVariable(const VarDecl *D, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleItaniumGuardVariable(const VarDecl *D, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= GV <object name> # Guard variable for one-time // # initialization CXXNameMangler Mangler(*this, Res); @@ -2560,7 +2564,7 @@ void MangleContext::mangleItaniumGuardVariable(const VarDecl *D, Mangler.mangleName(D); } -void MangleContext::mangleReferenceTemporary(const VarDecl *D, +void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D, llvm::SmallVectorImpl<char> &Res) { // We match the GCC mangling here. // <special-name> ::= GR <object name> @@ -2569,25 +2573,26 @@ void MangleContext::mangleReferenceTemporary(const VarDecl *D, Mangler.mangleName(D); } -void MangleContext::mangleCXXVTable(const CXXRecordDecl *RD, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= TV <type> # virtual table CXXNameMangler Mangler(*this, Res); Mangler.getStream() << "_ZTV"; Mangler.mangleNameOrStandardSubstitution(RD); } -void MangleContext::mangleCXXVTT(const CXXRecordDecl *RD, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= TT <type> # VTT structure CXXNameMangler Mangler(*this, Res); Mangler.getStream() << "_ZTT"; Mangler.mangleNameOrStandardSubstitution(RD); } -void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, - const CXXRecordDecl *Type, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, + int64_t Offset, + const CXXRecordDecl *Type, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= TC <type> <offset number> _ <base type> CXXNameMangler Mangler(*this, Res); Mangler.getStream() << "_ZTC"; @@ -2597,8 +2602,8 @@ void MangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, Mangler.mangleNameOrStandardSubstitution(Type); } -void MangleContext::mangleCXXRTTI(QualType Ty, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXRTTI(QualType Ty, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= TI <type> # typeinfo structure assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers"); CXXNameMangler Mangler(*this, Res); @@ -2606,10 +2611,15 @@ void MangleContext::mangleCXXRTTI(QualType Ty, Mangler.mangleType(Ty); } -void MangleContext::mangleCXXRTTIName(QualType Ty, - llvm::SmallVectorImpl<char> &Res) { +void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty, + llvm::SmallVectorImpl<char> &Res) { // <special-name> ::= TS <type> # typeinfo name (null terminated byte string) CXXNameMangler Mangler(*this, Res); Mangler.getStream() << "_ZTS"; Mangler.mangleType(Ty); } + +MangleContext *clang::createItaniumMangleContext(ASTContext &Context, + Diagnostic &Diags) { + return new ItaniumMangleContext(Context, Diags); +} diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp new file mode 100644 index 0000000000..83d9ed6678 --- /dev/null +++ b/lib/AST/Mangle.cpp @@ -0,0 +1,132 @@ +//===--- Mangle.cpp - Mangle C++ Names --------------------------*- C++ -*-===// +// +// The LLVM Compiler In |