// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/resolver/dependency_graph.h"

#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "src/ast/continue_statement.h"
#include "src/ast/discard_statement.h"
#include "src/ast/fallthrough_statement.h"
#include "src/ast/traverse_expressions.h"
#include "src/scope_stack.h"
#include "src/sem/intrinsic.h"
#include "src/utils/defer.h"
#include "src/utils/map.h"
#include "src/utils/scoped_assignment.h"
#include "src/utils/unique_vector.h"

#define TINT_DUMP_DEPENDENCY_GRAPH 0

namespace tint {
namespace resolver {
namespace {

// Forward declaration
struct Global;

/// Dependency describes how one global depends on another global
struct DependencyInfo {
  /// The source of the symbol that forms the dependency
  Source source;
  /// A string describing how the dependency is referenced. e.g. 'calls'
  const char* action = nullptr;
};

/// DependencyEdge describes the two Globals used to define a dependency
/// relationship.
struct DependencyEdge {
  /// The Global that depends on #to
  const Global* from;
  /// The Global that is depended on by #from
  const Global* to;
};

/// DependencyEdgeCmp implements the contracts of std::equal_to<DependencyEdge>
/// and std::hash<DependencyEdge>.
struct DependencyEdgeCmp {
  /// Equality operator
  bool operator()(const DependencyEdge& lhs, const DependencyEdge& rhs) const {
    return lhs.from == rhs.from && lhs.to == rhs.to;
  }
  /// Hashing operator
  inline std::size_t operator()(const DependencyEdge& d) const {
    return utils::Hash(d.from, d.to);
  }
};

/// A map of DependencyEdge to DependencyInfo
using DependencyEdges = std::unordered_map<DependencyEdge,
                                           DependencyInfo,
                                           DependencyEdgeCmp,
                                           DependencyEdgeCmp>;

/// Global describes a module-scope variable, type or function.
struct Global {
  explicit Global(const ast::Node* n) : node(n) {}

  /// The declaration ast::Node
  const ast::Node* node;
  /// A list of dependencies that this global depends on
  std::vector<Global*> deps;
};

/// A map of global name to Global
using GlobalMap = std::unordered_map<Symbol, Global*>;

/// Raises an ICE that a global ast::Node type was not handled by this system.
void UnhandledNode(diag::List& diagnostics, const ast::Node* node) {
  TINT_ICE(Resolver, diagnostics)
      << "unhandled node type: " << node->TypeInfo().name;
}

/// Raises an error diagnostic with the given message and source.
void AddError(diag::List& diagnostics,
              const std::string& msg,
              const Source& source) {
  diagnostics.add_error(diag::System::Resolver, msg, source);
}

/// Raises a note diagnostic with the given message and source.
void AddNote(diag::List& diagnostics,
             const std::string& msg,
             const Source& source) {
  diagnostics.add_note(diag::System::Resolver, msg, source);
}

/// DependencyScanner is used to traverse a module to build the list of
/// global-to-global dependencies.
class DependencyScanner {
 public:
  /// Constructor
  /// @param syms the program symbol table
  /// @param globals_by_name map of global symbol to Global pointer
  /// @param diagnostics diagnostic messages, appended with any errors found
  /// @param graph the dependency graph to populate with resolved symbols
  /// @param edges the map of globals-to-global dependency edges, which will
  /// be populated by calls to Scan()
  DependencyScanner(const SymbolTable& syms,
                    const GlobalMap& globals_by_name,
                    diag::List& diagnostics,
                    DependencyGraph& graph,
                    DependencyEdges& edges)
      : symbols_(syms),
        globals_(globals_by_name),
        diagnostics_(diagnostics),
        graph_(graph),
        dependency_edges_(edges) {
    // Register all the globals at global-scope
    for (auto it : globals_by_name) {
      scope_stack_.Set(it.first, it.second->node);
    }
  }

