Author: kadircet Date: Wed Jun 26 00:39:03 2019 New Revision: 364386 URL: http://llvm.org/viewvc/llvm-project?rev=364386&view=rev Log: [clang][Tooling] Infer target and mode from argv[0] when using JSONCompilationDatabase
Summary: Wraps JSON compilation database with a target and mode adding database wrapper. So that driver can correctly figure out which toolchain to use. Note that clients that wants to make use of this target discovery mechanism needs to link in TargetsInfos and initialize them at startup. Reviewers: ilya-biryukov Subscribers: mgorny, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D63755 Added: cfe/trunk/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp Modified: cfe/trunk/bindings/python/tests/cindex/test_cdb.py cfe/trunk/include/clang/Tooling/CompilationDatabase.h cfe/trunk/lib/Tooling/CMakeLists.txt cfe/trunk/lib/Tooling/JSONCompilationDatabase.cpp cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp Modified: cfe/trunk/bindings/python/tests/cindex/test_cdb.py URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/bindings/python/tests/cindex/test_cdb.py?rev=364386&r1=364385&r2=364386&view=diff ============================================================================== --- cfe/trunk/bindings/python/tests/cindex/test_cdb.py (original) +++ cfe/trunk/bindings/python/tests/cindex/test_cdb.py Wed Jun 26 00:39:03 2019 @@ -63,15 +63,16 @@ class TestCDB(unittest.TestCase): expected = [ { 'wd': '/home/john.doe/MyProject', 'file': '/home/john.doe/MyProject/project.cpp', - 'line': ['clang++', '-o', 'project.o', '-c', + 'line': ['clang++', '--driver-mode=g++', '-o', 'project.o', '-c', '/home/john.doe/MyProject/project.cpp']}, { 'wd': '/home/john.doe/MyProjectA', 'file': '/home/john.doe/MyProject/project2.cpp', - 'line': ['clang++', '-o', 'project2.o', '-c', + 'line': ['clang++', '--driver-mode=g++', '-o', 'project2.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, { 'wd': '/home/john.doe/MyProjectB', 'file': '/home/john.doe/MyProject/project2.cpp', - 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', + 'line': ['clang++', '--driver-mode=g++', '-DFEATURE=1', '-o', + 'project2-feature.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, ] @@ -89,7 +90,7 @@ class TestCDB(unittest.TestCase): self.assertEqual(len(cmds), 1) self.assertEqual(cmds[0].directory, os.path.dirname(file)) self.assertEqual(cmds[0].filename, file) - expected = [ 'clang++', '-o', 'project.o', '-c', + expected = [ 'clang++', '--driver-mode=g++', '-o', 'project.o', '-c', '/home/john.doe/MyProject/project.cpp'] for arg, exp in zip(cmds[0].arguments, expected): self.assertEqual(arg, exp) @@ -101,10 +102,11 @@ class TestCDB(unittest.TestCase): self.assertEqual(len(cmds), 2) expected = [ { 'wd': '/home/john.doe/MyProjectA', - 'line': ['clang++', '-o', 'project2.o', '-c', + 'line': ['clang++', '--driver-mode=g++', '-o', 'project2.o', '-c', '/home/john.doe/MyProject/project2.cpp']}, { 'wd': '/home/john.doe/MyProjectB', - 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', + 'line': ['clang++', '--driver-mode=g++', '-DFEATURE=1', '-o', + 'project2-feature.o', '-c', '/home/john.doe/MyProject/project2.cpp']} ] for i in range(len(cmds)): Modified: cfe/trunk/include/clang/Tooling/CompilationDatabase.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/CompilationDatabase.h?rev=364386&r1=364385&r2=364386&view=diff ============================================================================== --- cfe/trunk/include/clang/Tooling/CompilationDatabase.h (original) +++ cfe/trunk/include/clang/Tooling/CompilationDatabase.h Wed Jun 26 00:39:03 2019 @@ -213,6 +213,12 @@ private: std::unique_ptr<CompilationDatabase> inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>); +/// Returns a wrapped CompilationDatabase that will add -target and -mode flags +/// to commandline when they can be deduced from argv[0] of commandline returned +/// by underlying database. +std::unique_ptr<CompilationDatabase> +inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base); + } // namespace tooling } // namespace clang Modified: cfe/trunk/lib/Tooling/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/CMakeLists.txt?rev=364386&r1=364385&r2=364386&view=diff ============================================================================== --- cfe/trunk/lib/Tooling/CMakeLists.txt (original) +++ cfe/trunk/lib/Tooling/CMakeLists.txt Wed Jun 26 00:39:03 2019 @@ -17,6 +17,7 @@ add_clang_library(clangTooling Execution.cpp FileMatchTrie.cpp FixIt.cpp + GuessTargetAndModeCompilationDatabase.cpp InterpolatingCompilationDatabase.cpp JSONCompilationDatabase.cpp Refactoring.cpp Added: cfe/trunk/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp?rev=364386&view=auto ============================================================================== --- cfe/trunk/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp (added) +++ cfe/trunk/lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp Wed Jun 26 00:39:03 2019 @@ -0,0 +1,57 @@ +//===- GuessTargetAndModeCompilationDatabase.cpp --------------------------===// +// +// 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/CompilationDatabase.h" +#include "clang/Tooling/Tooling.h" +#include <memory> + +namespace clang { +namespace tooling { + +namespace { +class TargetAndModeAdderDatabase : public CompilationDatabase { +public: + TargetAndModeAdderDatabase(std::unique_ptr<CompilationDatabase> Base) + : Base(std::move(Base)) { + assert(this->Base != nullptr); + } + + std::vector<std::string> getAllFiles() const override { + return Base->getAllFiles(); + } + + std::vector<CompileCommand> getAllCompileCommands() const override { + return addTargetAndMode(Base->getAllCompileCommands()); + } + + std::vector<CompileCommand> + getCompileCommands(StringRef FilePath) const override { + return addTargetAndMode(Base->getCompileCommands(FilePath)); + } + +private: + std::vector<CompileCommand> + addTargetAndMode(std::vector<CompileCommand> Cmds) const { + for (auto &Cmd : Cmds) { + if (Cmd.CommandLine.empty()) + continue; + addTargetAndModeForProgramName(Cmd.CommandLine, Cmd.CommandLine.front()); + } + return Cmds; + } + std::unique_ptr<CompilationDatabase> Base; +}; +} // namespace + +std::unique_ptr<CompilationDatabase> +inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base) { + return llvm::make_unique<TargetAndModeAdderDatabase>(std::move(Base)); +} + +} // namespace tooling +} // namespace clang Modified: cfe/trunk/lib/Tooling/JSONCompilationDatabase.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/JSONCompilationDatabase.cpp?rev=364386&r1=364385&r2=364386&view=diff ============================================================================== --- cfe/trunk/lib/Tooling/JSONCompilationDatabase.cpp (original) +++ cfe/trunk/lib/Tooling/JSONCompilationDatabase.cpp Wed Jun 26 00:39:03 2019 @@ -14,7 +14,9 @@ #include "clang/Basic/LLVM.h" #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/CompilationDatabasePluginRegistry.h" +#include "clang/Tooling/Tooling.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -165,7 +167,9 @@ class JSONCompilationDatabasePlugin : pu llvm::sys::path::append(JSONDatabasePath, "compile_commands.json"); auto Base = JSONCompilationDatabase::loadFromFile( JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); - return Base ? inferMissingCompileCommands(std::move(Base)) : nullptr; + return Base ? inferTargetAndDriverMode( + inferMissingCompileCommands(std::move(Base))) + : nullptr; } }; Modified: cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp?rev=364386&r1=364385&r2=364386&view=diff ============================================================================== --- cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp (original) +++ cfe/trunk/unittests/Tooling/CompilationDatabaseTest.cpp Wed Jun 26 00:39:03 2019 @@ -9,10 +9,12 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclGroup.h" #include "clang/Frontend/FrontendAction.h" +#include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/FileMatchTrie.h" #include "clang/Tooling/JSONCompilationDatabase.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TargetSelect.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -632,7 +634,7 @@ struct MemCDB : public CompilationDataba } }; -class InterpolateTest : public ::testing::Test { +class MemDBTest : public ::testing::Test { protected: // Adds an entry to the underlying compilation database. // A flag is injected: -D <File>, so the command used can be identified. @@ -658,6 +660,11 @@ protected: return Result.str(); } + MemCDB::EntryMap Entries; +}; + +class InterpolateTest : public MemDBTest { +protected: // Look up the command from a relative path, and return it in string form. // The input file is not included in the returned command. std::string getCommand(llvm::StringRef F) { @@ -693,8 +700,6 @@ protected: llvm::sys::path::native(Result, llvm::sys::path::Style::posix); return Result.str(); } - - MemCDB::EntryMap Entries; }; TEST_F(InterpolateTest, Nearby) { @@ -804,5 +809,30 @@ TEST(CompileCommandTest, EqualityOperato EXPECT_TRUE(CCRef != CCTest); } +class TargetAndModeTest : public MemDBTest { +public: + TargetAndModeTest() { llvm::InitializeAllTargetInfos(); } + +protected: + // Look up the command from a relative path, and return it in string form. + std::string getCommand(llvm::StringRef F) { + auto Results = inferTargetAndDriverMode(llvm::make_unique<MemCDB>(Entries)) + ->getCompileCommands(path(F)); + if (Results.empty()) + return "none"; + return llvm::join(Results[0].CommandLine, " "); + } +}; + +TEST_F(TargetAndModeTest, TargetAndMode) { + add("foo.cpp", "clang-cl", ""); + add("bar.cpp", "x86_64-linux-clang", ""); + + EXPECT_EQ(getCommand("foo.cpp"), + "clang-cl --driver-mode=cl foo.cpp -D foo.cpp"); + EXPECT_EQ(getCommand("bar.cpp"), + "x86_64-linux-clang -target x86_64-linux bar.cpp -D bar.cpp"); +} + } // end namespace tooling } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits