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: 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 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: 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 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. 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. 148 virtual void mangleItaniumThreadLocalInit(const VarDecl *D, 149 raw_ostream &) { 150 llvm_unreachable("Target does not support mangling thread_local variables"); 151 } 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