//===--- DiagnosticEngine.h - Diagnostic Display Engine ---------*- 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 file declares the DiagnosticEngine class, which manages any diagnostics
//  emitted by Swift.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_DIAGNOSTICENGINE_H
#define SWIFT_BASIC_DIAGNOSTICENGINE_H

#include "swift/AST/Attr.h"
#include "swift/AST/TypeLoc.h"
#include "swift/AST/DeclNameLoc.h"
#include "swift/AST/DiagnosticConsumer.h"

namespace swift {
  class Decl;
  class DiagnosticEngine;
  class SourceManager;
  class ValueDecl;
  
  enum class PatternKind : uint8_t;
  enum class StaticSpellingKind : uint8_t;
  enum class DescriptiveDeclKind : uint8_t;
  enum DeclAttrKind : unsigned;

  /// \brief Enumeration describing all of possible diagnostics.
  ///
  /// Each of the diagnostics described in Diagnostics.def has an entry in
  /// this enumeration type that uniquely identifies it.
  enum class DiagID : uint32_t;

  /// \brief Describes a diagnostic along with its argument types.
  ///
  /// The diagnostics header introduces instances of this type for each 
  /// diagnostic, which provide both the set of argument types (used to
  /// check/convert the arguments at each call site) and the diagnostic ID
  /// (for other information about the diagnostic).
  template<typename ...ArgTypes>
  struct Diag {
    /// \brief The diagnostic ID corresponding to this diagnostic.
    DiagID ID;
  };

  namespace detail {
    /// \brief Describes how to pass a diagnostic argument of the given type.
    ///
    /// By default, diagnostic arguments are passed by value, because they
    /// tend to be small. Larger diagnostic arguments
    /// need to specialize this class template to pass by reference.
    template<typename T>
    struct PassArgument {
      typedef T type;
    };
  }
    
  /// \brief Describes the kind of diagnostic argument we're storing.
  ///
  enum class DiagnosticArgumentKind {
    String,
    Integer,
    Unsigned,
    Identifier,
    ObjCSelector,
    ValueDecl,
    Type,
    TypeRepr,
    PatternKind,
    StaticSpellingKind,
    DescriptiveDeclKind,
    DeclAttribute,
    VersionTuple,
    LayoutConstraint,
  };

  namespace diag {
    enum class RequirementKind : uint8_t;
  }

  /// \brief Variant type that holds a single diagnostic argument of a known
  /// type.
  ///
  /// All diagnostic arguments are converted to an instance of this class.
  class DiagnosticArgument {
    DiagnosticArgumentKind Kind;
    union {
      int IntegerVal;
      unsigned UnsignedVal;
      StringRef StringVal;
      DeclName IdentifierVal;
      ObjCSelector ObjCSelectorVal;
      ValueDecl *TheValueDecl;
      Type TypeVal;
      TypeRepr *TyR;
      PatternKind PatternKindVal;
      StaticSpellingKind StaticSpellingKindVal;
      DescriptiveDeclKind DescriptiveDeclKindVal;
      const DeclAttribute *DeclAttributeVal;
      clang::VersionTuple VersionVal;
      LayoutConstraint LayoutConstraintVal;
    };
    
  public:
    DiagnosticArgument(StringRef S)
      : Kind(DiagnosticArgumentKind::String), StringVal(S) {
    }

    DiagnosticArgument(int I) 
      : Kind(DiagnosticArgumentKind::Integer), IntegerVal(I) {
    }

    DiagnosticArgument(unsigned I) 
      : Kind(DiagnosticArgumentKind::Unsigned), UnsignedVal(I) {
    }

    DiagnosticArgument(DeclName D)
        : Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(D) {}

    DiagnosticArgument(DeclBaseName D)
        : Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(D) {}

    DiagnosticArgument(Identifier I)
      : Kind(DiagnosticArgumentKind::Identifier), IdentifierVal(I) {
    }

    DiagnosticArgument(ObjCSelector S)
      : Kind(DiagnosticArgumentKind::ObjCSelector), ObjCSelectorVal(S) {
    }

    DiagnosticArgument(ValueDecl *VD)
      : Kind(DiagnosticArgumentKind::ValueDecl), TheValueDecl(VD) {
    }

