Mangle.h revision f7ccbad5d9949e7ddd1cbef43d482553b811e026
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/StringRef.h"
21#include "llvm/ADT/SmallString.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 DeclContext;
31  class DiagnosticsEngine;
32  class FunctionDecl;
33  class NamedDecl;
34  class ObjCMethodDecl;
35  class VarDecl;
36  struct ThisAdjustment;
37  struct ThunkInfo;
38
39/// MangleBuffer - a convenient class for storing a name which is
40/// either the result of a mangling or is a constant string with
41/// external memory ownership.
42class MangleBuffer {
43public:
44  void setString(StringRef Ref) {
45    String = Ref;
46  }
47
48  SmallVectorImpl<char> &getBuffer() {
49    return Buffer;
50  }
51
52  StringRef getString() const {
53    if (!String.empty()) return String;
54    return Buffer.str();
55  }
56
57  operator StringRef() const {
58    return getString();
59  }
60
61private:
62  StringRef String;
63  SmallString<256> Buffer;
64};
65
66/// MangleContext - Context for tracking state which persists across multiple
67/// calls to the C++ name mangler.
68class MangleContext {
69  virtual void anchor();
70
71  ASTContext &Context;
72  DiagnosticsEngine &Diags;
73
74  llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
75  llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
76
77public:
78  explicit MangleContext(ASTContext &Context,
79                         DiagnosticsEngine &Diags)
80    : Context(Context), Diags(Diags) { }
81
82  virtual ~MangleContext() { }
83
84  ASTContext &getASTContext() const { return Context; }
85
86  DiagnosticsEngine &getDiags() const { return Diags; }
87
88  virtual void startNewFunction() { LocalBlockIds.clear(); }
89
90  unsigned getBlockId(const BlockDecl *BD, bool Local) {
91    llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
92      = Local? LocalBlockIds : GlobalBlockIds;
93    std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
94      Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
95    return Result.first->second;
96  }
97
98  /// @name Mangler Entry Points
99  /// @{
100
101  virtual bool shouldMangleDeclName(const NamedDecl *D) = 0;
102  virtual void mangleName(const NamedDecl *D, raw_ostream &)=0;
103  virtual void mangleThunk(const CXXMethodDecl *MD,
104                          const ThunkInfo &Thunk,
105                          raw_ostream &) = 0;
106  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
107                                  const ThisAdjustment &ThisAdjustment,
108                                  raw_ostream &) = 0;
109  virtual void mangleReferenceTemporary(const VarDecl *D,
110                                        raw_ostream &) = 0;
111  virtual void mangleCXXVTable(const CXXRecordDecl *RD,
112                               raw_ostream &) = 0;
113  virtual void mangleCXXVTT(const CXXRecordDecl *RD,
114                            raw_ostream &) = 0;
115  virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
116                                   const CXXRecordDecl *Type,
117                                   raw_ostream &) = 0;
118  virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
119  virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
120  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
121                             raw_ostream &) = 0;
122  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
123                             raw_ostream &) = 0;
124
125  void mangleGlobalBlock(const BlockDecl *BD,
126                         raw_ostream &Out);
127  void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
128                       const BlockDecl *BD, raw_ostream &Out);
129  void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
130                       const BlockDecl *BD, raw_ostream &Out);
131  void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
132                   raw_ostream &Out);
133  // Do the right thing.
134  void mangleBlock(const BlockDecl *BD, raw_ostream &Out);
135
136  void mangleObjCMethodName(const ObjCMethodDecl *MD,
137                            raw_ostream &);
138
139  // This is pretty lame.
140  virtual void mangleItaniumGuardVariable(const VarDecl *D,
141                                          raw_ostream &) {
142    llvm_unreachable("Target does not support mangling guard variables");
143  }
144  /// @}
145};
146
147MangleContext *createItaniumMangleContext(ASTContext &Context,
148                                          DiagnosticsEngine &Diags);
149MangleContext *createMicrosoftMangleContext(ASTContext &Context,
150                                            DiagnosticsEngine &Diags);
151
152}
153
154#endif
155