//===--- ASTConcept.h - Concepts Related AST Data Structures ----*- 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file provides AST data structures related to concepts.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_ASTCONCEPT_H
#define LLVM_CLANG_AST_ASTCONCEPT_H

#include "clang/AST/Expr.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include <utility>

namespace clang {
class ConceptDecl;
class ConceptSpecializationExpr;

/// The result of a constraint satisfaction check, containing the necessary
/// information to diagnose an unsatisfied constraint.
class ConstraintSatisfaction : public llvm::FoldingSetNode {
  // The template-like entity that 'owns' the constraint checked here (can be a
  // constrained entity or a concept).
  const NamedDecl *ConstraintOwner = nullptr;
  llvm::SmallVector<TemplateArgument, 4> TemplateArgs;

public:

  ConstraintSatisfaction() = default;

  ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
                         ArrayRef<TemplateArgument> TemplateArgs) :
      ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
                                                     TemplateArgs.end()) { }

  using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
  using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;

  bool IsSatisfied = false;

  /// \brief Pairs of unsatisfied atomic constraint expressions along with the
  /// substituted constraint expr, if the template arguments could be
  /// substituted into them, or a diagnostic if substitution resulted in an
  /// invalid expression.
  llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;

  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
    Profile(ID, C, ConstraintOwner, TemplateArgs);
  }

  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
                      const NamedDecl *ConstraintOwner,
                      ArrayRef<TemplateArgument> TemplateArgs);
};

/// Pairs of unsatisfied atomic constraint expressions along with the
/// substituted constraint expr, if the template arguments could be
/// substituted into them, or a diagnostic if substitution resulted in
/// an invalid expression.
using UnsatisfiedConstraintRecord =
    std::pair<const Expr *,
              llvm::PointerUnion<Expr *,
                                 std::pair<SourceLocation, StringRef> *>>;

/// \brief The result of a constraint satisfaction check, containing the
/// necessary information to diagnose an unsatisfied constraint.
///
/// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
struct ASTConstraintSatisfaction final :
    llvm::TrailingObjects<ASTConstraintSatisfaction,
                          UnsatisfiedConstraintRecord> {
  std::size_t NumRecords;
  bool IsSatisfied : 1;

  const UnsatisfiedConstraintRecord *begin() const {
    return getTrailingObjects<UnsatisfiedConstraintRecord>();
  }

  const UnsatisfiedConstraintRecord *end() const {
    return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
  }

  ASTConstraintSatisfaction(const ASTContext &C,
                            const ConstraintSatisfaction &Satisfaction);

  static ASTConstraintSatisfaction *
  Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
};

/// \brief Common data class for constructs that reference concepts with
/// template arguments.
class ConceptReference {
protected:
  // \brief The optional nested name specifier used when naming the concept.
  NestedNameSpecifierLoc NestedNameSpec;

  /// \brief The location of the template keyword, if specified when naming the
  /// concept.
  SourceLocation TemplateKWLoc;

  /// \brief The concept name used.
  DeclarationNameInfo ConceptName;

  /// \brief The declaration found by name lookup when the expression was
  /// created.
  /// Can differ from NamedConcept when, for example, the concept was found
  /// through a UsingShadowDecl.
  NamedDecl *FoundDecl;

  /// \brief The concept named.
  ConceptDecl *NamedConcept;

  /// \brief The template argument list source info used to specialize the
  /// concept.
  const ASTTemplateArgumentListInfo *ArgsAsWritten;

public:

  ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
                   DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
                   ConceptDecl *NamedConcept,
                   const ASTTemplateArgumentListInfo *ArgsAsWritten) :
      NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
      ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
      NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}

  ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
      FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}

  const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
    return NestedNameSpec;
  }

  const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }

  SourceLocation getConceptNameLoc() const {
    return getConceptNameInfo().getLoc();
  }

  SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }

  NamedDecl *getFoundDecl() const {
    return FoundDecl;
  }

  ConceptDecl *getNamedConcept() const {
    return NamedConcept;
  }

  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
    return ArgsAsWritten;
  }

  /// \brief Whether or not template arguments were explicitly specified in the
  /// concept reference (they might not be in type constraints, for example)
  bool hasExplicitTemplateArgs() const {
    return ArgsAsWritten != nullptr;
  }
};

class TypeConstraint : public ConceptReference {
  /// \brief The immediately-declared constraint expression introduced by this
  /// type-constraint.
  Expr *ImmediatelyDeclaredConstraint = nullptr;

public:
  TypeConstraint(NestedNameSpecifierLoc NNS,
                 DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
                 ConceptDecl *NamedConcept,
                 const ASTTemplateArgumentListInfo *ArgsAsWritten,
                 Expr *ImmediatelyDeclaredConstraint) :
      ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
                       FoundDecl, NamedConcept, ArgsAsWritten),
      ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}

  /// \brief Get the immediately-declared constraint expression introduced by
  /// this type-constraint, that is - the constraint expression that is added to
  /// the associated constraints of the enclosing declaration in practice.
  Expr *getImmediatelyDeclaredConstraint() const {
    return ImmediatelyDeclaredConstraint;
  }

  void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
};

} // clang

#endif // LLVM_CLANG_AST_ASTCONCEPT_H
