// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// This is the test driver for a nullability_test.
//
// A test is a C++ source file that contains code to be nullability-analyzed.
// The code can include calls to special assertion functions like nullable().
// These assert details of the analysis results (nullability of expressions).
// (These functions are declared in nullability_test.h, see details there).
//
// This tool's job is to parse the file, run the nullability analysis,
// check whether the assertions pass, and report the results.
//
// It can be invoked manually, and writes textual logs to stdout, but can also
// write Bazel structured test results.
// https://bazel.build/reference/test-encyclopedia
//
// The dataflow visualizer is useful in debugging test failures:
//   When running under Bazel, pass --test_arg=-log
//   When running manually, pass -dataflow-log=/some/scratch/dir

#include <assert.h>

#include <chrono>
#include <cstdlib>
#include <memory>
#include <optional>
#include <string>
#include <system_error>
#include <utility>
#include <vector>

#include "absl/log/check.h"
#include "nullability/pointer_nullability.h"
#include "nullability/pointer_nullability_analysis.h"
#include "nullability/pointer_nullability_lattice.h"
#include "nullability/pragma.h"
#include "nullability/test/test_headers.h"
#include "nullability/type_nullability.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/CanonicalType.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/Arena.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/StandaloneExecution.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/GlobPattern.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

namespace clang::tidy::nullability {
namespace {
llvm::cl::list<std::string> Sources(llvm::cl::Positional, llvm::cl::OneOrMore);
llvm::cl::opt<bool> EmitTestLog("log");

// Deal with unexpected llvm::Errors by exiting with failure status.
void require(llvm::Error E) {
  if (E) {
    llvm::errs() << toString(std::move(E)) << "\n";
    std::exit(1);
  }
}
template <typename T>
T require(llvm::Expected<T> E) {
  require(E.takeError());
  return std::move(*E);
}

// Emit diagnostics for nullability assertion failures.
class Diagnoser {
 public:
  Diagnoser(DiagnosticsEngine &Diags)
      : Diags(Diags),
        WrongNullability(Diags.getCustomDiagID(
            DiagnosticsEngine::Error, "expression is %1, expected %0")),
        WrongTypeCanonical(Diags.getCustomDiagID(
            DiagnosticsEngine::Error,
            "argument with type %1 could never match assertion %0")),
        WrongTypeNullability(Diags.getCustomDiagID(
            DiagnosticsEngine::Error, "static nullability is %1, expected %0")),
        WrongNodeKind(Diags.getCustomDiagID(
            DiagnosticsEngine::Error, "TEST on %0 node is not supported")),
        NoValue(Diags.getCustomDiagID(DiagnosticsEngine::Error,
                                      "no value for boolean expression")),
        NotProvable(Diags.getCustomDiagID(DiagnosticsEngine::Error,
                                          "expression cannot be proved true")),
        NotPossible(Diags.getCustomDiagID(DiagnosticsEngine::Error,
                                          "expression is provably false")) {}

  void diagnoseNullability(SourceLocation Call, SourceRange Arg,
                           NullabilityKind Want, NullabilityKind Got) {
    if (Want != Got) {
      Diags.Report(Call, WrongNullability)
          << Arg << getNullabilitySpelling(Want) << getNullabilitySpelling(Got);
    }
  }

  void diagnoseType(SourceLocation Call, SourceRange Arg, CanQualType WantCanon,
                    CanQualType GotCanon, const TypeNullability &WantNulls,
                    const TypeNullability &GotNulls) {
    if (WantCanon != GotCanon) {
      Diags.Report(Call, WrongTypeCanonical) << WantCanon << GotCanon;
    } else if (WantNulls != GotNulls) {
      Diags.Report(Call, WrongTypeNullability)
          << nullabilityToString(WantNulls) << nullabilityToString(GotNulls);
    }
  }

