//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>

namespace clang {
namespace tooling {

namespace {
/// Takes an ast consumer and returns it from CreateASTConsumer. This only
/// works with single translation unit compilations.
class TestAction : public clang::ASTFrontendAction {
public:
  /// Takes ownership of TestConsumer.
  explicit TestAction(std::unique_ptr<clang::ASTConsumer> TestConsumer)
      : TestConsumer(std::move(TestConsumer)) {}

protected:
  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(clang::CompilerInstance &compiler,
                    StringRef dummy) override {
    /// TestConsumer will be deleted by the framework calling us.
    return std::move(TestConsumer);
  }

private:
  std::unique_ptr<clang::ASTConsumer> TestConsumer;
};

class FindTopLevelDeclConsumer : public clang::ASTConsumer {
 public:
  explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
      : FoundTopLevelDecl(FoundTopLevelDecl) {}
  bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) override {
    *FoundTopLevelDecl = true;
    return true;
  }
 private:
  bool * const FoundTopLevelDecl;
};
} // end namespace

TEST(runToolOnCode, FindsNoTopLevelDeclOnEmptyCode) {
  bool FoundTopLevelDecl = false;
  EXPECT_TRUE(
      runToolOnCode(new TestAction(llvm::make_unique<FindTopLevelDeclConsumer>(
                        &FoundTopLevelDecl)),
                    ""));
  EXPECT_FALSE(FoundTopLevelDecl);
}

namespace {
class FindClassDeclXConsumer : public clang::ASTConsumer {
 public:
  FindClassDeclXConsumer(bool *FoundClassDeclX)
      : FoundClassDeclX(FoundClassDeclX) {}
  bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) override {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(
            *GroupRef.begin())) {
      if (Record->getName() == "X") {
        *FoundClassDeclX = true;
      }
    }
    return true;
  }
 private:
  bool *FoundClassDeclX;
};
bool FindClassDeclX(ASTUnit *AST) {
  for (std::vector<Decl *>::iterator i = AST->top_level_begin(),
                                     e = AST->top_level_end();
       i != e; ++i) {
    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) {
      if (Record->getName() == "X") {
        return true;
      }
    }
  }
  return false;
}
} // end namespace

TEST(runToolOnCode, FindsClassDecl) {
  bool FoundClassDeclX = false;
  EXPECT_TRUE(
      runToolOnCode(new TestAction(llvm::make_unique<FindClassDeclXConsumer>(
                        &FoundClassDeclX)),
                    "class X;"));
  EXPECT_TRUE(FoundClassDeclX);

  FoundClassDeclX = false;
  EXPECT_TRUE(
      runToolOnCode(new TestAction(llvm::make_unique<FindClassDeclXConsumer>(
                        &FoundClassDeclX)),
                    "class Y;"));
  EXPECT_FALSE(FoundClassDeclX);
}

TEST(buildASTFromCode, FindsClassDecl) {
  std::unique_ptr<ASTUnit> AST = buildASTFromCode("class X;");
  ASSERT_TRUE(AST.get());
  EXPECT_TRUE(FindClassDeclX(AST.get()));

  AST = buildASTFromCode("class Y;");
  ASSERT_TRUE(AST.get());
  EXPECT_FALSE(FindClassDeclX(AST.get()));
}

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory<SyntaxOnlyAction>());
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != nullptr);
}

struct IndependentFrontendActionCreator {
  std::unique_ptr<ASTConsumer> newASTConsumer() {
    return llvm::make_unique<FindTopLevelDeclConsumer>(nullptr);
  }
};

TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
  IndependentFrontendActionCreator Creator;
  std::unique_ptr<FrontendActionFactory> Factory(
      newFrontendActionFactory(&Creator));
  std::unique_ptr<FrontendAction> Action(Factory->create());
  EXPECT_TRUE(Action.get() != nullptr);
}

