//===--- ASTMangler.h - Swift AST symbol mangling ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_ASTMANGLER_H
#define SWIFT_AST_ASTMANGLER_H

#include "swift/Basic/Mangler.h"
#include "swift/AST/Types.h"
#include "swift/AST/Decl.h"

namespace clang {
class NamedDecl;
}

namespace swift {

class AbstractClosureExpr;
class ConformanceAccessPath;
class RootProtocolConformance;

namespace Mangle {

/// The mangler for AST declarations.
class ASTMangler : public Mangler {
protected:
  CanGenericSignature CurGenericSignature;
  ModuleDecl *Mod = nullptr;

  /// Optimize out protocol names if a type only conforms to one protocol.
  bool OptimizeProtocolNames = true;

  /// If enabled, use Objective-C runtime names when mangling @objc Swift
  /// protocols and classes.
  bool UseObjCRuntimeNames = false;

  /// If enabled, non-canonical types are allowed and type alias types get a
  /// special mangling.
  bool DWARFMangling;

  /// If enabled, entities that ought to have names but don't get a placeholder.
  ///
  /// If disabled, it is an error to try to mangle such an entity.
  bool AllowNamelessEntities = false;

  /// If enabled, some entities will be emitted as symbolic reference
  /// placeholders. The offsets of these references will be stored in the
  /// `SymbolicReferences` vector, and it is up to the consumer of the mangling
  /// to fill these in.
  bool AllowSymbolicReferences = false;

public:
  using SymbolicReferent = llvm::PointerUnion<const NominalTypeDecl *,
                                              const OpaqueTypeDecl *>;
protected:

  /// If set, the mangler calls this function to determine whether to symbolic
  /// reference a given entity. If null, the mangler acts as if it's set to
  /// always return true.
  std::function<bool (SymbolicReferent)> CanSymbolicReference;
  
  bool canSymbolicReference(SymbolicReferent referent) {
    return AllowSymbolicReferences
      && (!CanSymbolicReference || CanSymbolicReference(referent));
  }

  std::vector<std::pair<SymbolicReferent, unsigned>> SymbolicReferences;
  
public:
  enum class SymbolKind {
    Default,
    AsyncHandlerBody,
    DynamicThunk,
    SwiftAsObjCThunk,
    ObjCAsSwiftThunk,
  };

  ASTMangler(bool DWARFMangling = false)
    : DWARFMangling(DWARFMangling) {}

  void addTypeSubstitution(Type type) {
    type = dropProtocolsFromAssociatedTypes(type);
    addSubstitution(type.getPointer());
  }
  bool tryMangleTypeSubstitution(Type type) {
    type = dropProtocolsFromAssociatedTypes(type);
    return tryMangleSubstitution(type.getPointer());
  }

  std::string mangleClosureEntity(const AbstractClosureExpr *closure,
                                  SymbolKind SKind);

  std::string mangleEntity(const ValueDecl *decl,
                           SymbolKind SKind = SymbolKind::Default);

  std::string mangleDestructorEntity(const DestructorDecl *decl,
                                     bool isDeallocating,
                                     SymbolKind SKind = SymbolKind::Default);

  std::string mangleConstructorEntity(const ConstructorDecl *ctor,
                                      bool isAllocating,
                                      SymbolKind SKind = SymbolKind::Default);

  std::string mangleIVarInitDestroyEntity(const ClassDecl *decl,
                                          bool isDestroyer, SymbolKind SKind);

  std::string mangleAccessorEntity(AccessorKind kind,
                                   const AbstractStorageDecl *decl,
                                   bool isStatic,
                                   SymbolKind SKind);

  std::string mangleGlobalGetterEntity(const ValueDecl *decl,
                                       SymbolKind SKind = SymbolKind::Default);

  std::string mangleDefaultArgumentEntity(const DeclContext *func,
                                          unsigned index,
                                          SymbolKind SKind = SymbolKind::Default);

  std::string mangleInitializerEntity(const VarDecl *var, SymbolKind SKind);
  std::string mangleBackingInitializerEntity(const VarDecl *var,
                                             SymbolKind SKind = SymbolKind::Default);