  void diagnoseNoValue(const Expr &Arg) {
    Diags.Report(Arg.getSourceRange().getBegin(), NoValue)
        << Arg.getSourceRange();
  }

  void diagnoseNotProvable(const Expr &Arg) {
    Diags.Report(Arg.getSourceRange().getBegin(), NotProvable)
        << Arg.getSourceRange();
  }

  void diagnoseNotPossible(const Expr &Arg) {
    Diags.Report(Arg.getSourceRange().getBegin(), NotPossible)
        << Arg.getSourceRange();
  }

  void diagnoseBadTest(const DynTypedNode &N) {
    Diags.Report(N.getSourceRange().getBegin(), WrongNodeKind)
        << N.getNodeKind().asStringRef() << N.getSourceRange();
  }

 private:
  DiagnosticsEngine &Diags;
  unsigned WrongNullability;
  unsigned WrongTypeCanonical;
  unsigned WrongTypeNullability;
  unsigned WrongNodeKind;
  unsigned NoValue;
  unsigned NotProvable;
  unsigned NotPossible;
};

// Match a nullable()/nonnull()/unknown() call, return the nullability asserted.
std::optional<NullabilityKind> getAssertedNullability(const CallExpr &Call) {
  auto *FD = Call.getDirectCallee();
  if (!FD || !FD->getDeclContext()->isTranslationUnit() ||
      !FD->getDeclName().isIdentifier())
    return std::nullopt;
  return llvm::StringSwitch<std::optional<NullabilityKind>>(FD->getName())
      .Case("nullable", NullabilityKind::Nullable)
      .Case("nonnull", NullabilityKind::NonNull)
      .Case("unknown", NullabilityKind::Unspecified)
      .Default(std::nullopt);
}

// Match a type<...>() call, return the type asserted.
std::optional<QualType> getAssertedType(const CallExpr &Call) {
  // must be a call to ::type
  auto *FD = Call.getDirectCallee();
  if (!FD || !FD->getDeclContext()->isTranslationUnit() ||
      !FD->getDeclName().isIdentifier() || FD->getName() != "type")
    return std::nullopt;

  // must have template arguments, first is an explicitly-written type
  auto *DRE = dyn_cast<DeclRefExpr>(Call.getCallee()->IgnoreImplicit());
  if (!DRE || !DRE->hasExplicitTemplateArgs() ||
      DRE->getTemplateArgs()[0].getArgument().getKind() !=
          TemplateArgument::Type)
    return std::nullopt;

  return DRE->getTemplateArgs()[0].getTypeSourceInfo()->getType();
}

// Match a provable()/possible() call, return the name of the called function.
llvm::StringRef getBoolAssertionName(const CallExpr &Call) {
  if (Call.getNumArgs() != 1) return {};
  auto *FD = Call.getDirectCallee();
  if (!FD || !FD->getDeclContext()->isTranslationUnit() ||
      !FD->getDeclName().isIdentifier())
    return {};
  if (FD->getName() != "provable" && FD->getName() != "possible") return {};
  return FD->getName();
}

using AnalysisState =
    const dataflow::DataflowAnalysisState<PointerNullabilityLattice>;
// Maps the IDs of symbolic nullability variables (like "X" for symbolic::X)
// onto the actual symbolic nullability variables used in the analysis.
using SymbolicMap = llvm::DenseMap<StringRef, PointerTypeNullability>;

// If T is a symbolic nullability alias, return its ID.
// e.g. "X" if the alias is marked [[clang::annotate("symbolic_nullability:X")]]
std::optional<StringRef> getSymbolicID(TemplateDecl *TD) {
  if (!TD || !isa<TypeAliasTemplateDecl>(TD)) return std::nullopt;
  if (const auto *Annotate = TD->getTemplatedDecl()->getAttr<AnnotateAttr>()) {
    StringRef Annotation = Annotate->getAnnotation();
    if (Annotation.consume_front("symbolic_nullability:")) return Annotation;
  }
  return std::nullopt;
}

// We've seen a type<T>(expr) assertion, extract the nullability vector for T.
TypeNullability getAssertedTypeNullability(QualType T, SymbolicMap &Symbolic,
                                           dataflow::Arena &A) {
  // As a special case, we do not respect pragmas to interpret types within a
  // type<...> assertion. Doing so would on balance make tests less clear.
  TypeNullabilityDefaults EmptyDefaults;
  return getTypeNullability(
      T, FileID(), EmptyDefaults,
      // Given type< symbolic::X<int* _Nullable*> *_Nonnull >(...)
      // usual vector: [Nonnull, Unspecified, Nullable]
      //      we want: [Nonnull, Symbolic, Nullable].
      // We know symbolic::X<T>'s definition is T. When we see the substitution
      // of int* _Nullable* into T, we find its vector [Unspecified, Nullable]
      // and replace the outer nullability for the symbolic one.
      [&](const SubstTemplateTypeParmType *T)
          -> std::optional<TypeNullability> {
        if (auto ID =
                getSymbolicID(dyn_cast<TemplateDecl>(T->getAssociatedDecl()))) {
          auto Sym = Symbolic[*ID];
          if (!Sym.isSymbolic())
            // The test didn't bind anything to e.g. symbolic::X, but now wants
            // to assert that some expression has this type!
            // Create a variable now so we have something to assert against.
            // That way the test will fail with a reasonable error message.
            Sym = Symbolic[*ID] = PointerTypeNullability::createSymbolic(A);
          auto Result = getAssertedTypeNullability(T->desugar(), Symbolic, A);
          Result.front() = Sym;
          return Result;
        }
        return std::nullopt;
      });
}

// Match any special assertions, check the condition, diagnose on failure.
void diagnoseCall(const CallExpr &CE, const ASTContext &Ctx, Diagnoser &Diags,
                  const AnalysisState &State, SymbolicMap &Symbolic) {
  if (auto Want = getAssertedNullability(CE); Want && CE.getNumArgs() == 1) {
    auto &Arg = *CE.getArgs()[0];
    auto Got = getNullability(&Arg, State.Env);
    Diags.diagnoseNullability(CE.getBeginLoc(), Arg.getSourceRange(), *Want,
                              Got);
  }
  if (auto Want = getAssertedType(CE); Want && CE.getNumArgs() == 1) {
    auto &Got = *CE.getArgs()[0];
    auto WantCanon = Ctx.getCanonicalType(*Want);
    auto GotCanon = Ctx.getCanonicalType(Got.getType());
    auto WantNulls = getAssertedTypeNullability(
        *Want, Symbolic, State.Env.getDataflowAnalysisContext().arena());
    TypeNullability GotNulls = unspecifiedNullability(&Got);
    if (const auto *GN = State.Lattice.getTypeNullability(&Got)) GotNulls = *GN;
    Diags.diagnoseType(CE.getBeginLoc(), Got.getSourceRange(), WantCanon,
                       GotCanon, WantNulls, GotNulls);
  }
  if (llvm::StringRef Name = getBoolAssertionName(CE); !Name.empty()) {
    auto &Arg = *CE.getArgs()[0];
    auto *Val = State.Env.get<dataflow::BoolValue>(Arg);
    if (!Val) {
      Diags.diagnoseNoValue(Arg);
      return;
    }
    if (Name == "provable") {
      if (!State.Env.proves(Val->formula())) Diags.diagnoseNotProvable(Arg);
    } else {
      if (!State.Env.allows(Val->formula())) Diags.diagnoseNotPossible(Arg);
    }
  }
}

// Bind nullability variables for params marked symbolic::X<> etc.
// Returns the map from symbolic ID => nullability variables.
SymbolicMap bindSymbolicNullability(const FunctionDecl &Func,
                                    PointerNullabilityAnalysis &Analysis,
                                    dataflow::Arena &A) {
  SymbolicMap Result;
  for (const auto *Param : Func.parameters()) {
    // For now, only support symbolic on the top level of parameter types.
    if (auto *TST = Param->getType()->getAs<TemplateSpecializationType>())
      if (auto I = getSymbolicID(TST->getTemplateName().getAsTemplateDecl()))
        Result.try_emplace(*I, Analysis.assignNullabilityVariable(Param, A));
  }
  return Result;
}

// To run a test, we simply run the nullability analysis, and then walk the
// CFG afterwards looking for calls to our assertions - nullable() etc.
// These each assert properties attached to the analysis state at that point.
void runTest(const FunctionDecl &Func, const NullabilityPragmas &Pragmas,
             Diagnoser &Diags, std::unique_ptr<llvm::raw_ostream> LogStream) {
  std::unique_ptr<dataflow::Logger> Logger;
  if (LogStream)
    Logger = dataflow::Logger::html([&] {
      CHECK(LogStream) << "analyzing multiple functions?!";
      return std::move(LogStream);
    });
  dataflow::DataflowAnalysisContext::Options Opts;
  Opts.Log = Logger.get();
  dataflow::DataflowAnalysisContext DACtx(
      std::make_unique<dataflow::WatchedLiteralsSolver>(), Opts);
  auto &Ctx = Func.getDeclContext()->getParentASTContext();
  auto ACFG = require(dataflow::AdornedCFG::build(Func));
  dataflow::Environment Env(DACtx, Func);
  PointerNullabilityAnalysis Analysis(Ctx, Env, Pragmas);
  auto Symbolic = bindSymbolicNullability(Func, Analysis, DACtx.arena());
  dataflow::CFGEltCallbacks<PointerNullabilityAnalysis> PostAnalysisCallbacks;
  PostAnalysisCallbacks.After = [&](const CFGElement &Elt,
                                    AnalysisState &State) {
    if (auto CS = Elt.getAs<CFGStmt>())
      if (auto *CE = dyn_cast<CallExpr>(CS->getStmt()))
        diagnoseCall(*CE, Ctx, Diags, State, Symbolic);
  };
  require(runDataflowAnalysis(ACFG, Analysis, std::move(Env),
                              PostAnalysisCallbacks));
}

// Absorbs test start/end events and diagnostics.
// Produces stdout output, and also Bazel test.xml report.
class TestOutput : public DiagnosticConsumer {
 public:
  TestOutput()
      : Out(llvm::errs()),
        XMLStorage(openXML()),
        XML(XMLStorage ? *XMLStorage : llvm::nulls()) {
    XML << "<testsuites>\n";
  }
  ~TestOutput() override {
    XML << "</testsuites>\n";
    Out << "Passed " << PassingTests << " test(s)\n";
    if (!FailingTests.empty()) {
      Out << "Failed " << FailingTests.size() << " test(s):\n";
      for (const std::string &Name : FailingTests) Out << "  " << Name << "\n";
    }
  }

