File indexing completed on 2026-05-10 08:36:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_MANGLE_H
0014 #define LLVM_CLANG_AST_MANGLE_H
0015
0016 #include "clang/AST/Decl.h"
0017 #include "clang/AST/GlobalDecl.h"
0018 #include "clang/AST/Type.h"
0019 #include "clang/Basic/ABI.h"
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/Support/Casting.h"
0022 #include <optional>
0023
0024 namespace llvm {
0025 class raw_ostream;
0026 }
0027
0028 namespace clang {
0029 class ASTContext;
0030 class BlockDecl;
0031 class CXXConstructorDecl;
0032 class CXXDestructorDecl;
0033 class CXXMethodDecl;
0034 class FunctionDecl;
0035 struct MethodVFTableLocation;
0036 class NamedDecl;
0037 class ObjCMethodDecl;
0038 class StringLiteral;
0039 struct ThisAdjustment;
0040 struct ThunkInfo;
0041 class VarDecl;
0042
0043
0044
0045 class MangleContext {
0046 public:
0047 enum ManglerKind {
0048 MK_Itanium,
0049 MK_Microsoft
0050 };
0051
0052 private:
0053 virtual void anchor();
0054
0055 ASTContext &Context;
0056 DiagnosticsEngine &Diags;
0057 const ManglerKind Kind;
0058
0059
0060 bool IsAux = false;
0061
0062 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
0063 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
0064 llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
0065 llvm::DenseMap<const FunctionDecl*, unsigned> FuncAnonStructSize;
0066
0067 public:
0068 ManglerKind getKind() const { return Kind; }
0069
0070 bool isAux() const { return IsAux; }
0071
0072 explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
0073 ManglerKind Kind, bool IsAux = false)
0074 : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
0075
0076 virtual ~MangleContext() { }
0077
0078 ASTContext &getASTContext() const { return Context; }
0079
0080 DiagnosticsEngine &getDiags() const { return Diags; }
0081
0082 virtual void startNewFunction() { LocalBlockIds.clear(); }
0083
0084 unsigned getBlockId(const BlockDecl *BD, bool Local) {
0085 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
0086 = Local? LocalBlockIds : GlobalBlockIds;
0087 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
0088 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
0089 return Result.first->second;
0090 }
0091
0092 uint64_t getAnonymousStructId(const NamedDecl *D,
0093 const FunctionDecl *FD = nullptr) {
0094 auto FindResult = AnonStructIds.find(D);
0095 if (FindResult != AnonStructIds.end())
0096 return FindResult->second;
0097
0098
0099
0100 unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
0101 std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
0102 Result = AnonStructIds.insert(std::make_pair(D, Id));
0103 return Result.first->second;
0104 }
0105
0106 uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
0107 llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
0108 AnonStructIds.find(D);
0109
0110 if (Result == AnonStructIds.end())
0111 return 0;
0112 return Result->second;
0113 }
0114
0115 virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
0116
0117
0118
0119
0120 bool shouldMangleDeclName(const NamedDecl *D);
0121 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
0122 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
0123
0124 virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
0125 return false;
0126 }
0127
0128 virtual void needsUniqueInternalLinkageNames() { }
0129
0130
0131 void mangleName(GlobalDecl GD, raw_ostream &);
0132 virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
0133 virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
0134 bool ElideOverrideInfo, raw_ostream &) = 0;
0135 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
0136 const ThunkInfo &Thunk,
0137 bool ElideOverrideInfo, raw_ostream &) = 0;
0138 virtual void mangleReferenceTemporary(const VarDecl *D,
0139 unsigned ManglingNumber,
0140 raw_ostream &) = 0;
0141 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
0142 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
0143 virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
0144 bool NormalizeIntegers = false) = 0;
0145 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
0146 virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
0147
0148 void mangleGlobalBlock(const BlockDecl *BD,
0149 const NamedDecl *ID,
0150 raw_ostream &Out);
0151 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
0152 const BlockDecl *BD, raw_ostream &Out);
0153 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
0154 const BlockDecl *BD, raw_ostream &Out);
0155 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
0156 raw_ostream &Out);
0157
0158 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
0159 bool includePrefixByte = true,
0160 bool includeCategoryNamespace = true);
0161 void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
0162 raw_ostream &);
0163
0164 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
0165
0166 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
0167
0168 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
0169 raw_ostream &) = 0;
0170
0171 virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
0172 raw_ostream &Out) = 0;
0173
0174 virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
0175 raw_ostream &Out) = 0;
0176
0177
0178
0179
0180
0181 virtual void mangleCanonicalTypeName(QualType T, raw_ostream &,
0182 bool NormalizeIntegers = false) = 0;
0183
0184
0185 };
0186
0187 class ItaniumMangleContext : public MangleContext {
0188 public:
0189 using DiscriminatorOverrideTy =
0190 std::optional<unsigned> (*)(ASTContext &, const NamedDecl *);
0191 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
0192 bool IsAux = false)
0193 : MangleContext(C, D, MK_Itanium, IsAux) {}
0194
0195 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
0196 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
0197 const CXXRecordDecl *Type,
0198 raw_ostream &) = 0;
0199 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
0200 raw_ostream &) = 0;
0201 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
0202 raw_ostream &) = 0;
0203
0204 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
0205 raw_ostream &) = 0;
0206 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
0207 raw_ostream &) = 0;
0208
0209 virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
0210
0211 virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
0212
0213 virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
0214
0215
0216
0217 virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
0218 static bool classof(const MangleContext *C) {
0219 return C->getKind() == MK_Itanium;
0220 }
0221
0222 static ItaniumMangleContext *
0223 create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
0224 static ItaniumMangleContext *create(ASTContext &Context,
0225 DiagnosticsEngine &Diags,
0226 DiscriminatorOverrideTy Discriminator,
0227 bool IsAux = false);
0228 };
0229
0230 class MicrosoftMangleContext : public MangleContext {
0231 public:
0232 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
0233 bool IsAux = false)
0234 : MangleContext(C, D, MK_Microsoft, IsAux) {}
0235
0236
0237
0238
0239 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
0240 ArrayRef<const CXXRecordDecl *> BasePath,
0241 raw_ostream &Out) = 0;
0242
0243
0244
0245
0246 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
0247 ArrayRef<const CXXRecordDecl *> BasePath,
0248 raw_ostream &Out) = 0;
0249
0250 virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
0251 unsigned GuardNum,
0252 raw_ostream &Out) = 0;
0253
0254 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
0255 const MethodVFTableLocation &ML,
0256 raw_ostream &Out) = 0;
0257
0258 virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
0259 const CXXRecordDecl *DstRD,
0260 raw_ostream &Out) = 0;
0261
0262 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
0263 bool IsUnaligned, uint32_t NumEntries,
0264 raw_ostream &Out) = 0;
0265
0266 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
0267 raw_ostream &Out) = 0;
0268
0269 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
0270 CXXCtorType CT, uint32_t Size,
0271 uint32_t NVOffset, int32_t VBPtrOffset,
0272 uint32_t VBIndex, raw_ostream &Out) = 0;
0273
0274 virtual void mangleCXXRTTIBaseClassDescriptor(
0275 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
0276 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
0277
0278 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
0279 raw_ostream &Out) = 0;
0280 virtual void
0281 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
0282 raw_ostream &Out) = 0;
0283
0284 virtual void
0285 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
0286 ArrayRef<const CXXRecordDecl *> BasePath,
0287 raw_ostream &Out) = 0;
0288
0289 static bool classof(const MangleContext *C) {
0290 return C->getKind() == MK_Microsoft;
0291 }
0292
0293 static MicrosoftMangleContext *
0294 create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
0295 };
0296
0297 class ASTNameGenerator {
0298 public:
0299 explicit ASTNameGenerator(ASTContext &Ctx);
0300 ~ASTNameGenerator();
0301
0302
0303
0304 bool writeName(const Decl *D, raw_ostream &OS);
0305
0306
0307 std::string getName(const Decl *D);
0308
0309
0310
0311 std::vector<std::string> getAllManglings(const Decl *D);
0312
0313 private:
0314 class Implementation;
0315 std::unique_ptr<Implementation> Impl;
0316 };
0317 }
0318
0319 #endif