    DiagnosticArgument(Type T)
      : Kind(DiagnosticArgumentKind::Type), TypeVal(T) {
    }

    DiagnosticArgument(TypeRepr *T)
      : Kind(DiagnosticArgumentKind::TypeRepr), TyR(T) {
    }

    DiagnosticArgument(const TypeLoc &TL) {
      if (TypeRepr *tyR = TL.getTypeRepr()) {
        Kind = DiagnosticArgumentKind::TypeRepr;
        TyR = tyR;
      } else {
        Kind = DiagnosticArgumentKind::Type;
        TypeVal = TL.getType();
      }
    }

    DiagnosticArgument(PatternKind K)
        : Kind(DiagnosticArgumentKind::PatternKind), PatternKindVal(K) {}

    DiagnosticArgument(StaticSpellingKind SSK)
        : Kind(DiagnosticArgumentKind::StaticSpellingKind),
          StaticSpellingKindVal(SSK) {}

    DiagnosticArgument(DescriptiveDeclKind DDK)
        : Kind(DiagnosticArgumentKind::DescriptiveDeclKind),
          DescriptiveDeclKindVal(DDK) {}

    DiagnosticArgument(const DeclAttribute *attr)
        : Kind(DiagnosticArgumentKind::DeclAttribute),
          DeclAttributeVal(attr) {}

    DiagnosticArgument(clang::VersionTuple version)
      : Kind(DiagnosticArgumentKind::VersionTuple),
        VersionVal(version) { }

    DiagnosticArgument(LayoutConstraint L)
      : Kind(DiagnosticArgumentKind::LayoutConstraint), LayoutConstraintVal(L) {
    }
    /// Initializes a diagnostic argument using the underlying type of the
    /// given enum.
    template<
        typename EnumType,
        typename std::enable_if<std::is_enum<EnumType>::value>::type* = nullptr>
    DiagnosticArgument(EnumType value)
      : DiagnosticArgument(
          static_cast<typename std::underlying_type<EnumType>::type>(value)) {}

    DiagnosticArgumentKind getKind() const { return Kind; }

    StringRef getAsString() const {
      assert(Kind == DiagnosticArgumentKind::String);
      return StringVal;
    }

    int getAsInteger() const {
      assert(Kind == DiagnosticArgumentKind::Integer);
      return IntegerVal;
    }

    unsigned getAsUnsigned() const {
      assert(Kind == DiagnosticArgumentKind::Unsigned);
      return UnsignedVal;
    }

    DeclName getAsIdentifier() const {
      assert(Kind == DiagnosticArgumentKind::Identifier);
      return IdentifierVal;
    }

    ObjCSelector getAsObjCSelector() const {
      assert(Kind == DiagnosticArgumentKind::ObjCSelector);
      return ObjCSelectorVal;
    }

    ValueDecl *getAsValueDecl() const {
      assert(Kind == DiagnosticArgumentKind::ValueDecl);
      return TheValueDecl;
    }

    Type getAsType() const {
      assert(Kind == DiagnosticArgumentKind::Type);
      return TypeVal;
    }

    TypeRepr *getAsTypeRepr() const {
      assert(Kind == DiagnosticArgumentKind::TypeRepr);
      return TyR;
    }
    
    PatternKind getAsPatternKind() const {
      assert(Kind == DiagnosticArgumentKind::PatternKind);
      return PatternKindVal;
    }

    StaticSpellingKind getAsStaticSpellingKind() const {
      assert(Kind == DiagnosticArgumentKind::StaticSpellingKind);
      return StaticSpellingKindVal;
    }

    DescriptiveDeclKind getAsDescriptiveDeclKind() const {
      assert(Kind == DiagnosticArgumentKind::DescriptiveDeclKind);
      return DescriptiveDeclKindVal;
    }

    const DeclAttribute *getAsDeclAttribute() const {
      assert(Kind == DiagnosticArgumentKind::DeclAttribute);
      return DeclAttributeVal;
    }

    clang::VersionTuple getAsVersionTuple() const {
      assert(Kind == DiagnosticArgumentKind::VersionTuple);
      return VersionVal;
    }

