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
25namespace 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.
41class MangleContext {
42public:
43  enum ManglerKind {
44    MK_Itanium,
45    MK_Microsoft
46  };
47
48private:
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
59public:
60  ManglerKind getKind() const { return Kind; }
61
62  explicit MangleContext(ASTContext &Context,
63                         DiagnosticsEngine &Diags,
64                         ManglerKind Kind)
65      : Context(Context), Diags(Diags), Kind(Kind) {}
66
67  virtual ~MangleContext() { }
68
69  ASTContext &getASTContext() const { return Context; }
70
71  DiagnosticsEngine &getDiags() const { return Diags; }
72
73  virtual void startNewFunction() { LocalBlockIds.clear(); }
74
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
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  /// Generates a unique string for an externally visible type for use with TBAA
136  /// or type uniquing.
137  /// TODO: Extend this to internal types by generating names that are unique
138  /// across translation units so it can be used with LTO.
139  virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
140
141  /// @}
142};
143
144class ItaniumMangleContext : public MangleContext {
145public:
146  explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
147      : MangleContext(C, D, MK_Itanium) {}
148
149  virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
150  virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
151  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
152                                   const CXXRecordDecl *Type,
153                                   raw_ostream &) = 0;
154  virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
155                                            raw_ostream &) = 0;
156  virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
157                                               raw_ostream &) = 0;
158
159  static bool classof(const MangleContext *C) {
160    return C->getKind() == MK_Itanium;
161  }
162
163  static ItaniumMangleContext *create(ASTContext &Context,
164                                      DiagnosticsEngine &Diags);
165};
166
167class MicrosoftMangleContext : public MangleContext {
168public:
169  explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
170      : MangleContext(C, D, MK_Microsoft) {}
171
172  /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
173  /// to the vftable are included in the name.  It's up to the caller to pick
174  /// them correctly.
175  virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
176                                ArrayRef<const CXXRecordDecl *> BasePath,
177                                raw_ostream &Out) = 0;
178
179  /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
180  /// to the vbtable are included in the name.  It's up to the caller to pick
181  /// them correctly.
182  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
183                                ArrayRef<const CXXRecordDecl *> BasePath,
184                                raw_ostream &Out) = 0;
185
186  virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
187                                        raw_ostream &) = 0;
188
189  virtual void mangleCXXRTTIBaseClassDescriptor(
190      const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
191      uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
192
193  virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
194                                           raw_ostream &Out) = 0;
195  virtual void
196  mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
197                                        raw_ostream &Out) = 0;
198
199  virtual void
200  mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
201                                     ArrayRef<const CXXRecordDecl *> BasePath,
202                                     raw_ostream &Out) = 0;
203
204  static bool classof(const MangleContext *C) {
205    return C->getKind() == MK_Microsoft;
206  }
207
208  static MicrosoftMangleContext *create(ASTContext &Context,
209                                        DiagnosticsEngine &Diags);
210};
211}
212
213#endif
214