  std::string mangleNominalType(const NominalTypeDecl *decl);

  std::string mangleVTableThunk(const FuncDecl *Base,
                                const FuncDecl *Derived);

  std::string mangleConstructorVTableThunk(const ConstructorDecl *Base,
                                           const ConstructorDecl *Derived,
                                           bool isAllocating);

  std::string mangleWitnessTable(const RootProtocolConformance *C);

  std::string mangleWitnessThunk(const ProtocolConformance *Conformance,
                                 const ValueDecl *Requirement);

  std::string mangleClosureWitnessThunk(const ProtocolConformance *Conformance,
                                        const AbstractClosureExpr *Closure);

  std::string mangleGlobalVariableFull(const VarDecl *decl);

  std::string mangleGlobalInit(const PatternBindingDecl *decl,
                               unsigned entry,
                               bool isInitFunc);

  std::string mangleReabstractionThunkHelper(CanSILFunctionType ThunkType,
                                             Type FromType, Type ToType,
                                             Type SelfType,
                                             ModuleDecl *Module);

  /// Mangle a completion handler block implementation function, used for importing ObjC
  /// APIs as async.
  ///
  /// - If `predefined` is true, this mangles the symbol name of the completion handler
  /// predefined in the Swift runtime for the given type signature.
  std::string mangleObjCAsyncCompletionHandlerImpl(CanSILFunctionType BlockType,
                                                   CanType ResultType,
                                                   bool predefined);
  
  /// Mangle the derivative function (JVP/VJP) for the given:
  /// - Mangled original function name.
  /// - Derivative function kind.
  /// - Derivative function configuration: parameter/result indices and
  ///   derivative generic signature.
  std::string
  mangleAutoDiffDerivativeFunctionHelper(StringRef name,
                                         AutoDiffDerivativeFunctionKind kind,
                                         AutoDiffConfig config);

  /// Mangle the linear map (differential/pullback) for the given:
  /// - Mangled original function name.
  /// - Linear map kind.
  /// - Derivative function configuration: parameter/result indices and
  ///   derivative generic signature.
  std::string mangleAutoDiffLinearMapHelper(StringRef name,
                                            AutoDiffLinearMapKind kind,
                                            AutoDiffConfig config);

  /// Mangle the AutoDiff generated declaration for the given:
  /// - Generated declaration kind: linear map struct or branching trace enum.
  /// - Mangled original function name.
  /// - Basic block number.
  /// - Linear map kind: differential or pullback.
  /// - Derivative function configuration: parameter/result indices and
  ///   derivative generic signature.
  std::string
  mangleAutoDiffGeneratedDeclaration(AutoDiffGeneratedDeclarationKind declKind,
                                     StringRef origFnName, unsigned bbId,
                                     AutoDiffLinearMapKind linearMapKind,
                                     AutoDiffConfig config);

  /// Mangle a SIL differentiability witness key:
  /// - Mangled original function name.
  /// - Parameter indices.
  /// - Result indices.
  /// - Derivative generic signature (optional).
  std::string
  mangleSILDifferentiabilityWitnessKey(SILDifferentiabilityWitnessKey key);

  std::string mangleKeyPathGetterThunkHelper(const AbstractStorageDecl *property,
                                             GenericSignature signature,
                                             CanType baseType,
                                             SubstitutionMap subs,
                                             ResilienceExpansion expansion);
  std::string mangleKeyPathSetterThunkHelper(const AbstractStorageDecl *property,
                                             GenericSignature signature,
                                             CanType baseType,
                                             SubstitutionMap subs,
                                             ResilienceExpansion expansion);
  std::string mangleKeyPathEqualsHelper(ArrayRef<CanType> indices,
                                        GenericSignature signature,
                                        ResilienceExpansion expansion);
  std::string mangleKeyPathHashHelper(ArrayRef<CanType> indices,
                                      GenericSignature signature,
                                      ResilienceExpansion expansion);

  std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);

