summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp
diff options
context:
space:
mode:
authorpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
committerpatrick <patrick@openbsd.org>2020-08-03 14:31:31 +0000
commite5dd70708596ae51455a0ffa086a00c5b29f8583 (patch)
tree5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp
parentImport LLVM 10.0.0 release including clang, lld and lldb. (diff)
downloadwireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz
wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom tested by plenty
Diffstat (limited to 'gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp')
-rw-r--r--gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp b/gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp
new file mode 100644
index 00000000000..60f65661509
--- /dev/null
+++ b/gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp
@@ -0,0 +1,200 @@
+//===- 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/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/FormatVariadic.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 {
+
+/// Prints out all of the gathered dependencies into a string.
+class TestFileCollector : public DependencyFileGenerator {
+public:
+ TestFileCollector(DependencyOutputOptions &Opts,
+ std::vector<std::string> &Deps)
+ : DependencyFileGenerator(Opts), Deps(Deps) {}
+
+ void finishedMainFile(DiagnosticsEngine &Diags) override {
+ auto NewDeps = getDependencies();
+ Deps.insert(Deps.end(), NewDeps.begin(), NewDeps.end());
+ }
+
+private:
+ std::vector<std::string> &Deps;
+};
+
+class TestDependencyScanningAction : public tooling::ToolAction {
+public:
+ TestDependencyScanningAction(std::vector<std::string> &Deps) : Deps(Deps) {}
+
+ bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
+ FileManager *FileMgr,
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+ DiagnosticConsumer *DiagConsumer) override {
+ CompilerInstance Compiler(std::move(PCHContainerOps));
+ Compiler.setInvocation(std::move(Invocation));
+ Compiler.setFileManager(FileMgr);
+
+ Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
+ if (!Compiler.hasDiagnostics())
+ return false;
+
+ Compiler.createSourceManager(*FileMgr);
+ Compiler.addDependencyCollector(std::make_shared<TestFileCollector>(
+ Compiler.getInvocation().getDependencyOutputOpts(), Deps));
+
+ auto Action = std::make_unique<PreprocessOnlyAction>();
+ return Compiler.ExecuteAction(*Action);
+ }
+
+private:
+ std::vector<std::string> &Deps;
+};
+
+} // namespace
+
+TEST(DependencyScanner, ScanDepsReuseFilemanager) {
+ std::vector<std::string> Compilation = {"-c", "-E", "-MT", "test.cpp.o"};
+ StringRef CWD = "/root";
+ FixedCompilationDatabase CDB(CWD, Compilation);
+
+ auto VFS = new llvm::vfs::InMemoryFileSystem();
+ VFS->setCurrentWorkingDirectory(CWD);
+ auto Sept = llvm::sys::path::get_separator();
+ std::string HeaderPath = llvm::formatv("{0}root{0}header.h", Sept);
+ std::string SymlinkPath = llvm::formatv("{0}root{0}symlink.h", Sept);
+ std::string TestPath = llvm::formatv("{0}root{0}test.cpp", Sept);
+
+ VFS->addFile(HeaderPath, 0, llvm::MemoryBuffer::getMemBuffer("\n"));
+ VFS->addHardLink(SymlinkPath, HeaderPath);
+ VFS->addFile(TestPath, 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "#include \"symlink.h\"\n#include \"header.h\"\n"));
+
+ ClangTool Tool(CDB, {"test.cpp"}, std::make_shared<PCHContainerOperations>(),
+ VFS);
+ Tool.clearArgumentsAdjusters();
+ std::vector<std::string> Deps;
+ TestDependencyScanningAction Action(Deps);
+ Tool.run(&Action);
+ using llvm::sys::path::convert_to_slash;
+ // The first invocation should return dependencies in order of access.
+ ASSERT_EQ(Deps.size(), 3u);
+ EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[1]), "/root/symlink.h");
+ EXPECT_EQ(convert_to_slash(Deps[2]), "/root/header.h");
+
+ // The file manager should still have two FileEntries, as one file is a
+ // hardlink.
+ FileManager &Files = Tool.getFiles();
+ EXPECT_EQ(Files.getNumUniqueRealFiles(), 2u);
+
+ Deps.clear();
+ Tool.run(&Action);
+ // The second invocation should have the same order of dependencies.
+ ASSERT_EQ(Deps.size(), 3u);
+ EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[1]), "/root/symlink.h");
+ EXPECT_EQ(convert_to_slash(Deps[2]), "/root/header.h");
+
+ EXPECT_EQ(Files.getNumUniqueRealFiles(), 2u);
+}
+
+TEST(DependencyScanner, ScanDepsReuseFilemanagerSkippedFile) {
+ std::vector<std::string> Compilation = {"-c", "-E", "-MT", "test.cpp.o"};
+ StringRef CWD = "/root";
+ FixedCompilationDatabase CDB(CWD, Compilation);
+
+ auto VFS = new llvm::vfs::InMemoryFileSystem();
+ VFS->setCurrentWorkingDirectory(CWD);
+ auto Sept = llvm::sys::path::get_separator();
+ std::string HeaderPath = llvm::formatv("{0}root{0}header.h", Sept);
+ std::string SymlinkPath = llvm::formatv("{0}root{0}symlink.h", Sept);
+ std::string TestPath = llvm::formatv("{0}root{0}test.cpp", Sept);
+ std::string Test2Path = llvm::formatv("{0}root{0}test2.cpp", Sept);
+
+ VFS->addFile(HeaderPath, 0,
+ llvm::MemoryBuffer::getMemBuffer("#pragma once\n"));
+ VFS->addHardLink(SymlinkPath, HeaderPath);
+ VFS->addFile(TestPath, 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "#include \"header.h\"\n#include \"symlink.h\"\n"));
+ VFS->addFile(Test2Path, 0,
+ llvm::MemoryBuffer::getMemBuffer(
+ "#include \"symlink.h\"\n#include \"header.h\"\n"));
+
+ ClangTool Tool(CDB, {"test.cpp", "test2.cpp"},
+ std::make_shared<PCHContainerOperations>(), VFS);
+ Tool.clearArgumentsAdjusters();
+ std::vector<std::string> Deps;
+ TestDependencyScanningAction Action(Deps);
+ Tool.run(&Action);
+ using llvm::sys::path::convert_to_slash;
+ ASSERT_EQ(Deps.size(), 6u);
+ EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[1]), "/root/header.h");
+ EXPECT_EQ(convert_to_slash(Deps[2]), "/root/symlink.h");
+ EXPECT_EQ(convert_to_slash(Deps[3]), "/root/test2.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[4]), "/root/symlink.h");
+ EXPECT_EQ(convert_to_slash(Deps[5]), "/root/header.h");
+}
+
+TEST(DependencyScanner, ScanDepsReuseFilemanagerHasInclude) {
+ std::vector<std::string> Compilation = {"-c", "-E", "-MT", "test.cpp.o"};
+ StringRef CWD = "/root";
+ FixedCompilationDatabase CDB(CWD, Compilation);
+
+ auto VFS = new llvm::vfs::InMemoryFileSystem();
+ VFS->setCurrentWorkingDirectory(CWD);
+ auto Sept = llvm::sys::path::get_separator();
+ std::string HeaderPath = llvm::formatv("{0}root{0}header.h", Sept);
+ std::string SymlinkPath = llvm::formatv("{0}root{0}symlink.h", Sept);
+ std::string TestPath = llvm::formatv("{0}root{0}test.cpp", Sept);
+
+ VFS->addFile(HeaderPath, 0, llvm::MemoryBuffer::getMemBuffer("\n"));
+ VFS->addHardLink(SymlinkPath, HeaderPath);
+ VFS->addFile(
+ TestPath, 0,
+ llvm::MemoryBuffer::getMemBuffer("#if __has_include(\"header.h\") && "
+ "__has_include(\"symlink.h\")\n#endif"));
+
+ ClangTool Tool(CDB, {"test.cpp", "test.cpp"},
+ std::make_shared<PCHContainerOperations>(), VFS);
+ Tool.clearArgumentsAdjusters();
+ std::vector<std::string> Deps;
+ TestDependencyScanningAction Action(Deps);
+ Tool.run(&Action);
+ using llvm::sys::path::convert_to_slash;
+ ASSERT_EQ(Deps.size(), 6u);
+ EXPECT_EQ(convert_to_slash(Deps[0]), "/root/test.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[1]), "/root/header.h");
+ EXPECT_EQ(convert_to_slash(Deps[2]), "/root/symlink.h");
+ EXPECT_EQ(convert_to_slash(Deps[3]), "/root/test.cpp");
+ EXPECT_EQ(convert_to_slash(Deps[4]), "/root/header.h");
+ EXPECT_EQ(convert_to_slash(Deps[5]), "/root/symlink.h");
+}
+
+} // end namespace tooling
+} // end namespace clang