diff options
Diffstat (limited to 'tools/driver/driver.cpp')
-rw-r--r-- | tools/driver/driver.cpp | 66 |
1 files changed, 26 insertions, 40 deletions
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index b6fc981..fa0f0c2 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -15,12 +15,15 @@ #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Option.h" +#include "clang/Frontend/DiagnosticOptions.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Config/config.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Regex.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Host.h" #include "llvm/System/Path.h" @@ -28,38 +31,6 @@ using namespace clang; using namespace clang::driver; -class DriverDiagnosticPrinter : public DiagnosticClient { - std::string ProgName; - llvm::raw_ostream &OS; - -public: - DriverDiagnosticPrinter(const std::string _ProgName, - llvm::raw_ostream &_OS) - : ProgName(_ProgName), - OS(_OS) {} - - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); -}; - -void DriverDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, - const DiagnosticInfo &Info) { - OS << ProgName << ": "; - - switch (Level) { - case Diagnostic::Ignored: assert(0 && "Invalid diagnostic type"); - case Diagnostic::Note: OS << "note: "; break; - case Diagnostic::Warning: OS << "warning: "; break; - case Diagnostic::Error: OS << "error: "; break; - case Diagnostic::Fatal: OS << "fatal error: "; break; - } - - llvm::SmallString<100> OutStr; - Info.FormatDiagnostic(OutStr); - OS.write(OutStr.begin(), OutStr.size()); - OS << '\n'; -} - llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { if (!CanonicalPrefixes) return llvm::sys::Path(Argv0); @@ -71,7 +42,7 @@ llvm::sys::Path GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) { } static const char *SaveStringInSet(std::set<std::string> &SavedStrings, - const std::string &S) { + llvm::StringRef S) { return SavedStrings.insert(S).first->c_str(); } @@ -87,8 +58,8 @@ static const char *SaveStringInSet(std::set<std::string> &SavedStrings, /// /// '+': Add FOO as a new argument at the end of the command line. /// -/// 's/XXX/YYY/': Replace the literal argument XXX by YYY in the -/// command line. +/// 's/XXX/YYY/': Substitute the regular expression XXX with YYY in the command +/// line. /// /// 'xOPTION': Removes all instances of the literal argument OPTION. /// @@ -104,20 +75,34 @@ static const char *SaveStringInSet(std::set<std::string> &SavedStrings, /// \param SavedStrings - Set to use for storing string representations. void ApplyOneQAOverride(llvm::raw_ostream &OS, std::vector<const char*> &Args, - const std::string &Edit, + llvm::StringRef Edit, std::set<std::string> &SavedStrings) { // This does not need to be efficient. if (Edit[0] == '^') { const char *Str = - SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos)); + SaveStringInSet(SavedStrings, Edit.substr(1)); OS << "### Adding argument " << Str << " at beginning\n"; Args.insert(Args.begin() + 1, Str); } else if (Edit[0] == '+') { const char *Str = - SaveStringInSet(SavedStrings, Edit.substr(1, std::string::npos)); + SaveStringInSet(SavedStrings, Edit.substr(1)); OS << "### Adding argument " << Str << " at end\n"; Args.push_back(Str); + } else if (Edit[0] == 's' && Edit[1] == '/' && Edit.endswith("/") && + Edit.slice(2, Edit.size()-1).find('/') != llvm::StringRef::npos) { + llvm::StringRef MatchPattern = Edit.substr(2).split('/').first; + llvm::StringRef ReplPattern = Edit.substr(2).split('/').second; + ReplPattern = ReplPattern.slice(0, ReplPattern.size()-1); + + for (unsigned i = 1, e = Args.size(); i != e; ++i) { + std::string Repl = llvm::Regex(MatchPattern).sub(ReplPattern, Args[i]); + + if (Repl != Args[i]) { + OS << "### Replacing '" << Args[i] << "' with '" << Repl << "'\n"; + Args[i] = SaveStringInSet(SavedStrings, Repl); + } + } } else if (Edit[0] == 'x' || Edit[0] == 'X') { std::string Option = Edit.substr(1, std::string::npos); for (unsigned i = 1; i < Args.size();) { @@ -147,7 +132,7 @@ void ApplyOneQAOverride(llvm::raw_ostream &OS, ++i; } OS << "### Adding argument " << Edit << " at end\n"; - Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit)); + Args.push_back(SaveStringInSet(SavedStrings, '-' + Edit.str())); } else { OS << "### Unrecognized edit: " << Edit << "\n"; } @@ -203,7 +188,8 @@ int main(int argc, const char **argv) { llvm::sys::Path Path = GetExecutablePath(argv[0], CanonicalPrefixes); - DriverDiagnosticPrinter DiagClient(Path.getBasename(), llvm::errs()); + TextDiagnosticPrinter DiagClient(llvm::errs(), DiagnosticOptions()); + DiagClient.setPrefix(Path.getBasename()); Diagnostic Diags(&DiagClient); |