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;
38 /// MangleBuffer - a convenient class for storing a name which is
39 /// either the result of a mangling or is a constant string with
40 /// external memory ownership.
43 void setString(StringRef Ref) {
47 SmallVectorImpl<char> &getBuffer() {
51 StringRef getString() const {
52 if (!String.empty()) return String;
56 operator StringRef() const {
62 SmallString<256> Buffer;
65 /// MangleContext - Context for tracking state which persists across multiple
66 /// calls to the C++ name mangler.
75 virtual void anchor();
78 DiagnosticsEngine &Diags;
79 const ManglerKind Kind;
81 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
82 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
85 ManglerKind getKind() const { return Kind; }
87 explicit MangleContext(ASTContext &Context,
88 DiagnosticsEngine &Diags,
90 : Context(Context), Diags(Diags), Kind(Kind) {}
92 virtual ~MangleContext() { }
94 ASTContext &getASTContext() const { return Context; }
96 DiagnosticsEngine &getDiags() const { return Diags; }
98 virtual void startNewFunction() { LocalBlockIds.clear(); }
100 unsigned getBlockId(const BlockDecl *BD, bool Local) {
101 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
102 = Local? LocalBlockIds : GlobalBlockIds;
103 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
104 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
105 return Result.first->second;
108 /// @name Mangler Entry Points
111 bool shouldMangleDeclName(const NamedDecl *D);
112 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
114 // FIXME: consider replacing raw_ostream & with something like SmallString &.
115 void mangleName(const NamedDecl *D, raw_ostream &);
116 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
117 virtual void mangleThunk(const CXXMethodDecl *MD,
118 const ThunkInfo &Thunk,
120 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
121 const ThisAdjustment &ThisAdjustment,
123 virtual void mangleReferenceTemporary(const VarDecl *D,
125 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
126 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
127 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
129 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
132 void mangleGlobalBlock(const BlockDecl *BD,
135 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
136 const BlockDecl *BD, raw_ostream &Out);
137 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
138 const BlockDecl *BD, raw_ostream &Out);
139 void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
142 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
144 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
146 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
148 virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
151 /// Generates a unique string for an externally visible type for use with TBAA
152 /// or type uniquing.
153 /// TODO: Extend this to internal types by generating names that are unique
154 /// across translation units so it can be used with LTO.
155 virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
160 class ItaniumMangleContext : public MangleContext {
162 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
163 : MangleContext(C, D, MK_Itanium) {}
165 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
166 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
167 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
168 const CXXRecordDecl *Type,
170 virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
172 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
175 static bool classof(const MangleContext *C) {
176 return C->getKind() == MK_Itanium;
179 static ItaniumMangleContext *create(ASTContext &Context,
180 DiagnosticsEngine &Diags);
183 class MicrosoftMangleContext : public MangleContext {
185 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
186 : MangleContext(C, D, MK_Microsoft) {}
188 /// \brief Mangle vftable symbols. Only a subset of the bases along the path
189 /// to the vftable are included in the name. It's up to the caller to pick
191 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
192 ArrayRef<const CXXRecordDecl *> BasePath,
193 raw_ostream &Out) = 0;
195 /// \brief Mangle vbtable symbols. Only a subset of the bases along the path
196 /// to the vbtable are included in the name. It's up to the caller to pick
198 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
199 ArrayRef<const CXXRecordDecl *> BasePath,
200 raw_ostream &Out) = 0;
202 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
203 uint64_t OffsetInVFTable,
206 static bool classof(const MangleContext *C) {
207 return C->getKind() == MK_Microsoft;
210 static MicrosoftMangleContext *create(ASTContext &Context,
211 DiagnosticsEngine &Diags);