  void startSuite(llvm::StringRef Name) {
    XML << llvm::formatv("<testsuite name='{0}'>\n", escape(Name));
    Out << "=== Suite: " << Name << " ===\n";
  }
  void endSuite() { XML << "</testsuite>\n"; }

  void startTest(const FunctionDecl &F) {
    CurrentCase.emplace();
    CurrentCase->Name = F.getDeclName().getAsString();
    CurrentCase->Start = std::chrono::steady_clock::now();
    Out << "--- Test: " << CurrentCase->Name << " ---\n";
  }
  void endTest(llvm::StringRef LogPath) {
    assert(CurrentCase.has_value());
    if (CurrentCase->Failures.empty()) {
      Out << "PASS\n";
      ++PassingTests;
    } else {
      Out << "FAIL\n";
      FailingTests.emplace_back(CurrentCase->Name);
    }
    auto Millis = std::chrono::duration_cast<std::chrono::milliseconds>(
                      std::chrono::steady_clock::now() - CurrentCase->Start)
                      .count();
    XML << llvm::formatv("<testcase name='{0}' time='{1}'>\n",
                         escape(CurrentCase->Name), Millis);
    for (const auto &Failure : CurrentCase->Failures)
      XML << llvm::formatv("<failure message='{0}'>{1}</failure>\n",
                           escape(Failure.first), escape(Failure.second));
    if (!LogPath.empty()) {
      XML << llvm::formatv(
          "<properties><property name='test_output1' value='{0}'>"
          "</property></properties>",
          escape(LogPath));
      Out << "Log written to " << LogPath << "\n";
    } else if (!CurrentCase->Failures.empty()) {
      XML << "<error message='Note: run with --test_arg=-log for detailed "
             "analysis logs'></error>\n";
    }
    XML << "</testcase>\n";
    CurrentCase.reset();
  }
  bool hadErrors() const { return HadErrors; }

