aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2017-11-09 10:37:39 +0000
committerSam McCall <sam.mccall@gmail.com>2017-11-09 10:37:39 +0000
commit60d74e45888e2bab27bb003193e22acbc754c67a (patch)
tree9baa5df06875c7505fdf2c80a85cf71d4d0382e7
parent26d55e0346964a46978c873b4d4bde01df4ea977 (diff)
downloadllvm-60d74e45888e2bab27bb003193e22acbc754c67a.zip
llvm-60d74e45888e2bab27bb003193e22acbc754c67a.tar.gz
llvm-60d74e45888e2bab27bb003193e22acbc754c67a.tar.bz2
[Tooling] Use FixedCompilationDatabase when `compile_flags.txt` is found.
Summary: This is an alternative to JSONCompilationDatabase for simple projects that don't use a build system such as CMake. (You can also drop one in ~, to make your tools use e.g. C++11 by default) There's no facility for varying flags per-source-file or per-machine. Possibly this could be accommodated backwards-compatibly using cpp, but even if not the simplicity seems worthwhile for the cases that are addressed. Tested with clangd, works great! (requires clangd restart) Reviewers: klimek Subscribers: ilya-biryukov, cfe-commits Differential Revision: https://reviews.llvm.org/D39799 llvm-svn: 317777
-rw-r--r--clang/docs/JSONCompilationDatabase.rst6
-rw-r--r--clang/include/clang/Tooling/CompilationDatabase.h5
-rw-r--r--clang/lib/Tooling/CompilationDatabase.cpp38
-rw-r--r--clang/test/Tooling/Inputs/fixed-header.h1
-rw-r--r--clang/test/Tooling/fixed-database.cpp18
5 files changed, 66 insertions, 2 deletions
diff --git a/clang/docs/JSONCompilationDatabase.rst b/clang/docs/JSONCompilationDatabase.rst
index 8631e83..1f3441b 100644
--- a/clang/docs/JSONCompilationDatabase.rst
+++ b/clang/docs/JSONCompilationDatabase.rst
@@ -91,3 +91,9 @@ The convention is to name the file compile\_commands.json and put it at
the top of the build directory. Clang tools are pointed to the top of
the build directory to detect the file and use the compilation database
to parse C++ code in the source tree.
+
+Alternatives
+============
+For simple projects, Clang tools also recognize a compile_flags.txt file.
+This should contain one flag per line. The same flags will be used to compile
+any file.
diff --git a/clang/include/clang/Tooling/CompilationDatabase.h b/clang/include/clang/Tooling/CompilationDatabase.h
index 28af33a..e224579 100644
--- a/clang/include/clang/Tooling/CompilationDatabase.h
+++ b/clang/include/clang/Tooling/CompilationDatabase.h
@@ -182,6 +182,11 @@ public:
int &Argc, const char *const *Argv, std::string &ErrorMsg,
Twine Directory = ".");
+ /// Reads flags from the given file, one-per line.
+ /// Returns nullptr and sets ErrorMessage if we can't read the file.
+ static std::unique_ptr<FixedCompilationDatabase>
+ loadFromFile(StringRef Path, std::string &ErrorMsg);
+
/// \brief Constructs a compilation data base from a specified directory
/// and command line.
FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp
index 0e83557..f252ef0 100644
--- a/clang/lib/Tooling/CompilationDatabase.cpp
+++ b/clang/lib/Tooling/CompilationDatabase.cpp
@@ -10,6 +10,9 @@
// This file contains implementations of the CompilationDatabase base class
// and the FixedCompilationDatabase.
//
+// FIXME: Various functions that take a string &ErrorMessage should be upgraded
+// to Expected.
+//
//===----------------------------------------------------------------------===//
#include "clang/Tooling/CompilationDatabase.h"
@@ -26,6 +29,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/Option/Arg.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/LineIterator.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <sstream>
@@ -302,8 +306,22 @@ FixedCompilationDatabase::loadFromCommandLine(int &Argc,
std::vector<std::string> StrippedArgs;
if (!stripPositionalArgs(CommandLine, StrippedArgs, ErrorMsg))
return nullptr;
- return std::unique_ptr<FixedCompilationDatabase>(
- new FixedCompilationDatabase(Directory, StrippedArgs));
+ return llvm::make_unique<FixedCompilationDatabase>(Directory, StrippedArgs);
+}
+
+std::unique_ptr<FixedCompilationDatabase>
+FixedCompilationDatabase::loadFromFile(StringRef Path, std::string &ErrorMsg) {
+ ErrorMsg.clear();
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+ llvm::MemoryBuffer::getFile(Path);
+ if (std::error_code Result = File.getError()) {
+ ErrorMsg = "Error while opening fixed database: " + Result.message();
+ return nullptr;
+ }
+ std::vector<std::string> Args{llvm::line_iterator(**File),
+ llvm::line_iterator()};
+ return llvm::make_unique<FixedCompilationDatabase>(
+ llvm::sys::path::parent_path(Path), std::move(Args));
}
FixedCompilationDatabase::
@@ -334,6 +352,22 @@ FixedCompilationDatabase::getAllCompileCommands() const {
return std::vector<CompileCommand>();
}
+namespace {
+
+class FixedCompilationDatabasePlugin : public CompilationDatabasePlugin {
+ std::unique_ptr<CompilationDatabase>
+ loadFromDirectory(StringRef Directory, std::string &ErrorMessage) override {
+ SmallString<1024> DatabasePath(Directory);
+ llvm::sys::path::append(DatabasePath, "compile_flags.txt");
+ return FixedCompilationDatabase::loadFromFile(DatabasePath, ErrorMessage);
+ }
+};
+
+static CompilationDatabasePluginRegistry::Add<FixedCompilationDatabasePlugin>
+X("fixed-compilation-database", "Reads plain-text flags file");
+
+} // namespace
+
namespace clang {
namespace tooling {
diff --git a/clang/test/Tooling/Inputs/fixed-header.h b/clang/test/Tooling/Inputs/fixed-header.h
new file mode 100644
index 0000000..4ce318f
--- /dev/null
+++ b/clang/test/Tooling/Inputs/fixed-header.h
@@ -0,0 +1 @@
+#define SECRET_SYMBOL 1
diff --git a/clang/test/Tooling/fixed-database.cpp b/clang/test/Tooling/fixed-database.cpp
new file mode 100644
index 0000000..e0cdb1e
--- /dev/null
+++ b/clang/test/Tooling/fixed-database.cpp
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Src
+// RUN: cp "%s" "%t/Src/test.cpp"
+// RUN: mkdir -p %t/Include
+// RUN: cp "%S/Inputs/fixed-header.h" "%t/Include/"
+// -I flag is relative to %t (where compile_flags is), not Src/.
+// RUN: echo '-IInclude/' >> %t/compile_flags.txt
+// RUN: echo "-Dklazz=class" >> %t/compile_flags.txt
+// RUN: echo '-std=c++11' >> %t/compile_flags.txt
+// RUN: clang-check "%t/Src/test.cpp" 2>&1
+// RUN: not clang-check "%s" 2>&1 | FileCheck "%s" -check-prefix=NODB
+
+// NODB: unknown type name 'klazz'
+klazz F{};
+
+// NODB: 'fixed-header.h' file not found
+#include "fixed-header.h"
+static_assert(SECRET_SYMBOL == 1, "");