TEST(ToolInvocation, TestMapVirtualFile) {
  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem(
      new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
      new vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
  llvm::IntrusiveRefCntPtr<FileManager> Files(
      new FileManager(FileSystemOptions(), OverlayFileSystem));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.get());
  InMemoryFileSystem->addFile(
      "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("#include <abc>\n"));
  InMemoryFileSystem->addFile("def/abc", 0,
                              llvm::MemoryBuffer::getMemBuffer("\n"));
  EXPECT_TRUE(Invocation.run());
}

TEST(ToolInvocation, TestVirtualModulesCompilation) {
  // FIXME: Currently, this only tests that we don't exit with an error if a
  // mapped module.map is found on the include path. In the future, expand this
  // test to run a full modules enabled compilation, so we make sure we can
  // rerun modules compilations with a virtual file system.
  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem(
      new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
      new vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
  llvm::IntrusiveRefCntPtr<FileManager> Files(
      new FileManager(FileSystemOptions(), OverlayFileSystem));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  Args.push_back("-Idef");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
                                            Files.get());
  InMemoryFileSystem->addFile(
      "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("#include <abc>\n"));
  InMemoryFileSystem->addFile("def/abc", 0,
                              llvm::MemoryBuffer::getMemBuffer("\n"));
  // Add a module.map file in the include directory of our header, so we trigger
  // the module.map header search logic.
  InMemoryFileSystem->addFile("def/module.map", 0,
                              llvm::MemoryBuffer::getMemBuffer("\n"));
  EXPECT_TRUE(Invocation.run());
}

struct VerifyEndCallback : public SourceFileCallbacks {
  VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {}
  bool handleBeginSource(CompilerInstance &CI) override {
    ++BeginCalled;
    return true;
  }
  void handleEndSource() override { ++EndCalled; }
  std::unique_ptr<ASTConsumer> newASTConsumer() {
    return llvm::make_unique<FindTopLevelDeclConsumer>(&Matched);
  }
  unsigned BeginCalled;
  unsigned EndCalled;
  bool Matched;
};

#if !defined(_WIN32)
TEST(newFrontendActionFactory, InjectsSourceFileCallbacks) {
  VerifyEndCallback EndCallback;

  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory(&EndCallback, &EndCallback));
  Tool.run(Action.get());

  EXPECT_TRUE(EndCallback.Matched);
  EXPECT_EQ(2u, EndCallback.BeginCalled);
  EXPECT_EQ(2u, EndCallback.EndCalled);
}
#endif

struct SkipBodyConsumer : public clang::ASTConsumer {
  /// Skip the 'skipMe' function.
  bool shouldSkipFunctionBody(Decl *D) override {
    NamedDecl *F = dyn_cast<NamedDecl>(D);
    return F && F->getNameAsString() == "skipMe";
  }
};

struct SkipBodyAction : public clang::ASTFrontendAction {
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                 StringRef) override {
    Compiler.getFrontendOpts().SkipFunctionBodies = true;
    return llvm::make_unique<SkipBodyConsumer>();
  }
};

