//===- TemplateDeduction.h - C++ template argument deduction ----*- C++ -*-===/
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===/
//
//  This file provides types used with Sema's template argument deduction
// routines.
//
//===----------------------------------------------------------------------===/
#ifndef LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H
#define LLVM_CLANG_SEMA_TEMPLATE_DEDUCTION_H

#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/SmallVector.h"

namespace clang {

struct DeducedPack;
class TemplateArgumentList;
class Sema;

namespace sema {

/// \brief Provides information about an attempted template argument
/// deduction, whose success or failure was described by a
/// TemplateDeductionResult value.
class TemplateDeductionInfo {
  /// \brief The deduced template argument list.
  ///
  TemplateArgumentList *Deduced;

  /// \brief The source location at which template argument
  /// deduction is occurring.
  SourceLocation Loc;

  /// \brief Have we suppressed an error during deduction?
  bool HasSFINAEDiagnostic;

  /// \brief Warnings (and follow-on notes) that were suppressed due to
  /// SFINAE while performing template argument deduction.
  SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics;

  TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;
  void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION;

public:
  TemplateDeductionInfo(SourceLocation Loc)
    : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
      Expression(nullptr) {}

  /// \brief Returns the location at which template argument is
  /// occurring.
  SourceLocation getLocation() const {
    return Loc;
  }

  /// \brief Take ownership of the deduced template argument list.
  TemplateArgumentList *take() {
    TemplateArgumentList *Result = Deduced;
    Deduced = nullptr;
    return Result;
  }

  /// \brief Take ownership of the SFINAE diagnostic.
  void takeSFINAEDiagnostic(PartialDiagnosticAt &PD) {
    assert(HasSFINAEDiagnostic);
    PD.first = SuppressedDiagnostics.front().first;
    PD.second.swap(SuppressedDiagnostics.front().second);
    SuppressedDiagnostics.clear();
    HasSFINAEDiagnostic = false;
  }

  /// \brief Provide a new template argument list that contains the
  /// results of template argument deduction.
  void reset(TemplateArgumentList *NewDeduced) {
    Deduced = NewDeduced;
  }

  /// \brief Is a SFINAE diagnostic available?
  bool hasSFINAEDiagnostic() const {
    return HasSFINAEDiagnostic;
  }

  /// \brief Set the diagnostic which caused the SFINAE failure.
  void addSFINAEDiagnostic(SourceLocation Loc, PartialDiagnostic PD) {
    // Only collect the first diagnostic.
    if (HasSFINAEDiagnostic)
      return;
    SuppressedDiagnostics.clear();
    SuppressedDiagnostics.push_back(
        std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
    SuppressedDiagnostics.back().second.swap(PD);
    HasSFINAEDiagnostic = true;
  }

  /// \brief Add a new diagnostic to the set of diagnostics
  void addSuppressedDiagnostic(SourceLocation Loc,
                               PartialDiagnostic PD) {
    if (HasSFINAEDiagnostic)
      return;
    SuppressedDiagnostics.push_back(
        std::make_pair(Loc, PartialDiagnostic::NullDiagnostic()));
    SuppressedDiagnostics.back().second.swap(PD);
  }

  /// \brief Iterator over the set of suppressed diagnostics.
  typedef SmallVectorImpl<PartialDiagnosticAt>::const_iterator
    diag_iterator;

  /// \brief Returns an iterator at the beginning of the sequence of suppressed
  /// diagnostics.
  diag_iterator diag_begin() const { return SuppressedDiagnostics.begin(); }

  /// \brief Returns an iterator at the end of the sequence of suppressed
  /// diagnostics.
  diag_iterator diag_end() const { return SuppressedDiagnostics.end(); }

  /// \brief The template parameter to which a template argument
  /// deduction failure refers.
  ///
  /// Depending on the result of template argument deduction, this
  /// template parameter may have different meanings:
  ///
  ///   TDK_Incomplete: this is the first template parameter whose
  ///   corresponding template argument was not deduced.
  ///
  ///   TDK_Inconsistent: this is the template parameter for which
  ///   two different template argument values were deduced.
  TemplateParameter Param;

  /// \brief The first template argument to which the template
  /// argument deduction failure refers.
  ///
  /// Depending on the result of the template argument deduction,
  /// this template argument may have different meanings:
  ///
  ///   TDK_Inconsistent: this argument is the first value deduced
  ///   for the corresponding template parameter.
  ///
  ///   TDK_SubstitutionFailure: this argument is the template
  ///   argument we were instantiating when we encountered an error.
  ///
  ///   TDK_NonDeducedMismatch: this is the component of the 'parameter'
  ///   of the deduction, directly provided in the source code.
  TemplateArgument FirstArg;

  /// \brief The second template argument to which the template
  /// argument deduction failure refers.
  ///
  ///   TDK_NonDeducedMismatch: this is the mismatching component of the
  ///   'argument' of the deduction, from which we are deducing arguments.
  ///
  /// FIXME: Finish documenting this.
  TemplateArgument SecondArg;

  /// \brief The expression which caused a deduction failure.
  ///
  ///   TDK_FailedOverloadResolution: this argument is the reference to
  ///   an overloaded function which could not be resolved to a specific
  ///   function.
  Expr *Expression;

  /// \brief Information on packs that we're currently expanding.
  ///
  /// FIXME: This should be kept internal to SemaTemplateDeduction.
  SmallVector<DeducedPack *, 8> PendingDeducedPacks;
};

} // end namespace sema

/// A structure used to record information about a failed
/// template argument deduction, for diagnosis.
struct DeductionFailureInfo {
  /// A Sema::TemplateDeductionResult.
  unsigned Result : 8;

