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