  void BeginSourceFile(const LangOptions &LangOpts,
                       const Preprocessor *PP) override {
    this->LangOpts = LangOpts;
  }
  void HandleDiagnostic(DiagnosticsEngine::Level Level,
                        const Diagnostic &Info) override {
    llvm::SmallString<256> Message;
    Info.FormatDiagnostic(Message);

    // TODO: in the printed diagnostic, the absolute path to the file is shown.
    // This is hard to read and breaks linkification in log viewers.
    // This happens because the tooling makes input file paths absolute.
    // We should find a way to avoid this.
    std::string Rendered;
    llvm::raw_string_ostream OS(Rendered);
    clang::DiagnosticOptions DiagOpts;
    TextDiagnostic(OS, LangOpts, DiagOpts)
        .emitDiagnostic(
            FullSourceLoc(Info.getLocation(), Info.getSourceManager()), Level,
            Message, Info.getRanges(), Info.getFixItHints());

    Out << Rendered;
    if (Level >= DiagnosticsEngine::Error) {
      if (CurrentCase) CurrentCase->Failures.emplace_back(Message, Rendered);
      HadErrors = true;
    }
  }

 private:
  // Create test.xml file in the right place, if running under Bazel.
  static std::unique_ptr<llvm::raw_ostream> openXML() {
    if (const char *Filename = std::getenv("XML_OUTPUT_FILE")) {
      std::error_code EC;
      auto OS = std::make_unique<llvm::raw_fd_ostream>(Filename, EC);
      if (EC) {
        llvm::errs() << "Failed to open XML output " << Filename << ": "
                     << EC.message() << "\n";
      } else {
        return OS;
      }
    }
    return nullptr;
  }