  /// Walks the global declarations, resolving symbols, and determining the
  /// dependencies of each global.
  void Scan(Global* global) {
    TINT_SCOPED_ASSIGNMENT(current_global_, global);

    if (auto* str = global->node->As<ast::Struct>()) {
      Declare(str->name, str);
      for (auto* member : str->members) {
        TraverseType(member->type);
      }
      return;
    }
    if (auto* alias = global->node->As<ast::Alias>()) {
      Declare(alias->name, alias);
      TraverseType(alias->type);
      return;
    }
    if (auto* func = global->node->As<ast::Function>()) {
      Declare(func->symbol, func);
      TraverseDecorations(func->decorations);
      TraverseFunction(func);
      return;
    }
    if (auto* var = global->node->As<ast::Variable>()) {
      Declare(var->symbol, var);
      TraverseType(var->type);
      if (var->constructor) {
        TraverseExpression(var->constructor);
      }
      return;
    }
    UnhandledNode(diagnostics_, global->node);
  }

 private:
  /// Traverses the function, performing symbol resolution and determining
  /// global dependencies.
  void TraverseFunction(const ast::Function* func) {
    scope_stack_.Push();
    TINT_DEFER(scope_stack_.Pop());

    for (auto* param : func->params) {
      if (auto* shadows = scope_stack_.Get(param->symbol)) {
        graph_.shadows.emplace(param, shadows);
      }
      Declare(param->symbol, param);
      TraverseType(param->type);
    }
    if (func->body) {
      TraverseStatements(func->body->statements);
    }
    TraverseType(func->return_type);
  }

  /// Traverses the statements, performing symbol resolution and determining
  /// global dependencies.
  void TraverseStatements(const ast::StatementList& stmts) {
    for (auto* s : stmts) {
      TraverseStatement(s);
    }
  }

  /// Traverses the statement, performing symbol resolution and determining
  /// global dependencies.
  void TraverseStatement(const ast::Statement* stmt) {
    if (stmt == nullptr) {
      return;
    }
    if (auto* b = stmt->As<ast::AssignmentStatement>()) {
      TraverseExpression(b->lhs);
      TraverseExpression(b->rhs);
      return;
    }
    if (auto* b = stmt->As<ast::BlockStatement>()) {
      scope_stack_.Push();
      TINT_DEFER(scope_stack_.Pop());
      TraverseStatements(b->statements);
      return;
    }
    if (auto* r = stmt->As<ast::CallStatement>()) {
      TraverseExpression(r->expr);
      return;
    }
    if (auto* l = stmt->As<ast::ForLoopStatement>()) {
      scope_stack_.Push();
      TINT_DEFER(scope_stack_.Pop());
      TraverseStatement(l->initializer);
      TraverseExpression(l->condition);
      TraverseStatement(l->continuing);
      TraverseStatement(l->body);
      return;
    }
    if (auto* l = stmt->As<ast::LoopStatement>()) {
      scope_stack_.Push();
      TINT_DEFER(scope_stack_.Pop());
      TraverseStatements(l->body->statements);
      TraverseStatement(l->continuing);
      return;
    }
    if (auto* i = stmt->As<ast::IfStatement>()) {
      TraverseExpression(i->condition);
      TraverseStatement(i->body);
      for (auto* e : i->else_statements) {
        TraverseExpression(e->condition);
        TraverseStatement(e->body);
      }
      return;
    }
    if (auto* r = stmt->As<ast::ReturnStatement>()) {
      TraverseExpression(r->value);
      return;
    }
    if (auto* s = stmt->As<ast::SwitchStatement>()) {
      TraverseExpression(s->condition);
      for (auto* c : s->body) {
        for (auto* sel : c->selectors) {
          TraverseExpression(sel);
        }
        TraverseStatement(c->body);
      }
      return;
    }
    if (auto* v = stmt->As<ast::VariableDeclStatement>()) {
      if (auto* shadows = scope_stack_.Get(v->variable->symbol)) {
        graph_.shadows.emplace(v->variable, shadows);
      }
      TraverseType(v->variable->type);
      TraverseExpression(v->variable->constructor);
      Declare(v->variable->symbol, v->variable);
      return;
    }
    if (stmt->IsAnyOf<ast::BreakStatement, ast::ContinueStatement,
                      ast::DiscardStatement, ast::FallthroughStatement>()) {
      return;
    }

    UnhandledNode(diagnostics_, stmt);
  }

  /// Adds the symbol definition to the current scope, raising an error if two
  /// symbols collide within the same scope.
  void Declare(Symbol symbol, const ast::Node* node) {
    auto* old = scope_stack_.Set(symbol, node);
    if (old != nullptr && node != old) {
      auto name = symbols_.NameFor(symbol);
      AddError(diagnostics_, "redeclaration of '" + name + "'", node->source);
      AddNote(diagnostics_, "'" + name + "' previously declared here",
              old->source);
    }
  }

