//===--- GenericRequirement.h - Generic requirements ------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This class describes types for working with requirements of generic
// signatures and the layout of the generic arguments section of
// generic type metadata.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_GENERICREQUIREMENT_H
#define SWIFT_IRGEN_GENERICREQUIREMENT_H

#include "swift/AST/Type.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/DenseMapInfo.h"

namespace llvm {
class Value;
}

namespace swift {
class CanGenericSignature;
class ModuleDecl;
class NominalTypeDecl;
class ProtocolDecl;
class SubstitutionMap;

namespace irgen {
class Address;
class IRGenFunction;
class IRGenModule;

/// An abstract generic requirement.
struct GenericRequirement {
  CanType TypeParameter;
  ProtocolDecl *Protocol;
};

/// Given an array of substitutions that parallel the dependent
/// signature for which a requirement was emitted, emit the required
/// value.
llvm::Value *
emitGenericRequirementFromSubstitutions(IRGenFunction &IGF,
                                        CanGenericSignature signature,
                                        ModuleDecl &module,
                                        GenericRequirement requirement,
                                        const SubstitutionMap &subs);

using EmitGenericRequirementFn =
  llvm::function_ref<llvm::Value*(GenericRequirement reqt)>;
void emitInitOfGenericRequirementsBuffer(IRGenFunction &IGF,
                                         ArrayRef<GenericRequirement> reqts,
                                         Address buffer,
                                      EmitGenericRequirementFn emitRequirement);

using GetTypeParameterInContextFn =
  llvm::function_ref<CanType(CanType type)>;

/// Given a required value, map the requirement into the given
/// context and bind the value.
void bindGenericRequirement(IRGenFunction &IGF,
                            GenericRequirement requirement,
                            llvm::Value *requiredValue,
                            GetTypeParameterInContextFn getInContext);

void bindFromGenericRequirementsBuffer(IRGenFunction &IGF,
                                       ArrayRef<GenericRequirement> reqts,
                                       Address buffer,
                                       GetTypeParameterInContextFn getInContext);


/// A class describing the layout of the generic requirements of a
/// nominal type metadata.
///
/// The generic requirements are always laid out as a sequence of type
/// metadata (corresponding to the type parameters of the context established
/// by the type, minus anything fulfillable from its parent type metadata)
/// followed by a sequence of protocol witness tables (corresponding to the
/// root conformances of the context established by the type, again minus
/// anything fulfillable from its parent type metadata).
class GenericTypeRequirements {
  NominalTypeDecl *TheDecl;
  CanType ParentType;
  llvm::SmallVector<GenericRequirement, 4> Requirements;

public:
  GenericTypeRequirements(IRGenModule &IGM, NominalTypeDecl *decl);

  /// Return the layout chunks.
  ArrayRef<GenericRequirement> getRequirements() const {
    return Requirements;
  }

  /// Does this generic type have 
  bool hasParentType() const {
    return bool(ParentType);
  }

  CanType getParentType() const {
    return ParentType;
  }

  /// Return the number of entries required in order to store this data.
  unsigned getStorageSizeInWords() const {
    return Requirements.size();
  }

  /// Return the number of type metadata requirements.
  unsigned getNumTypeRequirements() const {
    unsigned count = 0;
    for (auto i = Requirements.begin(), e = Requirements.end(); i != e; ++i) {
      if (!i->Protocol) {
        count++;
      } else {
#ifndef NDEBUG
        // Assert that the rest of the requirements are conformance
        // requirements.
        for (++i; i != e; ++i) {
          assert(i->Protocol && "type requirement followed conformance!");
        }
#endif
        break;
      }
    }
    return count;
  }

  bool empty() const { return Requirements.empty(); }

  using FulfillmentCallback =
    llvm::function_ref<void(unsigned requirementIndex,
                            CanType type,
                            Optional<ProtocolConformanceRef> conf)>;
  void enumerateFulfillments(IRGenModule &IGM, const SubstitutionMap &subs,
                             FulfillmentCallback callback);

  void emitInitOfBuffer(IRGenFunction &IGF, const SubstitutionMap &subs,
                        Address buffer);

  void bindFromBuffer(IRGenFunction &IGF, Address buffer,
                      GetTypeParameterInContextFn getInContext);
};

} // end namespace irgen
} // end namespace swift

namespace llvm {
  template <> struct DenseMapInfo<swift::irgen::GenericRequirement> {
    using GenericRequirement = swift::irgen::GenericRequirement;
    using CanTypeInfo = llvm::DenseMapInfo<swift::CanType>;
    static GenericRequirement getEmptyKey() {
      return { CanTypeInfo::getEmptyKey(), nullptr };
    }
    static GenericRequirement getTombstoneKey() {
      return { CanTypeInfo::getTombstoneKey(), nullptr };
    }
    static llvm::hash_code getHashValue(GenericRequirement req) {
      return hash_combine(CanTypeInfo::getHashValue(req.TypeParameter),
                          hash_value(req.Protocol));
    }
    static bool isEqual(GenericRequirement lhs, GenericRequirement rhs) {
      return (lhs.TypeParameter == rhs.TypeParameter &&
              lhs.Protocol == rhs.Protocol);
    }
  };
}

#endif