  static std::string escape(llvm::StringRef Raw) {
    std::string S;
    llvm::raw_string_ostream OS(S);
    llvm::printHTMLEscaped(Raw, OS);
    return S;
  }

  bool HadErrors = false;
  int PassingTests = 0;
  // Names of failing tests. These need to be strings, not `StringRef`s, because
  // this class may outlive the AST.
  llvm::SmallVector<std::string> FailingTests;
  LangOptions LangOpts;

  llvm::raw_ostream &Out;  // Plain-text output stream.
  std::unique_ptr<llvm::raw_ostream> XMLStorage;
  llvm::raw_ostream &XML;  // test.xml output stream (or null stream if no XML).

  // Gather info about the currently running test case.
  // The <testcase> element can only be written once it's finished.
  struct TestCase {
    std::string Name;
    std::vector<std::pair<std::string, std::string>> Failures;
    std::chrono::steady_clock::time_point Start;
  };
  std::optional<TestCase> CurrentCase;
};

// Provides a filter for running only specific tests.
struct TestFilter {
  llvm::SmallVector<llvm::GlobPattern> PositivePatterns, NegativePatterns;

  bool shouldRun(llvm::StringRef Name) const {
    auto PatternMatchesName = [&](const llvm::GlobPattern &Pattern) {
      return Pattern.match(Name);
    };
    if (!PositivePatterns.empty() &&
        !llvm::any_of(PositivePatterns, PatternMatchesName))
      return false;
    return !llvm::any_of(NegativePatterns, PatternMatchesName);
  }
};

llvm::Expected<llvm::SmallVector<llvm::GlobPattern>> globsFromPatternString(
    llvm::StringRef PatternStr) {
  llvm::SmallVector<llvm::GlobPattern> Globs;
  llvm::SmallVector<llvm::StringRef> Patterns;
  PatternStr.split(Patterns, ':');
  for (auto Pattern : Patterns) {
    if (Pattern.empty()) continue;
    llvm::GlobPattern Glob;
    if (llvm::Error Err = llvm::GlobPattern::create(Pattern).moveInto(Glob))
      return Err;
    Globs.push_back(std::move(Glob));
  }
  return Globs;
}

llvm::Expected<TestFilter> getTestFilter() {
  // Test filter syntax is the same as that of GoogleTest.
  llvm::StringRef TestFilterStr = getenv("TESTBRIDGE_TEST_ONLY");
  auto [PositivePatternsStr, NegativePatternsStr] = TestFilterStr.split('-');

  TestFilter Filter;
  if (llvm::Error Err = globsFromPatternString(PositivePatternsStr)
                            .moveInto(Filter.PositivePatterns))
    return Err;
  if (llvm::Error Err = globsFromPatternString(NegativePatternsStr)
                            .moveInto(Filter.NegativePatterns))
    return Err;

  return Filter;
}

// AST consumer that analyzes [[clang::annotate("test")]] functions as tests.
class Consumer : public ASTConsumer {
 public:
  Consumer(TestOutput &Output, const TestFilter &Filter,
           const NullabilityPragmas &Pragmas)
      : Pragmas(Pragmas), Output(Output), Filter(Filter) {}

