1 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Defines the C++ name mangling interface.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_MANGLE_H
15 #define LLVM_CLANG_AST_MANGLE_H
17 #include "clang/AST/Type.h"
18 #include "clang/Basic/ABI.h"
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/Support/Casting.h"
29 class CXXConstructorDecl;
30 class CXXDestructorDecl;
33 struct MethodVFTableLocation;
37 struct ThisAdjustment;
41 /// MangleContext - Context for tracking state which persists across multiple
42 /// calls to the C++ name mangler.
51 virtual void anchor();
54 DiagnosticsEngine &Diags;
55 const ManglerKind Kind;
57 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
58 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
59 llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
62 ManglerKind getKind() const { return Kind; }
64 explicit MangleContext(ASTContext &Context,
65 DiagnosticsEngine &Diags,
67 : Context(Context), Diags(Diags), Kind(Kind) {}
69 virtual ~MangleContext() { }
71 ASTContext &getASTContext() const { return Context; }
73 DiagnosticsEngine &getDiags() const { return Diags; }
75 virtual void startNewFunction() { LocalBlockIds.clear(); }
77 unsigned getBlockId(const BlockDecl *BD, bool Local) {
78 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
79 = Local? LocalBlockIds : GlobalBlockIds;
80 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
81 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
82 return Result.first->second;
85 uint64_t getAnonymousStructId(const TagDecl *TD) {
86 std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
87 Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
88 return Result.first->second;
91 /// @name Mangler Entry Points
94 bool shouldMangleDeclName(const NamedDecl *D);
95 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
96 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
98 // FIXME: consider replacing raw_ostream & with something like SmallString &.
99 void mangleName(const NamedDecl *D, raw_ostream &);
100 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
101 virtual void mangleThunk(const CXXMethodDecl *MD,
102 const ThunkInfo &Thunk,
104 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
105 const ThisAdjustment &ThisAdjustment,
107 virtual void mangleReferenceTemporary(const VarDecl *D,
108 unsigned ManglingNumber,
110 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
111 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
112 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
114 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
116 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
118 void mangleGlobalBlock(const BlockDecl *BD,
121 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
122 const BlockDecl *BD, raw_ostream &Out);
123 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
124 const BlockDecl *BD, raw_ostream &Out);
125 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
128 void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
129 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
131 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
133 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
135 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
138 virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
139 raw_ostream &Out) = 0;
141 virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
142 raw_ostream &Out) = 0;
144 /// Generates a unique string for an externally visible type for use with TBAA
145 /// or type uniquing.
146 /// TODO: Extend this to internal types by generating names that are unique
147 /// across translation units so it can be used with LTO.
148 virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
153 class ItaniumMangleContext : public MangleContext {
155 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
156 : MangleContext(C, D, MK_Itanium) {}
158 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
159 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
160 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
161 const CXXRecordDecl *Type,
163 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
165 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
168 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
170 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
173 static bool classof(const MangleContext *C) {
174 return C->getKind() == MK_Itanium;
177 static ItaniumMangleContext *create(ASTContext &Context,
178 DiagnosticsEngine &Diags);
181 class MicrosoftMangleContext : public MangleContext {
183 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
184 : MangleContext(C, D, MK_Microsoft) {}
186 /// Mangle vftable symbols. Only a subset of the bases along the path
187 /// to the vftable are included in the name. It's up to the caller to pick
189 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
190 ArrayRef<const CXXRecordDecl *> BasePath,
191 raw_ostream &Out) = 0;
193 /// Mangle vbtable symbols. Only a subset of the bases along the path
194 /// to the vbtable are included in the name. It's up to the caller to pick
196 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
197 ArrayRef<const CXXRecordDecl *> BasePath,
198 raw_ostream &Out) = 0;
200 virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
202 raw_ostream &Out) = 0;
204 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
205 const MethodVFTableLocation &ML,
206 raw_ostream &Out) = 0;
208 virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
209 const CXXRecordDecl *DstRD,
210 raw_ostream &Out) = 0;
212 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
213 bool IsUnaligned, uint32_t NumEntries,
214 raw_ostream &Out) = 0;
216 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
217 raw_ostream &Out) = 0;
219 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
220 CXXCtorType CT, uint32_t Size,
221 uint32_t NVOffset, int32_t VBPtrOffset,
222 uint32_t VBIndex, raw_ostream &Out) = 0;
224 virtual void mangleCXXRTTIBaseClassDescriptor(
225 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
226 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
228 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
229 raw_ostream &Out) = 0;
231 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
232 raw_ostream &Out) = 0;
235 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
236 ArrayRef<const CXXRecordDecl *> BasePath,
237 raw_ostream &Out) = 0;
239 static bool classof(const MangleContext *C) {
240 return C->getKind() == MK_Microsoft;
243 static MicrosoftMangleContext *create(ASTContext &Context,
244 DiagnosticsEngine &Diags);