summaryrefslogtreecommitdiffstats
path: root/lib/Tooling
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2017-05-24 11:57:37 +0000
committerSerge Pavlov <sepavloff@gmail.com>2017-05-24 11:57:37 +0000
commit5bfd35d62f24a6013bbb2a7a2b78338f158d2b4a (patch)
tree47e7c6ed549340d393b27de16803a91f098dcdf1 /lib/Tooling
parenteaa2b10ecb6c19ac50b204c4c62e99434234bb80 (diff)
Method loadFromCommandLine should be able to report errors
Now FixedCompilationDatabase::loadFromCommandLine has no means to report which error occurred if it fails to create compilation object. This is a block for implementing D33013, because after that change driver will refuse to create compilation if command line contains erroneous options. This change adds additional argument to loadFromCommandLine, which is assigned error message text if compilation object was not created. This is the same way as other methods of CompilationDatabase report failure. Differential Revision: https://reviews.llvm.org/D33272 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303741 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Tooling')
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp7
-rw-r--r--lib/Tooling/CompilationDatabase.cpp42
-rw-r--r--lib/Tooling/Tooling.cpp2
3 files changed, 33 insertions, 18 deletions
diff --git a/lib/Tooling/CommonOptionsParser.cpp b/lib/Tooling/CommonOptionsParser.cpp
index 5a44061cbd..9e9689e6b2 100644
--- a/lib/Tooling/CommonOptionsParser.cpp
+++ b/lib/Tooling/CommonOptionsParser.cpp
@@ -116,7 +116,11 @@ CommonOptionsParser::CommonOptionsParser(
cl::HideUnrelatedOptions(Category);
- Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc, argv));
+ std::string ErrorMessage;
+ Compilations =
+ FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage);
+ if (!Compilations && !ErrorMessage.empty())
+ llvm::errs() << ErrorMessage;
cl::ParseCommandLineOptions(argc, argv, Overview);
cl::PrintOptionValues();
@@ -125,7 +129,6 @@ CommonOptionsParser::CommonOptionsParser(
SourcePathList.empty())
return;
if (!Compilations) {
- std::string ErrorMessage;
if (!BuildPath.empty()) {
Compilations =
CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage);
diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp
index 8ca0b2df70..77c5b547ca 100644
--- a/lib/Tooling/CompilationDatabase.cpp
+++ b/lib/Tooling/CompilationDatabase.cpp
@@ -27,6 +27,7 @@
#include "llvm/Option/Arg.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include <sstream>
#include <system_error>
using namespace clang;
@@ -150,23 +151,21 @@ private:
// options.
class UnusedInputDiagConsumer : public DiagnosticConsumer {
public:
- UnusedInputDiagConsumer() : Other(nullptr) {}
-
- // Useful for debugging, chain diagnostics to another consumer after
- // recording for our own purposes.
- UnusedInputDiagConsumer(DiagnosticConsumer *Other) : Other(Other) {}
+ UnusedInputDiagConsumer(DiagnosticConsumer &Other) : Other(Other) {}
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
const Diagnostic &Info) override {
if (Info.getID() == clang::diag::warn_drv_input_file_unused) {
// Arg 1 for this diagnostic is the option that didn't get used.
UnusedInputs.push_back(Info.getArgStdStr(0));
+ } else if (DiagLevel >= DiagnosticsEngine::Error) {
+ // If driver failed to create compilation object, show the diagnostics
+ // to user.
+ Other.HandleDiagnostic(DiagLevel, Info);
}
- if (Other)
- Other->HandleDiagnostic(DiagLevel, Info);
}
- DiagnosticConsumer *Other;
+ DiagnosticConsumer &Other;
SmallVector<std::string, 2> UnusedInputs;
};
@@ -205,9 +204,12 @@ private:
/// \li false if \c Args cannot be used for compilation jobs (e.g.
/// contains an option like -E or -version).
static bool stripPositionalArgs(std::vector<const char *> Args,
- std::vector<std::string> &Result) {
+ std::vector<std::string> &Result,
+ std::string &ErrorMsg) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
- UnusedInputDiagConsumer DiagClient;
+ llvm::raw_string_ostream Output(ErrorMsg);
+ TextDiagnosticPrinter DiagnosticPrinter(Output, &*DiagOpts);
+ UnusedInputDiagConsumer DiagClient(DiagnosticPrinter);
DiagnosticsEngine Diagnostics(
IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
&*DiagOpts, &DiagClient, false);
@@ -245,6 +247,8 @@ static bool stripPositionalArgs(std::vector<const char *> Args,
const std::unique_ptr<driver::Compilation> Compilation(
NewDriver->BuildCompilation(Args));
+ if (!Compilation)
+ return false;
const driver::JobList &Jobs = Compilation->getJobs();
@@ -258,8 +262,7 @@ static bool stripPositionalArgs(std::vector<const char *> Args,
}
if (CompileAnalyzer.Inputs.empty()) {
- // No compile jobs found.
- // FIXME: Emit a warning of some kind?
+ ErrorMsg = "warning: no compile jobs found\n";
return false;
}
@@ -280,8 +283,14 @@ static bool stripPositionalArgs(std::vector<const char *> Args,
return true;
}
-FixedCompilationDatabase *FixedCompilationDatabase::loadFromCommandLine(
- int &Argc, const char *const *Argv, Twine Directory) {
+std::unique_ptr<FixedCompilationDatabase>
+FixedCompilationDatabase::loadFromCommandLine(int &Argc,
+ const char *const *Argv,
+ std::string &ErrorMsg,
+ Twine Directory) {
+ ErrorMsg.clear();
+ if (Argc == 0)
+ return nullptr;
const char *const *DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
if (DoubleDash == Argv + Argc)
return nullptr;
@@ -289,9 +298,10 @@ FixedCompilationDatabase *FixedCompilationDatabase::loadFromCommandLine(
Argc = DoubleDash - Argv;
std::vector<std::string> StrippedArgs;
- if (!stripPositionalArgs(CommandLine, StrippedArgs))
+ if (!stripPositionalArgs(CommandLine, StrippedArgs, ErrorMsg))
return nullptr;
- return new FixedCompilationDatabase(Directory, StrippedArgs);
+ return std::unique_ptr<FixedCompilationDatabase>(
+ new FixedCompilationDatabase(Directory, StrippedArgs));
}
FixedCompilationDatabase::
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 9e1181281f..2e093dd9af 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -260,6 +260,8 @@ bool ToolInvocation::run() {
Driver->setCheckInputsExist(false);
const std::unique_ptr<clang::driver::Compilation> Compilation(
Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
+ if (!Compilation)
+ return false;
const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
&Diagnostics, Compilation.get());
if (!CC1Args) {