Mangle.h revision 01f3d00bc5074a2f105eda35ef7aee8088e938d6
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/Casting.h" 23#include "llvm/Support/raw_ostream.h" 24 25namespace clang { 26 class ASTContext; 27 class BlockDecl; 28 class CXXConstructorDecl; 29 class CXXDestructorDecl; 30 class CXXMethodDecl; 31 class FunctionDecl; 32 class NamedDecl; 33 class ObjCMethodDecl; 34 class VarDecl; 35 struct ThisAdjustment; 36 struct ThunkInfo; 37 38/// MangleBuffer - a convenient class for storing a name which is 39/// either the result of a mangling or is a constant string with 40/// external memory ownership. 41class MangleBuffer { 42public: 43 void setString(StringRef Ref) { 44 String = Ref; 45 } 46 47 SmallVectorImpl<char> &getBuffer() { 48 return Buffer; 49 } 50 51 StringRef getString() const { 52 if (!String.empty()) return String; 53 return Buffer.str(); 54 } 55 56 operator StringRef() const { 57 return getString(); 58 } 59 60private: 61 StringRef String; 62 SmallString<256> Buffer; 63}; 64 65/// MangleContext - Context for tracking state which persists across multiple 66/// calls to the C++ name mangler. 67class MangleContext { 68public: 69 enum ManglerKind { 70 MK_Itanium, 71 MK_Microsoft 72 }; 73 74private: 75 virtual void anchor(); 76 77 ASTContext &Context; 78 DiagnosticsEngine &Diags; 79 const ManglerKind Kind; 80 81 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; 82 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; 83 84public: 85 ManglerKind getKind() const { return Kind; } 86 87 explicit MangleContext(ASTContext &Context, 88 DiagnosticsEngine &Diags, 89 ManglerKind Kind) 90 : Context(Context), Diags(Diags), Kind(Kind) {} 91 92 virtual ~MangleContext() { } 93 94 ASTContext &getASTContext() const { return Context; } 95 96 DiagnosticsEngine &getDiags() const { return Diags; } 97 98 virtual void startNewFunction() { LocalBlockIds.clear(); } 99 100 unsigned getBlockId(const BlockDecl *BD, bool Local) { 101 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds 102 = Local? LocalBlockIds : GlobalBlockIds; 103 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool> 104 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size())); 105 return Result.first->second; 106 } 107 108 /// @name Mangler Entry Points 109 /// @{ 110 111 bool shouldMangleDeclName(const NamedDecl *D); 112 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0; 113 114 // FIXME: consider replacing raw_ostream & with something like SmallString &. 115 void mangleName(const NamedDecl *D, raw_ostream &); 116 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; 117 virtual void mangleThunk(const CXXMethodDecl *MD, 118 const ThunkInfo &Thunk, 119 raw_ostream &) = 0; 120 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, 121 const ThisAdjustment &ThisAdjustment, 122 raw_ostream &) = 0; 123 virtual void mangleReferenceTemporary(const VarDecl *D, 124 raw_ostream &) = 0; 125 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; 126 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; 127 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, 128 raw_ostream &) = 0; 129 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 130 raw_ostream &) = 0; 131 132 void mangleGlobalBlock(const BlockDecl *BD, 133 const NamedDecl *ID, 134 raw_ostream &Out); 135 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, 136 const BlockDecl *BD, raw_ostream &Out); 137 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, 138 const BlockDecl *BD, raw_ostream &Out); 139 void mangleBlock(const DeclContext *DC, const BlockDecl *BD, 140 raw_ostream &Out); 141 142 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); 143 144 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; 145 146 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0; 147 148 virtual void mangleDynamicAtExitDestructor(const VarDecl *D, 149 raw_ostream &) = 0; 150 151 /// Generates a unique string for an externally visible type for use with TBAA 152 /// or type uniquing. 153 /// TODO: Extend this to internal types by generating names that are unique 154 /// across translation units so it can be used with LTO. 155 virtual void mangleTypeName(QualType T, raw_ostream &) = 0; 156 157 /// @} 158}; 159 160class ItaniumMangleContext : public MangleContext { 161public: 162 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) 163 : MangleContext(C, D, MK_Itanium) {} 164 165 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; 166 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; 167 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, 168 const CXXRecordDecl *Type, 169 raw_ostream &) = 0; 170 virtual void mangleItaniumThreadLocalInit(const VarDecl *D, 171 raw_ostream &) = 0; 172 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, 173 raw_ostream &) = 0; 174 175 static bool classof(const MangleContext *C) { 176 return C->getKind() == MK_Itanium; 177 } 178 179 static ItaniumMangleContext *create(ASTContext &Context, 180 DiagnosticsEngine &Diags); 181}; 182 183class MicrosoftMangleContext : public MangleContext { 184public: 185 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D) 186 : MangleContext(C, D, MK_Microsoft) {} 187 188 /// \brief Mangle vftable symbols. Only a subset of the bases along the path 189 /// to the vftable are included in the name. It's up to the caller to pick 190 /// them correctly. 191 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, 192 ArrayRef<const CXXRecordDecl *> BasePath, 193 raw_ostream &Out) = 0; 194 195 /// \brief Mangle vbtable symbols. Only a subset of the bases along the path 196 /// to the vbtable are included in the name. It's up to the caller to pick 197 /// them correctly. 198 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, 199 ArrayRef<const CXXRecordDecl *> BasePath, 200 raw_ostream &Out) = 0; 201 202 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, 203 uint64_t OffsetInVFTable, 204 raw_ostream &) = 0; 205 206 static bool classof(const MangleContext *C) { 207 return C->getKind() == MK_Microsoft; 208 } 209 210 static MicrosoftMangleContext *create(ASTContext &Context, 211 DiagnosticsEngine &Diags); 212}; 213} 214 215#endif 216