  /// Traverses the expression, performing symbol resolution and determining
  /// global dependencies.
  void TraverseExpression(const ast::Expression* root) {
    if (!root) {
      return;
    }
    ast::TraverseExpressions(
        root, diagnostics_, [&](const ast::Expression* expr) {
          if (auto* ident = expr->As<ast::IdentifierExpression>()) {
            auto* node = scope_stack_.Get(ident->symbol);
            if (node == nullptr) {
              if (!IsIntrinsic(ident->symbol)) {
                UnknownSymbol(ident->symbol, ident->source, "identifier");
              }
              return ast::TraverseAction::Descend;
            }
            auto global_it = globals_.find(ident->symbol);
            if (global_it != globals_.end() &&
                node == global_it->second->node) {
              ResolveGlobalDependency(ident, ident->symbol, "identifier",
                                      "references");
            } else {
              graph_.resolved_symbols.emplace(ident, node);
            }
          }
          if (auto* call = expr->As<ast::CallExpression>()) {
            if (call->target.name) {
              if (!IsIntrinsic(call->target.name->symbol)) {
                ResolveGlobalDependency(call->target.name,
                                        call->target.name->symbol, "function",
                                        "calls");
                graph_.resolved_symbols.emplace(
                    call,
                    utils::Lookup(graph_.resolved_symbols, call->target.name));
              }
            }
            if (call->target.type) {
              TraverseType(call->target.type);
              graph_.resolved_symbols.emplace(
                  call,
                  utils::Lookup(graph_.resolved_symbols, call->target.type));
            }
          }
          return ast::TraverseAction::Descend;
        });
  }

  /// Traverses the type node, performing symbol resolution and determining
  /// global dependencies.
  void TraverseType(const ast::Type* ty) {
    if (ty == nullptr) {
      return;
    }
    if (auto* arr = ty->As<ast::Array>()) {
      TraverseType(arr->type);
      TraverseExpression(arr->count);
      return;
    }
    if (auto* atomic = ty->As<ast::Atomic>()) {
      TraverseType(atomic->type);
      return;
    }
    if (auto* mat = ty->As<ast::Matrix>()) {
      TraverseType(mat->type);
      return;
    }
    if (auto* ptr = ty->As<ast::Pointer>()) {
      TraverseType(ptr->type);
      return;
    }
    if (auto* tn = ty->As<ast::TypeName>()) {
      ResolveGlobalDependency(tn, tn->name, "type", "references");
      return;
    }
    if (auto* vec = ty->As<ast::Vector>()) {
      TraverseType(vec->type);
      return;
    }
    if (auto* tex = ty->As<ast::SampledTexture>()) {
      TraverseType(tex->type);
      return;
    }
    if (auto* tex = ty->As<ast::MultisampledTexture>()) {
      TraverseType(tex->type);
      return;
    }
    if (ty->IsAnyOf<ast::Void, ast::Bool, ast::I32, ast::U32, ast::F32,
                    ast::DepthTexture, ast::DepthMultisampledTexture,
                    ast::StorageTexture, ast::ExternalTexture,
                    ast::Sampler>()) {
      return;
    }

    UnhandledNode(diagnostics_, ty);
  }

  /// Traverses the decoration list, performing symbol resolution and
  /// determining global dependencies.
  void TraverseDecorations(const ast::DecorationList& decos) {
    for (auto* deco : decos) {
      TraverseDecoration(deco);
    }
  }

  /// Traverses the decoration, performing symbol resolution and determining
  /// global dependencies.
  void TraverseDecoration(const ast::Decoration* deco) {
    if (auto* wg = deco->As<ast::WorkgroupDecoration>()) {
      TraverseExpression(wg->x);
      TraverseExpression(wg->y);
      TraverseExpression(wg->z);
      return;
    }
    if (deco->IsAnyOf<ast::BindingDecoration, ast::BuiltinDecoration,
                      ast::GroupDecoration, ast::InternalDecoration,
                      ast::InterpolateDecoration, ast::InvariantDecoration,
                      ast::LocationDecoration, ast::OverrideDecoration,
                      ast::StageDecoration, ast::StrideDecoration,
                      ast::StructBlockDecoration,
                      ast::StructMemberAlignDecoration,
                      ast::StructMemberOffsetDecoration,
                      ast::StructMemberSizeDecoration>()) {
      return;
    }

    UnhandledNode(diagnostics_, deco);
  }

