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 25 namespace 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 StringLiteral; 35 struct ThisAdjustment; 36 struct ThunkInfo; 37 class VarDecl; 38 39 /// MangleContext - Context for tracking state which persists across multiple 40 /// calls to the C++ name mangler. 41 class MangleContext { 42 public: 43 enum ManglerKind { 44 MK_Itanium, 45 MK_Microsoft 46 }; 47 48 private: 49 virtual void anchor(); 50 51 ASTContext &Context; 52 DiagnosticsEngine &Diags; 53 const ManglerKind Kind; 54 55 llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds; 56 llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds; 57 llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds; 58 59 public: getKind()60 ManglerKind getKind() const { return Kind; } 61 MangleContext(ASTContext & Context,DiagnosticsEngine & Diags,ManglerKind Kind)62 explicit MangleContext(ASTContext &Context, 63 DiagnosticsEngine &Diags, 64 ManglerKind Kind) 65 : Context(Context), Diags(Diags), Kind(Kind) {} 66 ~MangleContext()67 virtual ~MangleContext() { } 68 getASTContext()69 ASTContext &getASTContext() const { return Context; } 70 getDiags()71 DiagnosticsEngine &getDiags() const { return Diags; } 72 startNewFunction()73 virtual void startNewFunction() { LocalBlockIds.clear(); } 74 getBlockId(const BlockDecl * BD,bool Local)75 unsigned getBlockId(const BlockDecl *BD, bool Local) { 76 llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds 77 = Local? LocalBlockIds : GlobalBlockIds; 78 std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool> 79 Result = BlockIds.insert(std::make_pair(BD, BlockIds.size())); 80 return Result.first->second; 81 } 82 getAnonymousStructId(const TagDecl * TD)83 uint64_t getAnonymousStructId(const TagDecl *TD) { 84 std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool> 85 Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size())); 86 return Result.first->second; 87 } 88 89 /// @name Mangler Entry Points 90 /// @{ 91 92 bool shouldMangleDeclName(const NamedDecl *D); 93 virtual bool shouldMangleCXXName(const NamedDecl *D) = 0; 94 virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; 95 96 // FIXME: consider replacing raw_ostream & with something like SmallString &. 97 void mangleName(const NamedDecl *D, raw_ostream &); 98 virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; 99 virtual void mangleThunk(const CXXMethodDecl *MD, 100 const ThunkInfo &Thunk, 101 raw_ostream &) = 0; 102 virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, 103 const ThisAdjustment &ThisAdjustment, 104 raw_ostream &) = 0; 105 virtual void mangleReferenceTemporary(const VarDecl *D, 106 unsigned ManglingNumber, 107 raw_ostream &) = 0; 108 virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; 109 virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; 110 virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, 111 raw_ostream &) = 0; 112 virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, 113 raw_ostream &) = 0; 114 virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0; 115 116 void mangleGlobalBlock(const BlockDecl *BD, 117 const NamedDecl *ID, 118 raw_ostream &Out); 119 void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT, 120 const BlockDecl *BD, raw_ostream &Out); 121 void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT, 122 const BlockDecl *BD, raw_ostream &Out); 123 void mangleBlock(const DeclContext *DC, const BlockDecl *BD, 124 raw_ostream &Out); 125 126 void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); 127 128 virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; 129 130 virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0; 131 132 virtual void mangleDynamicAtExitDestructor(const VarDecl *D, 133 raw_ostream &) = 0; 134 135 virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, 136 raw_ostream &Out) = 0; 137 138 virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, 139 raw_ostream &Out) = 0; 140 141 /// Generates a unique string for an externally visible type for use with TBAA 142 /// or type uniquing. 143 /// TODO: Extend this to internal types by generating names that are unique 144 /// across translation units so it can be used with LTO. 145 virtual void mangleTypeName(QualType T, raw_ostream &) = 0; 146 147 virtual void mangleCXXVTableBitSet(const CXXRecordDecl *RD, 148 raw_ostream &) = 0; 149 150 /// @} 151 }; 152 153 class ItaniumMangleContext : public MangleContext { 154 public: ItaniumMangleContext(ASTContext & C,DiagnosticsEngine & D)155 explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) 156 : MangleContext(C, D, MK_Itanium) {} 157 158 virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; 159 virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; 160 virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, 161 const CXXRecordDecl *Type, 162 raw_ostream &) = 0; 163 virtual void mangleItaniumThreadLocalInit(const VarDecl *D, 164 raw_ostream &) = 0; 165 virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, 166 raw_ostream &) = 0; 167 168 virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D, 169 raw_ostream &) = 0; 170 virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D, 171 raw_ostream &) = 0; 172 classof(const MangleContext * C)173 static bool classof(const MangleContext *C) { 174 return C->getKind() == MK_Itanium; 175 } 176 177 static ItaniumMangleContext *create(ASTContext &Context, 178 DiagnosticsEngine &Diags); 179 }; 180 181 class MicrosoftMangleContext : public MangleContext { 182 public: MicrosoftMangleContext(ASTContext & C,DiagnosticsEngine & D)183 explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D) 184 : MangleContext(C, D, MK_Microsoft) {} 185 186 /// \brief Mangle vftable symbols. Only a subset of the bases along the path 187 /// to the vftable are included in the name. It's up to the caller to pick 188 /// them correctly. 189 virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, 190 ArrayRef<const CXXRecordDecl *> BasePath, 191 raw_ostream &Out) = 0; 192 193 /// \brief Mangle vbtable symbols. Only a subset of the bases along the path 194 /// to the vbtable are included in the name. It's up to the caller to pick 195 /// them correctly. 196 virtual void mangleCXXVBTable(const CXXRecordDecl *Derived, 197 ArrayRef<const CXXRecordDecl *> BasePath, 198 raw_ostream &Out) = 0; 199 200 virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, 201 raw_ostream &) = 0; 202 203 virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, 204 uint32_t NumEntries, raw_ostream &Out) = 0; 205 206 virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, 207 raw_ostream &Out) = 0; 208 209 virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, 210 CXXCtorType CT, uint32_t Size, 211 uint32_t NVOffset, int32_t VBPtrOffset, 212 uint32_t VBIndex, raw_ostream &Out) = 0; 213 214 virtual void mangleCXXCatchHandlerType(QualType T, uint32_t Flags, 215 raw_ostream &Out) = 0; 216 217 virtual void mangleCXXRTTIBaseClassDescriptor( 218 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, 219 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0; 220 221 virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived, 222 raw_ostream &Out) = 0; 223 virtual void 224 mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived, 225 raw_ostream &Out) = 0; 226 227 virtual void 228 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived, 229 ArrayRef<const CXXRecordDecl *> BasePath, 230 raw_ostream &Out) = 0; 231 classof(const MangleContext * C)232 static bool classof(const MangleContext *C) { 233 return C->getKind() == MK_Microsoft; 234 } 235 236 static MicrosoftMangleContext *create(ASTContext &Context, 237 DiagnosticsEngine &Diags); 238 }; 239 } 240 241 #endif 242