 private:
  void Initialize(ASTContext &Context) override {
    Diagnoser.emplace(Context.getDiagnostics());
  }

  void HandleTranslationUnit(ASTContext &Ctx) override {
    assert(Diagnoser.has_value());
    if (Ctx.getDiagnostics().hasUncompilableErrorOccurred()) return;
    // Walk the AST, calling runTestAt on every TEST annotation.
    struct TestVisitor : public RecursiveASTVisitor<TestVisitor> {
      Consumer &Outer;
      ASTContext &Ctx;

      bool VisitAnnotateAttr(AnnotateAttr *A) {
        if (A->getAnnotation() == "test")
          Outer.runTestAt(DynTypedNode::create(*A), Ctx);
        return true;
      }
    };
    TestVisitor{{}, *this, Ctx}.TraverseAST(Ctx);
  }
  // Starting at a TEST annotation, find the associated test and run it.
  void runTestAt(const DynTypedNode &Test, ASTContext &Ctx) {
    if (const auto *FD = Test.get<FunctionDecl>()) {
      if (FD->getIdentifier() != nullptr && !Filter.shouldRun(FD->getName()))
        return;

      // This is a test we can run directly.
      Output.startTest(*FD);
      auto [LogPath, LogStream] = openTestLog(FD->getDeclName().getAsString());
      runTest(*FD, Pragmas, *Diagnoser, std::move(LogStream));
      Output.endTest(LogPath);
    } else if (Test.get<Attr>() || Test.get<TypeLoc>()) {
      // Walk up to find out what decl etc this marker is attached to.
      auto Parents = Ctx.getParents(Test);
      CHECK(!Parents.empty());
      for (const auto &Parent : Parents) runTestAt(Parent, Ctx);
    } else {
      // Uh-oh, TEST marker was in the wrong place!
      Diagnoser->diagnoseBadTest(Test);
    }
  }
  // Decide whether to write a per-test detailed log file that Bazel can find.
  // We do this if the "-log" flag is set (--test_arg=-log).
  // If we are writing one, create it and return its path and an open stream.
  std::pair<std::string, std::unique_ptr<llvm::raw_ostream>> openTestLog(
      llvm::StringRef Name) {
    const char *RootDir = ::getenv("TEST_UNDECLARED_OUTPUTS_DIR");
    if (!EmitTestLog || !RootDir) return {"", nullptr};
    llvm::SmallString<256> PathModel(RootDir), Path;
    llvm::sys::path::append(PathModel, Name + "-%%%%%%%%.html");
    int FD;
    if (auto EC = llvm::sys::fs::createUniqueFile(PathModel, FD, Path))
      return {"", nullptr};
    llvm::StringRef RelativePath = Path;
    RelativePath.consume_front(RootDir);
    while (!RelativePath.empty() &&
           llvm::sys::path::is_separator(RelativePath.front()))
      RelativePath = RelativePath.drop_front();
    return {RelativePath.str(),
            std::make_unique<llvm::raw_fd_ostream>(FD, /*ShouldClose=*/true)};
  }