  /// Adds the dependency to the currently processed global
  void ResolveGlobalDependency(const ast::Node* from,
                               Symbol to,
                               const char* use,
                               const char* action) {
    auto global_it = globals_.find(to);
    if (global_it != globals_.end()) {
      auto* global = global_it->second;
      if (dependency_edges_
              .emplace(DependencyEdge{current_global_, global},
                       DependencyInfo{from->source, action})
              .second) {
        current_global_->deps.emplace_back(global);
      }
      graph_.resolved_symbols.emplace(from, global->node);
    } else {
      UnknownSymbol(to, from->source, use);
    }
  }

  /// @returns true if `name` is the name of an intrinsic function
  bool IsIntrinsic(Symbol name) const {
    return sem::ParseIntrinsicType(symbols_.NameFor(name)) !=
           sem::IntrinsicType::kNone;
  }

  /// Appends an error to the diagnostics that the given symbol cannot be
  /// resolved.
  void UnknownSymbol(Symbol name, Source source, const char* use) {
    AddError(
        diagnostics_,
        "unknown " + std::string(use) + ": '" + symbols_.NameFor(name) + "'",
        source);
  }

  using VariableMap = std::unordered_map<Symbol, const ast::Variable*>;
  const SymbolTable& symbols_;
  const GlobalMap& globals_;
  diag::List& diagnostics_;
  DependencyGraph& graph_;
  DependencyEdges& dependency_edges_;

  ScopeStack<const ast::Node*> scope_stack_;
  Global* current_global_ = nullptr;
};

/// The global dependency analysis system
struct DependencyAnalysis {
 public:
  /// Constructor
  DependencyAnalysis(const SymbolTable& symbols,
                     diag::List& diagnostics,
                     DependencyGraph& graph)
      : symbols_(symbols), diagnostics_(diagnostics), graph_(graph) {}

  /// Performs global dependency analysis on the module, emitting any errors to
  /// #diagnostics.
  /// @returns true if analysis found no errors, otherwise false.
  bool Run(const ast::Module& module, bool allow_out_of_order_decls) {
    // Collect all the named globals from the AST module
    GatherGlobals(module);

    // Traverse the named globals to build the dependency graph
    DetermineDependencies();

    // Sort the globals into dependency order
    SortGlobals();

#if TINT_DUMP_DEPENDENCY_GRAPH
    DumpDependencyGraph();
#endif

    if (!allow_out_of_order_decls) {
      // Prevent out-of-order declarations.
      ErrorOnOutOfOrderDeclarations();
    }

    graph_.ordered_globals = std::move(sorted_);

    return !diagnostics_.contains_errors();
  }

 private:
  /// @param node the ast::Node of the global declaration
  /// @returns the symbol of the global declaration node
  /// @note will raise an ICE if the node is not a type, function or variable
  /// declaration
  Symbol SymbolOf(const ast::Node* node) const {
    if (auto* td = node->As<ast::TypeDecl>()) {
      return td->name;
    }
    if (auto* func = node->As<ast::Function>()) {
      return func->symbol;
    }
    if (auto* var = node->As<ast::Variable>()) {
      return var->symbol;
    }
    UnhandledNode(diagnostics_, node);
    return {};
  }

  /// @param node the ast::Node of the global declaration
  /// @returns the name of the global declaration node
  /// @note will raise an ICE if the node is not a type, function or variable
  /// declaration
  std::string NameOf(const ast::Node* node) const {
    return symbols_.NameFor(SymbolOf(node));
  }

  /// @param node the ast::Node of the global declaration
  /// @returns a string representation of the global declaration kind
  /// @note will raise an ICE if the node is not a type, function or variable
  /// declaration
  std::string KindOf(const ast::Node* node) {
    if (node->Is<ast::Struct>()) {
      return "struct";
    }
    if (node->Is<ast::Alias>()) {
      return "alias";
    }
    if (node->Is<ast::Function>()) {
      return "function";
    }
    if (auto* var = node->As<ast::Variable>()) {
      return var->is_const ? "let" : "var";
    }
    UnhandledNode(diagnostics_, node);
    return {};
  }