    LayoutConstraint getAsLayoutConstraint() const {
      assert(Kind == DiagnosticArgumentKind::LayoutConstraint);
      return LayoutConstraintVal;
    }
  };
  
  struct DiagnosticFormatOptions {
    const std::string OpeningQuotationMark;
    const std::string ClosingQuotationMark;
    const std::string AKAFormatString;

    DiagnosticFormatOptions(std::string OpeningQuotationMark,
                            std::string ClosingQuotationMark,
                            std::string AKAFormatString)
        : OpeningQuotationMark(OpeningQuotationMark),
          ClosingQuotationMark(ClosingQuotationMark),
          AKAFormatString(AKAFormatString) {}

    DiagnosticFormatOptions()
        : OpeningQuotationMark("'"), ClosingQuotationMark("'"),
          AKAFormatString("'%1$s' (aka '%2$s')") {}
  };
  
  /// Diagnostic - This is a specific instance of a diagnostic along with all of
  /// the DiagnosticArguments that it requires. 
  class Diagnostic {
  public:
    typedef DiagnosticInfo::FixIt FixIt;

  private:
    DiagID ID;
    SmallVector<DiagnosticArgument, 3> Args;
    SmallVector<CharSourceRange, 2> Ranges;
    SmallVector<FixIt, 2> FixIts;
    SourceLoc Loc;
    const Decl *Decl = nullptr;

  public:
    // All constructors are intentionally implicit.
    template<typename ...ArgTypes>
    Diagnostic(Diag<ArgTypes...> ID,
               typename detail::PassArgument<ArgTypes>::type... VArgs)
      : ID(ID.ID) {
      DiagnosticArgument DiagArgs[] = { 
        DiagnosticArgument(0), std::move(VArgs)... 
      };
      Args.append(DiagArgs + 1, DiagArgs + 1 + sizeof...(VArgs));
    }

    /*implicit*/Diagnostic(DiagID ID, ArrayRef<DiagnosticArgument> Args)
      : ID(ID), Args(Args.begin(), Args.end()) {}
    
    // Accessors.
    DiagID getID() const { return ID; }
    ArrayRef<DiagnosticArgument> getArgs() const { return Args; }
    ArrayRef<CharSourceRange> getRanges() const { return Ranges; }
    ArrayRef<FixIt> getFixIts() const { return FixIts; }
    SourceLoc getLoc() const { return Loc; }
    const class Decl *getDecl() const { return Decl; }

    void setLoc(SourceLoc loc) { Loc = loc; }
    void setDecl(const class Decl *decl) { Decl = decl; }

    /// Returns true if this object represents a particular diagnostic.
    ///
    /// \code
    /// someDiag.is(diag::invalid_diagnostic)
    /// \endcode
    template<typename ...OtherArgTypes>
    bool is(Diag<OtherArgTypes...> Other) const {
      return ID == Other.ID;
    }

    void addRange(CharSourceRange R) {
      Ranges.push_back(R);
    }

    // Avoid copying the fix-it text more than necessary.
    void addFixIt(FixIt &&F) {
      FixIts.push_back(std::move(F));
    }
  };
  
  /// \brief Describes an in-flight diagnostic, which is currently active
  /// within the diagnostic engine and can be augmented within additional
  /// information (source ranges, Fix-Its, etc.).
  ///
  /// Only a single in-flight diagnostic can be active at one time, and all
  /// additional information must be emitted through the active in-flight
  /// diagnostic.
  class InFlightDiagnostic {
    friend class DiagnosticEngine;
    
    DiagnosticEngine *Engine;
    bool IsActive;
    
    /// \brief Create a new in-flight diagnostic. 
    ///
    /// This constructor is only available to the DiagnosticEngine.
    InFlightDiagnostic(DiagnosticEngine &Engine)
      : Engine(&Engine), IsActive(true) { }
    
    InFlightDiagnostic(const InFlightDiagnostic &) = delete;
    InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete;
    InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete;

  public:
    /// \brief Create an active but unattached in-flight diagnostic.
    /// 
    /// The resulting diagnostic can be used as a dummy, accepting the
    /// syntax to add additional information to a diagnostic without
    /// actually emitting a diagnostic.
    InFlightDiagnostic() : Engine(0), IsActive(true) { }
    