  const NullabilityPragmas &Pragmas;
  TestOutput &Output;
  std::optional<Diagnoser> Diagnoser;
  const TestFilter &Filter;
};

}  // namespace
}  // namespace clang::tidy::nullability

int main(int argc, const char **argv) {
  using namespace clang::tidy::nullability;
  struct Factory : public clang::tooling::SourceFileCallbacks {
    TestOutput Output;
    TestFilter Filter;
    NullabilityPragmas Pragmas;

    std::unique_ptr<clang::ASTConsumer> newASTConsumer() {
      return std::make_unique<Consumer>(Output, Filter, Pragmas);
    }
    bool handleBeginSource(clang::CompilerInstance &CI) override {
      registerPragmaHandler(CI.getPreprocessor(), Pragmas);
      const auto &SM = CI.getSourceManager();
      llvm::StringRef FilenameStem =
          llvm::sys::path::stem(llvm::sys::path::filename(
              SM.getBufferName(SM.getLocForStartOfFile(SM.getMainFileID()))));
      llvm::StringRef LangStd =
          clang::LangStandard::getLangStandardForKind(CI.getLangOpts().LangStd)
              .getName();
      std::string SuiteName =
          (llvm::Twine(FilenameStem) + " (" + LangStd + ")").str();
      Output.startSuite(SuiteName);
      CI.getDiagnostics().setClient(&Output, /*Owns=*/false);
      return true;
    }
    void handleEndSource() override { Output.endSuite(); }
  } F;
  std::string Err;
  auto CDB = clang::tooling::FixedCompilationDatabase::loadFromCommandLine(
      argc, argv, Err);
  llvm::cl::ParseCommandLineOptions(argc, argv);
  if (!CDB) {
    llvm::errs() << "Usage: nullability_test source.cc\n" << Err << "\n";
    exit(1);
  }
  if (llvm::Error E = getTestFilter().moveInto(F.Filter)) {
    llvm::errs() << "Invalid test filter: " << E << "\n";
    exit(1);
  }
  clang::tooling::StandaloneToolExecutor Executor{*CDB, Sources};
  for (const auto &Entry :
       llvm::ArrayRef(test_headers_create(), test_headers_size()))
    Executor.mapVirtualFile(Entry.name, Entry.data);
  // Run in C++17 and C++20 mode to cover differences in the AST between modes
  // (e.g. C++20 can contain `CXXRewrittenBinaryOperator`).
  for (const char *CxxMode : {"-std=c++17", "-std=c++20"})
    require(Executor.execute(clang::tooling::newFrontendActionFactory(&F, &F),
                             clang::tooling::getInsertArgumentAdjuster(
                                 // Ensure test_headers are on the include path.
                                 {"-isystem.", CxxMode},
                                 clang::tooling::ArgumentInsertPosition::END)));
  return F.Output.hadErrors() ? 1 : 0;
}
