Extract ABI-specific parts of MangleContext into separate classes

Reviewed at http://llvm-reviews.chandlerc.com/D1807

llvm-svn: 191878
This commit is contained in:
Timur Iskhodzhanov 2013-10-03 06:26:13 +00:00
parent 42e8a63e4f
commit 6745522f89
9 changed files with 187 additions and 195 deletions

View File

@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
@ -64,18 +65,29 @@ private:
/// MangleContext - Context for tracking state which persists across multiple
/// calls to the C++ name mangler.
class MangleContext {
public:
enum ManglerKind {
MK_Itanium,
MK_Microsoft
};
private:
virtual void anchor();
ASTContext &Context;
DiagnosticsEngine &Diags;
const ManglerKind Kind;
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
public:
ManglerKind getKind() const { return Kind; }
explicit MangleContext(ASTContext &Context,
DiagnosticsEngine &Diags)
: Context(Context), Diags(Diags) { }
DiagnosticsEngine &Diags,
ManglerKind Kind)
: Context(Context), Diags(Diags), Kind(Kind) {}
virtual ~MangleContext() { }
@ -97,7 +109,9 @@ public:
/// @{
virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
// FIXME: consider replacing raw_ostream & with something like SmallString &.
virtual void mangleName(const NamedDecl *D, raw_ostream &) = 0;
virtual void mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &) = 0;
@ -106,27 +120,6 @@ public:
raw_ostream &) = 0;
virtual void mangleReferenceTemporary(const VarDecl *D,
raw_ostream &) = 0;
// FIXME: Some of these objects only exist in select ABIs. We should probably
// only declare them in ABI-specific manglers?
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &) = 0;
/// \brief Mangle vftable symbols. Only a subset of the bases along the path
/// to the vftable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &) = 0;
/// \brief Mangle vbtable symbols. Only a subset of the bases along the path
/// to the vbtable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
@ -144,35 +137,67 @@ public:
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
raw_ostream &Out);
void mangleObjCMethodName(const ObjCMethodDecl *MD,
raw_ostream &);
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
virtual void mangleStaticGuardVariable(const VarDecl *D,
raw_ostream &Out) = 0;
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) = 0;
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) = 0;
// FIXME: Revisit this once we know what we need to do for MSVC compatibility.
virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
raw_ostream &) {
llvm_unreachable("Target does not support mangling thread_local variables");
}
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &) {
llvm_unreachable("Target does not support mangling thread_local variables");
}
raw_ostream &) = 0;
/// @}
};
MangleContext *createItaniumMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags);
MangleContext *createMicrosoftMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags);
class ItaniumMangleContext : public MangleContext {
public:
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Itanium) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &) = 0;
virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
raw_ostream &) = 0;
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &) = 0;
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags);
};
class MicrosoftMangleContext : public MangleContext {
public:
explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Microsoft) {}
/// \brief Mangle vftable symbols. Only a subset of the bases along the path
/// to the vftable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
/// \brief Mangle vbtable symbols. Only a subset of the bases along the path
/// to the vbtable are included in the name. It's up to the caller to pick
/// them correctly.
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Microsoft;
}
static MicrosoftMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags);
};
}
#endif

View File

@ -7981,9 +7981,9 @@ MangleContext *ASTContext::createMangleContext() {
case TargetCXXABI::GenericItanium:
case TargetCXXABI::GenericARM:
case TargetCXXABI::iOS:
return createItaniumMangleContext(*this, getDiagnostics());
return ItaniumMangleContext::create(*this, getDiagnostics());
case TargetCXXABI::Microsoft:
return createMicrosoftMangleContext(*this, getDiagnostics());
return MicrosoftMangleContext::create(*this, getDiagnostics());
}
llvm_unreachable("Unsupported ABI");
}

View File

