123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- Mangle.h - Mangle C++ Names ----------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // Defines the C++ name mangling interface.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_MANGLE_H
- #define LLVM_CLANG_AST_MANGLE_H
- #include "clang/AST/Decl.h"
- #include "clang/AST/GlobalDecl.h"
- #include "clang/AST/Type.h"
- #include "clang/Basic/ABI.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/Support/Casting.h"
- namespace llvm {
- class raw_ostream;
- }
- namespace clang {
- class ASTContext;
- class BlockDecl;
- class CXXConstructorDecl;
- class CXXDestructorDecl;
- class CXXMethodDecl;
- class FunctionDecl;
- struct MethodVFTableLocation;
- class NamedDecl;
- class ObjCMethodDecl;
- class StringLiteral;
- struct ThisAdjustment;
- struct ThunkInfo;
- class VarDecl;
- /// MangleContext - Context for tracking state which persists across multiple
- /// calls to the C++ name mangler.
- class MangleContext {
- public:
- enum ManglerKind {
- MK_Itanium,
- MK_Microsoft
- };
- private:
- virtual void anchor();
- ASTContext &Context;
- DiagnosticsEngine &Diags;
- const ManglerKind Kind;
- llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
- llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
- llvm::DenseMap<const NamedDecl*, uint64_t> AnonStructIds;
- public:
- ManglerKind getKind() const { return Kind; }
- explicit MangleContext(ASTContext &Context,
- DiagnosticsEngine &Diags,
- ManglerKind Kind)
- : Context(Context), Diags(Diags), Kind(Kind) {}
- virtual ~MangleContext() { }
- ASTContext &getASTContext() const { return Context; }
- DiagnosticsEngine &getDiags() const { return Diags; }
- virtual void startNewFunction() { LocalBlockIds.clear(); }
- unsigned getBlockId(const BlockDecl *BD, bool Local) {
- llvm::DenseMap<const BlockDecl *, unsigned> &BlockIds
- = Local? LocalBlockIds : GlobalBlockIds;
- std::pair<llvm::DenseMap<const BlockDecl *, unsigned>::iterator, bool>
- Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
- return Result.first->second;
- }
- uint64_t getAnonymousStructId(const NamedDecl *D) {
- std::pair<llvm::DenseMap<const NamedDecl *, uint64_t>::iterator, bool>
- Result = AnonStructIds.insert(std::make_pair(D, AnonStructIds.size()));
- return Result.first->second;
- }
- uint64_t getAnonymousStructIdForDebugInfo(const NamedDecl *D) {
- llvm::DenseMap<const NamedDecl *, uint64_t>::iterator Result =
- AnonStructIds.find(D);
- // The decl should already be inserted, but return 0 in case it is not.
- if (Result == AnonStructIds.end())
- return 0;
- return Result->second;
- }
- virtual std::string getLambdaString(const CXXRecordDecl *Lambda) = 0;
- /// @name Mangler Entry Points
- /// @{
- bool shouldMangleDeclName(const NamedDecl *D);
- virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
- virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
- virtual bool isUniqueInternalLinkageDecl(const NamedDecl *ND) {
- return false;
- }
- virtual void needsUniqueInternalLinkageNames() { }
- // FIXME: consider replacing raw_ostream & with something like SmallString &.
- void mangleName(GlobalDecl GD, raw_ostream &);
- virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0;
- virtual void mangleThunk(const CXXMethodDecl *MD,
- const ThunkInfo &Thunk,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
- const ThisAdjustment &ThisAdjustment,
- raw_ostream &) = 0;
- virtual void mangleReferenceTemporary(const VarDecl *D,
- unsigned ManglingNumber,
- raw_ostream &) = 0;
- virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
- virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
- virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
- virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
- void mangleGlobalBlock(const BlockDecl *BD,
- const NamedDecl *ID,
- raw_ostream &Out);
- void mangleCtorBlock(const CXXConstructorDecl *CD, CXXCtorType CT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleDtorBlock(const CXXDestructorDecl *CD, CXXDtorType DT,
- const BlockDecl *BD, raw_ostream &Out);
- void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
- raw_ostream &Out);
- void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
- bool includePrefixByte = true,
- bool includeCategoryNamespace = true);
- void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
- raw_ostream &);
- virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
- virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &) = 0;
- virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
- raw_ostream &) = 0;
- virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
- virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl,
- raw_ostream &Out) = 0;
- /// Generates a unique string for an externally visible type for use with TBAA
- /// or type uniquing.
- /// TODO: Extend this to internal types by generating names that are unique
- /// across translation units so it can be used with LTO.
- virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
- /// @}
- };
- class ItaniumMangleContext : public MangleContext {
- public:
- using DiscriminatorOverrideTy =
- llvm::Optional<unsigned> (*)(ASTContext &, const NamedDecl *);
- explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Itanium) {}
- virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
- virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
- const CXXRecordDecl *Type,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalInit(const VarDecl *D,
- raw_ostream &) = 0;
- virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D,
- raw_ostream &) = 0;
- virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D,
- raw_ostream &) = 0;
- virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D,
- raw_ostream &) = 0;
- virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0;
- virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
- // This has to live here, otherwise the CXXNameMangler won't have access to
- // it.
- virtual DiscriminatorOverrideTy getDiscriminatorOverride() const = 0;
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Itanium;
- }
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
- static ItaniumMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags,
- DiscriminatorOverrideTy Discriminator);
- };
- class MicrosoftMangleContext : public MangleContext {
- public:
- explicit MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D)
- : MangleContext(C, D, MK_Microsoft) {}
- /// Mangle vftable symbols. Only a subset of the bases along the path
- /// to the vftable are included in the name. It's up to the caller to pick
- /// them correctly.
- virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
- /// Mangle vbtable symbols. Only a subset of the bases along the path
- /// to the vbtable are included in the name. It's up to the caller to pick
- /// them correctly.
- virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
- virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD,
- unsigned GuardNum,
- raw_ostream &Out) = 0;
- virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- const MethodVFTableLocation &ML,
- raw_ostream &Out) = 0;
- virtual void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
- const CXXRecordDecl *DstRD,
- raw_ostream &Out) = 0;
- virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,
- bool IsUnaligned, uint32_t NumEntries,
- raw_ostream &Out) = 0;
- virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,
- raw_ostream &Out) = 0;
- virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,
- CXXCtorType CT, uint32_t Size,
- uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBIndex, raw_ostream &Out) = 0;
- virtual void mangleCXXRTTIBaseClassDescriptor(
- const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
- uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
- virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
- virtual void
- mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
- raw_ostream &Out) = 0;
- virtual void
- mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
- ArrayRef<const CXXRecordDecl *> BasePath,
- raw_ostream &Out) = 0;
- static bool classof(const MangleContext *C) {
- return C->getKind() == MK_Microsoft;
- }
- static MicrosoftMangleContext *create(ASTContext &Context,
- DiagnosticsEngine &Diags);
- };
- class ASTNameGenerator {
- public:
- explicit ASTNameGenerator(ASTContext &Ctx);
- ~ASTNameGenerator();
- /// Writes name for \p D to \p OS.
- /// \returns true on failure, false on success.
- bool writeName(const Decl *D, raw_ostream &OS);
- /// \returns name for \p D
- std::string getName(const Decl *D);
- /// \returns all applicable mangled names.
- /// For example C++ constructors/destructors can have multiple.
- std::vector<std::string> getAllManglings(const Decl *D);
- private:
- class Implementation;
- std::unique_ptr<Implementation> Impl;
- };
- }
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|