• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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"
24 
25 namespace clang {
26   class ASTContext;
27   class BlockDecl;
28   class CXXConstructorDecl;
29   class CXXDestructorDecl;
30   class CXXMethodDecl;
31   class FunctionDecl;
32   class NamedDecl;
33   class ObjCMethodDecl;
34   class StringLiteral;
35   struct ThisAdjustment;
36   struct ThunkInfo;
37   class VarDecl;
38 
39 /// MangleContext - Context for tracking state which persists across multiple
40 /// calls to the C++ name mangler.
41 class MangleContext {
42 public:
43   enum ManglerKind {
44     MK_Itanium,
45     MK_Microsoft
46   };
47 
48 private:
49   virtual void anchor();
50 
51   ASTContext &Context;
52   DiagnosticsEngine &Diags;
53   const ManglerKind Kind;
54 
55   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
56   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
57   llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
58 
59 public:
getKind()60   ManglerKind getKind() const { return Kind; }
61 
MangleContext(ASTContext & Context,DiagnosticsEngine & Diags,ManglerKind Kind)62   explicit MangleContext(ASTContext &Context,
63                          DiagnosticsEngine &Diags,
64                          ManglerKind Kind)
65       : Context(Context), Diags(Diags), Kind(Kind) {}
66 
~MangleContext()67   virtual ~MangleContext() { }
68 
getASTContext()69   ASTContext &getASTContext() const { return Context; }
70 
getDiags()71   DiagnosticsEngine &getDiags() const { return Diags; }
72 
startNewFunction()73   virtual void startNewFunction() { LocalBlockIds.clear(); }
74 
getBlockId(const BlockDecl * BD,bool Local)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;
81   }
82 
getAnonymousStructId(const TagDecl * TD)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;
87   }
88 
89   /// @name Mangler Entry Points
90   /// @{
91 
92   bool shouldMangleDeclName(const NamedDecl *D);
93   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
94   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
95 
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,
101                           raw_ostream &) = 0;
102   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
103                                   const ThisAdjustment &ThisAdjustment,
104                                   raw_ostream &) = 0;
105   virtual void mangleReferenceTemporary(const VarDecl *D,
106                                         unsigned ManglingNumber,
107                                         raw_ostream &) = 0;
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,
111                              raw_ostream &) = 0;
112   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
113                              raw_ostream &) = 0;
114   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
115 
116   void mangleGlobalBlock(const BlockDecl *BD,
117                          const NamedDecl *ID,
118                          raw_ostream &Out);
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,
124                    raw_ostream &Out);
125 
126   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
127 
128   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
129 
130   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
131 
132   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
133                                              raw_ostream &) = 0;
134 
135   virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
136                                          raw_ostream &Out) = 0;
137 
138   virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
139                                      raw_ostream &Out) = 0;
140 
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;
146 
147   virtual void mangleCXXVTableBitSet(const CXXRecordDecl *RD,
148                                      raw_ostream &) = 0;
149 
150   /// @}
151 };
152 
153 class ItaniumMangleContext : public MangleContext {
154 public:
ItaniumMangleContext(ASTContext & C,DiagnosticsEngine & D)155   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
156       : MangleContext(C, D, MK_Itanium) {}
157 
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,
162                                    raw_ostream &) = 0;
163   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
164                                             raw_ostream &) = 0;
165   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
166                                                raw_ostream &) = 0;
167 
168   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
169                                    raw_ostream &) = 0;
170   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
171                                    raw_ostream &) = 0;
172 
classof(const MangleContext * C)173   static bool classof(const MangleContext *C) {
174     return C->getKind() == MK_Itanium;
175   }
176 
177   static ItaniumMangleContext *create(ASTContext &Context,
178                                       DiagnosticsEngine &Diags);
179 };
180 
181 class MicrosoftMangleContext : public MangleContext {
182 public:
MicrosoftMangleContext(ASTContext & C,DiagnosticsEngine & D)183   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
184       : MangleContext(C, D, MK_Microsoft) {}
185 
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
188   /// them correctly.
189   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
190                                 ArrayRef<const CXXRecordDecl *> BasePath,
191                                 raw_ostream &Out) = 0;
192 
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
195   /// them correctly.
196   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
197                                 ArrayRef<const CXXRecordDecl *> BasePath,
198                                 raw_ostream &Out) = 0;
199 
200   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
201                                         raw_ostream &) = 0;
202 
203   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
204                                   uint32_t NumEntries, raw_ostream &Out) = 0;
205 
206   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
207                                            raw_ostream &Out) = 0;
208 
209   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
210                                       CXXCtorType CT, uint32_t Size,
211                                       uint32_t NVOffset, int32_t VBPtrOffset,
212                                       uint32_t VBIndex, raw_ostream &Out) = 0;
213 
214   virtual void mangleCXXCatchHandlerType(QualType T, uint32_t Flags,
215                                          raw_ostream &Out) = 0;
216 
217   virtual void mangleCXXRTTIBaseClassDescriptor(
218       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
219       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
220 
221   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
222                                            raw_ostream &Out) = 0;
223   virtual void
224   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
225                                         raw_ostream &Out) = 0;
226 
227   virtual void
228   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
229                                      ArrayRef<const CXXRecordDecl *> BasePath,
230                                      raw_ostream &Out) = 0;
231 
classof(const MangleContext * C)232   static bool classof(const MangleContext *C) {
233     return C->getKind() == MK_Microsoft;
234   }
235 
236   static MicrosoftMangleContext *create(ASTContext &Context,
237                                         DiagnosticsEngine &Diags);
238 };
239 }
240 
241 #endif
242