  /// \brief Indicates whether a diagnostic is stored in Diagnostic.
  unsigned HasDiagnostic : 1;

  /// \brief Opaque pointer containing additional data about
  /// this deduction failure.
  void *Data;

  /// \brief A diagnostic indicating why deduction failed.
  union {
    void *Align;
    char Diagnostic[sizeof(PartialDiagnosticAt)];
  };

  /// \brief Retrieve the diagnostic which caused this deduction failure,
  /// if any.
  PartialDiagnosticAt *getSFINAEDiagnostic();

  /// \brief Retrieve the template parameter this deduction failure
  /// refers to, if any.
  TemplateParameter getTemplateParameter();

  /// \brief Retrieve the template argument list associated with this
  /// deduction failure, if any.
  TemplateArgumentList *getTemplateArgumentList();

  /// \brief Return the first template argument this deduction failure
  /// refers to, if any.
  const TemplateArgument *getFirstArg();

  /// \brief Return the second template argument this deduction failure
  /// refers to, if any.
  const TemplateArgument *getSecondArg();

  /// \brief Return the expression this deduction failure refers to,
  /// if any.
  Expr *getExpr();

  /// \brief Free any memory associated with this deduction failure.
  void Destroy();
};

/// TemplateSpecCandidate - This is a generalization of OverloadCandidate
/// which keeps track of template argument deduction failure info, when
/// handling explicit specializations (and instantiations) of templates
/// beyond function overloading.
/// For now, assume that the candidates are non-matching specializations.
/// TODO: In the future, we may need to unify/generalize this with
/// OverloadCandidate.
struct TemplateSpecCandidate {
  /// Specialization - The actual specialization that this candidate
  /// represents. When NULL, this may be a built-in candidate.
  Decl *Specialization;

  /// Template argument deduction info
  DeductionFailureInfo DeductionFailure;

  void set(Decl *Spec, DeductionFailureInfo Info) {
    Specialization = Spec;
    DeductionFailure = Info;
  }

  /// Diagnose a template argument deduction failure.
  void NoteDeductionFailure(Sema &S);
};

/// TemplateSpecCandidateSet - A set of generalized overload candidates,
/// used in template specializations.
/// TODO: In the future, we may need to unify/generalize this with
/// OverloadCandidateSet.
class TemplateSpecCandidateSet {
  SmallVector<TemplateSpecCandidate, 16> Candidates;
  SourceLocation Loc;

  TemplateSpecCandidateSet(
      const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;
  void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION;

  void destroyCandidates();

public:
  TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {}
  ~TemplateSpecCandidateSet() { destroyCandidates(); }

  SourceLocation getLocation() const { return Loc; }

  /// \brief Clear out all of the candidates.
  /// TODO: This may be unnecessary.
  void clear();

  typedef SmallVector<TemplateSpecCandidate, 16>::iterator iterator;
  iterator begin() { return Candidates.begin(); }
  iterator end() { return Candidates.end(); }

  size_t size() const { return Candidates.size(); }
  bool empty() const { return Candidates.empty(); }

  /// \brief Add a new candidate with NumConversions conversion sequence slots
  /// to the overload set.
  TemplateSpecCandidate &addCandidate() {
    Candidates.push_back(TemplateSpecCandidate());
    return Candidates.back();
  }

  void NoteCandidates(Sema &S, SourceLocation Loc);

  void NoteCandidates(Sema &S, SourceLocation Loc) const {
    const_cast<TemplateSpecCandidateSet *>(this)->NoteCandidates(S, Loc);
  }
};

} // end namespace clang

#endif
