Mangle.h revision 93b717ac956f5c82f7895ed8874cbd514c6d0a4e
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 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.
41class MangleBuffer {
42public:
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
60private:
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.
67class MangleContext {
68public:
69  enum ManglerKind {
70    MK_Itanium,
71    MK_Microsoft
72  };
73
74private:
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
84public:
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  /// @}
152};
153
154class ItaniumMangleContext : public MangleContext {
155public:
156  explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
157      : MangleContext(C, D, MK_Itanium) {}
158
159  virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
160  virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
161  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
162                                   const CXXRecordDecl *Type,
163                                   raw_ostream &) = 0;
164  virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
165                                            raw_ostream &) = 0;
166  virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
167                                               raw_ostream &) = 0;
168
169  static bool classof(const MangleContext *C) {
170    return C->getKind() == MK_Itanium;
171  }
172
173  static ItaniumMangleContext *create(ASTContext &Context,
174                                      DiagnosticsEngine &Diags);
175};
176
177class MicrosoftMangleContext : public MangleContext {
178public:
179  explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
180      : MangleContext(C, D, MK_Microsoft) {}
181
182  /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
183  /// to the vftable are included in the name.  It's up to the caller to pick
184  /// them correctly.
185  virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
186                                ArrayRef<const CXXRecordDecl *> BasePath,
187                                raw_ostream &Out) = 0;
188
189  /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
190  /// to the vbtable are included in the name.  It's up to the caller to pick
191  /// them correctly.
192  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
193                                ArrayRef<const CXXRecordDecl *> BasePath,
194                                raw_ostream &Out) = 0;
195
196  virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
197                                        int OffsetInVFTable, raw_ostream &) = 0;
198
199  static bool classof(const MangleContext *C) {
200    return C->getKind() == MK_Microsoft;
201  }
202
203  static MicrosoftMangleContext *create(ASTContext &Context,
204                                        DiagnosticsEngine &Diags);
205};
206}
207
208#endif
209