    /// \brief Transfer an in-flight diagnostic to a new object, which is
    /// typically used when returning in-flight diagnostics.
    InFlightDiagnostic(InFlightDiagnostic &&Other)
      : Engine(Other.Engine), IsActive(Other.IsActive) {
      Other.IsActive = false;
    }
    
    ~InFlightDiagnostic() {
      if (IsActive)
        flush();
    }
    
    /// \brief Flush the active diagnostic to the diagnostic output engine.
    void flush();

    /// \brief Add a token-based range to the currently-active diagnostic.
    InFlightDiagnostic &highlight(SourceRange R);

    /// \brief Add a character-based range to the currently-active diagnostic.
    InFlightDiagnostic &highlightChars(SourceLoc Start, SourceLoc End);

    /// \brief Add a token-based replacement fix-it to the currently-active
    /// diagnostic.
    InFlightDiagnostic &fixItReplace(SourceRange R, StringRef Str);

    /// \brief Add a character-based replacement fix-it to the currently-active
    /// diagnostic.
    InFlightDiagnostic &fixItReplaceChars(SourceLoc Start, SourceLoc End,
                                          StringRef Str);

    /// \brief Add an insertion fix-it to the currently-active diagnostic.
    InFlightDiagnostic &fixItInsert(SourceLoc L, StringRef Str) {
      return fixItReplaceChars(L, L, Str);
    }

    /// \brief Add an insertion fix-it to the currently-active diagnostic.  The
    /// text is inserted immediately *after* the token specified.
    ///
    InFlightDiagnostic &fixItInsertAfter(SourceLoc L, StringRef);

    /// \brief Add a token-based removal fix-it to the currently-active
    /// diagnostic.
    InFlightDiagnostic &fixItRemove(SourceRange R);
    
    /// \brief Add a character-based removal fix-it to the currently-active
    /// diagnostic.
    InFlightDiagnostic &fixItRemoveChars(SourceLoc Start, SourceLoc End) {
      return fixItReplaceChars(Start, End, {});
    }

    /// \brief Add two replacement fix-it exchanging source ranges to the
    /// currently-active diagnostic.
    InFlightDiagnostic &fixItExchange(SourceRange R1, SourceRange R2);
  };

  /// \brief Class to track, map, and remap diagnostic severity and fatality
  ///
  class DiagnosticState {
  public:
    /// \brief Describes the current behavior to take with a diagnostic
    enum class Behavior : uint8_t {
      Unspecified,
      Ignore,
      Note,
      Warning,
      Error,
      Fatal,
    };

  private:
    /// \brief Whether we should continue to emit diagnostics, even after a
    /// fatal error
    bool showDiagnosticsAfterFatalError = false;

    /// \brief Don't emit any warnings
    bool suppressWarnings = false;

    /// \brief Emit all warnings as errors
    bool warningsAsErrors = false;

    /// \brief Whether a fatal error has occurred
    bool fatalErrorOccurred = false;

    /// \brief Whether any error diagnostics have been emitted.
    bool anyErrorOccurred = false;

    /// \brief Track the previous emitted Behavior, useful for notes
    Behavior previousBehavior = Behavior::Unspecified;

    /// \brief Track settable, per-diagnostic state that we store
    std::vector<Behavior> perDiagnosticBehavior;

  public:
    DiagnosticState();

    /// \brief Figure out the Behavior for the given diagnostic, taking current
    /// state such as fatality into account.
    Behavior determineBehavior(DiagID id);

    bool hadAnyError() const { return anyErrorOccurred; }
    bool hasFatalErrorOccurred() const { return fatalErrorOccurred; }

    void setShowDiagnosticsAfterFatalError(bool val = true) {
      showDiagnosticsAfterFatalError = val;
    }
    bool getShowDiagnosticsAfterFatalError() {
      return showDiagnosticsAfterFatalError;
    }

    /// \brief Whether to skip emitting warnings
    void setSuppressWarnings(bool val) { suppressWarnings = val; }
    bool getSuppressWarnings() const { return suppressWarnings; }