  /// Traverses `module`, collecting all the global declarations and populating
  /// the #globals and #declaration_order fields.
  void GatherGlobals(const ast::Module& module) {
    for (auto* node : module.GlobalDeclarations()) {
      auto* global = allocator_.Create(node);
      globals_.emplace(SymbolOf(node), global);
      declaration_order_.emplace_back(global);
    }
  }

  /// Walks the global declarations, determining the dependencies of each global
  /// and adding these to each global's Global::deps field.
  void DetermineDependencies() {
    DependencyScanner scanner(symbols_, globals_, diagnostics_, graph_,
                              dependency_edges_);
    for (auto* global : declaration_order_) {
      scanner.Scan(global);
    }
  }

  /// Performs a depth-first traversal of `root`'s dependencies, calling `enter`
  /// as the function decends into each dependency and `exit` when bubbling back
  /// up towards the root.
  /// @param enter is a function with the signature: `bool(Global*)`. The
  /// `enter` function returns true if TraverseDependencies() should traverse
  /// the dependency, otherwise it will be skipped.
  /// @param exit is a function with the signature: `void(Global*)`. The `exit`
  /// function is only called if the corresponding `enter` call returned true.
  template <typename ENTER, typename EXIT>
  void TraverseDependencies(const Global* root, ENTER&& enter, EXIT&& exit) {
    // Entry is a single entry in the traversal stack. Entry points to a
    // dep_idx'th dependency of Entry::global.
    struct Entry {
      const Global* global;  // The parent global
      size_t dep_idx;        // The dependency index in `global->deps`
    };

    if (!enter(root)) {
      return;
    }

    std::vector<Entry> stack{Entry{root, 0}};
    while (true) {
      auto& entry = stack.back();
      // Have we exhausted the dependencies of entry.global?
      if (entry.dep_idx < entry.global->deps.size()) {
        // No, there's more dependencies to traverse.
        auto& dep = entry.global->deps[entry.dep_idx];
        // Does the caller want to enter this dependency?
        if (enter(dep)) {                  // Yes.
          stack.push_back(Entry{dep, 0});  // Enter the dependency.
        } else {
          entry.dep_idx++;  // No. Skip this node.
        }
      } else {
        // Yes. Time to back up.
        // Exit this global, pop the stack, and if there's another parent node,
        // increment its dependency index, and loop again.
        exit(entry.global);
        stack.pop_back();
        if (stack.empty()) {
          return;  // All done.
        }
        stack.back().dep_idx++;
      }
    }
  }

  /// SortGlobals sorts the globals into dependency order, erroring if cyclic
  /// dependencies are found. The sorted dependencies are assigned to #sorted.
  void SortGlobals() {
    if (diagnostics_.contains_errors()) {
      return;  // This code assumes there are no undeclared identifiers.
    }

    std::unordered_set<const Global*> visited;
    for (auto* global : declaration_order_) {
      utils::UniqueVector<const Global*> stack;
      TraverseDependencies(
          global,
          [&](const Global* g) {  // Enter
            if (!stack.add(g)) {
              CyclicDependencyFound(g, stack);
              return false;
            }
            if (sorted_.contains(g->node)) {
              return false;  // Visited this global already.
            }
            return true;
          },
          [&](const Global* g) {  // Exit
            sorted_.add(g->node);
            stack.pop_back();
          });

      sorted_.add(global->node);
    }
  }

  /// DepInfoFor() looks up the global dependency information for the dependency
  /// of global `from` depending on `to`.
  /// @note will raise an ICE if the edge is not found.
  DependencyInfo DepInfoFor(const Global* from, const Global* to) const {
    auto it = dependency_edges_.find(DependencyEdge{from, to});
    if (it != dependency_edges_.end()) {
      return it->second;
    }
    TINT_ICE(Resolver, diagnostics_)
        << "failed to find dependency info for edge: '" << NameOf(from->node)
        << "' -> '" << NameOf(to->node) << "'";
    return {};
  }

