diff options
author | 2020-08-03 14:31:31 +0000 | |
---|---|---|
committer | 2020-08-03 14:31:31 +0000 | |
commit | e5dd70708596ae51455a0ffa086a00c5b29f8583 (patch) | |
tree | 5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/unittests/Tooling/DependencyScannerTest.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-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.cpp | 200 |
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 |