Mangle.h revision a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1d
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/raw_ostream.h"
23
24namespace clang {
25  class ASTContext;
26  class BlockDecl;
27  class CXXConstructorDecl;
28  class CXXDestructorDecl;
29  class CXXMethodDecl;
30  class FunctionDecl;
31  class NamedDecl;
32  class ObjCMethodDecl;
33  class VarDecl;
34  struct ThisAdjustment;
35  struct ThunkInfo;
36
37/// MangleBuffer - a convenient class for storing a name which is
38/// either the result of a mangling or is a constant string with
39/// external memory ownership.
40class MangleBuffer {
41public:
42  void setString(StringRef Ref) {
43    String = Ref;
44  }
45
46  SmallVectorImpl<char> &getBuffer() {
47    return Buffer;
48  }
49
50  StringRef getString() const {
51    if (!String.empty()) return String;
52    return Buffer.str();
53  }
54
55  operator StringRef() const {
56    return getString();
57  }
58
59private:
60  StringRef String;
61  SmallString<256> Buffer;
62};
63
64/// MangleContext - Context for tracking state which persists across multiple
65/// calls to the C++ name mangler.
66class MangleContext {
67  virtual void anchor();
68
69  ASTContext &Context;
70  DiagnosticsEngine &Diags;
71
72  llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
73  llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
74
75public:
76  explicit MangleContext(ASTContext &Context,
77                         DiagnosticsEngine &Diags)
78    : Context(Context), Diags(Diags) { }
79
80  virtual ~MangleContext() { }
81
82  ASTContext &getASTContext() const { return Context; }
83
84  DiagnosticsEngine &getDiags() const { return Diags; }
85
86  virtual void startNewFunction() { LocalBlockIds.clear(); }
87
88  unsigned getBlockId(const BlockDecl *BD, bool Local) {
89    llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
90      = Local? LocalBlockIds : GlobalBlockIds;
91    std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
92      Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
93    return Result.first->second;
94  }
95
96  /// @name Mangler Entry Points
97  /// @{
98
99  virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
100  virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
101  virtual void mangleThunk(const CXXMethodDecl *MD,
102                          const ThunkInfo &Thunk,
103                          raw_ostream &) = 0;
104  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
105                                  const ThisAdjustment &ThisAdjustment,
106                                  raw_ostream &) = 0;
107  virtual void mangleReferenceTemporary(const VarDecl *D,
108                                        raw_ostream &) = 0;
109  // FIXME: Some of these objects only exist in select ABIs. We should probably
110  // only declare them in ABI-specific manglers?
111  virtual void mangleCXXVTable(const CXXRecordDecl *RD,
112                               raw_ostream &) = 0;
113  /// \brief Mangle vftable symbols.  Only a subset of the bases along the path
114  /// to the vftable are included in the name.  It's up to the caller to pick
115  /// them correctly.
116  virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
117                                ArrayRef<const CXXRecordDecl *> BasePath,
118                                raw_ostream &Out) = 0;
119  virtual void mangleCXXVTT(const CXXRecordDecl *RD,
120                            raw_ostream &) = 0;
121  /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
122  /// to the vbtable are included in the name.  It's up to the caller to pick
123  /// them correctly.
124  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
125                                ArrayRef<const CXXRecordDecl *> BasePath,
126                                raw_ostream &Out) = 0;
127  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
128                                   const CXXRecordDecl *Type,
129                                   raw_ostream &) = 0;
130  virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
131  virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
132  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
133                             raw_ostream &) = 0;
134  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
135                             raw_ostream &) = 0;
136
137  void mangleGlobalBlock(const BlockDecl *BD,
138                         const NamedDecl *ID,
139                         raw_ostream &Out);
140  void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
141                       const BlockDecl *BD, raw_ostream &Out);
142  void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
143                       const BlockDecl *BD, raw_ostream &Out);
144  void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
145                   raw_ostream &Out);
146
147  void mangleObjCMethodName(const ObjCMethodDecl *MD,
148                            raw_ostream &);
149
150  virtual void mangleStaticGuardVariable(const VarDecl *D,
151                                         raw_ostream &Out) = 0;
152
153  virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) = 0;
154
155  virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
156                                             raw_ostream &Out) = 0;
157
158  // FIXME: Revisit this once we know what we need to do for MSVC compatibility.
159  virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
160                                            raw_ostream &) {
161    llvm_unreachable("Target does not support mangling thread_local variables");
162  }
163  virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
164                                               raw_ostream &) {
165    llvm_unreachable("Target does not support mangling thread_local variables");
166  }
167
168  /// @}
169};
170
171MangleContext *createItaniumMangleContext(ASTContext &Context,
172                                          DiagnosticsEngine &Diags);
173MangleContext *createMicrosoftMangleContext(ASTContext &Context,
174                                            DiagnosticsEngine &Diags);
175
176}
177
178#endif
179