  // TODO(crbug.com/tint/1266): Errors if there are any uses of globals before
  // their declaration. Out-of-order declarations was added to the WGSL
  // specification with https://github.com/gpuweb/gpuweb/pull/2244, but Mozilla
  // have objections to this change so this feature is currently disabled via
  // this function.
  void ErrorOnOutOfOrderDeclarations() {
    if (diagnostics_.contains_errors()) {
      // Might have already errored about cyclic dependencies. No need to report
      // out-of-order errors as well.
      return;
    }
    std::unordered_set<const Global*> seen;
    for (auto* global : declaration_order_) {
      for (auto* dep : global->deps) {
        if (!seen.count(dep)) {
          auto info = DepInfoFor(global, dep);
          auto name = NameOf(dep->node);
          AddError(diagnostics_,
                   KindOf(dep->node) + " '" + name +
                       "' used before it has been declared",
                   info.source);
          AddNote(diagnostics_,
                  KindOf(dep->node) + " '" + name + "' declared here",
                  dep->node->source);
        }
      }
      seen.emplace(global);
    }
  }

  /// CyclicDependencyFound() emits an error diagnostic for a cyclic dependency.
  /// @param root is the global that starts the cyclic dependency, which must be
  /// found in `stack`.
  /// @param stack is the global dependency stack that contains a loop.
  void CyclicDependencyFound(const Global* root,
                             const std::vector<const Global*>& stack) {
    std::stringstream msg;
    msg << "cyclic dependency found: ";
    constexpr size_t kLoopNotStarted = ~0u;
    size_t loop_start = kLoopNotStarted;
    for (size_t i = 0; i < stack.size(); i++) {
      auto* e = stack[i];
      if (loop_start == kLoopNotStarted && e == root) {
        loop_start = i;
      }
      if (loop_start != kLoopNotStarted) {
        msg << "'" << NameOf(e->node) << "' -> ";
      }
    }
    msg << "'" << NameOf(root->node) << "'";
    AddError(diagnostics_, msg.str(), root->node->source);
    for (size_t i = loop_start; i < stack.size(); i++) {
      auto* from = stack[i];
      auto* to = (i + 1 < stack.size()) ? stack[i + 1] : stack[loop_start];
      auto info = DepInfoFor(from, to);
      AddNote(diagnostics_,
              KindOf(from->node) + " '" + NameOf(from->node) + "' " +
                  info.action + " " + KindOf(to->node) + " '" +
                  NameOf(to->node) + "' here",
              info.source);
    }
  }

#if TINT_DUMP_DEPENDENCY_GRAPH
  void DumpDependencyGraph() {
    printf("=========================\n");
    printf("------ declaration ------ \n");
    for (auto* global : declaration_order_) {
      printf("%s\n", NameOf(global->node).c_str());
    }
    printf("------ dependencies ------ \n");
    for (auto* node : sorted) {
      auto symbol = SymbolOf(node);
      auto* global = globals.at(symbol);
      printf("%s depends on:\n", symbols.NameFor(symbol).c_str());
      for (auto& dep : global->deps) {
        printf("  %s\n", NameOf(dep.global->node).c_str());
      }
    }
    printf("=========================\n");
  }
#endif  // TINT_DUMP_DEPENDENCY_GRAPH

  /// Program symbols
  const SymbolTable& symbols_;

  /// Program diagnostics
  diag::List& diagnostics_;

  /// The resulting dependency graph
  DependencyGraph& graph_;

  /// Allocator of Globals
  BlockAllocator<Global> allocator_;

  /// Global map, keyed by name. Populated by GatherGlobals().
  GlobalMap globals_;

  /// Map of DependencyEdge to DependencyInfo. Populated by
  /// DetermineDependencies().
  DependencyEdges dependency_edges_;

  /// Globals in declaration order. Populated by GatherGlobals().
  std::vector<Global*> declaration_order_;

  /// Globals in sorted dependency order. Populated by SortGlobals().
  utils::UniqueVector<const ast::Node*> sorted_;
};

}  // namespace

DependencyGraph::DependencyGraph() = default;
DependencyGraph::DependencyGraph(DependencyGraph&&) = default;
DependencyGraph::~DependencyGraph() = default;

bool DependencyGraph::Build(const ast::Module& module,
                            const SymbolTable& symbols,
                            diag::List& diagnostics,
                            DependencyGraph& output,
                            bool allow_out_of_order_decls) {
  DependencyAnalysis da{symbols, diagnostics, output};
  return da.Run(module, allow_out_of_order_decls);
}

}  // namespace resolver
}  // namespace tint
