xref: /openbsd-src/gnu/llvm/clang/include/clang/AST/Mangle.h (revision f1dd7b858388b4a23f4f67a4957ec5ff656ebbe8)
1 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines the C++ name mangling interface.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_MANGLE_H
14 #define LLVM_CLANG_AST_MANGLE_H
15 
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/GlobalDecl.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 NamedDecl*, uint64_t> AnonStructIds;
61 
62 public:
63   ManglerKind getKind() const { return Kind; }
64 
65   explicit MangleContext(ASTContext &Context,
66                          DiagnosticsEngine &Diags,
67                          ManglerKind Kind)
68       : Context(Context), Diags(Diags), Kind(Kind) {}
69 
70   virtual ~MangleContext() { }
71 
72   ASTContext &getASTContext() const { return Context; }
73 
74   DiagnosticsEngine &getDiags() const { return Diags; }
75 
76   virtual void startNewFunction() { LocalBlockIds.clear(); }
77 
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 
86   uint64_t getAnonymousStructId(const NamedDecl *D) {
87     std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
88         Result = AnonStructIds.insert(std::make_pair(D, 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(GlobalDecl GD, raw_ostream &);
101   virtual void mangleCXXName(GlobalDecl GD, 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 mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
114   virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
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 mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
127   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
128 
129   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
130 
131   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
132 
133   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
134                                              raw_ostream &) = 0;
135 
136   virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
137                                          raw_ostream &Out) = 0;
138 
139   virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
140                                      raw_ostream &Out) = 0;
141 
142   /// Generates a unique string for an externally visible type for use with TBAA
143   /// or type uniquing.
144   /// TODO: Extend this to internal types by generating names that are unique
145   /// across translation units so it can be used with LTO.
146   virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
147 
148   /// @}
149 };
150 
151 class ItaniumMangleContext : public MangleContext {
152   bool IsUniqueNameMangler = false;
153 public:
154   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
155       : MangleContext(C, D, MK_Itanium) {}
156   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
157                                 bool IsUniqueNameMangler)
158       : MangleContext(C, D, MK_Itanium),
159         IsUniqueNameMangler(IsUniqueNameMangler) {}
160 
161   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
162   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
163   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
164                                    const CXXRecordDecl *Type,
165                                    raw_ostream &) = 0;
166   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
167                                             raw_ostream &) = 0;
168   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
169                                                raw_ostream &) = 0;
170 
171   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
172                                    raw_ostream &) = 0;
173   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
174                                    raw_ostream &) = 0;
175 
176   virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
177 
178   virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
179 
180   bool isUniqueNameMangler() { return IsUniqueNameMangler; }
181 
182   static bool classof(const MangleContext *C) {
183     return C->getKind() == MK_Itanium;
184   }
185 
186   static ItaniumMangleContext *create(ASTContext &Context,
187                                       DiagnosticsEngine &Diags,
188                                       bool IsUniqueNameMangler = false);
189 };
190 
191 class MicrosoftMangleContext : public MangleContext {
192 public:
193   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
194       : MangleContext(C, D, MK_Microsoft) {}
195 
196   /// Mangle vftable symbols.  Only a subset of the bases along the path
197   /// to the vftable are included in the name.  It's up to the caller to pick
198   /// them correctly.
199   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
200                                 ArrayRef<const CXXRecordDecl *> BasePath,
201                                 raw_ostream &Out) = 0;
202 
203   /// Mangle vbtable symbols.  Only a subset of the bases along the path
204   /// to the vbtable are included in the name.  It's up to the caller to pick
205   /// them correctly.
206   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
207                                 ArrayRef<const CXXRecordDecl *> BasePath,
208                                 raw_ostream &Out) = 0;
209 
210   virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
211                                                    unsigned GuardNum,
212                                                    raw_ostream &Out) = 0;
213 
214   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
215                                         const MethodVFTableLocation &ML,
216                                         raw_ostream &Out) = 0;
217 
218   virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
219                                                const CXXRecordDecl *DstRD,
220                                                raw_ostream &Out) = 0;
221 
222   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
223                                   bool IsUnaligned, uint32_t NumEntries,
224                                   raw_ostream &Out) = 0;
225 
226   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
227                                            raw_ostream &Out) = 0;
228 
229   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
230                                       CXXCtorType CT, uint32_t Size,
231                                       uint32_t NVOffset, int32_t VBPtrOffset,
232                                       uint32_t VBIndex, raw_ostream &Out) = 0;
233 
234   virtual void mangleCXXRTTIBaseClassDescriptor(
235       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
236       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
237 
238   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
239                                            raw_ostream &Out) = 0;
240   virtual void
241   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
242                                         raw_ostream &Out) = 0;
243 
244   virtual void
245   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
246                                      ArrayRef<const CXXRecordDecl *> BasePath,
247                                      raw_ostream &Out) = 0;
248 
249   static bool classof(const MangleContext *C) {
250     return C->getKind() == MK_Microsoft;
251   }
252 
253   static MicrosoftMangleContext *create(ASTContext &Context,
254                                         DiagnosticsEngine &Diags);
255 };
256 
257 class ASTNameGenerator {
258 public:
259   explicit ASTNameGenerator(ASTContext &Ctx);
260   ~ASTNameGenerator();
261 
262   /// Writes name for \p D to \p OS.
263   /// \returns true on failure, false on success.
264   bool writeName(const Decl *D, raw_ostream &OS);
265 
266   /// \returns name for \p D
267   std::string getName(const Decl *D);
268 
269   /// \returns all applicable mangled names.
270   /// For example C++ constructors/destructors can have multiple.
271   std::vector<std::string> getAllManglings(const Decl *D);
272 
273 private:
274   class Implementation;
275   std::unique_ptr<Implementation> Impl;
276 };
277 }
278 
279 #endif
280