TEST(runToolOnCode, TestSkipFunctionBody) {
  std::vector<std::string> Args = {"-std=c++11"};
  std::vector<std::string> Args2 = {"-fno-delayed-template-parsing"};

  EXPECT_TRUE(runToolOnCode(new SkipBodyAction,
                            "int skipMe() { an_error_here }"));
  EXPECT_FALSE(runToolOnCode(new SkipBodyAction,
                             "int skipMeNot() { an_error_here }"));

  // Test constructors with initializers
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new SkipBodyAction,
      "struct skipMe { skipMe() : an_error() { more error } };", Args));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new SkipBodyAction, "struct skipMe { skipMe(); };"
                          "skipMe::skipMe() : an_error([](){;}) { more error }",
      Args));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new SkipBodyAction, "struct skipMe { skipMe(); };"
                          "skipMe::skipMe() : an_error{[](){;}} { more error }",
      Args));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new SkipBodyAction,
      "struct skipMe { skipMe(); };"
      "skipMe::skipMe() : a<b<c>(e)>>(), f{}, g() { error }",
      Args));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new SkipBodyAction, "struct skipMe { skipMe() : bases()... { error } };",
      Args));

  EXPECT_FALSE(runToolOnCodeWithArgs(
      new SkipBodyAction, "struct skipMeNot { skipMeNot() : an_error() { } };",
      Args));
  EXPECT_FALSE(runToolOnCodeWithArgs(new SkipBodyAction,
                                     "struct skipMeNot { skipMeNot(); };"
                                     "skipMeNot::skipMeNot() : an_error() { }",
                                     Args));

  // Try/catch
  EXPECT_TRUE(runToolOnCode(
      new SkipBodyAction,
      "void skipMe() try { an_error() } catch(error) { error };"));
  EXPECT_TRUE(runToolOnCode(
      new SkipBodyAction,
      "struct S { void skipMe() try { an_error() } catch(error) { error } };"));
  EXPECT_TRUE(
      runToolOnCode(new SkipBodyAction,
                    "void skipMe() try { an_error() } catch(error) { error; }"
                    "catch(error) { error } catch (error) { }"));
  EXPECT_FALSE(runToolOnCode(
      new SkipBodyAction,
      "void skipMe() try something;")); // don't crash while parsing

  // Template
  EXPECT_TRUE(runToolOnCode(
      new SkipBodyAction, "template<typename T> int skipMe() { an_error_here }"
                          "int x = skipMe<int>();"));
  EXPECT_FALSE(runToolOnCodeWithArgs(
      new SkipBodyAction,
      "template<typename T> int skipMeNot() { an_error_here }", Args2));
}

TEST(runToolOnCodeWithArgs, TestNoDepFile) {
  llvm::SmallString<32> DepFilePath;
  ASSERT_FALSE(llvm::sys::fs::getPotentiallyUniqueTempFileName("depfile", "d",
                                                               DepFilePath));
  std::vector<std::string> Args;
  Args.push_back("-MMD");
  Args.push_back("-MT");
  Args.push_back(DepFilePath.str());
  Args.push_back("-MF");
  Args.push_back(DepFilePath.str());
  EXPECT_TRUE(runToolOnCodeWithArgs(new SkipBodyAction, "", Args));
  EXPECT_FALSE(llvm::sys::fs::exists(DepFilePath.str()));
  EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str()));
}

struct CheckColoredDiagnosticsAction : public clang::ASTFrontendAction {
  CheckColoredDiagnosticsAction(bool ShouldShowColor)
      : ShouldShowColor(ShouldShowColor) {}
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                 StringRef) override {
    if (Compiler.getDiagnosticOpts().ShowColors != ShouldShowColor)
      Compiler.getDiagnostics().Report(
          Compiler.getDiagnostics().getCustomDiagID(
              DiagnosticsEngine::Fatal,
              "getDiagnosticOpts().ShowColors != ShouldShowColor"));
    return llvm::make_unique<ASTConsumer>();
  }

private:
  bool ShouldShowColor = true;
};

TEST(runToolOnCodeWithArgs, DiagnosticsColor) {

  EXPECT_TRUE(runToolOnCodeWithArgs(new CheckColoredDiagnosticsAction(true), "",
                                    {"-fcolor-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(new CheckColoredDiagnosticsAction(false),
                                    "", {"-fno-color-diagnostics"}));
  EXPECT_TRUE(
      runToolOnCodeWithArgs(new CheckColoredDiagnosticsAction(true), "",
                            {"-fno-color-diagnostics", "-fcolor-diagnostics"}));
  EXPECT_TRUE(
      runToolOnCodeWithArgs(new CheckColoredDiagnosticsAction(false), "",
                            {"-fcolor-diagnostics", "-fno-color-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      new CheckColoredDiagnosticsAction(true), "",
      {"-fno-color-diagnostics", "-fdiagnostics-color=always"}));

  // Check that this test would fail if ShowColors is not what it should.
  EXPECT_FALSE(runToolOnCodeWithArgs(new CheckColoredDiagnosticsAction(false),
                                     "", {"-fcolor-diagnostics"}));
}

TEST(ClangToolTest, ArgumentAdjusters) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "void a() {}");

  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());

  bool Found = false;
  bool Ran = false;
  ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
      [&Found, &Ran](const CommandLineArguments &Args, StringRef /*unused*/) {
    Ran = true;
    if (std::find(Args.begin(), Args.end(), "-fsyntax-only") != Args.end())
      Found = true;
    return Args;
  };
  Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
  Tool.run(Action.get());
  EXPECT_TRUE(Ran);
  EXPECT_TRUE(Found);

  Ran = Found = false;
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
  Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
  Tool.run(Action.get());
  EXPECT_TRUE(Ran);
  EXPECT_FALSE(Found);
}

