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 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(llvm::StringRef Ref)42 void setString(llvm::StringRef Ref) { 43 String = Ref; 44 } 45 getBuffer()46 llvm::SmallVectorImpl<char> &getBuffer() { 47 return Buffer; 48 } 49 getString()50 llvm::StringRef getString() const { 51 if (!String.empty()) return String; 52 return Buffer.str(); 53 } 54 StringRef()55 operator llvm::StringRef() const { 56 return getString(); 57 } 58 59 private: 60 llvm::StringRef String; 61 llvm::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 ASTContext &Context; 68 Diagnostic &Diags; 69 70 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; 71 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; 72 73 public: MangleContext(ASTContext & Context,Diagnostic & Diags)74 explicit MangleContext(ASTContext &Context, 75 Diagnostic &Diags) 76 : Context(Context), Diags(Diags) { } 77 ~MangleContext()78 virtual ~MangleContext() { } 79 getASTContext()80 ASTContext &getASTContext() const { return Context; } 81 getDiags()82 Diagnostic &getDiags() const { return Diags; } 83 startNewFunction()84 virtual void startNewFunction() { LocalBlockIds.clear(); } 85 getBlockId(const BlockDecl * BD,bool Local)86 unsigned getBlockId(const BlockDecl *BD, bool Local) { 87 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds 88 = Local? LocalBlockIds : GlobalBlockIds; 89 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool> 90 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size())); 91 return Result.first->second; 92 } 93 94 /// @name Mangler Entry Points 95 /// @{ 96 97 virtual bool shouldMangleDeclName(const NamedDecl *D) = 0; 98 virtual void mangleName(const NamedDecl *D, llvm::raw_ostream &)=0; 99 virtual void mangleThunk(const CXXMethodDecl *MD, 100 const ThunkInfo &Thunk, 101 llvm::raw_ostream &) = 0; 102 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, 103 const ThisAdjustment &ThisAdjustment, 104 llvm::raw_ostream &) = 0; 105 virtual void mangleReferenceTemporary(const VarDecl *D, 106 llvm::raw_ostream &) = 0; 107 virtual void mangleCXXVTable(const CXXRecordDecl *RD, 108 llvm::raw_ostream &) = 0; 109 virtual void mangleCXXVTT(const CXXRecordDecl *RD, 110 llvm::raw_ostream &) = 0; 111 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, 112 const CXXRecordDecl *Type, 113 llvm::raw_ostream &) = 0; 114 virtual void mangleCXXRTTI(QualType T, llvm::raw_ostream &) = 0; 115 virtual void mangleCXXRTTIName(QualType T, llvm::raw_ostream &) = 0; 116 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, 117 llvm::raw_ostream &) = 0; 118 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 119 llvm::raw_ostream &) = 0; 120 121 void mangleGlobalBlock(const BlockDecl *BD, 122 llvm::raw_ostream &Out); 123 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, 124 const BlockDecl *BD, llvm::raw_ostream &Out); 125 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, 126 const BlockDecl *BD, llvm::raw_ostream &Out); 127 void mangleBlock(const DeclContext *DC, const BlockDecl *BD, 128 llvm::raw_ostream &Out); 129 // Do the right thing. 130 void mangleBlock(const BlockDecl *BD, llvm::raw_ostream &Out); 131 132 void mangleObjCMethodName(const ObjCMethodDecl *MD, 133 llvm::raw_ostream &); 134 135 // This is pretty lame. mangleItaniumGuardVariable(const VarDecl * D,llvm::raw_ostream &)136 virtual void mangleItaniumGuardVariable(const VarDecl *D, 137 llvm::raw_ostream &) { 138 assert(0 && "Target does not support mangling guard variables"); 139 } 140 /// @} 141 }; 142 143 MangleContext *createItaniumMangleContext(ASTContext &Context, 144 Diagnostic &Diags); 145 MangleContext *createMicrosoftMangleContext(ASTContext &Context, 146 Diagnostic &Diags); 147 148 } 149 150 #endif 151