• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
24 namespace 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.
40 class MangleBuffer {
41 public:
setString(StringRef Ref)42   void setString(StringRef Ref) {
43     String = Ref;
44   }
45 
getBuffer()46   SmallVectorImpl<char> &getBuffer() {
47     return Buffer;
48   }
49 
getString()50   StringRef getString() const {
51     if (!String.empty()) return String;
52     return Buffer.str();
53   }
54 
StringRef()55   operator StringRef() const {
56     return getString();
57   }
58 
59 private:
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.
66 class 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 
75 public:
MangleContext(ASTContext & Context,DiagnosticsEngine & Diags)76   explicit MangleContext(ASTContext &Context,
77                          DiagnosticsEngine &Diags)
78     : Context(Context), Diags(Diags) { }
79 
~MangleContext()80   virtual ~MangleContext() { }
81 
getASTContext()82   ASTContext &getASTContext() const { return Context; }
83 
getDiags()84   DiagnosticsEngine &getDiags() const { return Diags; }
85 
startNewFunction()86   virtual void startNewFunction() { LocalBlockIds.clear(); }
87 
getBlockId(const BlockDecl * BD,bool Local)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   virtual void mangleCXXVTable(const CXXRecordDecl *RD,
110                                raw_ostream &) = 0;
111   virtual void mangleCXXVTT(const CXXRecordDecl *RD,
112                             raw_ostream &) = 0;
113   /// \brief Mangle vbtable symbols.  Only a subset of the bases along the path
114   /// to the vbtable are included in the name.  It's up to the caller to pick
115   /// them correctly.
116   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
117                                 ArrayRef<const CXXRecordDecl *> BasePath,
118                                 raw_ostream &Out) = 0;
119   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
120                                    const CXXRecordDecl *Type,
121                                    raw_ostream &) = 0;
122   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
123   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
124   virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
125                              raw_ostream &) = 0;
126   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
127                              raw_ostream &) = 0;
128 
129   void mangleGlobalBlock(const BlockDecl *BD,
130                          const NamedDecl *ID,
131                          raw_ostream &Out);
132   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
133                        const BlockDecl *BD, raw_ostream &Out);
134   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
135                        const BlockDecl *BD, raw_ostream &Out);
136   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
137                    raw_ostream &Out);
138 
139   void mangleObjCMethodName(const ObjCMethodDecl *MD,
140                             raw_ostream &);
141 
142   // This is pretty lame.
mangleItaniumGuardVariable(const VarDecl * D,raw_ostream &)143   virtual void mangleItaniumGuardVariable(const VarDecl *D,
144                                           raw_ostream &) {
145     llvm_unreachable("Target does not support mangling guard variables");
146   }
147   // FIXME: Revisit this once we know what we need to do for MSVC compatibility.
mangleItaniumThreadLocalInit(const VarDecl * D,raw_ostream &)148   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
149                                             raw_ostream &) {
150     llvm_unreachable("Target does not support mangling thread_local variables");
151   }
mangleItaniumThreadLocalWrapper(const VarDecl * D,raw_ostream &)152   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
153                                                raw_ostream &) {
154     llvm_unreachable("Target does not support mangling thread_local variables");
155   }
156 
157   /// @}
158 };
159 
160 MangleContext *createItaniumMangleContext(ASTContext &Context,
161                                           DiagnosticsEngine &Diags);
162 MangleContext *createMicrosoftMangleContext(ASTContext &Context,
163                                             DiagnosticsEngine &Diags);
164 
165 }
166 
167 #endif
168