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;
147 virtual void mangleCXXVTableBitSet(const CXXRecordDecl *RD,
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 /// \brief 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 /// \brief 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,
207 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
208 uint32_t NumEntries, raw_ostream &Out) = 0;
210 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
211 raw_ostream &Out) = 0;
213 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
214 CXXCtorType CT, uint32_t Size,
215 uint32_t NVOffset, int32_t VBPtrOffset,
216 uint32_t VBIndex, raw_ostream &Out) = 0;
218 virtual void mangleCXXCatchHandlerType(QualType T, uint32_t Flags,
219 raw_ostream &Out) = 0;
221 virtual void mangleCXXRTTIBaseClassDescriptor(
222 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
223 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
225 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
226 raw_ostream &Out) = 0;
228 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
229 raw_ostream &Out) = 0;
232 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
233 ArrayRef<const CXXRecordDecl *> BasePath,
234 raw_ostream &Out) = 0;
236 static bool classof(const MangleContext *C) {
237 return C->getKind() == MK_Microsoft;
240 static MicrosoftMangleContext *create(ASTContext &Context,
241 DiagnosticsEngine &Diags);