  /// Create a mangled name to be used for _typeName constant propagation.
  std::string mangleTypeForTypeName(Type type);

  std::string mangleOpaqueTypeDescriptor(const OpaqueTypeDecl *decl);
  
  std::string mangleDeclType(const ValueDecl *decl);
  
  std::string mangleObjCRuntimeName(const NominalTypeDecl *Nominal);

  std::string mangleTypeWithoutPrefix(Type type) {
    appendType(type);
    return finalize();
  }

  std::string mangleTypeAsUSR(Type decl);

  std::string mangleTypeAsContextUSR(const NominalTypeDecl *type);

  std::string mangleDeclAsUSR(const ValueDecl *Decl, StringRef USRPrefix);

  std::string mangleAccessorEntityAsUSR(AccessorKind kind,
                                        const AbstractStorageDecl *decl,
                                        StringRef USRPrefix,
                                        bool IsStatic);

  std::string mangleLocalTypeDecl(const TypeDecl *type);

  std::string mangleOpaqueTypeDecl(const OpaqueTypeDecl *decl);

  std::string mangleOpaqueTypeDecl(const ValueDecl *decl);

  enum SpecialContext {
    ObjCContext,
    ClangImporterContext,
  };
  
  static Optional<SpecialContext>
  getSpecialManglingContext(const ValueDecl *decl, bool useObjCProtocolNames);

  static const clang::NamedDecl *
  getClangDeclForMangling(const ValueDecl *decl);

protected:

  void appendSymbolKind(SymbolKind SKind);

  void appendType(Type type, const ValueDecl *forDecl = nullptr);
  
  void appendDeclName(const ValueDecl *decl);

  GenericTypeParamType *appendAssocType(DependentMemberType *DepTy,
                                        bool &isAssocTypeAtDepth);

  void appendOpWithGenericParamIndex(StringRef,
                                     const GenericTypeParamType *paramTy);

  void bindGenericParameters(const DeclContext *DC);

  void bindGenericParameters(CanGenericSignature sig);

  /// Mangles a sugared type iff we are mangling for the debugger.
  template <class T> void appendSugaredType(Type type,
                                            const ValueDecl *forDecl) {
    assert(DWARFMangling &&
           "sugared types are only legal when mangling for the debugger");
    auto *BlandTy = cast<T>(type.getPointer())->getSinglyDesugaredType();
    appendType(BlandTy, forDecl);
  }

  void appendBoundGenericArgs(Type type, bool &isFirstArgList);

  /// Append the bound generics arguments for the given declaration context
  /// based on a complete substitution map.
  ///
  /// \returns the number of generic parameters that were emitted
  /// thus far.
  unsigned appendBoundGenericArgs(DeclContext *dc,
                                  SubstitutionMap subs,
                                  bool &isFirstArgList);
  
  /// Append the bound generic arguments as a flat list, disregarding depth.
  void appendFlatGenericArgs(SubstitutionMap subs);

  /// Append any retroactive conformances.
  void appendRetroactiveConformances(Type type);
  void appendRetroactiveConformances(SubstitutionMap subMap,
                                     ModuleDecl *fromModule);
  void appendImplFunctionType(SILFunctionType *fn);

  void appendContextOf(const ValueDecl *decl);

  void appendContext(const DeclContext *ctx, StringRef useModuleName);

  void appendModule(const ModuleDecl *module, StringRef useModuleName);

  void appendProtocolName(const ProtocolDecl *protocol,
                          bool allowStandardSubstitution = true);

  void appendAnyGenericType(const GenericTypeDecl *decl);

  enum FunctionManglingKind {
    NoFunctionMangling,
    FunctionMangling,
    AsyncHandlerBodyMangling
  };

  void appendFunction(AnyFunctionType *fn,
                    FunctionManglingKind functionMangling = NoFunctionMangling,
                    const ValueDecl *forDecl = nullptr);
  void appendFunctionType(AnyFunctionType *fn, bool isAutoClosure = false,
                          const ValueDecl *forDecl = nullptr);
  void appendClangType(AnyFunctionType *fn);
  template <typename FnType>
  void appendClangType(FnType *fn, llvm::raw_svector_ostream &os);

