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:
parent
42e8a63e4f
commit
6745522f89
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue