//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Tooling.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"
#include "gtest/gtest.h"
#include <algorithm>
#include <string>
#include <vector>

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(
      std::make_unique<TestAction>(
          std::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;
}

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

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

  FoundClassDeclX = false;
  EXPECT_TRUE(runToolOnCode(
      std::make_unique<TestAction>(
          std::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(buildASTFromCode, ReportsErrors) {
  TestDiagnosticConsumer Consumer;
  std::unique_ptr<ASTUnit> AST = buildASTFromCodeWithArgs(
      "int x = \"A\";", {}, "input.cc", "clang-tool",
      std::make_shared<PCHContainerOperations>(),
      getClangStripDependencyFileAdjuster(), FileContentMappings(), &Consumer);
  EXPECT_TRUE(AST.get());
  EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
}

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 std::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<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::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, std::make_unique<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<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::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, std::make_unique<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());
}

TEST(ToolInvocation, DiagnosticsEngineProperlyInitializedForCC1Construction) {
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
  llvm::IntrusiveRefCntPtr<FileManager> Files(
      new FileManager(FileSystemOptions(), OverlayFileSystem));

  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  // Unknown warning option will result in a warning.
  Args.push_back("-fexpensive-optimizations");
  // Argument that will suppress the warning above.
  Args.push_back("-Wno-ignored-optimization-argument");
  Args.push_back("-E");
  Args.push_back("test.cpp");

  clang::tooling::ToolInvocation Invocation(
      Args, std::make_unique<SyntaxOnlyAction>(), Files.get());
  InMemoryFileSystem->addFile("test.cpp", 0,
                              llvm::MemoryBuffer::getMemBuffer(""));
  TextDiagnosticBuffer Consumer;
  Invocation.setDiagnosticConsumer(&Consumer);
  EXPECT_TRUE(Invocation.run());
  // Check that the warning was ignored due to the '-Wno-xxx' argument.
  EXPECT_EQ(std::distance(Consumer.warn_begin(), Consumer.warn_end()), 0u);
}

TEST(ToolInvocation, CustomDiagnosticOptionsOverwriteParsedOnes) {
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
  llvm::IntrusiveRefCntPtr<FileManager> Files(
      new FileManager(FileSystemOptions(), OverlayFileSystem));

  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  // Unknown warning option will result in a warning.
  Args.push_back("-fexpensive-optimizations");
  // Argument that will suppress the warning above.
  Args.push_back("-Wno-ignored-optimization-argument");
  Args.push_back("-E");
  Args.push_back("test.cpp");

  clang::tooling::ToolInvocation Invocation(
      Args, std::make_unique<SyntaxOnlyAction>(), Files.get());
  InMemoryFileSystem->addFile("test.cpp", 0,
                              llvm::MemoryBuffer::getMemBuffer(""));
  TextDiagnosticBuffer Consumer;
  Invocation.setDiagnosticConsumer(&Consumer);

  // Inject custom `DiagnosticOptions` for command-line parsing.
  auto DiagOpts = llvm::makeIntrusiveRefCnt<DiagnosticOptions>();
  Invocation.setDiagnosticOptions(&*DiagOpts);

  EXPECT_TRUE(Invocation.run());
  // Check that the warning was issued during command-line parsing due to the
  // custom `DiagnosticOptions` without '-Wno-xxx'.
  EXPECT_EQ(std::distance(Consumer.warn_begin(), Consumer.warn_end()), 1u);
}

struct DiagnosticConsumerExpectingSourceManager : public DiagnosticConsumer {
  bool SawSourceManager;

  DiagnosticConsumerExpectingSourceManager() : SawSourceManager(false) {}

  void HandleDiagnostic(clang::DiagnosticsEngine::Level,
                        const clang::Diagnostic &info) override {
    SawSourceManager = info.hasSourceManager();
  }
};

TEST(ToolInvocation, DiagConsumerExpectingSourceManager) {
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::vfs::InMemoryFileSystem);
  OverlayFileSystem->pushOverlay(InMemoryFileSystem);
  llvm::IntrusiveRefCntPtr<FileManager> Files(
      new FileManager(FileSystemOptions(), OverlayFileSystem));
  std::vector<std::string> Args;
  Args.push_back("tool-executable");
  // Note: intentional error; user probably meant -ferror-limit=0.
  Args.push_back("-ferror-limit=-1");
  Args.push_back("-fsyntax-only");
  Args.push_back("test.cpp");
  clang::tooling::ToolInvocation Invocation(
      Args, std::make_unique<SyntaxOnlyAction>(), Files.get());
  InMemoryFileSystem->addFile(
      "test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int main() {}\n"));

  DiagnosticConsumerExpectingSourceManager Consumer;
  Invocation.setDiagnosticConsumer(&Consumer);

  EXPECT_TRUE(Invocation.run());
  EXPECT_TRUE(Consumer.SawSourceManager);
}

namespace {
/// Overlays the real filesystem with the given VFS and returns the result.
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>
overlayRealFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
  auto RFS = llvm::vfs::getRealFileSystem();
  auto OverlayFS = llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(RFS);
  OverlayFS->pushOverlay(VFS);
  return OverlayFS;
}

struct CommandLineExtractorTest : public ::testing::Test {
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
  driver::Driver Driver;

public:
  CommandLineExtractorTest()
      : InMemoryFS(new llvm::vfs::InMemoryFileSystem),
        Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)),
        Driver("clang", llvm::sys::getDefaultTargetTriple(), *Diags,
               "clang LLVM compiler", overlayRealFS(InMemoryFS)) {}

  void addFile(StringRef Name, StringRef Content) {
    InMemoryFS->addFile(Name, 0, llvm::MemoryBuffer::getMemBuffer(Content));
  }

  const llvm::opt::ArgStringList *
  extractCC1Arguments(llvm::ArrayRef<const char *> Argv) {
    const std::unique_ptr<driver::Compilation> Compilation(
        Driver.BuildCompilation(llvm::makeArrayRef(Argv)));

    return getCC1Arguments(Diags.get(), Compilation.get());
  }
};
} // namespace

TEST_F(CommandLineExtractorTest, AcceptOffloading) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {"clang",     "-target",  "arm64-apple-macosx11.0.0",
                        "-x",        "hip",      "test.c",
                        "-nogpulib", "-nogpuinc"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, AcceptOffloadingCompile) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {"clang",  "-target",   "arm64-apple-macosx11.0.0",
                        "-c",     "-x",        "hip",
                        "test.c", "-nogpulib", "-nogpuinc"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, AcceptOffloadingSyntaxOnly) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {
      "clang",         "-target",   "arm64-apple-macosx11.0.0",
      "-fsyntax-only", "-x",        "hip",
      "test.c",        "-nogpulib", "-nogpuinc"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, AcceptExternalAssembler) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {
      "clang", "-target", "arm64-apple-macosx11.0.0", "-fno-integrated-as",
      "-c",    "test.c"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, AcceptEmbedBitcode) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {"clang", "-target",         "arm64-apple-macosx11.0.0",
                        "-c",    "-fembed-bitcode", "test.c"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, AcceptSaveTemps) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {"clang", "-target",     "arm64-apple-macosx11.0.0",
                        "-c",    "-save-temps", "test.c"};
  EXPECT_NE(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, RejectMultipleArchitectures) {
  addFile("test.c", "int main() {}\n");
  const char *Args[] = {"clang", "-target", "arm64-apple-macosx11.0.0",
                        "-arch", "x86_64",  "-arch",
                        "arm64", "-c",      "test.c"};
  EXPECT_EQ(extractCC1Arguments(Args), nullptr);
}