  void appendFunctionSignature(AnyFunctionType *fn,
                               const ValueDecl *forDecl,
                               FunctionManglingKind functionMangling);

  void appendFunctionInputType(ArrayRef<AnyFunctionType::Param> params,
                               const ValueDecl *forDecl = nullptr);
  void appendFunctionResultType(Type resultType,
                                const ValueDecl *forDecl = nullptr);

  void appendTypeList(Type listTy, const ValueDecl *forDecl = nullptr);
  void appendTypeListElement(Identifier name, Type elementType,
                             ParameterTypeFlags flags,
                             const ValueDecl *forDecl = nullptr);

  /// Append a generic signature to the mangling.
  ///
  /// \param sig The generic signature.
  ///
  /// \param contextSig The signature of the known context. This function
  /// will only mangle the difference between \c sig and \c contextSig.
  ///
  /// \returns \c true if a generic signature was appended, \c false
  /// if it was empty.
  bool appendGenericSignature(GenericSignature sig,
                              GenericSignature contextSig = GenericSignature());

  void appendRequirement(const Requirement &reqt);

  void appendGenericSignatureParts(TypeArrayView<GenericTypeParamType> params,
                                   unsigned initialParamDepth,
                                   ArrayRef<Requirement> requirements);

  DependentMemberType *dropProtocolFromAssociatedType(DependentMemberType *dmt);
  Type dropProtocolsFromAssociatedTypes(Type type);

  void appendAssociatedTypeName(DependentMemberType *dmt);

  void appendClosureEntity(const SerializedAbstractClosureExpr *closure);
  
  void appendClosureEntity(const AbstractClosureExpr *closure);

  void appendClosureComponents(Type Ty, unsigned discriminator, bool isImplicit,
                               const DeclContext *parentContext);

  void appendDefaultArgumentEntity(const DeclContext *ctx, unsigned index);

  void appendInitializerEntity(const VarDecl *var);
  void appendBackingInitializerEntity(const VarDecl *var);

  CanType getDeclTypeForMangling(const ValueDecl *decl,
                                 GenericSignature &genericSig,
                                 GenericSignature &parentGenericSig);

  

  void appendDeclType(const ValueDecl *decl,
                    FunctionManglingKind functionMangling = NoFunctionMangling);

  bool tryAppendStandardSubstitution(const GenericTypeDecl *type);

  void appendConstructorEntity(const ConstructorDecl *ctor, bool isAllocating);
  
  void appendDestructorEntity(const DestructorDecl *decl, bool isDeallocating);

  /// \param accessorKindCode The code to describe the accessor and addressor
  /// kind. Usually retrieved using getCodeForAccessorKind.
  /// \param decl The storage decl for which to mangle the accessor
  /// \param isStatic Whether or not the accessor is static
  void appendAccessorEntity(StringRef accessorKindCode,
                            const AbstractStorageDecl *decl, bool isStatic);

  void appendEntity(const ValueDecl *decl, StringRef EntityOp, bool isStatic);

  void appendEntity(const ValueDecl *decl, bool isAsyncHandlerBody = false);

  void appendProtocolConformance(const ProtocolConformance *conformance);
  void appendProtocolConformanceRef(const RootProtocolConformance *conformance);
  void appendAnyProtocolConformance(CanGenericSignature genericSig,
                                    CanType conformingType,
                                    ProtocolConformanceRef conformance);
  void appendConcreteProtocolConformance(
                                        const ProtocolConformance *conformance);
  void appendDependentProtocolConformance(const ConformanceAccessPath &path);
  void appendOpParamForLayoutConstraint(LayoutConstraint Layout);
  
  void appendSymbolicReference(SymbolicReferent referent);
  
  void appendOpaqueDeclName(const OpaqueTypeDecl *opaqueDecl);
};

} // end namespace Mangle
} // end namespace swift

#endif // SWIFT_AST_ASTMANGLER_H
