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