TEST(ClangToolTest, BaseVirtualFileSystemUsage) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem(
      new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem(
      new vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);

  InMemoryFileSystem->addFile(
      "a.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int main() {}"));

  ClangTool Tool(Compilations, std::vector<std::string>(1, "a.cpp"),
                 std::make_shared<PCHContainerOperations>(), OverlayFileSystem);
  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());
  EXPECT_EQ(0, Tool.run(Action.get()));
}

// Check getClangStripDependencyFileAdjuster doesn't strip args after -MD/-MMD.
TEST(ClangToolTest, StripDependencyFileAdjuster) {
  FixedCompilationDatabase Compilations("/", {"-MD", "-c", "-MMD", "-w"});

  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "void a() {}");

  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());

  CommandLineArguments FinalArgs;
  ArgumentsAdjuster CheckFlagsAdjuster =
    [&FinalArgs](const CommandLineArguments &Args, StringRef /*unused*/) {
      FinalArgs = Args;
      return Args;
    };
  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(getClangStripDependencyFileAdjuster());
  Tool.appendArgumentsAdjuster(CheckFlagsAdjuster);
  Tool.run(Action.get());

  auto HasFlag = [&FinalArgs](const std::string &Flag) {
    return std::find(FinalArgs.begin(), FinalArgs.end(), Flag) !=
           FinalArgs.end();
  };
  EXPECT_FALSE(HasFlag("-MD"));
  EXPECT_FALSE(HasFlag("-MMD"));
  EXPECT_TRUE(HasFlag("-c"));
  EXPECT_TRUE(HasFlag("-w"));
}

namespace {
/// Find a target name such that looking for it in TargetRegistry by that name
/// returns the same target. We expect that there is at least one target
/// configured with this property.
std::string getAnyTarget() {
  llvm::InitializeAllTargets();
  for (const auto &Target : llvm::TargetRegistry::targets()) {
    std::string Error;
    StringRef TargetName(Target.getName());
    if (TargetName == "x86-64")
      TargetName = "x86_64";
    if (llvm::TargetRegistry::lookupTarget(TargetName, Error) == &Target) {
      return TargetName;
    }
  }
  return "";
}
}

TEST(addTargetAndModeForProgramName, AddsTargetAndMode) {
  std::string Target = getAnyTarget();
  ASSERT_FALSE(Target.empty());

  std::vector<std::string> Args = {"clang", "-foo"};
  addTargetAndModeForProgramName(Args, "");
  EXPECT_EQ((std::vector<std::string>{"clang", "-foo"}), Args);
  addTargetAndModeForProgramName(Args, Target + "-g++");
  EXPECT_EQ((std::vector<std::string>{"clang", "-target", Target,
                                      "--driver-mode=g++", "-foo"}),
            Args);
}

TEST(addTargetAndModeForProgramName, PathIgnored) {
  std::string Target = getAnyTarget();
  ASSERT_FALSE(Target.empty());

  SmallString<32> ToolPath;
  llvm::sys::path::append(ToolPath, "foo", "bar", Target + "-g++");

  std::vector<std::string> Args = {"clang", "-foo"};
  addTargetAndModeForProgramName(Args, ToolPath);
  EXPECT_EQ((std::vector<std::string>{"clang", "-target", Target,
                                      "--driver-mode=g++", "-foo"}),
            Args);
}

