#ifndef LLVM_CLANG_AST_MANGLE_H
#define LLVM_CLANG_AST_MANGLE_H
#include "clang/AST/Decl.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/ABI.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Casting.h"
namespace llvm {
class raw_ostream;
}
namespace clang {
class ASTContext;
class BlockDecl;
class CXXConstructorDecl;
class CXXDestructorDecl;
class CXXMethodDecl;
class FunctionDecl;
struct MethodVFTableLocation;
class NamedDecl;
class ObjCMethodDecl;
class StringLiteral;
struct ThisAdjustment;
struct ThunkInfo;
class VarDecl;
class MangleContext {
public:
enum ManglerKind {
MK_Itanium,
MK_Microsoft
};
private:
virtual void anchor();
ASTContext &Context;
DiagnosticsEngine &Diags;
const ManglerKind Kind;
bool IsAux = false;
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
public:
ManglerKind getKind() const { return Kind; }
bool isAux() const { return IsAux; }
explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
ManglerKind Kind, bool IsAux = false)
: Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
virtual ~MangleContext() { }
ASTContext &getASTContext() const { return Context; }
DiagnosticsEngine &getDiags() const { return Diags; }
virtual void startNewFunction() { LocalBlockIds.clear(); }
unsigned getBlockId(const BlockDecl *BD, bool Local) {
llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
= Local? LocalBlockIds : GlobalBlockIds;
std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
return Result.first->second;
}
uint64_t getAnonymousStructId(const NamedDecl *D) {
std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
return Result.first->second;
}
uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
AnonStructIds.find(D);
if (Result == AnonStructIds.end())
return 0;
return Result->second;
}
virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
bool shouldMangleDeclName(const NamedDecl *D);
virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
return false;
}
virtual void needsUniqueInternalLinkageNames() { }
void mangleName(GlobalDecl GD, raw_ostream &);
virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
virtual void mangleThunk(const CXXMethodDecl *MD,
const ThunkInfo &Thunk,
raw_ostream &) = 0;
virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
const ThisAdjustment &ThisAdjustment,
raw_ostream &) = 0;
virtual void mangleReferenceTemporary(const VarDecl *D,
unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
void mangleGlobalBlock(const BlockDecl *BD,
const NamedDecl *ID,
raw_ostream &Out);
void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
const BlockDecl *BD, raw_ostream &Out);
void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
const BlockDecl *BD, raw_ostream &Out);
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
raw_ostream &Out);
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
bool includePrefixByte = true,
bool includeCategoryNamespace = true);
void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
raw_ostream &);
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &) = 0;
virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
raw_ostream &Out) = 0;
virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
raw_ostream &Out) = 0;
virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
};
class ItaniumMangleContext : public MangleContext {
public:
using DiscriminatorOverrideTy =
llvm::Optional<unsigned> (*)(ASTContext &, const NamedDecl *);
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
bool IsAux = false)
: MangleContext(C, D, MK_Itanium, IsAux) {}
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;
virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
raw_ostream &) = 0;
virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
raw_ostream &) = 0;
virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
static ItaniumMangleContext *
create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags,
DiscriminatorOverrideTy Discriminator,
bool IsAux = false);
};
class MicrosoftMangleContext : public MangleContext {
public:
explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
bool IsAux = false)
: MangleContext(C, D, MK_Microsoft, IsAux) {}
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
ArrayRef<const CXXRecordDecl *> BasePath,
raw_ostream &Out) = 0;
virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
unsigned GuardNum,
raw_ostream &Out) = 0;
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
const MethodVFTableLocation &ML,
raw_ostream &Out) = 0;
virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
const CXXRecordDecl *DstRD,
raw_ostream &Out) = 0;
virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
bool IsUnaligned, uint32_t NumEntries,
raw_ostream &Out) = 0;
virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
raw_ostream &Out) = 0;
virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
CXXCtorType CT, uint32_t Size,
uint32_t NVOffset, int32_t VBPtrOffset,
uint32_t VBIndex, raw_ostream &Out) = 0;
virtual void mangleCXXRTTIBaseClassDescriptor(
const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
raw_ostream &Out) = 0;
virtual void
mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
raw_ostream &Out) = 0;
virtual void
mangleCXXRTTICompleteObjectLocator(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, bool IsAux = false);
};
class ASTNameGenerator {
public:
explicit ASTNameGenerator(ASTContext &Ctx);
~ASTNameGenerator();
bool writeName(const Decl *D, raw_ostream &OS);
std::string getName(const Decl *D);
std::vector<std::string> getAllManglings(const Decl *D);
private:
class Implementation;
std::unique_ptr<Implementation> Impl;
};
}
#endif