Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Defines the C++ name mangling interface.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_CLANG_AST_MANGLE_H
  14. #define LLVM_CLANG_AST_MANGLE_H
  15.  
  16. #include "clang/AST/Decl.h"
  17. #include "clang/AST/GlobalDecl.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. #include <optional>
  23.  
  24. namespace llvm {
  25.   class raw_ostream;
  26. }
  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.  
  43. /// MangleContext - Context for tracking state which persists across multiple
  44. /// calls to the C++ name mangler.
  45. class MangleContext {
  46. public:
  47.   enum ManglerKind {
  48.     MK_Itanium,
  49.     MK_Microsoft
  50.   };
  51.  
  52. private:
  53.   virtual void anchor();
  54.  
  55.   ASTContext &Context;
  56.   DiagnosticsEngine &Diags;
  57.   const ManglerKind Kind;
  58.   /// For aux target. If true, uses mangling number for aux target from
  59.   /// ASTContext.
  60.   bool IsAux = false;
  61.  
  62.   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
  63.   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
  64.   llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
  65.   llvm::DenseMap<const FunctionDecl*, unsigned> FuncAnonStructSize;
  66.  
  67. public:
  68.   ManglerKind getKind() const { return Kind; }
  69.  
  70.   bool isAux() const { return IsAux; }
  71.  
  72.   explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
  73.                          ManglerKind Kind, bool IsAux = false)
  74.       : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
  75.  
  76.   virtual ~MangleContext() { }
  77.  
  78.   ASTContext &getASTContext() const { return Context; }
  79.  
  80.   DiagnosticsEngine &getDiags() const { return Diags; }
  81.  
  82.   virtual void startNewFunction() { LocalBlockIds.clear(); }
  83.  
  84.   unsigned getBlockId(const BlockDecl *BD, bool Local) {
  85.     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
  86.       = Local? LocalBlockIds : GlobalBlockIds;
  87.     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
  88.       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
  89.     return Result.first->second;
  90.   }
  91.  
  92.   uint64_t getAnonymousStructId(const NamedDecl *D,
  93.                                 const FunctionDecl *FD = nullptr) {
  94.     auto FindResult = AnonStructIds.find(D);
  95.     if (FindResult != AnonStructIds.end())
  96.       return FindResult->second;
  97.  
  98.     // If FunctionDecl is passed in, the anonymous structID will be per-function
  99.     // based.
  100.     unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
  101.     std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
  102.         Result = AnonStructIds.insert(std::make_pair(D, Id));
  103.     return Result.first->second;
  104.   }
  105.  
  106.   uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
  107.     llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
  108.         AnonStructIds.find(D);
  109.     // The decl should already be inserted, but return 0 in case it is not.
  110.     if (Result == AnonStructIds.end())
  111.       return 0;
  112.     return Result->second;
  113.   }
  114.  
  115.   virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
  116.  
  117.   /// @name Mangler Entry Points
  118.   /// @{
  119.  
  120.   bool shouldMangleDeclName(const NamedDecl *D);
  121.   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
  122.   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
  123.  
  124.   virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
  125.     return false;
  126.   }
  127.  
  128.   virtual void needsUniqueInternalLinkageNames() { }
  129.  
  130.   // FIXME: consider replacing raw_ostream & with something like SmallString &.
  131.   void mangleName(GlobalDecl GD, raw_ostream &);
  132.   virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
  133.   virtual void mangleThunk(const CXXMethodDecl *MD,
  134.                           const ThunkInfo &Thunk,
  135.                           raw_ostream &) = 0;
  136.   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
  137.                                   const ThisAdjustment &ThisAdjustment,
  138.                                   raw_ostream &) = 0;
  139.   virtual void mangleReferenceTemporary(const VarDecl *D,
  140.                                         unsigned ManglingNumber,
  141.                                         raw_ostream &) = 0;
  142.   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
  143.   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
  144.   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
  145.   virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
  146.  
  147.   void mangleGlobalBlock(const BlockDecl *BD,
  148.                          const NamedDecl *ID,
  149.                          raw_ostream &Out);
  150.   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
  151.                        const BlockDecl *BD, raw_ostream &Out);
  152.   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
  153.                        const BlockDecl *BD, raw_ostream &Out);
  154.   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
  155.                    raw_ostream &Out);
  156.  
  157.   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
  158.                             bool includePrefixByte = true,
  159.                             bool includeCategoryNamespace = true);
  160.   void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
  161.                                         raw_ostream &);
  162.  
  163.   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
  164.  
  165.   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
  166.  
  167.   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
  168.                                              raw_ostream &) = 0;
  169.  
  170.   virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
  171.                                          raw_ostream &Out) = 0;
  172.  
  173.   virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
  174.                                      raw_ostream &Out) = 0;
  175.  
  176.   /// Generates a unique string for an externally visible type for use with TBAA
  177.   /// or type uniquing.
  178.   /// TODO: Extend this to internal types by generating names that are unique
  179.   /// across translation units so it can be used with LTO.
  180.   virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
  181.  
  182.   /// @}
  183. };
  184.  
  185. class ItaniumMangleContext : public MangleContext {
  186. public:
  187.   using DiscriminatorOverrideTy =
  188.       std::optional<unsigned> (*)(ASTContext &, const NamedDecl *);
  189.   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
  190.                                 bool IsAux = false)
  191.       : MangleContext(C, D, MK_Itanium, IsAux) {}
  192.  
  193.   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
  194.   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
  195.   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
  196.                                    const CXXRecordDecl *Type,
  197.                                    raw_ostream &) = 0;
  198.   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
  199.                                             raw_ostream &) = 0;
  200.   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
  201.                                                raw_ostream &) = 0;
  202.  
  203.   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
  204.                                    raw_ostream &) = 0;
  205.   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
  206.                                    raw_ostream &) = 0;
  207.  
  208.   virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
  209.  
  210.   virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
  211.  
  212.   virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
  213.  
  214.   // This has to live here, otherwise the CXXNameMangler won't have access to
  215.   // it.
  216.   virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
  217.   static bool classof(const MangleContext *C) {
  218.     return C->getKind() == MK_Itanium;
  219.   }
  220.  
  221.   static ItaniumMangleContext *
  222.   create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
  223.   static ItaniumMangleContext *create(ASTContext &Context,
  224.                                       DiagnosticsEngine &Diags,
  225.                                       DiscriminatorOverrideTy Discriminator,
  226.                                       bool IsAux = false);
  227. };
  228.  
  229. class MicrosoftMangleContext : public MangleContext {
  230. public:
  231.   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
  232.                                   bool IsAux = false)
  233.       : MangleContext(C, D, MK_Microsoft, IsAux) {}
  234.  
  235.   /// Mangle vftable symbols.  Only a subset of the bases along the path
  236.   /// to the vftable are included in the name.  It's up to the caller to pick
  237.   /// them correctly.
  238.   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
  239.                                 ArrayRef<const CXXRecordDecl *> BasePath,
  240.                                 raw_ostream &Out) = 0;
  241.  
  242.   /// Mangle vbtable symbols.  Only a subset of the bases along the path
  243.   /// to the vbtable are included in the name.  It's up to the caller to pick
  244.   /// them correctly.
  245.   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
  246.                                 ArrayRef<const CXXRecordDecl *> BasePath,
  247.                                 raw_ostream &Out) = 0;
  248.  
  249.   virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
  250.                                                    unsigned GuardNum,
  251.                                                    raw_ostream &Out) = 0;
  252.  
  253.   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
  254.                                         const MethodVFTableLocation &ML,
  255.                                         raw_ostream &Out) = 0;
  256.  
  257.   virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
  258.                                                const CXXRecordDecl *DstRD,
  259.                                                raw_ostream &Out) = 0;
  260.  
  261.   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
  262.                                   bool IsUnaligned, uint32_t NumEntries,
  263.                                   raw_ostream &Out) = 0;
  264.  
  265.   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
  266.                                            raw_ostream &Out) = 0;
  267.  
  268.   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
  269.                                       CXXCtorType CT, uint32_t Size,
  270.                                       uint32_t NVOffset, int32_t VBPtrOffset,
  271.                                       uint32_t VBIndex, raw_ostream &Out) = 0;
  272.  
  273.   virtual void mangleCXXRTTIBaseClassDescriptor(
  274.       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
  275.       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
  276.  
  277.   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
  278.                                            raw_ostream &Out) = 0;
  279.   virtual void
  280.   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
  281.                                         raw_ostream &Out) = 0;
  282.  
  283.   virtual void
  284.   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
  285.                                      ArrayRef<const CXXRecordDecl *> BasePath,
  286.                                      raw_ostream &Out) = 0;
  287.  
  288.   static bool classof(const MangleContext *C) {
  289.     return C->getKind() == MK_Microsoft;
  290.   }
  291.  
  292.   static MicrosoftMangleContext *
  293.   create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
  294. };
  295.  
  296. class ASTNameGenerator {
  297. public:
  298.   explicit ASTNameGenerator(ASTContext &Ctx);
  299.   ~ASTNameGenerator();
  300.  
  301.   /// Writes name for \p D to \p OS.
  302.   /// \returns true on failure, false on success.
  303.   bool writeName(const Decl *D, raw_ostream &OS);
  304.  
  305.   /// \returns name for \p D
  306.   std::string getName(const Decl *D);
  307.  
  308.   /// \returns all applicable mangled names.
  309.   /// For example C++ constructors/destructors can have multiple.
  310.   std::vector<std::string> getAllManglings(const Decl *D);
  311.  
  312. private:
  313.   class Implementation;
  314.   std::unique_ptr<Implementation> Impl;
  315. };
  316. }
  317.  
  318. #endif
  319.