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/Decl.h"
18 #include "clang/AST/Type.h"
19 #include "clang/Basic/ABI.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/raw_ostream.h"
29 class CXXConstructorDecl;
30 class CXXDestructorDecl;
36 struct ThisAdjustment;
40 /// MangleContext - Context for tracking state which persists across multiple
41 /// calls to the C++ name mangler.
50 virtual void anchor();
53 DiagnosticsEngine &Diags;
54 const ManglerKind Kind;
56 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
57 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
58 llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
61 ManglerKind getKind() const { return Kind; }
63 explicit MangleContext(ASTContext &Context,
64 DiagnosticsEngine &Diags,
66 : Context(Context), Diags(Diags), Kind(Kind) {}
68 virtual ~MangleContext() { }
70 ASTContext &getASTContext() const { return Context; }
72 DiagnosticsEngine &getDiags() const { return Diags; }
74 virtual void startNewFunction() { LocalBlockIds.clear(); }
76 unsigned getBlockId(const BlockDecl *BD, bool Local) {
77 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
78 = Local? LocalBlockIds : GlobalBlockIds;
79 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
80 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
81 return Result.first->second;
84 uint64_t getAnonymousStructId(const TagDecl *TD) {
85 std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
86 Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
87 return Result.first->second;
90 /// @name Mangler Entry Points
93 bool shouldMangleDeclName(const NamedDecl *D);
94 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
95 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
97 // FIXME: consider replacing raw_ostream & with something like SmallString &.
98 void mangleName(const NamedDecl *D, raw_ostream &);
99 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
100 virtual void mangleThunk(const CXXMethodDecl *MD,
101 const ThunkInfo &Thunk,
103 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
104 const ThisAdjustment &ThisAdjustment,
106 virtual void mangleReferenceTemporary(const VarDecl *D,
107 unsigned ManglingNumber,
109 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
110 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
111 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
113 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
115 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
117 void mangleGlobalBlock(const BlockDecl *BD,
120 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
121 const BlockDecl *BD, raw_ostream &Out);
122 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
123 const BlockDecl *BD, raw_ostream &Out);
124 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
127 void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
128 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
130 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
132 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
134 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
137 virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
138 raw_ostream &Out) = 0;
140 virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
141 raw_ostream &Out) = 0;
143 /// Generates a unique string for an externally visible type for use with TBAA
144 /// or type uniquing.
145 /// TODO: Extend this to internal types by generating names that are unique
146 /// across translation units so it can be used with LTO.
147 virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
152 class ItaniumMangleContext : public MangleContext {
154 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
155 : MangleContext(C, D, MK_Itanium) {}
157 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
158 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
159 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
160 const CXXRecordDecl *Type,
162 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
164 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
167 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
169 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
172 static bool classof(const MangleContext *C) {
173 return C->getKind() == MK_Itanium;
176 static ItaniumMangleContext *create(ASTContext &Context,
177 DiagnosticsEngine &Diags);
180 class MicrosoftMangleContext : public MangleContext {
182 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
183 : MangleContext(C, D, MK_Microsoft) {}
185 /// \brief Mangle vftable symbols. Only a subset of the bases along the path
186 /// to the vftable are included in the name. It's up to the caller to pick
188 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
189 ArrayRef<const CXXRecordDecl *> BasePath,
190 raw_ostream &Out) = 0;
192 /// \brief Mangle vbtable symbols. Only a subset of the bases along the path
193 /// to the vbtable are included in the name. It's up to the caller to pick
195 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
196 ArrayRef<const CXXRecordDecl *> BasePath,
197 raw_ostream &Out) = 0;
199 virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
201 raw_ostream &Out) = 0;
203 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
206 virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
207 const CXXRecordDecl *DstRD,
208 raw_ostream &Out) = 0;
210 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
211 bool IsUnaligned, uint32_t NumEntries,
212 raw_ostream &Out) = 0;
214 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
215 raw_ostream &Out) = 0;
217 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
218 CXXCtorType CT, uint32_t Size,
219 uint32_t NVOffset, int32_t VBPtrOffset,
220 uint32_t VBIndex, 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);