Skip to content

Commit

Permalink
[Tooling] Use FixedCompilationDatabase when compile_flags.txt is fo…
Browse files Browse the repository at this point in the history
…und.

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
  • Loading branch information
sam-mccall committed Nov 9, 2017
1 parent 26d55e0 commit 60d74e4
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
6 changes: 6 additions & 0 deletions clang/docs/JSONCompilationDatabase.rst
Expand Up @@ -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.
5 changes: 5 additions & 0 deletions clang/include/clang/Tooling/CompilationDatabase.h
Expand Up @@ -182,6 +182,11 @@ class FixedCompilationDatabase : public CompilationDatabase {
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);
Expand Down
38 changes: 36 additions & 2 deletions clang/lib/Tooling/CompilationDatabase.cpp
Expand Up @@ -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"
Expand All @@ -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>
Expand Down Expand Up @@ -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::
Expand Down Expand Up @@ -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 {

Expand Down
1 change: 1 addition & 0 deletions clang/test/Tooling/Inputs/fixed-header.h
@@ -0,0 +1 @@
#define SECRET_SYMBOL 1
18 changes: 18 additions & 0 deletions 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, "");

0 comments on commit 60d74e4

Please sign in to comment.