Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:38

0001 //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Defines the C++ name mangling interface.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_MANGLE_H
0014 #define LLVM_CLANG_AST_MANGLE_H
0015 
0016 #include "clang/AST/Decl.h"
0017 #include "clang/AST/GlobalDecl.h"
0018 #include "clang/AST/Type.h"
0019 #include "clang/Basic/ABI.h"
0020 #include "llvm/ADT/DenseMap.h"
0021 #include "llvm/Support/Casting.h"
0022 #include <optional>
0023 
0024 namespace llvm {
0025   class raw_ostream;
0026 }
0027 
0028 namespace clang {
0029   class ASTContext;
0030   class BlockDecl;
0031   class CXXConstructorDecl;
0032   class CXXDestructorDecl;
0033   class CXXMethodDecl;
0034   class FunctionDecl;
0035   struct MethodVFTableLocation;
0036   class NamedDecl;
0037   class ObjCMethodDecl;
0038   class StringLiteral;
0039   struct ThisAdjustment;
0040   struct ThunkInfo;
0041   class VarDecl;
0042 
0043 /// MangleContext - Context for tracking state which persists across multiple
0044 /// calls to the C++ name mangler.
0045 class MangleContext {
0046 public:
0047   enum ManglerKind {
0048     MK_Itanium,
0049     MK_Microsoft
0050   };
0051 
0052 private:
0053   virtual void anchor();
0054 
0055   ASTContext &Context;
0056   DiagnosticsEngine &Diags;
0057   const ManglerKind Kind;
0058   /// For aux target. If true, uses mangling number for aux target from
0059   /// ASTContext.
0060   bool IsAux = false;
0061 
0062   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
0063   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
0064   llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
0065   llvm::DenseMap<const FunctionDecl*, unsigned> FuncAnonStructSize;
0066 
0067 public:
0068   ManglerKind getKind() const { return Kind; }
0069 
0070   bool isAux() const { return IsAux; }
0071 
0072   explicit MangleContext(ASTContext &Context, DiagnosticsEngine &Diags,
0073                          ManglerKind Kind, bool IsAux = false)
0074       : Context(Context), Diags(Diags), Kind(Kind), IsAux(IsAux) {}
0075 
0076   virtual ~MangleContext() { }
0077 
0078   ASTContext &getASTContext() const { return Context; }
0079 
0080   DiagnosticsEngine &getDiags() const { return Diags; }
0081 
0082   virtual void startNewFunction() { LocalBlockIds.clear(); }
0083 
0084   unsigned getBlockId(const BlockDecl *BD, bool Local) {
0085     llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
0086       = Local? LocalBlockIds : GlobalBlockIds;
0087     std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
0088       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
0089     return Result.first->second;
0090   }
0091 
0092   uint64_t getAnonymousStructId(const NamedDecl *D,
0093                                 const FunctionDecl *FD = nullptr) {
0094     auto FindResult = AnonStructIds.find(D);
0095     if (FindResult != AnonStructIds.end())
0096       return FindResult->second;
0097 
0098     // If FunctionDecl is passed in, the anonymous structID will be per-function
0099     // based.
0100     unsigned Id = FD ? FuncAnonStructSize[FD]++ : AnonStructIds.size();
0101     std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
0102         Result = AnonStructIds.insert(std::make_pair(D, Id));
0103     return Result.first->second;
0104   }
0105 
0106   uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
0107     llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
0108         AnonStructIds.find(D);
0109     // The decl should already be inserted, but return 0 in case it is not.
0110     if (Result == AnonStructIds.end())
0111       return 0;
0112     return Result->second;
0113   }
0114 
0115   virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
0116 
0117   /// @name Mangler Entry Points
0118   /// @{
0119 
0120   bool shouldMangleDeclName(const NamedDecl *D);
0121   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
0122   virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
0123 
0124   virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
0125     return false;
0126   }
0127 
0128   virtual void needsUniqueInternalLinkageNames() { }
0129 
0130   // FIXME: consider replacing raw_ostream & with something like SmallString &.
0131   void mangleName(GlobalDecl GD, raw_ostream &);
0132   virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
0133   virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
0134                            bool ElideOverrideInfo, raw_ostream &) = 0;
0135   virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
0136                                   const ThunkInfo &Thunk,
0137                                   bool ElideOverrideInfo, raw_ostream &) = 0;
0138   virtual void mangleReferenceTemporary(const VarDecl *D,
0139                                         unsigned ManglingNumber,
0140                                         raw_ostream &) = 0;
0141   virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
0142   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
0143   virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
0144                                  bool NormalizeIntegers = false) = 0;
0145   virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
0146   virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
0147 
0148   void mangleGlobalBlock(const BlockDecl *BD,
0149                          const NamedDecl *ID,
0150                          raw_ostream &Out);
0151   void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
0152                        const BlockDecl *BD, raw_ostream &Out);
0153   void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
0154                        const BlockDecl *BD, raw_ostream &Out);
0155   void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
0156                    raw_ostream &Out);
0157 
0158   void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
0159                             bool includePrefixByte = true,
0160                             bool includeCategoryNamespace = true);
0161   void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
0162                                         raw_ostream &);
0163 
0164   virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
0165 
0166   virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
0167 
0168   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
0169                                              raw_ostream &) = 0;
0170 
0171   virtual void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,
0172                                          raw_ostream &Out) = 0;
0173 
0174   virtual void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,
0175                                      raw_ostream &Out) = 0;
0176 
0177   /// Generates a unique string for an externally visible type for use with TBAA
0178   /// or type uniquing.
0179   /// TODO: Extend this to internal types by generating names that are unique
0180   /// across translation units so it can be used with LTO.
0181   virtual void mangleCanonicalTypeName(QualType T, raw_ostream &,
0182                                        bool NormalizeIntegers = false) = 0;
0183 
0184   /// @}
0185 };
0186 
0187 class ItaniumMangleContext : public MangleContext {
0188 public:
0189   using DiscriminatorOverrideTy =
0190       std::optional<unsigned> (*)(ASTContext &, const NamedDecl *);
0191   explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
0192                                 bool IsAux = false)
0193       : MangleContext(C, D, MK_Itanium, IsAux) {}
0194 
0195   virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
0196   virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
0197                                    const CXXRecordDecl *Type,
0198                                    raw_ostream &) = 0;
0199   virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
0200                                             raw_ostream &) = 0;
0201   virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
0202                                                raw_ostream &) = 0;
0203 
0204   virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
0205                                    raw_ostream &) = 0;
0206   virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
0207                                    raw_ostream &) = 0;
0208 
0209   virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
0210 
0211   virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
0212 
0213   virtual void mangleModuleInitializer(const Module *Module, raw_ostream &) = 0;
0214 
0215   // This has to live here, otherwise the CXXNameMangler won't have access to
0216   // it.
0217   virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
0218   static bool classof(const MangleContext *C) {
0219     return C->getKind() == MK_Itanium;
0220   }
0221 
0222   static ItaniumMangleContext *
0223   create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
0224   static ItaniumMangleContext *create(ASTContext &Context,
0225                                       DiagnosticsEngine &Diags,
0226                                       DiscriminatorOverrideTy Discriminator,
0227                                       bool IsAux = false);
0228 };
0229 
0230 class MicrosoftMangleContext : public MangleContext {
0231 public:
0232   explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D,
0233                                   bool IsAux = false)
0234       : MangleContext(C, D, MK_Microsoft, IsAux) {}
0235 
0236   /// Mangle vftable symbols.  Only a subset of the bases along the path
0237   /// to the vftable are included in the name.  It's up to the caller to pick
0238   /// them correctly.
0239   virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
0240                                 ArrayRef<const CXXRecordDecl *> BasePath,
0241                                 raw_ostream &Out) = 0;
0242 
0243   /// Mangle vbtable symbols.  Only a subset of the bases along the path
0244   /// to the vbtable are included in the name.  It's up to the caller to pick
0245   /// them correctly.
0246   virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
0247                                 ArrayRef<const CXXRecordDecl *> BasePath,
0248                                 raw_ostream &Out) = 0;
0249 
0250   virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
0251                                                    unsigned GuardNum,
0252                                                    raw_ostream &Out) = 0;
0253 
0254   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
0255                                         const MethodVFTableLocation &ML,
0256                                         raw_ostream &Out) = 0;
0257 
0258   virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
0259                                                const CXXRecordDecl *DstRD,
0260                                                raw_ostream &Out) = 0;
0261 
0262   virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
0263                                   bool IsUnaligned, uint32_t NumEntries,
0264                                   raw_ostream &Out) = 0;
0265 
0266   virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
0267                                            raw_ostream &Out) = 0;
0268 
0269   virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
0270                                       CXXCtorType CT, uint32_t Size,
0271                                       uint32_t NVOffset, int32_t VBPtrOffset,
0272                                       uint32_t VBIndex, raw_ostream &Out) = 0;
0273 
0274   virtual void mangleCXXRTTIBaseClassDescriptor(
0275       const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
0276       uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
0277 
0278   virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
0279                                            raw_ostream &Out) = 0;
0280   virtual void
0281   mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
0282                                         raw_ostream &Out) = 0;
0283 
0284   virtual void
0285   mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
0286                                      ArrayRef<const CXXRecordDecl *> BasePath,
0287                                      raw_ostream &Out) = 0;
0288 
0289   static bool classof(const MangleContext *C) {
0290     return C->getKind() == MK_Microsoft;
0291   }
0292 
0293   static MicrosoftMangleContext *
0294   create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux = false);
0295 };
0296 
0297 class ASTNameGenerator {
0298 public:
0299   explicit ASTNameGenerator(ASTContext &Ctx);
0300   ~ASTNameGenerator();
0301 
0302   /// Writes name for \p D to \p OS.
0303   /// \returns true on failure, false on success.
0304   bool writeName(const Decl *D, raw_ostream &OS);
0305 
0306   /// \returns name for \p D
0307   std::string getName(const Decl *D);
0308 
0309   /// \returns all applicable mangled names.
0310   /// For example C++ constructors/destructors can have multiple.
0311   std::vector<std::string> getAllManglings(const Decl *D);
0312 
0313 private:
0314   class Implementation;
0315   std::unique_ptr<Implementation> Impl;
0316 };
0317 }
0318 
0319 #endif