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 VarDecl;
35   struct ThisAdjustment;
36   struct ThunkInfo;
37 
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.
41 class MangleBuffer {
42 public:
43   void setString(StringRef Ref) {
44     String = Ref;
45   }
46 
47   SmallVectorImpl<char> &getBuffer() {
48     return Buffer;
49   }
50 
51   StringRef getString() const {
52     if (!String.empty()) return String;
53     return Buffer.str();
54   }
55 
56   operator StringRef() const {
57     return getString();
58   }
59 
60 private:
61   StringRef String;
62   SmallString<256> Buffer;
63 };
64 
65 /// MangleContext - Context for tracking state which persists across multiple
66 /// calls to the C++ name mangler.
67 class MangleContext {
68 public:
69   enum ManglerKind {
70     MK_Itanium,
71     MK_Microsoft
72   };
73 
74 private:
75   virtual void anchor();
76 
77   ASTContext &Context;
78   DiagnosticsEngine &Diags;
79   const ManglerKind Kind;
80 
81   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
82   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
83 
84 public:
85   ManglerKind getKind() const { return Kind; }
86 
87   explicit MangleContext(ASTContext &Context,
88                          DiagnosticsEngine &Diags,
89                          ManglerKind Kind)
90       : Context(Context), Diags(Diags), Kind(Kind) {}
91 
92   virtual ~MangleContext() { }
93 
94   ASTContext &getASTContext() const { return Context; }
95 
96   DiagnosticsEngine &getDiags() const { return Diags; }
97 
98   virtual void startNewFunction() { LocalBlockIds.clear(); }
99 
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;
106   }
107 
108   /// @name Mangler Entry Points
109   /// @{
110 
111   bool shouldMangleDeclName(const NamedDecl *D);
112   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
113 
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,
119                           raw_ostream &) = 0;
120   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
121                                   const ThisAdjustment &ThisAdjustment,
122                                   raw_ostream &) = 0;
123   virtual void mangleReferenceTemporary(const VarDecl *D,
124                                         raw_ostream &) = 0;
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,
128                              raw_ostream &) = 0;
129   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
130                              raw_ostream &) = 0;
131 
132   void mangleGlobalBlock(const BlockDecl *BD,
133                          const NamedDecl *ID,
134                          raw_ostream &Out);
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,
140                    raw_ostream &Out);
141 
142   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
143 
144   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
145 
146   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
147 
148   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
149                                              raw_ostream &) = 0;
150 
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;
156 
157   /// @}
158 };
159 
160 class ItaniumMangleContext : public MangleContext {
161 public:
162   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
163       : MangleContext(C, D, MK_Itanium) {}
164 
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,
169                                    raw_ostream &) = 0;
170   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
171                                             raw_ostream &) = 0;
172   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
173                                                raw_ostream &) = 0;
174 
175   static bool classof(const MangleContext *C) {
176     return C->getKind() == MK_Itanium;
177   }
178 
179   static ItaniumMangleContext *create(ASTContext &Context,
180                                       DiagnosticsEngine &Diags);
181 };
182 
183 class MicrosoftMangleContext : public MangleContext {
184 public:
185   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
186       : MangleContext(C, D, MK_Microsoft) {}
187 
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
190   /// them correctly.
191   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
192                                 ArrayRef<const CXXRecordDecl *> BasePath,
193                                 raw_ostream &Out) = 0;
194 
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
197   /// them correctly.
198   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
199                                 ArrayRef<const CXXRecordDecl *> BasePath,
200                                 raw_ostream &Out) = 0;
201 
202   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
203                                         int OffsetInVFTable, raw_ostream &) = 0;
204 
205   static bool classof(const MangleContext *C) {
206     return C->getKind() == MK_Microsoft;
207   }
208 
209   static MicrosoftMangleContext *create(ASTContext &Context,
210                                         DiagnosticsEngine &Diags);
211 };
212 }
213 
214 #endif
215