r190620 - Move Compilation::PrintJob and PrintDiagnosticJob into Job::Print.
Hans Wennborg
hans at hanshq.net
Thu Sep 12 11:23:34 PDT 2013
Author: hans
Date: Thu Sep 12 13:23:34 2013
New Revision: 190620
URL: http://llvm.org/viewvc/llvm-project?rev=190620&view=rev
Log:
Move Compilation::PrintJob and PrintDiagnosticJob into Job::Print.
This moves the code to Job.cpp, which seems like a more natural fit,
and replaces the "is this a JobList? is this a Command?" logic with
a virtual function call.
It also removes the code duplication between PrintJob and
PrintDiagnosticJob and simplifies the code a little.
There's no functionality change here, except that the Executable is
now always printed within quotes, whereas it would previously not be
quoted in crash reports, which I think was a bug.
Differential Revision: http://llvm-reviews.chandlerc.com/D1653
Modified:
cfe/trunk/examples/clang-interpreter/main.cpp
cfe/trunk/include/clang/Driver/Compilation.h
cfe/trunk/include/clang/Driver/Job.h
cfe/trunk/lib/Driver/Compilation.cpp
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/lib/Driver/Job.cpp
cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp
cfe/trunk/lib/Tooling/Tooling.cpp
cfe/trunk/test/Driver/crash-report.c
Modified: cfe/trunk/examples/clang-interpreter/main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/clang-interpreter/main.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/examples/clang-interpreter/main.cpp (original)
+++ cfe/trunk/examples/clang-interpreter/main.cpp Thu Sep 12 13:23:34 2013
@@ -95,7 +95,7 @@ int main(int argc, const char **argv, ch
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
- C->PrintJob(OS, C->getJobs(), "; ", true);
+ Jobs.Print(OS, "; ", true);
Diags.Report(diag::err_fe_expected_compiler_job) << OS.str();
return 1;
}
@@ -118,7 +118,7 @@ int main(int argc, const char **argv, ch
// Show the invocation, with -v.
if (CI->getHeaderSearchOpts().Verbose) {
llvm::errs() << "clang invocation:\n";
- C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
+ Jobs.Print(llvm::errs(), "\n", true);
llvm::errs() << "\n";
}
Modified: cfe/trunk/include/clang/Driver/Compilation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Compilation.h?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Compilation.h (original)
+++ cfe/trunk/include/clang/Driver/Compilation.h Thu Sep 12 13:23:34 2013
@@ -155,23 +155,6 @@ public:
const JobAction *JA,
bool IssueErrors = false) const;
- /// PrintJob - Print one job in -### format.
- ///
- /// \param OS - The stream to print on.
- /// \param J - The job to print.
- /// \param Terminator - A string to print at the end of the line.
- /// \param Quote - Should separate arguments be quoted.
- void PrintJob(raw_ostream &OS, const Job &J,
- const char *Terminator, bool Quote) const;
-
- /// PrintDiagnosticJob - Print one job in -### format, but with the
- /// superfluous options removed, which are not necessary for
- /// reproducing the crash.
- ///
- /// \param OS - The stream to print on.
- /// \param J - The job to print.
- void PrintDiagnosticJob(raw_ostream &OS, const Job &J) const;
-
/// ExecuteCommand - Execute an actual command.
///
/// \param FailingCommand - For non-zero results, this will be set to the
Modified: cfe/trunk/include/clang/Driver/Job.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Job.h?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Job.h (original)
+++ cfe/trunk/include/clang/Driver/Job.h Thu Sep 12 13:23:34 2013
@@ -14,6 +14,10 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Option/Option.h"
+namespace llvm {
+ class raw_ostream;
+}
+
namespace clang {
namespace driver {
class Action;
@@ -38,13 +42,20 @@ public:
virtual ~Job();
JobClass getKind() const { return Kind; }
+
+ /// Print - Print this Job in -### format.
+ ///
+ /// \param OS - The stream to print on.
+ /// \param Terminator - A string to print at the end of the line.
+ /// \param Quote - Should separate arguments be quoted.
+ /// \param CrashReport - Whether to print for inclusion in a crash report.
+ virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
+ bool Quote, bool CrashReport = false) const = 0;
};
/// Command - An executable path/name and argument vector to
/// execute.
class Command : public Job {
- virtual void anchor();
-
/// Source - The action which caused the creation of this job.
const Action &Source;
@@ -62,6 +73,9 @@ public:
Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
const llvm::opt::ArgStringList &_Arguments);
+ virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
+ bool Quote, bool CrashReport = false) const;
+
/// getSource - Return the Action which caused the creation of this job.
const Action &getSource() const { return Source; }
@@ -92,6 +106,9 @@ public:
JobList();
virtual ~JobList();
+ virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
+ bool Quote, bool CrashReport = false) const;
+
/// Add a job to the list (taking ownership).
void addJob(Job *J) { Jobs.push_back(J); }
Modified: cfe/trunk/lib/Driver/Compilation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Compilation.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Compilation.cpp (original)
+++ cfe/trunk/lib/Driver/Compilation.cpp Thu Sep 12 13:23:34 2013
@@ -14,7 +14,6 @@
#include "clang/Driver/Options.h"
#include "clang/Driver/ToolChain.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Program.h"
@@ -71,136 +70,6 @@ const DerivedArgList &Compilation::getAr
return *Entry;
}
-void Compilation::PrintJob(raw_ostream &OS, const Job &J,
- const char *Terminator, bool Quote) const {
- if (const Command *C = dyn_cast<Command>(&J)) {
- OS << " \"" << C->getExecutable() << '"';
- for (ArgStringList::const_iterator it = C->getArguments().begin(),
- ie = C->getArguments().end(); it != ie; ++it) {
- OS << ' ';
- if (!Quote && !std::strpbrk(*it, " \"\\$")) {
- OS << *it;
- continue;
- }
-
- // Quote the argument and escape shell special characters; this isn't
- // really complete but is good enough.
- OS << '"';
- for (const char *s = *it; *s; ++s) {
- if (*s == '"' || *s == '\\' || *s == '$')
- OS << '\\';
- OS << *s;
- }
- OS << '"';
- }
- OS << Terminator;
- } else {
- const JobList *Jobs = cast<JobList>(&J);
- for (JobList::const_iterator
- it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
- PrintJob(OS, **it, Terminator, Quote);
- }
-}
-
-static bool skipArg(const char *Flag, bool &SkipNextArg) {
- StringRef FlagRef(Flag);
-
- // Assume we're going to see -Flag <Arg>.
- SkipNextArg = true;
-
- // These flags are all of the form -Flag <Arg> and are treated as two
- // arguments. Therefore, we need to skip the flag and the next argument.
- bool Res = llvm::StringSwitch<bool>(Flag)
- .Cases("-I", "-MF", "-MT", "-MQ", true)
- .Cases("-o", "-coverage-file", "-dependency-file", true)
- .Cases("-fdebug-compilation-dir", "-idirafter", true)
- .Cases("-include", "-include-pch", "-internal-isystem", true)
- .Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
- .Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
- .Cases("-resource-dir", "-serialize-diagnostic-file", true)
- .Case("-dwarf-debug-flags", true)
- .Default(false);
-
- // Match found.
- if (Res)
- return Res;
-
- // The remaining flags are treated as a single argument.
- SkipNextArg = false;
-
- // These flags are all of the form -Flag and have no second argument.
- Res = llvm::StringSwitch<bool>(Flag)
- .Cases("-M", "-MM", "-MG", "-MP", "-MD", true)
- .Case("-MMD", true)
- .Default(false);
-
- // Match found.
- if (Res)
- return Res;
-
- // These flags are treated as a single argument (e.g., -F<Dir>).
- if (FlagRef.startswith("-F") || FlagRef.startswith("-I"))
- return true;
-
- return false;
-}
-
-static bool quoteNextArg(const char *flag) {
- return llvm::StringSwitch<bool>(flag)
- .Case("-D", true)
- .Default(false);
-}
-
-void Compilation::PrintDiagnosticJob(raw_ostream &OS, const Job &J) const {
- if (const Command *C = dyn_cast<Command>(&J)) {
- OS << C->getExecutable();
- unsigned QuoteNextArg = 0;
- for (ArgStringList::const_iterator it = C->getArguments().begin(),
- ie = C->getArguments().end(); it != ie; ++it) {
-
- bool SkipNext;
- if (skipArg(*it, SkipNext)) {
- if (SkipNext) ++it;
- continue;
- }
-
- if (!QuoteNextArg)
- QuoteNextArg = quoteNextArg(*it) ? 2 : 0;
-
- OS << ' ';
-
- if (QuoteNextArg == 1)
- OS << '"';
-
- if (!std::strpbrk(*it, " \"\\$")) {
- OS << *it;
- } else {
- // Quote the argument and escape shell special characters; this isn't
- // really complete but is good enough.
- OS << '"';
- for (const char *s = *it; *s; ++s) {
- if (*s == '"' || *s == '\\' || *s == '$')
- OS << '\\';
- OS << *s;
- }
- OS << '"';
- }
-
- if (QuoteNextArg) {
- if (QuoteNextArg == 1)
- OS << '"';
- --QuoteNextArg;
- }
- }
- OS << '\n';
- } else {
- const JobList *Jobs = cast<JobList>(&J);
- for (JobList::const_iterator
- it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
- PrintDiagnosticJob(OS, **it);
- }
-}
-
bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
std::string P(File);
@@ -288,7 +157,7 @@ int Compilation::ExecuteCommand(const Co
if (getDriver().CCPrintOptions)
*OS << "[Logging clang options]";
- PrintJob(*OS, C, "\n", /*Quote=*/getDriver().CCPrintOptions);
+ C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions);
if (OS != &llvm::errs())
delete OS;
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Sep 12 13:23:34 2013
@@ -441,11 +441,11 @@ void Driver::generateCompilationDiagnost
std::string Cmd;
llvm::raw_string_ostream OS(Cmd);
if (FailingCommand)
- C.PrintDiagnosticJob(OS, *FailingCommand);
+ FailingCommand->Print(OS, "\n", /*Quote*/ false, /*CrashReport*/ true);
else
// Crash triggered by FORCE_CLANG_DIAGNOSTICS_CRASH, which doesn't have an
// associated FailingCommand, so just pass all jobs.
- C.PrintDiagnosticJob(OS, C.getJobs());
+ C.getJobs().Print(OS, "\n", /*Quote*/ false, /*CrashReport*/ true);
OS.flush();
// Keep track of whether we produce any errors while trying to produce
@@ -578,7 +578,7 @@ int Driver::ExecuteCompilation(const Com
SmallVectorImpl< std::pair<int, const Command *> > &FailingCommands) const {
// Just print if -### was present.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
- C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
+ C.getJobs().Print(llvm::errs(), "\n", true);
return 0;
}
Modified: cfe/trunk/lib/Driver/Job.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Job.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Job.cpp (original)
+++ cfe/trunk/lib/Driver/Job.cpp Thu Sep 12 13:23:34 2013
@@ -9,19 +9,109 @@
#include "clang/Driver/Job.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
using namespace clang::driver;
+using llvm::raw_ostream;
+using llvm::StringRef;
Job::~Job() {}
-void Command::anchor() {}
-
Command::Command(const Action &_Source, const Tool &_Creator,
const char *_Executable,
const llvm::opt::ArgStringList &_Arguments)
: Job(CommandClass), Source(_Source), Creator(_Creator),
Executable(_Executable), Arguments(_Arguments) {}
+static int skipArgs(const char *Flag) {
+ // These flags are all of the form -Flag <Arg> and are treated as two
+ // arguments. Therefore, we need to skip the flag and the next argument.
+ bool Res = llvm::StringSwitch<bool>(Flag)
+ .Cases("-I", "-MF", "-MT", "-MQ", true)
+ .Cases("-o", "-coverage-file", "-dependency-file", true)
+ .Cases("-fdebug-compilation-dir", "-idirafter", true)
+ .Cases("-include", "-include-pch", "-internal-isystem", true)
+ .Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
+ .Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
+ .Cases("-resource-dir", "-serialize-diagnostic-file", true)
+ .Case("-dwarf-debug-flags", true)
+ .Default(false);
+
+ // Match found.
+ if (Res)
+ return 2;
+
+ // The remaining flags are treated as a single argument.
+
+ // These flags are all of the form -Flag and have no second argument.
+ Res = llvm::StringSwitch<bool>(Flag)
+ .Cases("-M", "-MM", "-MG", "-MP", "-MD", true)
+ .Case("-MMD", true)
+ .Default(false);
+
+ // Match found.
+ if (Res)
+ return 1;
+
+ // These flags are treated as a single argument (e.g., -F<Dir>).
+ StringRef FlagRef(Flag);
+ if (FlagRef.startswith("-F") || FlagRef.startswith("-I"))
+ return 1;
+
+ return 0;
+}
+
+static bool quoteNextArg(const char *flag) {
+ return llvm::StringSwitch<bool>(flag)
+ .Case("-D", true)
+ .Default(false);
+}
+
+static void PrintArg(raw_ostream &OS, const char *Arg, bool Quote) {
+ const bool Escape = std::strpbrk(Arg, "\"\\$");
+
+ if (!Quote && !Escape) {
+ OS << Arg;
+ return;
+ }
+
+ // Quote and escape. This isn't really complete, but good enough.
+ OS << '"';
+ while (const char c = *Arg++) {
+ if (c == '"' || c == '\\' || c == '$')
+ OS << '\\';
+ OS << c;
+ }
+ OS << '"';
+}
+
+void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote,
+ bool CrashReport) const {
+ OS << " \"" << Executable << '"';
+
+ for (size_t i = 0, e = Arguments.size(); i < e; ++i) {
+ const char *const Arg = Arguments[i];
+
+ if (CrashReport) {
+ if (int Skip = skipArgs(Arg)) {
+ i += Skip - 1;
+ continue;
+ }
+ }
+
+ OS << ' ';
+ PrintArg(OS, Arg, Quote);
+
+ if (CrashReport && quoteNextArg(Arg) && i + 1 < e) {
+ OS << ' ';
+ PrintArg(OS, Arguments[++i], true);
+ }
+ }
+ OS << Terminator;
+}
+
JobList::JobList() : Job(JobListClass) {}
JobList::~JobList() {
@@ -29,6 +119,12 @@ JobList::~JobList() {
delete *it;
}
+void JobList::Print(raw_ostream &OS, const char *Terminator, bool Quote,
+ bool CrashReport) const {
+ for (const_iterator it = begin(), ie = end(); it != ie; ++it)
+ (*it)->Print(OS, Terminator, Quote, CrashReport);
+}
+
void JobList::clear() {
DeleteContainerPointers(Jobs);
}
Modified: cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp (original)
+++ cfe/trunk/lib/Frontend/CreateInvocationFromCommandLine.cpp Thu Sep 12 13:23:34 2013
@@ -56,7 +56,7 @@ clang::createInvocationFromCommandLine(A
// Just print the cc1 options if -### was present.
if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
- C->PrintJob(llvm::errs(), C->getJobs(), "\n", true);
+ C->getJobs().Print(llvm::errs(), "\n", true);
return 0;
}
@@ -66,7 +66,7 @@ clang::createInvocationFromCommandLine(A
if (Jobs.size() != 1 || !isa<driver::Command>(*Jobs.begin())) {
SmallString<256> Msg;
llvm::raw_svector_ostream OS(Msg);
- C->PrintJob(OS, C->getJobs(), "; ", true);
+ Jobs.Print(OS, "; ", true);
Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
return 0;
}
Modified: cfe/trunk/lib/Tooling/Tooling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Tooling.cpp (original)
+++ cfe/trunk/lib/Tooling/Tooling.cpp Thu Sep 12 13:23:34 2013
@@ -67,7 +67,7 @@ static const llvm::opt::ArgStringList *g
if (Jobs.size() != 1 || !isa<clang::driver::Command>(*Jobs.begin())) {
SmallString<256> error_msg;
llvm::raw_svector_ostream error_stream(error_msg);
- Compilation->PrintJob(error_stream, Compilation->getJobs(), "; ", true);
+ Jobs.Print(error_stream, "; ", true);
Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
<< error_stream.str();
return NULL;
@@ -185,7 +185,7 @@ bool ToolInvocation::runInvocation(
// Show the invocation, with -v.
if (Invocation->getHeaderSearchOpts().Verbose) {
llvm::errs() << "clang Invocation:\n";
- Compilation->PrintJob(llvm::errs(), Compilation->getJobs(), "\n", true);
+ Compilation->getJobs().Print(llvm::errs(), "\n", true);
llvm::errs() << "\n";
}
Modified: cfe/trunk/test/Driver/crash-report.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/crash-report.c?rev=190620&r1=190619&r2=190620&view=diff
==============================================================================
--- cfe/trunk/test/Driver/crash-report.c (original)
+++ cfe/trunk/test/Driver/crash-report.c Thu Sep 12 13:23:34 2013
@@ -22,6 +22,7 @@
// CHECK-NEXT: note: diagnostic msg: {{.*}}.c
FOO
// CHECKSRC: FOO
+// CHECKSH: -cc1
// CHECKSH: -D "FOO=BAR"
// CHECKSH-NOT: -F/tmp/
// CHECKSH-NOT: -I /tmp/
More information about the cfe-commits
mailing list