Mangle.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Defines the C++ name mangling interface.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_AST_MANGLE_H
  18. #define LLVM_CLANG_AST_MANGLE_H
  19. #include "clang/AST/Decl.h"
  20. #include "clang/AST/GlobalDecl.h"
  21. #include "clang/AST/Type.h"
  22. #include "clang/Basic/ABI.h"
  23. #include "llvm/ADT/DenseMap.h"
  24. #include "llvm/Support/Casting.h"
  25. namespace llvm {
  26. class raw_ostream;
  27. }
  28. namespace clang {
  29. class ASTContext;
  30. class BlockDecl;
  31. class CXXConstructorDecl;
  32. class CXXDestructorDecl;
  33. class CXXMethodDecl;
  34. class FunctionDecl;
  35. struct MethodVFTableLocation;
  36. class NamedDecl;
  37. class ObjCMethodDecl;
  38. class StringLiteral;
  39. struct ThisAdjustment;
  40. struct ThunkInfo;
  41. class VarDecl;
  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. private:
  51. virtual void anchor();
  52. ASTContext &Context;
  53. DiagnosticsEngine &Diags;
  54. const ManglerKind Kind;
  55. llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
  56. llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
  57. llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
  58. public:
  59. ManglerKind getKind() const { return Kind; }
  60. explicit MangleContext(ASTContext &Context,
  61. DiagnosticsEngine &Diags,
  62. ManglerKind Kind)
  63. : Context(Context), Diags(Diags), Kind(Kind) {}
  64. virtual ~MangleContext() { }
  65. ASTContext &getASTContext() const { return Context; }
  66. DiagnosticsEngine &getDiags() const { return Diags; }
  67. virtual void startNewFunction() { LocalBlockIds.clear(); }
  68. unsigned getBlockId(const BlockDecl *BD, bool Local) {
  69. llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
  70. = Local? LocalBlockIds : GlobalBlockIds;
  71. std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
  72. Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
  73. return Result.first->second;
  74. }
  75. uint64_t getAnonymousStructId(const NamedDecl *D) {
  76. std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
  77. Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
  78. return Result.first->second;
  79. }
  80. uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
  81. llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
  82. AnonStructIds.find(D);
  83. // The decl should already be inserted, but return 0 in case it is not.
  84. if (Result == AnonStructIds.end())
  85. return 0;
  86. return Result->second;
  87. }
  88. virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
  89. /// @name Mangler Entry Points
  90. /// @{
  91. bool shouldMangleDeclName(const NamedDecl *D);
  92. virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
  93. virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
  94. virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
  95. return false;
  96. }
  97. virtual void needsUniqueInternalLinkageNames() { }
  98. // FIXME: consider replacing raw_ostream & with something like SmallString &.
  99. void mangleName(GlobalDecl GD, raw_ostream &);
  100. virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
  101. virtual void mangleThunk(const CXXMethodDecl *MD,
  102. const ThunkInfo &Thunk,
  103. raw_ostream &) = 0;
  104. virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
  105. const ThisAdjustment &ThisAdjustment,
  106. raw_ostream &) = 0;
  107. virtual void mangleReferenceTemporary(const VarDecl *D,
  108. unsigned ManglingNumber,
  109. raw_ostream &) = 0;
  110. virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
  111. virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
  112. virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
  113. virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
  114. void mangleGlobalBlock(const BlockDecl *BD,
  115. const NamedDecl *ID,
  116. raw_ostream &Out);
  117. void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
  118. const BlockDecl *BD, raw_ostream &Out);
  119. void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
  120. const BlockDecl *BD, raw_ostream &Out);
  121. void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
  122. raw_ostream &Out);
  123. void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
  124. bool includePrefixByte = true,
  125. bool includeCategoryNamespace = true);
  126. void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
  127. raw_ostream &);
  128. virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
  129. virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
  130. virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
  131. raw_ostream &) = 0;
  132. virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
  133. raw_ostream &Out) = 0;
  134. virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
  135. raw_ostream &Out) = 0;
  136. /// Generates a unique string for an externally visible type for use with TBAA
  137. /// or type uniquing.
  138. /// TODO: Extend this to internal types by generating names that are unique
  139. /// across translation units so it can be used with LTO.
  140. virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
  141. /// @}
  142. };
  143. class ItaniumMangleContext : public MangleContext {
  144. public:
  145. using DiscriminatorOverrideTy =
  146. llvm::Optional<unsigned> (*)(ASTContext &, const NamedDecl *);
  147. explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
  148. : MangleContext(C, D, MK_Itanium) {}
  149. virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
  150. virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
  151. virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
  152. const CXXRecordDecl *Type,
  153. raw_ostream &) = 0;
  154. virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
  155. raw_ostream &) = 0;
  156. virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
  157. raw_ostream &) = 0;
  158. virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
  159. raw_ostream &) = 0;
  160. virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
  161. raw_ostream &) = 0;
  162. virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
  163. virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
  164. // This has to live here, otherwise the CXXNameMangler won't have access to
  165. // it.
  166. virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
  167. static bool classof(const MangleContext *C) {
  168. return C->getKind() == MK_Itanium;
  169. }
  170. static ItaniumMangleContext *create(ASTContext &Context,
  171. DiagnosticsEngine &Diags);
  172. static ItaniumMangleContext *create(ASTContext &Context,
  173. DiagnosticsEngine &Diags,
  174. DiscriminatorOverrideTy Discriminator);
  175. };
  176. class MicrosoftMangleContext : public MangleContext {
  177. public:
  178. explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
  179. : MangleContext(C, D, MK_Microsoft) {}
  180. /// Mangle vftable symbols. Only a subset of the bases along the path
  181. /// to the vftable are included in the name. It's up to the caller to pick
  182. /// them correctly.
  183. virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
  184. ArrayRef<const CXXRecordDecl *> BasePath,
  185. raw_ostream &Out) = 0;
  186. /// Mangle vbtable symbols. Only a subset of the bases along the path
  187. /// to the vbtable are included in the name. It's up to the caller to pick
  188. /// them correctly.
  189. virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
  190. ArrayRef<const CXXRecordDecl *> BasePath,
  191. raw_ostream &Out) = 0;
  192. virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
  193. unsigned GuardNum,
  194. raw_ostream &Out) = 0;
  195. virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
  196. const MethodVFTableLocation &ML,
  197. raw_ostream &Out) = 0;
  198. virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
  199. const CXXRecordDecl *DstRD,
  200. raw_ostream &Out) = 0;
  201. virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
  202. bool IsUnaligned, uint32_t NumEntries,
  203. raw_ostream &Out) = 0;
  204. virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
  205. raw_ostream &Out) = 0;
  206. virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
  207. CXXCtorType CT, uint32_t Size,
  208. uint32_t NVOffset, int32_t VBPtrOffset,
  209. uint32_t VBIndex, raw_ostream &Out) = 0;
  210. virtual void mangleCXXRTTIBaseClassDescriptor(
  211. const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
  212. uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
  213. virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
  214. raw_ostream &Out) = 0;
  215. virtual void
  216. mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
  217. raw_ostream &Out) = 0;
  218. virtual void
  219. mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
  220. ArrayRef<const CXXRecordDecl *> BasePath,
  221. raw_ostream &Out) = 0;
  222. static bool classof(const MangleContext *C) {
  223. return C->getKind() == MK_Microsoft;
  224. }
  225. static MicrosoftMangleContext *create(ASTContext &Context,
  226. DiagnosticsEngine &Diags);
  227. };
  228. class ASTNameGenerator {
  229. public:
  230. explicit ASTNameGenerator(ASTContext &Ctx);
  231. ~ASTNameGenerator();
  232. /// Writes name for \p D to \p OS.
  233. /// \returns true on failure, false on success.
  234. bool writeName(const Decl *D, raw_ostream &OS);
  235. /// \returns name for \p D
  236. std::string getName(const Decl *D);
  237. /// \returns all applicable mangled names.
  238. /// For example C++ constructors/destructors can have multiple.
  239. std::vector<std::string> getAllManglings(const Decl *D);
  240. private:
  241. class Implementation;
  242. std::unique_ptr<Implementation> Impl;
  243. };
  244. }
  245. #endif
  246. #ifdef __GNUC__
  247. #pragma GCC diagnostic pop
  248. #endif