@ -104,16 +104,16 @@ static const NamedDecl *getStructor(const NamedDecl *decl) {
static const unsigned UnknownArity = ~0U;
class ItaniumMangleContext : public MangleContext {
class ItaniumMangleContextImpl : public ItaniumMangleContext {
llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
public:
explicit ItaniumMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags)
: MangleContext(Context, Diags) { }
explicit ItaniumMangleContextImpl(ASTContext &Context,
DiagnosticsEngine &Diags)
: ItaniumMangleContext(Context, Diags) {}
uint64_t getAnonymousStructId(const TagDecl *TD) {
std::pair<llvm::DenseMap<const TagDecl *,
@ -137,14 +137,8 @@ public:
raw_ostream &);
void mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &);
void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out);
void mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &);
void mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out);
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &);
@ -198,7 +192,7 @@ public:
/// CXXNameMangler - Manage the mangling of a single name.
class CXXNameMangler {
ItaniumMangleContext &Context;
ItaniumMangleContextImpl &Context;
raw_ostream &Out;
/// The "structor" is the top-level declaration being mangled, if
@ -254,7 +248,7 @@ class CXXNameMangler {
ASTContext &getASTContext() const { return Context.getASTContext(); }
public:
CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const NamedDecl *D = 0)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),
SeqID(0) {
@ -262,11 +256,11 @@ public:
assert(!D || (!isa<CXXDestructorDecl>(D) &&
!isa<CXXConstructorDecl>(D)));
}
CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
SeqID(0) { }
CXXNameMangler(ItaniumMangleContext &C, raw_ostream &Out_,
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const CXXDestructorDecl *D, CXXDtorType Type)
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
SeqID(0) { }
@ -390,7 +384,7 @@ private:
}
bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
bool ItaniumMangleContextImpl::shouldMangleDeclName(const NamedDecl *D) {
// In C, functions with no attributes never need to be mangled. Fastpath them.
if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
@ -3638,8 +3632,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 ItaniumMangleContext::mangleName(const NamedDecl *D,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleName(const NamedDecl *D,
raw_ostream &Out) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
"Invalid mangleName() call, argument is not a variable or function!");
assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
@ -3653,23 +3647,23 @@ void ItaniumMangleContext::mangleName(const NamedDecl *D,
return Mangler.mangle(D);
}
void ItaniumMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
CXXCtorType Type,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
CXXCtorType Type,
raw_ostream &Out) {
CXXNameMangler Mangler(*this, Out, D, Type);
Mangler.mangle(D);
}
void ItaniumMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
CXXDtorType Type,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
CXXDtorType Type,
raw_ostream &Out) {
CXXNameMangler Mangler(*this, Out, D, Type);
Mangler.mangle(D);
}
void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &Out) {
// <special-name> ::= T <call-offset> <base encoding>
// # base is the nominal target function of thunk
// <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
@ -3695,11 +3689,9 @@ void ItaniumMangleContext::mangleThunk(const CXXMethodDecl *MD,
Mangler.mangleFunctionEncoding(MD);
}
void
ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
CXXDtorType Type,
const ThisAdjustment &ThisAdjustment,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXDtorThunk(
const CXXDestructorDecl *DD, CXXDtorType Type,
const ThisAdjustment &ThisAdjustment, raw_ostream &Out) {
// <special-name> ::= T <call-offset> <base encoding>
// # base is the nominal target function of thunk
CXXNameMangler Mangler(*this, Out, DD, Type);
@ -3714,8 +3706,8 @@ ItaniumMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
/// mangleGuardVariable - Returns the mangled name for a guard variable
/// for the passed in VarDecl.
void ItaniumMangleContext::mangleStaticGuardVariable(const VarDecl *D,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleStaticGuardVariable(const VarDecl *D,
raw_ostream &Out) {
// <special-name> ::= GV <object name> # Guard variable for one-time
// # initialization
CXXNameMangler Mangler(*this, Out);
@ -3723,16 +3715,16 @@ void ItaniumMangleContext::mangleStaticGuardVariable(const VarDecl *D,
Mangler.mangleName(D);
}
void ItaniumMangleContext::mangleDynamicInitializer(const VarDecl *MD,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleDynamicInitializer(const VarDecl *MD,
raw_ostream &Out) {
// These symbols are internal in the Itanium ABI, so the names don't matter.
// Clang has traditionally used this symbol and allowed LLVM to adjust it to
// avoid duplicate symbols.
Out << "__cxx_global_var_init";
}
void ItaniumMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) {
// Prefix the mangling of D with __dtor_.
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "__dtor_";
@ -3742,24 +3734,25 @@ void ItaniumMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
Mangler.getStream() << D->getName();
}
void ItaniumMangleContext::mangleItaniumThreadLocalInit(const VarDecl *D,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleItaniumThreadLocalInit(const VarDecl *D,
raw_ostream &Out) {
// <special-name> ::= TH <object name>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTH";
Mangler.mangleName(D);
}
void ItaniumMangleContext::mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &Out) {
void
ItaniumMangleContextImpl::mangleItaniumThreadLocalWrapper(const VarDecl *D,
raw_ostream &Out) {
// <special-name> ::= TW <object name>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTW";
Mangler.mangleName(D);
}
void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleReferenceTemporary(const VarDecl *D,
raw_ostream &Out) {
// We match the GCC mangling here.
// <special-name> ::= GR <object name>
CXXNameMangler Mangler(*this, Out);
@ -3767,41 +3760,26 @@ void ItaniumMangleContext::mangleReferenceTemporary(const VarDecl *D,
Mangler.mangleName(D);
}
void ItaniumMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &Out) {
// <special-name> ::= TV <type> # virtual table
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTV";
Mangler.mangleNameOrStandardSubstitution(RD);
}
void
ItaniumMangleContext::mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) {
llvm_unreachable(
"The Itanium C++ ABI does not have vftables (use vtables instead)!");
}
void ItaniumMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &Out) {
// <special-name> ::= TT <type> # VTT structure
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTT";
Mangler.mangleNameOrStandardSubstitution(RD);
}
void
ItaniumMangleContext::mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) {
llvm_unreachable("The Itanium C++ ABI does not have virtual base tables!");
}
void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &Out) {
// <special-name> ::= TC <type> <offset number> _ <base type>
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTC";
@ -3811,8 +3789,7 @@ void ItaniumMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
Mangler.mangleNameOrStandardSubstitution(Type);
}
void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {
// <special-name> ::= TI <type> # typeinfo structure
assert(!Ty.hasQualifiers() && "RTTI info cannot have top-level qualifiers");
CXXNameMangler Mangler(*this, Out);
@ -3820,15 +3797,15 @@ void ItaniumMangleContext::mangleCXXRTTI(QualType Ty,
Mangler.mangleType(Ty);
}
void ItaniumMangleContext::mangleCXXRTTIName(QualType Ty,
raw_ostream &Out) {
void ItaniumMangleContextImpl::mangleCXXRTTIName(QualType Ty,
raw_ostream &Out) {
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
CXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "_ZTS";
Mangler.mangleType(Ty);
}
MangleContext *clang::createItaniumMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags) {
return new ItaniumMangleContext(Context, Diags);
ItaniumMangleContext *
ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new ItaniumMangleContextImpl(Context, Diags);
}

View File

@ -172,12 +172,12 @@ private:
void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA);
};
/// MicrosoftMangleContext - Overrides the default MangleContext for the
/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
/// Microsoft Visual C++ ABI.
class MicrosoftMangleContext : public MangleContext {
class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
public:
MicrosoftMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags) : MangleContext(Context, Diags) { }
MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
: MicrosoftMangleContext(Context, Diags) {}
virtual bool shouldMangleDeclName(const NamedDecl *D);
virtual void mangleName(const NamedDecl *D, raw_ostream &Out);
virtual void mangleThunk(const CXXMethodDecl *MD,
@ -186,19 +186,12 @@ public:
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
const ThisAdjustment &ThisAdjustment,
raw_ostream &);
virtual void mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &);
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out);
virtual void mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &);
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out);
virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &);
virtual void mangleCXXRTTI(QualType T, raw_ostream &);
virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
@ -217,7 +210,7 @@ private:
}
bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
bool MicrosoftMangleContextImpl::shouldMangleDeclName(const NamedDecl *D) {
// In C, functions with no attributes never need to be mangled. Fastpath them.
if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
@ -1854,8 +1847,8 @@ void MicrosoftCXXNameMangler::mangleType(const AtomicType *T,
<< Range;
}
void MicrosoftMangleContext::mangleName(const NamedDecl *D,
raw_ostream &Out) {
void MicrosoftMangleContextImpl::mangleName(const NamedDecl *D,
raw_ostream &Out) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
"Invalid mangleName() call, argument is not a variable or function!");
assert(!isa<CXXConstructorDecl>(D) && !isa<CXXDestructorDecl>(D) &&
@ -1869,9 +1862,9 @@ void MicrosoftMangleContext::mangleName(const NamedDecl *D,
return Mangler.mangle(D);
}
void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &Out) {
void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &Out) {
// FIXME: this is not yet a complete implementation, but merely a
// reasonably-working stub to avoid crashing when required to emit a thunk.
MicrosoftCXXNameMangler Mangler(*this, Out);
@ -1892,22 +1885,16 @@ void MicrosoftMangleContext::mangleThunk(const CXXMethodDecl *MD,
Mangler.mangleFunctionType(MD->getType()->castAs<FunctionProtoType>(), MD, false, true);
}
void MicrosoftMangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
CXXDtorType Type,
const ThisAdjustment &,
raw_ostream &) {
void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,
CXXDtorType Type,
const ThisAdjustment &,
raw_ostream &) {
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle thunk for this destructor yet");
getDiags().Report(DD->getLocation(), DiagID);
}
void MicrosoftMangleContext::mangleCXXVTable(const CXXRecordDecl *RD,
raw_ostream &Out) {
llvm_unreachable(
"The Microsoft C++ ABI does not have vtables (use vftables instead)!");
}
void MicrosoftMangleContext::mangleCXXVFTable(
void MicrosoftMangleContextImpl::mangleCXXVFTable(
const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) {
// <mangled-name> ::= ?_7 <class-name> <storage-class>
@ -1926,7 +1913,7 @@ void MicrosoftMangleContext::mangleCXXVFTable(
Mangler.getStream() << '@';
}
void MicrosoftMangleContext::mangleCXXVBTable(
void MicrosoftMangleContextImpl::mangleCXXVBTable(
const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) {
// <mangled-name> ::= ?_8 <class-name> <storage-class>
@ -1945,53 +1932,45 @@ void MicrosoftMangleContext::mangleCXXVBTable(
Mangler.getStream() << '@';
}
void MicrosoftMangleContext::mangleCXXVTT(const CXXRecordDecl *RD,
raw_ostream &) {
llvm_unreachable("The MS C++ ABI does not have virtual table tables!");
}
void MicrosoftMangleContext::mangleCXXCtorVTable(const CXXRecordDecl *RD,
int64_t Offset,
const CXXRecordDecl *Type,
raw_ostream &) {
llvm_unreachable("The MS C++ ABI does not have constructor vtables!");
}
void MicrosoftMangleContext::mangleCXXRTTI(QualType T,
raw_ostream &) {
void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &) {
// FIXME: Give a location...
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle RTTI descriptors for type %0 yet");
getDiags().Report(DiagID)
<< T.getBaseTypeIdentifier();
}
void MicrosoftMangleContext::mangleCXXRTTIName(QualType T,
raw_ostream &) {
void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, raw_ostream &) {
// FIXME: Give a location...
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle the name of type %0 into RTTI descriptors yet");
getDiags().Report(DiagID)
<< T.getBaseTypeIdentifier();
}
void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D,
CXXCtorType Type,
raw_ostream & Out) {
void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
CXXCtorType Type,
raw_ostream &Out) {
MicrosoftCXXNameMangler mangler(*this, Out);
mangler.mangle(D);
}
void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D,
CXXDtorType Type,
raw_ostream & Out) {
void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D,
CXXDtorType Type,
raw_ostream &Out) {
MicrosoftCXXNameMangler mangler(*this, Out, D, Type);
mangler.mangle(D);
}
void MicrosoftMangleContext::mangleReferenceTemporary(const VarDecl *VD,
raw_ostream &) {
void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
raw_ostream &) {
unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
"cannot mangle this reference temporary yet");
getDiags().Report(VD->getLocation(), DiagID);
}
void MicrosoftMangleContext::mangleStaticGuardVariable(const VarDecl *VD,
raw_ostream &Out) {
void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
raw_ostream &Out) {
// <guard-name> ::= ?_B <postfix> @51
// ::= ?$S <guard-num> @ <postfix> @4IA
@ -2010,9 +1989,9 @@ void MicrosoftMangleContext::mangleStaticGuardVariable(const VarDecl *VD,
Mangler.getStream() << (Visible ? "@51" : "@4IA");
}
void MicrosoftMangleContext::mangleInitFiniStub(const VarDecl *D,
raw_ostream &Out,
char CharCode) {
void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
raw_ostream &Out,
char CharCode) {
MicrosoftCXXNameMangler Mangler(*this, Out);
Mangler.getStream() << "\01??__" << CharCode;
Mangler.mangleName(D);
@ -2021,19 +2000,20 @@ void MicrosoftMangleContext::mangleInitFiniStub(const VarDecl *D,
Mangler.getStream() << "YAXXZ";
}
void MicrosoftMangleContext::mangleDynamicInitializer(const VarDecl *D,
raw_ostream &Out) {
void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,
raw_ostream &Out) {
// <initializer-name> ::= ?__E <name> YAXXZ
mangleInitFiniStub(D, Out, 'E');
}
void MicrosoftMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) {
void
MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) {
// <destructor-name> ::= ?__F <name> YAXXZ
mangleInitFiniStub(D, Out, 'F');
}
MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags) {
return new MicrosoftMangleContext(Context, Diags);
MicrosoftMangleContext *
MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
return new MicrosoftMangleContextImpl(Context, Diags);
}

View File

@ -102,7 +102,8 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
CGM.getCXXABI().getMangleContext().mangleCXXVTT(RD, Out);
cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
.mangleCXXVTT(RD, Out);
Out.flush();
StringRef Name = OutName.str();

View File

@ -650,9 +650,9 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Get the mangled construction vtable name.
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
CGM.getCXXABI().getMangleContext().
mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(), Base.getBase(),
Out);
cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
.mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),
Base.getBase(), Out);
Out.flush();
StringRef Name = OutName.str();

