#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 {
/// 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() { }
/// @{
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;
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,
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;
+ raw_ostream &) = 0;
+
+ /// @}
+};
- // FIXME: Revisit this once we know what we need to do for MSVC compatibility.
+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 &) {
- llvm_unreachable("Target does not support mangling thread_local variables");
- }
+ raw_ostream &) = 0;
virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
- raw_ostream &) {
- llvm_unreachable("Target does not support mangling thread_local variables");
+ raw_ostream &) = 0;
+
+ static bool classof(const MangleContext *C) {
+ return C->getKind() == MK_Itanium;
}
- /// @}
+ static ItaniumMangleContext *create(ASTContext &Context,
+ DiagnosticsEngine &Diags);
};
-MangleContext *createItaniumMangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags);
-MangleContext *createMicrosoftMangleContext(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
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");
}
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 *,
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 &);
/// 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
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) {
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) { }
}
-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;
/// 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) &&
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>
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);
/// 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);
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_";
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);
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";
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);
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);
}
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,
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,
}
-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;
<< 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) &&
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);
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>
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>
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
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);
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);
}
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();
// 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();
bool UseARMMethodPtrABI;
bool UseARMGuardVarABI;
+ ItaniumMangleContext &getMangleContext() {
+ return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());
+ }
+
public:
ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
bool UseARMMethodPtrABI = false,
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();
CharUnits cookieSize);
private:
+ MicrosoftMangleContext &getMangleContext() {
+ return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext());
+ }
+
llvm::Constant *getZeroInt() {
return llvm::ConstantInt::get(CGM.IntTy, 0);
}
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(
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?");
}
.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);
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();