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.

llvm-svn: 123386
This commit is contained in:
Peter Collingbourne 2011-01-13 18:57:25 +00:00
parent 018778af3d
commit 0ff0b37627
24 changed files with 1652 additions and 1481 deletions

View File

@ -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;

View File

@ -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(); }
MangleContext *createItaniumMangleContext(ASTContext &Context,
Diagnostic &Diags);
MangleContext *createMicrosoftMangleContext(ASTContext &Context,
Diagnostic &Diags);
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);
};
}
}
#endif

View File

@ -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

View File

@ -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() {}

View File

@ -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

View File

@ -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);
}

132
clang/lib/AST/Mangle.cpp Normal file
View File

@ -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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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());

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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());
}

View File

@ -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.

View File

@ -35,7 +35,6 @@ add_clang_library(clangCodeGen
CodeGenTBAA.cpp
CodeGenTypes.cpp
ItaniumCXXABI.cpp
Mangle.cpp
MicrosoftCXXABI.cpp
ModuleBuilder.cpp
TargetInfo.cpp

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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"

View File

@ -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

View File

@ -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 {

View File

@ -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);

File diff suppressed because it is too large Load Diff