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 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, 114 const CXXRecordDecl *Type, 115 raw_ostream &) = 0; 116 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; 117 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; 118 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, 119 raw_ostream &) = 0; 120 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 121 raw_ostream &) = 0; 122 123 void mangleGlobalBlock(const BlockDecl *BD, 124 const NamedDecl *ID, 125 raw_ostream &Out); 126 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, 127 const BlockDecl *BD, raw_ostream &Out); 128 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, 129 const BlockDecl *BD, raw_ostream &Out); 130 void mangleBlock(const DeclContext *DC, const BlockDecl *BD, 131 raw_ostream &Out); 132 // Do the right thing. 133 void mangleBlock(const BlockDecl *BD, raw_ostream &Out, 134 const NamedDecl *ID=0); 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 147 MangleContext *createItaniumMangleContext(ASTContext &Context, 148 DiagnosticsEngine &Diags); 149 MangleContext *createMicrosoftMangleContext(ASTContext &Context, 150 DiagnosticsEngine &Diags); 151 152 } 153 154 #endif 155