aboutsummaryrefslogtreecommitdiff
path: root/lib
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 /lib
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
Diffstat (limited to 'lib')
-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/Mangle.h179
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp1158
22 files changed, 1485 insertions, 1593 deletions
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 Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements generic name mangling support for blocks and Objective-C.
+//
+//===----------------------------------------------------------------------===//
+#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"
+
+#define MANGLE_CHECKER 0
+
+#if MANGLE_CHECKER
+#include <cxxabi.h>
+#endif
+
+using namespace clang;
+
+// FIXME: For blocks we currently mimic GCC's mangling scheme, which leaves
+// much to be desired. Come up with a better mangling scheme.
+
+namespace {
+
+static void mangleFunctionBlock(MangleContext &Context,
+ llvm::StringRef Outer,
+ const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ llvm::raw_svector_ostream Out(Res);
+ Out << "__" << Outer << "_block_invoke_" << Context.getBlockId(BD, true);
+}
+
+static void checkMangleDC(const DeclContext *DC, const BlockDecl *BD) {
+#ifndef NDEBUG
+ const DeclContext *ExpectedDC = BD->getDeclContext();
+ while (isa<BlockDecl>(ExpectedDC) || isa<EnumDecl>(ExpectedDC))
+ ExpectedDC = ExpectedDC->getParent();
+ assert(DC == ExpectedDC && "Given decl context did not match expected!");
+#endif
+}
+
+}
+
+void MangleContext::mangleGlobalBlock(const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ llvm::raw_svector_ostream Out(Res);
+ Out << "__block_global_" << getBlockId(BD, false);
+}
+
+void MangleContext::mangleCtorBlock(const CXXConstructorDecl *CD,
+ CXXCtorType CT, const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ checkMangleDC(CD, BD);
+ llvm::SmallString<64> Buffer;
+ mangleCXXCtor(CD, CT, Buffer);
+ mangleFunctionBlock(*this, Buffer, BD, Res);
+}
+
+void MangleContext::mangleDtorBlock(const CXXDestructorDecl *DD,
+ CXXDtorType DT, const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ checkMangleDC(DD, BD);
+ llvm::SmallString<64> Buffer;
+ mangleCXXDtor(DD, DT, Buffer);
+ mangleFunctionBlock(*this, Buffer, BD, Res);
+}
+
+void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ assert(!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC));
+ checkMangleDC(DC, BD);
+
+ llvm::SmallString<64> Buffer;
+ if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
+ mangleObjCMethodName(Method, Buffer);
+ } else {
+ const NamedDecl *ND = cast<NamedDecl>(DC);
+ if (IdentifierInfo *II = ND->getIdentifier())
+ Buffer = II->getName();
+ 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?
+ mangleName(ND, Buffer);
+ }
+ }
+
+ mangleFunctionBlock(*this, Buffer, BD, Res);
+}
+
+void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
+ llvm::SmallVectorImpl<char> &Res) {
+ llvm::SmallString<64> Name;
+ llvm::raw_svector_ostream OS(Name), Out(Res);
+
+ 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();
+}
+
+void MangleContext::mangleBlock(const BlockDecl *BD,
+ llvm::SmallVectorImpl<char> &Res) {
+ const DeclContext *DC = BD->getDeclContext();
+ while (isa<BlockDecl>(DC) || isa<EnumDecl>(DC))
+ DC = DC->getParent();
+ if (DC->isFunctionOrMethod())
+ mangleBlock(DC, BD, Res);
+ else
+ mangleGlobalBlock(BD, Res);
+}
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
new file mode 100644
index 0000000000..ef50899e43
--- /dev/null
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -0,0 +1,1184 @@
+//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides C++ name mangling targetting the Microsoft Visual C++ ABI.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/Mangle.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/CharUnits.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"
+
+using namespace clang;
+
+namespace {
+
+/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftCXXNameMangler {
+ MangleContext &Context;
+ llvm::raw_svector_ostream Out;
+
+ ASTContext &getASTContext() const { return Context.getASTContext(); }
+
+public:
+ MicrosoftCXXNameMangler(MangleContext &C, llvm::SmallVectorImpl<char> &Res)
+ : Context(C), Out(Res) { }
+
+ void mangle(const NamedDecl *D, llvm::StringRef Prefix = "?");
+ void mangleName(const NamedDecl *ND);
+ void mangleFunctionEncoding(const FunctionDecl *FD);
+ void mangleVariableEncoding(const VarDecl *VD);
+ void mangleNumber(int64_t Number);
+ void mangleType(QualType T);
+
+private:
+ void mangleUnqualifiedName(const NamedDecl *ND) {
+ mangleUnqualifiedName(ND, ND->getDeclName());
+ }
+ void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
+ void mangleSourceName(const IdentifierInfo *II);
+ void manglePostfix(const DeclContext *DC, bool NoFunction=false);
+ void mangleOperatorName(OverloadedOperatorKind OO);
+ void mangleQualifiers(Qualifiers Quals, bool IsMember);
+
+ 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(const FunctionType *T, const FunctionDecl *D,
+ bool IsStructor, bool IsInstMethod);
+ void mangleType(const ArrayType *T, bool IsGlobal);
+ void mangleExtraDimensions(QualType T);
+ void mangleFunctionClass(const FunctionDecl *FD);
+ void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);
+ void mangleThrowSpecification(const FunctionProtoType *T);
+
+};
+
+/// MicrosoftMangleContext - Overrides the default MangleContext for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftMangleContext : public MangleContext {
+public:
+ MicrosoftMangleContext(ASTContext &Context,
+ Diagnostic &Diags) : MangleContext(Context, Diags) { }
+ virtual bool shouldMangleDeclName(const NamedDecl *D);
+ virtual void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
+ virtual void mangleThunk(const CXXMethodDecl *MD,
+ const ThunkInfo &Thunk,
+ llvm::SmallVectorImpl<char> &);
+ virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+ const ThisAdjustment &ThisAdjustment,
+ llvm::SmallVectorImpl<char> &);
+ virtual void mangleCXXVTable(const CXXRecordDecl *RD,
+ llvm::SmallVectorImpl<char> &);
+ virtual void mangleCXXVTT(const CXXRecordDecl *RD,
+ llvm::SmallVectorImpl<char> &);
+ 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> &);
+ virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+ llvm::SmallVectorImpl<char> &);
+ virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+ llvm::SmallVectorImpl<char> &);
+ virtual void mangleReferenceTemporary(const clang::VarDecl *,
+ llvm::SmallVectorImpl<char> &);
+};
+
+}
+
+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 MicrosoftMangleContext::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 internal linkage are not mangled.
+ if (!FD) {
+ const DeclContext *DC = D->getDeclContext();
+ if (DC->isTranslationUnit() && D->getLinkage() == InternalLinkage)
+ return false;
+ }
+
+ // C functions and "main" are not mangled.
+ if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
+ return false;
+
+ return true;
+}
+
+void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
+ llvm::StringRef Prefix) {
+ // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
+ // Therefore it's really important that we don't decorate the
+ // name with leading underscores or leading/trailing at signs. So, emit a
+ // asm marker at the start so we get the name right.
+ Out << '\01'; // LLVM IR Marker for __asm("foo")
+
+ // 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 << ALA->getLabel();
+ return;
+ }
+
+ // <mangled-name> ::= ? <name> <type-encoding>
+ Out << Prefix;
+ mangleName(D);
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ mangleFunctionEncoding(FD);
+ else if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+ mangleVariableEncoding(VD);
+ // TODO: Fields? Can MSVC even mangle them?
+}
+
+void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
+ // <type-encoding> ::= <function-class> <function-type>
+
+ // Don't mangle in the type if this isn't a decl we should typically mangle.
+ if (!Context.shouldMangleDeclName(FD))
+ return;
+
+ // We should never ever see a FunctionNoProtoType at this p