diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/Compilation.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/Driver/Compilation.cpp | 100 | 
1 files changed, 100 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp index c962fca0bf9a..124e50c32ea4 100644 --- a/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp +++ b/contrib/llvm/tools/clang/lib/Driver/Compilation.cpp @@ -17,6 +17,7 @@  #include "clang/Driver/ToolChain.h"  #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Support/Program.h"  #include <sys/stat.h> @@ -101,6 +102,105 @@ void Compilation::PrintJob(raw_ostream &OS, const Job &J,    }  } +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", "-fmodule-cache-path", "-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::CleanupFileList(const ArgStringList &Files,                                    bool IssueErrors) const {    bool Success = true;  | 