View File

@ -41,6 +41,10 @@ protected:
bool UseARMMethodPtrABI;
bool UseARMGuardVarABI;
ItaniumMangleContext &getMangleContext() {
return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());
}
public:
ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
bool UseARMMethodPtrABI = false,
@ -997,7 +1001,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
CGM.getCXXABI().getMangleContext().mangleCXXVTable(RD, Out);
getMangleContext().mangleCXXVTable(RD, Out);
Out.flush();
StringRef Name = OutName.str();

View File

@ -215,6 +215,10 @@ public:
CharUnits cookieSize);
private:
MicrosoftMangleContext &getMangleContext() {
return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext());
}
llvm::Constant *getZeroInt() {
return llvm::ConstantInt::get(CGM.IntTy, 0);
}
@ -678,11 +682,11 @@ llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
return VTableAddressPoint;
}
static void mangleVFTableName(CodeGenModule &CGM, const CXXRecordDecl *RD,
const VFPtrInfo &VFPtr, SmallString<256> &Name) {
static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
const CXXRecordDecl *RD, const VFPtrInfo &VFPtr,
SmallString<256> &Name) {
llvm::raw_svector_ostream Out(Name);
CGM.getCXXABI().getMangleContext().mangleCXXVFTable(
RD, VFPtr.PathToMangle, Out);
MangleContext.mangleCXXVFTable(RD, VFPtr.PathToMangle, Out);
}
llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
@ -722,7 +726,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
llvm::StringSet<> ObservedMangledNames;
for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
SmallString<256> Name;
mangleVFTableName(CGM, RD, VFPtrs[J], Name);
mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name);
if (!ObservedMangledNames.insert(Name.str()))
llvm_unreachable("Already saw this mangling before?");
}
@ -739,7 +743,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
.getNumVTableComponents());
SmallString<256> Name;
mangleVFTableName(CGM, RD, VFPtrs[J], Name);
mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name);
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage);
VTable->setUnnamedAddr(true);

View File

@ -170,7 +170,8 @@ VBTableBuilder::getAddrOfVBTable(const CXXRecordDecl *ReusingBase,
SmallString<256> OutName;
llvm::raw_svector_ostream Out(OutName);
MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
MicrosoftMangleContext &Mangler =
cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext());
Mangler.mangleCXXVBTable(MostDerived, BasePath, Out);
Out.flush();
StringRef Name = OutName.str();