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/ADT/SmallString.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/raw_ostream.h"
28 class CXXConstructorDecl;
29 class CXXDestructorDecl;
35 struct ThisAdjustment;
39 /// MangleContext - Context for tracking state which persists across multiple
40 /// calls to the C++ name mangler.
49 virtual void anchor();
52 DiagnosticsEngine &Diags;
53 const ManglerKind Kind;
55 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
56 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
57 llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
60 ManglerKind getKind() const { return Kind; }
62 explicit MangleContext(ASTContext &Context,
63 DiagnosticsEngine &Diags,
65 : Context(Context), Diags(Diags), Kind(Kind) {}
67 virtual ~MangleContext() { }
69 ASTContext &getASTContext() const { return Context; }
71 DiagnosticsEngine &getDiags() const { return Diags; }
73 virtual void startNewFunction() { LocalBlockIds.clear(); }
75 unsigned getBlockId(const BlockDecl *BD, bool Local) {
76 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
77 = Local? LocalBlockIds : GlobalBlockIds;
78 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
79 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
80 return Result.first->second;
83 uint64_t getAnonymousStructId(const TagDecl *TD) {
84 std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
85 Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
86 return Result.first->second;
89 /// @name Mangler Entry Points
92 bool shouldMangleDeclName(const NamedDecl *D);
93 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
94 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
96 // FIXME: consider replacing raw_ostream & with something like SmallString &.
97 void mangleName(const NamedDecl *D, raw_ostream &);
98 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
99 virtual void mangleThunk(const CXXMethodDecl *MD,
100 const ThunkInfo &Thunk,
102 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
103 const ThisAdjustment &ThisAdjustment,
105 virtual void mangleReferenceTemporary(const VarDecl *D,
106 unsigned ManglingNumber,
108 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
109 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
110 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
112 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
114 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
116 void mangleGlobalBlock(const BlockDecl *BD,
119 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
120 const BlockDecl *BD, raw_ostream &Out);
121 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
122 const BlockDecl *BD, raw_ostream &Out);
123 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
126 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
128 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
130 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
132 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
135 virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
136 raw_ostream &Out) = 0;
138 virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
139 raw_ostream &Out) = 0;
141 /// Generates a unique string for an externally visible type for use with TBAA
142 /// or type uniquing.
143 /// TODO: Extend this to internal types by generating names that are unique
144 /// across translation units so it can be used with LTO.
145 virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
150 class ItaniumMangleContext : public MangleContext {
152 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
153 : MangleContext(C, D, MK_Itanium) {}
155 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
156 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
157 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
158 const CXXRecordDecl *Type,
160 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
162 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
165 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
167 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
170 static bool classof(const MangleContext *C) {
171 return C->getKind() == MK_Itanium;
174 static ItaniumMangleContext *create(ASTContext &Context,
175 DiagnosticsEngine &Diags);
178 class MicrosoftMangleContext : public MangleContext {
180 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
181 : MangleContext(C, D, MK_Microsoft) {}
183 /// \brief Mangle vftable symbols. Only a subset of the bases along the path
184 /// to the vftable are included in the name. It's up to the caller to pick
186 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
187 ArrayRef<const CXXRecordDecl *> BasePath,
188 raw_ostream &Out) = 0;
190 /// \brief Mangle vbtable symbols. Only a subset of the bases along the path
191 /// to the vbtable are included in the name. It's up to the caller to pick
193 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
194 ArrayRef<const CXXRecordDecl *> BasePath,
195 raw_ostream &Out) = 0;
197 virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
199 raw_ostream &Out) = 0;
201 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
204 virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
205 const CXXRecordDecl *DstRD,
206 raw_ostream &Out) = 0;
208 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
209 uint32_t NumEntries, raw_ostream &Out) = 0;
211 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
212 raw_ostream &Out) = 0;
214 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
215 CXXCtorType CT, uint32_t Size,
216 uint32_t NVOffset, int32_t VBPtrOffset,
217 uint32_t VBIndex, raw_ostream &Out) = 0;
219 virtual void mangleCXXCatchHandlerType(QualType T, uint32_t Flags,
220 raw_ostream &Out) = 0;
222 virtual void mangleCXXRTTIBaseClassDescriptor(
223 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
224 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
226 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
227 raw_ostream &Out) = 0;
229 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
230 raw_ostream &Out) = 0;
233 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
234 ArrayRef<const CXXRecordDecl *> BasePath,
235 raw_ostream &Out) = 0;
237 static bool classof(const MangleContext *C) {
238 return C->getKind() == MK_Microsoft;
241 static MicrosoftMangleContext *create(ASTContext &Context,
242 DiagnosticsEngine &Diags);