//===--- Mangle.h - Interface to Swift symbol mangling ----------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #ifndef __SWIFT_AST_MANGLE_H__ #define __SWIFT_AST_MANGLE_H__ #include "llvm/ADT/DenseMap.h" #include "swift/AST/Types.h" #include "swift/AST/Decl.h" #include "swift/AST/GenericSignature.h" namespace swift { class AbstractClosureExpr; namespace Mangle { enum class IncludeType : bool { No, Yes }; enum class OperatorFixity { NotOperator, Infix, Prefix, Postfix }; /// A class for mangling declarations. The Mangler accumulates name fragments /// with the mangleXXX methods, and the final string is constructed with the /// `finalize` method, after which the Mangler should not be used. class Mangler { struct ArchetypeInfo { unsigned Depth; unsigned Index; }; llvm::SmallVector Storage; llvm::raw_svector_ostream Buffer; llvm::DenseMap Substitutions; llvm::DenseMap Archetypes; CanGenericSignature CurGenericSignature; unsigned ArchetypesDepth = 0; ModuleDecl *Mod = nullptr; const DeclContext *DeclCtx = nullptr; /// If enabled, Arche- and Alias types are mangled with context. bool DWARFMangling; /// If enabled, non-ASCII names are encoded in modified Punycode. bool UsePunycode; public: enum BindGenerics : unsigned { /// We don't intend to mangle any sort of type within this context /// and so do not require its generic parameters to be bound. None, /// We are going to mangle a method declared in this context /// (which must be a type context) and do not need its generic /// parameters, or the parameters from its enclosing types, to be /// bound because we will bind them as part of processing the /// method's formal signature. Enclosing, /// We intend to mangle a type which may be dependent on the /// context and so require all generic parameters to be bound. All }; class ContextStack { Mangler &M; unsigned OldDepth; ContextStack(const ContextStack &) = delete; ContextStack &operator=(const ContextStack &) = delete; public: ContextStack(Mangler &M) : M(M), OldDepth(M.ArchetypesDepth) { M.ArchetypesDepth = 0; } ~ContextStack() { M.ArchetypesDepth = OldDepth; } }; /// Finish the mangling of the symbol and return the mangled name. std::string finalize(); /// Finish the mangling of the symbol and write the mangled name into /// \p stream. void finalize(llvm::raw_ostream &stream); void setModuleContext(ModuleDecl *M) { Mod = M; } /// \param DWARFMangling - use the 'Qq' mangling format for /// archetypes and the 'a' mangling for alias types. /// \param usePunycode - emit modified Punycode instead of UTF-8. Mangler(bool DWARFMangling = false, bool usePunycode = true) : Buffer(Storage), DWARFMangling(DWARFMangling), UsePunycode(usePunycode) {} void mangleContextOf(const ValueDecl *decl, BindGenerics shouldBind); void mangleContext(const DeclContext *ctx, BindGenerics shouldBind); void mangleModule(const ModuleDecl *module); void mangleDeclName(const ValueDecl *decl); void mangleDeclType(const ValueDecl *decl, unsigned uncurryingLevel); void mangleEntity(const ValueDecl *decl, unsigned uncurryingLevel); void mangleConstructorEntity(const ConstructorDecl *ctor, bool isAllocating, unsigned uncurryingLevel); void mangleDestructorEntity(const DestructorDecl *decl, bool isDeallocating); void mangleIVarInitDestroyEntity(const ClassDecl *decl, bool isDestroyer); void mangleAccessorEntity(AccessorKind kind, AddressorKind addressorKind, const AbstractStorageDecl *decl); void mangleAddressorEntity(const ValueDecl *decl); void mangleGlobalGetterEntity(ValueDecl *decl); void mangleDefaultArgumentEntity(const DeclContext *ctx, unsigned index); void mangleInitializerEntity(const VarDecl *var); void mangleClosureEntity(const SerializedAbstractClosureExpr *closure, unsigned uncurryingLevel); void mangleClosureEntity(const AbstractClosureExpr *closure, unsigned uncurryingLevel); void mangleNominalType(const NominalTypeDecl *decl, BindGenerics shouldBind, CanGenericSignature extGenericSig = nullptr, const GenericParamList *extGenericParams = nullptr); void mangleProtocolDecl(const ProtocolDecl *protocol); void mangleType(Type type, unsigned uncurryingLevel); void mangleDirectness(bool isIndirect); void mangleProtocolName(const ProtocolDecl *protocol); void mangleProtocolConformance(const ProtocolConformance *conformance); void bindGenericParameters(CanGenericSignature sig, const GenericParamList *genericParams); void addSubstitution(const void *ptr); void mangleDeclTypeForDebugger(const ValueDecl *decl); void mangleTypeForDebugger(Type decl, const DeclContext *DC); void mangleGenericSignature(const GenericSignature *sig); void mangleFieldOffsetFull(const ValueDecl *decl, bool isIndirect); void mangleTypeMetadataFull(CanType ty, bool isPattern); void mangleTypeFullMetadataFull(CanType ty); void mangleGlobalVariableFull(const VarDecl *decl); /// Adds the string \p S into the mangled name. void append(StringRef S); /// Adds the char \p C into the mangled name. void append(char C); /// Add the already mangled symbol \p Name as an identifier. (using the /// length prefix). void mangleIdentifierSymbol(StringRef Name); /// Add the already mangled symbol \p Name. This gives the mangler the /// opportunity to decode \p Name before adding it to the mangled name. void appendSymbol(StringRef Name); /// Mangle the integer \p Nat into the name. void mangleNatural(const APInt &Nat); /// Mangles globalinit_token and globalinit_func, which are used to /// initialize global variables. /// \param decl The global variable or one of the global variables of a /// pattern, e.g. var (a, b) = (1, 2) /// \param counter A consecutive number inside the compiled file. /// \param isInitFunc If true it's a globalinit_func, otherwise a /// globalinit_token. void mangleGlobalInit(const VarDecl *decl, int counter, bool isInitFunc); void mangleIdentifier(StringRef ref, OperatorFixity fixity = OperatorFixity::NotOperator, bool isOperator=false); void resetArchetypesDepth() { ArchetypesDepth = 0; } private: void mangleFunctionType(AnyFunctionType *fn, unsigned uncurryingLevel); void mangleProtocolList(ArrayRef protocols); void mangleProtocolList(ArrayRef protocols); void mangleIdentifier(Identifier ident, OperatorFixity fixity = OperatorFixity::NotOperator); void mangleClosureComponents(Type Ty, unsigned discriminator, bool isImplicit, const DeclContext *parentContext, const DeclContext *localContext); bool tryMangleStandardSubstitution(const NominalTypeDecl *type); bool tryMangleSubstitution(const void *ptr); /// \brief Mangles a sugared type iff we are mangling for the debugger. template void mangleSugaredType(Type type) { assert(DWARFMangling && "sugared types are only legal when mangling for the debugger"); auto *BlandTy = cast(type.getPointer())->getSinglyDesugaredType(); mangleType(BlandTy, 0); } void mangleGenericSignatureParts(ArrayRef params, unsigned initialParamDepth, ArrayRef requirements); Type getDeclTypeForMangling(const ValueDecl *decl, ArrayRef &genericParams, unsigned &initialParamIndex, ArrayRef &requirements, SmallVectorImpl &requirementsBuf); void mangleGenericParamIndex(GenericTypeParamType *paramTy); void mangleAssociatedTypeName(DependentMemberType *dmt, bool canAbbreviate); void mangleConstrainedType(CanType type); CanGenericSignature getCanonicalSignatureOrNull(GenericSignature *sig, ModuleDecl &M); }; } // end namespace Mangle } // end namespace swift #endif