    /// \brief Whether to treat warnings as errors
    void setWarningsAsErrors(bool val) { warningsAsErrors = val; }
    bool getWarningsAsErrors() const { return warningsAsErrors; }

    void resetHadAnyError() {
      anyErrorOccurred = false;
      fatalErrorOccurred = false;
    }

    /// Set per-diagnostic behavior
    void setDiagnosticBehavior(DiagID id, Behavior behavior) {
      perDiagnosticBehavior[(unsigned)id] = behavior;
    }

  private:
    // Make the state movable only
    DiagnosticState(const DiagnosticState &) = delete;
    const DiagnosticState &operator=(const DiagnosticState &) = delete;

    DiagnosticState(DiagnosticState &&) = default;
    DiagnosticState &operator=(DiagnosticState &&) = default;
  };
    
  /// \brief Class responsible for formatting diagnostics and presenting them
  /// to the user.
  class DiagnosticEngine {
    /// \brief The source manager used to interpret source locations and
    /// display diagnostics.
    SourceManager &SourceMgr;

    /// \brief The diagnostic consumer(s) that will be responsible for actually
    /// emitting diagnostics.
    SmallVector<DiagnosticConsumer *, 2> Consumers;

    /// \brief Tracks diagnostic behaviors and state
    DiagnosticState state;

    /// \brief The currently active diagnostic, if there is one.
    Optional<Diagnostic> ActiveDiagnostic;

    /// \brief All diagnostics that have are no longer active but have not yet
    /// been emitted due to an open transaction.
    SmallVector<Diagnostic, 4> TentativeDiagnostics;

    /// \brief The set of declarations for which we have pretty-printed
    /// results that we can point to on the command line.
    llvm::DenseMap<const Decl *, SourceLoc> PrettyPrintedDeclarations;

    /// \brief The number of open diagnostic transactions. Diagnostics are only
    /// emitted once all transactions have closed.
    unsigned TransactionCount = 0;

    friend class InFlightDiagnostic;
    friend class DiagnosticTransaction;
    
  public:
    explicit DiagnosticEngine(SourceManager &SourceMgr)
      : SourceMgr(SourceMgr), ActiveDiagnostic() {
    }

    /// hadAnyError - return true if any *error* diagnostics have been emitted.
    bool hadAnyError() const { return state.hadAnyError(); }

    bool hasFatalErrorOccurred() const {
      return state.hasFatalErrorOccurred();
    }

    void setShowDiagnosticsAfterFatalError(bool val = true) {
      state.setShowDiagnosticsAfterFatalError(val);
    }
    bool getShowDiagnosticsAfterFatalError() {
      return state.getShowDiagnosticsAfterFatalError();
    }

    /// \brief Whether to skip emitting warnings
    void setSuppressWarnings(bool val) { state.setSuppressWarnings(val); }
    bool getSuppressWarnings() const {
      return state.getSuppressWarnings();
    }

    /// \brief Whether to treat warnings as errors
    void setWarningsAsErrors(bool val) { state.setWarningsAsErrors(val); }
    bool getWarningsAsErrors() const {
      return state.getWarningsAsErrors();
    }

    void ignoreDiagnostic(DiagID id) {
      state.setDiagnosticBehavior(id, DiagnosticState::Behavior::Ignore);
    }

    void resetHadAnyError() {
      state.resetHadAnyError();
    }

    /// \brief Add an additional DiagnosticConsumer to receive diagnostics.
    void addConsumer(DiagnosticConsumer &Consumer) {
      Consumers.push_back(&Consumer);
    }

    /// \brief Remove and return all \c DiagnosticConsumers.
    std::vector<DiagnosticConsumer *> takeConsumers() {
      auto Result = std::vector<DiagnosticConsumer*>(Consumers.begin(),
                                                     Consumers.end());
      Consumers.clear();
      return Result;
    }

    /// \brief Emit a diagnostic using a preformatted array of diagnostic
    /// arguments.
    ///
    /// \param Loc The location to which the diagnostic refers in the source
    /// code.
    ///
    /// \param ID The diagnostic ID.
    ///
    /// \param Args The preformatted set of diagnostic arguments. The caller
    /// must ensure that the diagnostic arguments have the appropriate type.
    ///
    /// \returns An in-flight diagnostic, to which additional information can
    /// be attached.
    InFlightDiagnostic diagnose(SourceLoc Loc, DiagID ID, 
                                ArrayRef<DiagnosticArgument> Args) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = Diagnostic(ID, Args);
      ActiveDiagnostic->setLoc(Loc);
      return InFlightDiagnostic(*this);
    }

