aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2011-01-13 18:57:25 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2011-01-13 18:57:25 +0000
commit14110477887e3dc168ffc6c191e72d705051f99e (patch)
treedbb92d800ccd0adbb96c1d29c6d277c432648c11
parentc421f546e63b2f85caa1ca0d94d508f99bb871cb (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.h3
-rw-r--r--include/clang/AST/Mangle.h (renamed from lib/CodeGen/Mangle.h)105
-rw-r--r--include/clang/Basic/ABI.h126
-rw-r--r--lib/AST/ASTContext.cpp13
-rw-r--r--lib/AST/CMakeLists.txt3
-rw-r--r--lib/AST/ItaniumMangle.cpp (renamed from lib/CodeGen/Mangle.cpp)218
-rw-r--r--lib/AST/Mangle.cpp132
-rw-r--r--lib/AST/MicrosoftMangle.cpp1184
-rw-r--r--lib/CodeGen/CGBlocks.cpp2
-rw-r--r--lib/CodeGen/CGCXX.cpp2
-rw-r--r--lib/CodeGen/CGCXX.h36
-rw-r--r--lib/CodeGen/CGCXXABI.h10
-rw-r--r--lib/CodeGen/CGDecl.cpp2
-rw-r--r--lib/CodeGen/CGObjC.cpp2
-rw-r--r--lib/CodeGen/CGVTables.h89
-rw-r--r--lib/CodeGen/CMakeLists.txt1
-rw-r--r--lib/CodeGen/CodeGenFunction.h2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp20
-rw-r--r--lib/CodeGen/CodeGenModule.h9
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp2
-rw-r--r--lib/CodeGen/CodeGenTBAA.h2
-rw-r--r--lib/CodeGen/GlobalDecl.h2
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp10
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp1158
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