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