    /// \brief Emit a diagnostic using a preformatted array of diagnostic
    /// arguments.
    ///
    /// \param Loc The declaration name location to which the
    /// diagnostic refers in the source code.
    ///
    /// \param ID The diagnostic ID.
    ///
    /// \param Args The preformatted set of diagnostic arguments. The caller
    /// must ensure that the diagnostic arguments have the appropriate type.
    ///
    /// \returns An in-flight diagnostic, to which additional information can
    /// be attached.
    InFlightDiagnostic diagnose(DeclNameLoc Loc, DiagID ID, 
                                ArrayRef<DiagnosticArgument> Args) {
      return diagnose(Loc.getBaseNameLoc(), ID, Args);
    }

    /// \brief Emit an already-constructed diagnostic at the given location.
    ///
    /// \param Loc The location to which the diagnostic refers in the source
    /// code.
    ///
    /// \param D The diagnostic.
    ///
    /// \returns An in-flight diagnostic, to which additional information can
    /// be attached.
    InFlightDiagnostic diagnose(SourceLoc Loc, const Diagnostic &D) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = D;
      ActiveDiagnostic->setLoc(Loc);
      return InFlightDiagnostic(*this);
    }
    
    /// \brief Emit a diagnostic with the given set of diagnostic arguments.
    ///
    /// \param Loc The location to which the diagnostic refers in the source
    /// code.
    ///
    /// \param ID The diagnostic to be emitted.
    ///
    /// \param Args The diagnostic arguments, which will be converted to
    /// the types expected by the diagnostic \p ID.
    template<typename ...ArgTypes>
    InFlightDiagnostic 
    diagnose(SourceLoc Loc, Diag<ArgTypes...> ID,
             typename detail::PassArgument<ArgTypes>::type... Args) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = Diagnostic(ID, std::move(Args)...);
      ActiveDiagnostic->setLoc(Loc);
      return InFlightDiagnostic(*this);
    }

    /// \brief Emit a diagnostic with the given set of diagnostic arguments.
    ///
    /// \param Loc The declaration name location to which the
    /// diagnostic refers in the source code.
    ///
    /// \param ID The diagnostic to be emitted.
    ///
    /// \param Args The diagnostic arguments, which will be converted to
    /// the types expected by the diagnostic \p ID.
    template<typename ...ArgTypes>
    InFlightDiagnostic 
    diagnose(DeclNameLoc Loc, Diag<ArgTypes...> ID,
             typename detail::PassArgument<ArgTypes>::type... Args) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = Diagnostic(ID, std::move(Args)...);
      ActiveDiagnostic->setLoc(Loc.getBaseNameLoc());
      return InFlightDiagnostic(*this);
    }

    /// \brief Emit a diagnostic using a preformatted array of diagnostic
    /// arguments.
    ///
    /// \param decl The declaration to which this diagnostic refers, which
    /// may or may not have associated source-location information.
    ///
    /// \param id The diagnostic ID.
    ///
    /// \param args The preformatted set of diagnostic arguments. The caller
    /// must ensure that the diagnostic arguments have the appropriate type.
    ///
    /// \returns An in-flight diagnostic, to which additional information can
    /// be attached.
    InFlightDiagnostic diagnose(const Decl *decl, DiagID id,
                                ArrayRef<DiagnosticArgument> args) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = Diagnostic(id, args);
      ActiveDiagnostic->setDecl(decl);
      return InFlightDiagnostic(*this);
    }

    /// \brief Emit an already-constructed diagnostic referencing the given
    /// declaration.
    ///
    /// \param decl The declaration to which this diagnostic refers, which
    /// may or may not have associated source-location information.
    ///
    /// \param diag The diagnostic.
    ///
    /// \returns An in-flight diagnostic, to which additional information can
    /// be attached.
    InFlightDiagnostic diagnose(const Decl *decl, const Diagnostic &diag) {
      assert(!ActiveDiagnostic && "Already have an active diagnostic");
      ActiveDiagnostic = diag;
      ActiveDiagnostic->setDecl(decl);
      return InFlightDiagnostic(*this);
    }

    /// \brief Emit a diagnostic with the given set of diagnostic arguments.
    ///
    /// \param decl The declaration to which this diagnostic refers, which
    /// may or may not have associated source-location information.
    ///
    /// \param id The diagnostic to be emitted.
    ///
    /// \param args The diagnostic arguments, which will be converted to
    /// the types expected by the diagnostic \p ID.
    template<typename ...ArgTypes>
    InFlightDiagnostic
    diagnose(const Decl *decl, Diag<ArgTypes...> id,
             typename detail::PassArgument<ArgTypes>::type... args) {
      ActiveDiagnostic = Diagnostic(id, std::move(args)...);
      ActiveDiagnostic->setDecl(decl);
      return InFlightDiagnostic(*this);
    }

    /// \returns true if diagnostic is marked with PointsToFirstBadToken
    /// option.
    bool isDiagnosticPointsToFirstBadToken(DiagID id) const;

    /// \returns true if any diagnostic consumer gave an error while invoking
    //// \c finishProcessing.
    bool finishProcessing();
    
    /// \brief Format the given diagnostic text and place the result in the given
    /// buffer.
    static void formatDiagnosticText(
        llvm::raw_ostream &Out, StringRef InText,
        ArrayRef<DiagnosticArgument> FormatArgs,
        DiagnosticFormatOptions FormatOpts = DiagnosticFormatOptions());

  private:
    /// \brief Flush the active diagnostic.
    void flushActiveDiagnostic();
    
    /// \brief Retrieve the active diagnostic.
    Diagnostic &getActiveDiagnostic() { return *ActiveDiagnostic; }

    /// \brief Send \c diag to all diagnostic consumers.
    void emitDiagnostic(const Diagnostic &diag);

    /// \brief Send all tentative diagnostics to all diagnostic consumers and
    /// delete them.
    void emitTentativeDiagnostics();
  };

  /// \brief Represents a diagnostic transaction. While a transaction is
  /// open, all recorded diagnostics are saved until the transaction commits,
  /// at which point they are emitted. If the transaction is instead aborted,
  /// the diagnostics are erased. Transactions may be nested but must be closed
  /// in LIFO order. An open transaction is implicitly committed upon
  /// destruction.
  class DiagnosticTransaction {
    DiagnosticEngine &Engine;

    /// \brief How many tentative diagnostics there were when the transaction
    /// was opened.
    unsigned PrevDiagnostics;

    /// \brief How many other transactions were open when this transaction was
    /// opened.
    unsigned Depth;

    /// \brief Whether this transaction is currently open.
    bool IsOpen = true;

  public:
    explicit DiagnosticTransaction(DiagnosticEngine &engine)
      : Engine(engine),
        PrevDiagnostics(Engine.TentativeDiagnostics.size()),
        Depth(Engine.TransactionCount),
        IsOpen(true)
    {
      assert(!Engine.ActiveDiagnostic);
      Engine.TransactionCount++;
    }

    ~DiagnosticTransaction() {
      if (IsOpen) {
        commit();
      }
    }

    /// \brief Abort and close this transaction and erase all diagnostics
    /// record while it was open.
    void abort() {
      close();
      Engine.TentativeDiagnostics.erase(
        Engine.TentativeDiagnostics.begin() + PrevDiagnostics,
        Engine.TentativeDiagnostics.end());
    }

    /// \brief Commit and close this transaction. If this is the top-level
    /// transaction, emit any diagnostics that were recorded while it was open.
    void commit() {
      close();
      if (Depth == 0) {
        assert(PrevDiagnostics == 0);
        Engine.emitTentativeDiagnostics();
      }
    }

  private:
    void close() {
      assert(IsOpen && "only open transactions may be closed");
      IsOpen = false;
      Engine.TransactionCount--;
      assert(Depth == Engine.TransactionCount &&
             "transactions must be closed LIFO");
    }
  };
} // end namespace swift

#endif