TEST_F(CommandLineExtractorTest, RejectMultipleInputFiles) {
  addFile("one.c", "void one() {}\n");
  addFile("two.c", "void two() {}\n");
  const char *Args[] = {"clang", "-target", "arm64-apple-macosx11.0.0",
                        "-c",    "one.c",   "two.c"};
  EXPECT_EQ(extractCC1Arguments(Args), nullptr);
}

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 std::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 std::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(std::make_unique<SkipBodyAction>(),
                            "int skipMe() { an_error_here }"));
  EXPECT_FALSE(runToolOnCode(std::make_unique<SkipBodyAction>(),
                             "int skipMeNot() { an_error_here }"));

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

  EXPECT_FALSE(runToolOnCodeWithArgs(
      std::make_unique<SkipBodyAction>(), "struct skipMeNot { skipMeNot() : an_error() { } };",
      Args));
  EXPECT_FALSE(runToolOnCodeWithArgs(std::make_unique<SkipBodyAction>(),
                                     "struct skipMeNot { skipMeNot(); };"
                                     "skipMeNot::skipMeNot() : an_error() { }",
                                     Args));

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

  // Template
  EXPECT_TRUE(runToolOnCode(
      std::make_unique<SkipBodyAction>(), "template<typename T> int skipMe() { an_error_here }"
                          "int x = skipMe<int>();"));
  EXPECT_FALSE(runToolOnCodeWithArgs(
      std::make_unique<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(std::string(DepFilePath.str()));
  Args.push_back("-MF");
  Args.push_back(std::string(DepFilePath.str()));
  EXPECT_TRUE(runToolOnCodeWithArgs(std::make_unique<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 std::make_unique<ASTConsumer>();
  }

private:
  bool ShouldShowColor = true;
};

TEST(runToolOnCodeWithArgs, DiagnosticsColor) {
  EXPECT_TRUE(runToolOnCodeWithArgs(
      std::make_unique<CheckColoredDiagnosticsAction>(true), "",
      {"-fcolor-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      std::make_unique<CheckColoredDiagnosticsAction>(false), "",
      {"-fno-color-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      std::make_unique<CheckColoredDiagnosticsAction>(true), "",
      {"-fno-color-diagnostics", "-fcolor-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      std::make_unique<CheckColoredDiagnosticsAction>(false), "",
      {"-fcolor-diagnostics", "-fno-color-diagnostics"}));
  EXPECT_TRUE(runToolOnCodeWithArgs(
      std::make_unique<CheckColoredDiagnosticsAction>(true), "",
      {"-fno-color-diagnostics", "-fdiagnostics-color=always"}));

  // Check that this test would fail if ShowColors is not what it should.
  EXPECT_FALSE(runToolOnCodeWithArgs(
      std::make_unique<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 (llvm::is_contained(Args, "-fsyntax-only"))
      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, NoDoubleSyntaxOnly) {
  FixedCompilationDatabase Compilations("/", {"-fsyntax-only"});

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

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

  size_t SyntaxOnlyCount = 0;
  ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
      [&SyntaxOnlyCount](const CommandLineArguments &Args,
                         StringRef /*unused*/) {
        for (llvm::StringRef Arg : Args) {
          if (Arg == "-fsyntax-only")
            ++SyntaxOnlyCount;
        }
        return Args;
      };

  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
  Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
  Tool.run(Action.get());
  EXPECT_EQ(SyntaxOnlyCount, 1U);
}

TEST(ClangToolTest, NoOutputCommands) {
  FixedCompilationDatabase Compilations("/", {"-save-temps", "-save-temps=cwd",
                                              "--save-temps",
                                              "--save-temps=somedir"});

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

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

  const std::vector<llvm::StringRef> OutputCommands = {"-save-temps"};
  bool Ran = false;
  ArgumentsAdjuster CheckSyntaxOnlyAdjuster =
      [&OutputCommands, &Ran](const CommandLineArguments &Args,
                              StringRef /*unused*/) {
        for (llvm::StringRef Arg : Args) {
          for (llvm::StringRef OutputCommand : OutputCommands)
            EXPECT_FALSE(Arg.contains(OutputCommand));
        }
        Ran = true;
        return Args;
      };

  Tool.clearArgumentsAdjusters();
  Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
  Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster);
  Tool.run(Action.get());
  EXPECT_TRUE(Ran);
}

TEST(ClangToolTest, BaseVirtualFileSystemUsage) {
  FixedCompilationDatabase Compilations("/", std::vector<std::string>());
  llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem(
      new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem()));
  llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
      new llvm::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 llvm::find(FinalArgs, Flag) != FinalArgs.end();
  };
  EXPECT_FALSE(HasFlag("-MD"));
  EXPECT_FALSE(HasFlag("-MMD"));
  EXPECT_TRUE(HasFlag("-c"));
  EXPECT_TRUE(HasFlag("-w"));
}

// Check getClangStripDependencyFileAdjuster strips /showIncludes and variants
TEST(ClangToolTest, StripDependencyFileAdjusterShowIncludes) {
  FixedCompilationDatabase Compilations(
      "/", {"/showIncludes", "/showIncludes:user", "-showIncludes",
            "-showIncludes:user", "-c"});

  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 llvm::find(FinalArgs, Flag) != FinalArgs.end();
  };
  EXPECT_FALSE(HasFlag("/showIncludes"));
  EXPECT_FALSE(HasFlag("/showIncludes:user"));
  EXPECT_FALSE(HasFlag("-showIncludes"));
  EXPECT_FALSE(HasFlag("-showIncludes:user"));
  EXPECT_TRUE(HasFlag("-c"));
}

// Check getClangStripDependencyFileAdjuster doesn't strip args when using the
// MSVC cl.exe driver
TEST(ClangToolTest, StripDependencyFileAdjusterMsvc) {
  FixedCompilationDatabase Compilations(
      "/", {"--driver-mode=cl", "-MD", "-MDd", "-MT", "-O1", "-MTd", "-MP"});

  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 llvm::find(FinalArgs, Flag) != FinalArgs.end();
  };
  EXPECT_TRUE(HasFlag("-MD"));
  EXPECT_TRUE(HasFlag("-MDd"));
  EXPECT_TRUE(HasFlag("-MT"));
  EXPECT_TRUE(HasFlag("-O1"));
  EXPECT_TRUE(HasFlag("-MTd"));
  EXPECT_TRUE(HasFlag("-MP"));
}

// Check getClangStripPluginsAdjuster strips plugin related args.
TEST(ClangToolTest, StripPluginsAdjuster) {
  FixedCompilationDatabase Compilations(
      "/", {"-Xclang", "-add-plugin", "-Xclang", "random-plugin"});

  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(getStripPluginsAdjuster());
  Tool.appendArgumentsAdjuster(CheckFlagsAdjuster);
  Tool.run(Action.get());

  auto HasFlag = [&FinalArgs](const std::string &Flag) {
    return llvm::find(FinalArgs, Flag) != FinalArgs.end();
  };
  EXPECT_FALSE(HasFlag("-Xclang"));
  EXPECT_FALSE(HasFlag("-add-plugin"));
  EXPECT_FALSE(HasFlag("-random-plugin"));
}

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(std::string(TargetName), Error) ==
        &Target) {
      return std::string(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);
}

#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());
}

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 std::make_unique<Consumer>();
    }
  };

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

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