TEST(addTargetAndModeForProgramName, IgnoresExistingTarget) {
  std::string Target = getAnyTarget();
  ASSERT_FALSE(Target.empty());

  std::vector<std::string> Args = {"clang", "-foo", "-target", "something"};
  addTargetAndModeForProgramName(Args, Target + "-g++");
  EXPECT_EQ((std::vector<std::string>{"clang", "--driver-mode=g++", "-foo",
                                      "-target", "something"}),
            Args);

  std::vector<std::string> ArgsAlt = {"clang", "-foo", "-target=something"};
  addTargetAndModeForProgramName(ArgsAlt, Target + "-g++");
  EXPECT_EQ((std::vector<std::string>{"clang", "--driver-mode=g++", "-foo",
                                      "-target=something"}),
            ArgsAlt);
}

TEST(addTargetAndModeForProgramName, IgnoresExistingMode) {
  std::string Target = getAnyTarget();
  ASSERT_FALSE(Target.empty());

  std::vector<std::string> Args = {"clang", "-foo", "--driver-mode=abc"};
  addTargetAndModeForProgramName(Args, Target + "-g++");
  EXPECT_EQ((std::vector<std::string>{"clang", "-target", Target, "-foo",
                                      "--driver-mode=abc"}),
            Args);

  std::vector<std::string> ArgsAlt = {"clang", "-foo", "--driver-mode", "abc"};
  addTargetAndModeForProgramName(ArgsAlt, Target + "-g++");
  EXPECT_EQ((std::vector<std::string>{"clang", "-target", Target, "-foo",
                                      "--driver-mode", "abc"}),
            ArgsAlt);
}

#ifndef _WIN32
TEST(ClangToolTest, BuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());

  std::vector<std::string> Sources;
  Sources.push_back("/a.cc");
  Sources.push_back("/b.cc");
  ClangTool Tool(Compilations, Sources);

  Tool.mapVirtualFile("/a.cc", "void a() {}");
  Tool.mapVirtualFile("/b.cc", "void b() {}");

  std::vector<std::unique_ptr<ASTUnit>> ASTs;
  EXPECT_EQ(0, Tool.buildASTs(ASTs));
  EXPECT_EQ(2u, ASTs.size());
}

struct TestDiagnosticConsumer : public DiagnosticConsumer {
  TestDiagnosticConsumer() : NumDiagnosticsSeen(0) {}
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                        const Diagnostic &Info) override {
    ++NumDiagnosticsSeen;
  }
  unsigned NumDiagnosticsSeen;
};

TEST(ClangToolTest, InjectDiagnosticConsumer) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  std::unique_ptr<FrontendActionFactory> Action(
      newFrontendActionFactory<SyntaxOnlyAction>());
  Tool.run(Action.get());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}

TEST(ClangToolTest, InjectDiagnosticConsumerInBuildASTs) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
  Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
  TestDiagnosticConsumer Consumer;
  Tool.setDiagnosticConsumer(&Consumer);
  std::vector<std::unique_ptr<ASTUnit>> ASTs;
  Tool.buildASTs(ASTs);
  EXPECT_EQ(1u, ASTs.size());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}
#endif

TEST(runToolOnCode, TestResetDiagnostics) {
  // This is a tool that resets the diagnostic during the compilation.
  struct ResetDiagnosticAction : public clang::ASTFrontendAction {
    std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
                                                   StringRef) override {
      struct Consumer : public clang::ASTConsumer {
        bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
          auto &Diags = (*D.begin())->getASTContext().getDiagnostics();
          // Ignore any error
          Diags.Reset();
          // Disable warnings because computing the CFG might crash.
          Diags.setIgnoreAllWarnings(true);
          return true;
        }
      };
      return llvm::make_unique<Consumer>();
    }
  };

  // Should not crash
  EXPECT_FALSE(
      runToolOnCode(new ResetDiagnosticAction,
                    "struct Foo { Foo(int); ~Foo(); struct Fwd _fwd; };"
                    "void func() { long x; Foo f(x); }"));
}

} // end namespace tooling
} // end namespace clang
