Mangle.h revision 01f3d00bc5074a2f105eda35ef7aee8088e938d6
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  /// 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
160class ItaniumMangleContext : public MangleContext {
161public:
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
183class MicrosoftMangleContext : public MangleContext {
184public:
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                                        uint64_t OffsetInVFTable,
204                                        raw_ostream &) = 0;
205
206  static bool classof(const MangleContext *C) {
207    return C->getKind() == MK_Microsoft;
208  }
209
210  static MicrosoftMangleContext *create(ASTContext &Context,
211                                        DiagnosticsEngine &Diags);
212};
213}
214
215#endif
216