1 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Defines the C++ name mangling interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_MANGLE_H
15 #define LLVM_CLANG_AST_MANGLE_H
16 
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/Support/Casting.h"
22 
23 namespace llvm {
24   class raw_ostream;
25 }
26 
27 namespace clang {
28   class ASTContext;
29   class BlockDecl;
30   class CXXConstructorDecl;
31   class CXXDestructorDecl;
32   class CXXMethodDecl;
33   class FunctionDecl;
34   struct MethodVFTableLocation;
35   class NamedDecl;
36   class ObjCMethodDecl;
37   class StringLiteral;
38   struct ThisAdjustment;
39   struct ThunkInfo;
40   class VarDecl;
41 
42 /// MangleContext - Context for tracking state which persists across multiple
43 /// calls to the C++ name mangler.
44 class MangleContext {
45 public:
46   enum ManglerKind {
47     MK_Itanium,
48     MK_Microsoft
49   };
50 
51 private:
52   virtual void anchor();
53 
54   ASTContext &Context;
55   DiagnosticsEngine &Diags;
56   const ManglerKind Kind;
57 
58   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
59   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
60   llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
61 
62 public:
getKind()63   ManglerKind getKind() const { return Kind; }
64 
MangleContext(ASTContext & Context,DiagnosticsEngine & Diags,ManglerKind Kind)65   explicit MangleContext(ASTContext &Context,
66                          DiagnosticsEngine &Diags,
67                          ManglerKind Kind)
68       : Context(Context), Diags(Diags), Kind(Kind) {}
69 
~MangleContext()70   virtual ~MangleContext() { }
71 
getASTContext()72   ASTContext &getASTContext() const { return Context; }
73 
getDiags()74   DiagnosticsEngine &getDiags() const { return Diags; }
75 
startNewFunction()76   virtual void startNewFunction() { LocalBlockIds.clear(); }
77 
getBlockId(const BlockDecl * BD,bool Local)78   unsigned getBlockId(const BlockDecl *BD, bool Local) {
79     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
80       = Local? LocalBlockIds : GlobalBlockIds;
81     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
82       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
83     return Result.first->second;
84   }
85 
getAnonymousStructId(const TagDecl * TD)86   uint64_t getAnonymousStructId(const TagDecl *TD) {
87     std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
88         Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
89     return Result.first->second;
90   }
91 
92   /// @name Mangler Entry Points
93   /// @{
94 
95   bool shouldMangleDeclName(const NamedDecl *D);
96   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
97   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
98 
99   // FIXME: consider replacing raw_ostream & with something like SmallString &.
100   void mangleName(const NamedDecl *D, raw_ostream &);
101   virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0;
102   virtual void mangleThunk(const CXXMethodDecl *MD,
103                           const ThunkInfo &Thunk,
104                           raw_ostream &) = 0;
105   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
106                                   const ThisAdjustment &ThisAdjustment,
107                                   raw_ostream &) = 0;
108   virtual void mangleReferenceTemporary(const VarDecl *D,
109                                         unsigned ManglingNumber,
110                                         raw_ostream &) = 0;
111   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
112   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
113   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
114                              raw_ostream &) = 0;
115   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
116                              raw_ostream &) = 0;
117   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
118 
119   void mangleGlobalBlock(const BlockDecl *BD,
120                          const NamedDecl *ID,
121                          raw_ostream &Out);
122   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
123                        const BlockDecl *BD, raw_ostream &Out);
124   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
125                        const BlockDecl *BD, raw_ostream &Out);
126   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
127                    raw_ostream &Out);
128 
129   void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
130   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
131 
132   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
133 
134   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
135 
136   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
137                                              raw_ostream &) = 0;
138 
139   virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
140                                          raw_ostream &Out) = 0;
141 
142   virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
143                                      raw_ostream &Out) = 0;
144 
145   /// Generates a unique string for an externally visible type for use with TBAA
146   /// or type uniquing.
147   /// TODO: Extend this to internal types by generating names that are unique
148   /// across translation units so it can be used with LTO.
149   virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
150 
151   /// @}
152 };
153 
154 class ItaniumMangleContext : public MangleContext {
155 public:
ItaniumMangleContext(ASTContext & C,DiagnosticsEngine & D)156   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
157       : MangleContext(C, D, MK_Itanium) {}
158 
159   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
160   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
161   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
162                                    const CXXRecordDecl *Type,
163                                    raw_ostream &) = 0;
164   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
165                                             raw_ostream &) = 0;
166   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
167                                                raw_ostream &) = 0;
168 
169   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
170                                    raw_ostream &) = 0;
171   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
172                                    raw_ostream &) = 0;
173 
classof(const MangleContext * C)174   static bool classof(const MangleContext *C) {
175     return C->getKind() == MK_Itanium;
176   }
177 
178   static ItaniumMangleContext *create(ASTContext &Context,
179                                       DiagnosticsEngine &Diags);
180 };
181 
182 class MicrosoftMangleContext : public MangleContext {
183 public:
MicrosoftMangleContext(ASTContext & C,DiagnosticsEngine & D)184   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
185       : MangleContext(C, D, MK_Microsoft) {}
186 
187   /// Mangle vftable symbols.  Only a subset of the bases along the path
188   /// to the vftable are included in the name.  It's up to the caller to pick
189   /// them correctly.
190   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
191                                 ArrayRef<const CXXRecordDecl *> BasePath,
192                                 raw_ostream &Out) = 0;
193 
194   /// Mangle vbtable symbols.  Only a subset of the bases along the path
195   /// to the vbtable are included in the name.  It's up to the caller to pick
196   /// them correctly.
197   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
198                                 ArrayRef<const CXXRecordDecl *> BasePath,
199                                 raw_ostream &Out) = 0;
200 
201   virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
202                                                    unsigned GuardNum,
203                                                    raw_ostream &Out) = 0;
204 
205   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
206                                         const MethodVFTableLocation &ML,
207                                         raw_ostream &Out) = 0;
208 
209   virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
210                                                const CXXRecordDecl *DstRD,
211                                                raw_ostream &Out) = 0;
212 
213   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
214                                   bool IsUnaligned, uint32_t NumEntries,
215                                   raw_ostream &Out) = 0;
216 
217   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
218                                            raw_ostream &Out) = 0;
219 
220   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
221                                       CXXCtorType CT, uint32_t Size,
222                                       uint32_t NVOffset, int32_t VBPtrOffset,
223                                       uint32_t VBIndex, raw_ostream &Out) = 0;
224 
225   virtual void mangleCXXRTTIBaseClassDescriptor(
226       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
227       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
228 
229   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
230                                            raw_ostream &Out) = 0;
231   virtual void
232   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
233                                         raw_ostream &Out) = 0;
234 
235   virtual void
236   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
237                                      ArrayRef<const CXXRecordDecl *> BasePath,
238                                      raw_ostream &Out) = 0;
239 
classof(const MangleContext * C)240   static bool classof(const MangleContext *C) {
241     return C->getKind() == MK_Microsoft;
242   }
243 
244   static MicrosoftMangleContext *create(ASTContext &Context,
245                                         DiagnosticsEngine &Diags);
246 };
247 }
248 
249 #endif
250