From 4ad4b3ebbe5769143389dccfcfadb666a4ba5940 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 12 Mar 2009 08:55:43 +0000 Subject: [PATCH] Driver: Use standard Diagnostic interface for diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66786 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Diagnostic.h | 3 ++- include/clang/Basic/DiagnosticDriverKinds.def | 22 +++++++++++++++ include/clang/Basic/DiagnosticDriverKinds.td | 18 +++++++++++++ include/clang/Driver/Driver.h | 14 +++++++--- include/clang/Driver/DriverDiagnostic.h | 27 +++++++++++++++++++ lib/Basic/Diagnostic.cpp | 16 +++++++++-- lib/Driver/Driver.cpp | 21 +++++++-------- tools/driver/Makefile | 9 +++++-- tools/driver/driver.cpp | 18 +++++++++++-- 9 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 include/clang/Basic/DiagnosticDriverKinds.def create mode 100644 include/clang/Basic/DiagnosticDriverKinds.td create mode 100644 include/clang/Driver/DriverDiagnostic.h diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 3675e69212..f504cad29f 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -32,7 +32,8 @@ namespace clang { namespace diag { // Start position for diagnostics. enum { - DIAG_START_LEX = 300, + DIAG_START_DRIVER = 300, + DIAG_START_LEX = DIAG_START_DRIVER + 100, DIAG_START_PARSE = DIAG_START_LEX + 300, DIAG_START_AST = DIAG_START_PARSE + 300, DIAG_START_SEMA = DIAG_START_AST + 100, diff --git a/include/clang/Basic/DiagnosticDriverKinds.def b/include/clang/Basic/DiagnosticDriverKinds.def new file mode 100644 index 0000000000..aaa1f20170 --- /dev/null +++ b/include/clang/Basic/DiagnosticDriverKinds.def @@ -0,0 +1,22 @@ +//==--- DiagnosticDriverKinds.def - libdriver diagnostics -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifdef DRIVERSTART +__DRIVERSTART = DIAG_START_DRIVER, +#undef DRIVERSTART +#endif + +DIAG(driver_no_such_file, ERROR, + "no such file or directory: '%0'") +DIAG(driver_unsupported_opt, ERROR, + "unsupported option '%0'") +DIAG(driver_unknown_stdin_type, ERROR, + "-E or -x required when input is from standard input") +DIAG(driver_unknown_language, ERROR, + "language not recognized: '%0'") diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td new file mode 100644 index 0000000000..f84c79772d --- /dev/null +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -0,0 +1,18 @@ +//==--- DiagnosticDriverKinds.td - libdriver diagnostics ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +let Component = "Driver" in { + +def driver_no_such_file : Error<"no such file or directory: '%0'"> +def driver_unsupported_opt : Error<"unsupported option '%0'"> +def driver_unknown_stdin_type : Error< + "-E or -x required when input is from standard input"> +def driver_unknown_language : Error<"language not recognized: '%0'"> + +} diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 12b2264c3d..1dcb8af8f1 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -10,6 +10,8 @@ #ifndef CLANG_DRIVER_DRIVER_H_ #define CLANG_DRIVER_DRIVER_H_ +#include "clang/Basic/Diagnostic.h" + #include #include #include @@ -32,10 +34,17 @@ namespace driver { class Driver { OptTable *Opts; + Diagnostic &Diags; + /// ParseArgStrings - Parse the given list of strings into an /// ArgList. ArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd); + // Diag - Forwarding function for diagnostics. + DiagnosticBuilder Diag(unsigned DiagID) { + return Diags.Report(FullSourceLoc(), DiagID); + } + // FIXME: Privatize once interface is stable. public: /// The name the driver was invoked as. @@ -83,7 +92,8 @@ public: public: Driver(const char *_Name, const char *_Dir, - const char *_DefaultHostTriple); + const char *_DefaultHostTriple, + Diagnostic &_Diags); ~Driver(); const OptTable &getOpts() const { return *Opts; } @@ -117,8 +127,6 @@ public: /// \param Actions - The list to store the resulting actions onto. void BuildActions(const ArgList &Args, llvm::SmallVector &Actions); - - llvm::raw_ostream &Diag(const char *Message) const; }; } // end namespace driver diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h new file mode 100644 index 0000000000..d68f964019 --- /dev/null +++ b/include/clang/Driver/DriverDiagnostic.h @@ -0,0 +1,27 @@ +//===--- DiagnosticDriver.h - Diagnostics for libdriver ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVERDIAGNOSTIC_H +#define LLVM_CLANG_DRIVERDIAGNOSTIC_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#define DRIVERSTART +#include "clang/Basic/DiagnosticDriverKinds.def" +#undef DIAG + NUM_BUILTIN_DRIVER_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp index fa5ca57dfe..3e3802ae20 100644 --- a/lib/Basic/Diagnostic.cpp +++ b/lib/Basic/Diagnostic.cpp @@ -44,6 +44,10 @@ static unsigned char DiagnosticFlagsCommon[] = { #include "clang/Basic/DiagnosticCommonKinds.def" 0 }; +static unsigned char DiagnosticFlagsDriver[] = { +#include "clang/Basic/DiagnosticDriverKinds.def" + 0 +}; static unsigned char DiagnosticFlagsLex[] = { #include "clang/Basic/DiagnosticLexKinds.def" 0 @@ -72,8 +76,10 @@ static unsigned getBuiltinDiagClass(unsigned DiagID) { assert(DiagID < diag::DIAG_UPPER_LIMIT && "Diagnostic ID out of range!"); unsigned res; - if (DiagID < diag::DIAG_START_LEX) + if (DiagID < diag::DIAG_START_DRIVER) res = DiagnosticFlagsCommon[DiagID]; + else if (DiagID < diag::DIAG_START_LEX) + res = DiagnosticFlagsDriver[DiagID - diag::DIAG_START_DRIVER - 1]; else if (DiagID < diag::DIAG_START_PARSE) res = DiagnosticFlagsLex[DiagID - diag::DIAG_START_LEX - 1]; else if (DiagID < diag::DIAG_START_AST) @@ -94,6 +100,10 @@ static const char * const DiagnosticTextCommon[] = { #include "clang/Basic/DiagnosticCommonKinds.def" 0 }; +static const char * const DiagnosticTextDriver[] = { +#include "clang/Basic/DiagnosticDriverKinds.def" + 0 +}; static const char * const DiagnosticTextLex[] = { #include "clang/Basic/DiagnosticLexKinds.def" 0 @@ -237,8 +247,10 @@ bool Diagnostic::isBuiltinNote(unsigned DiagID) { /// getDescription - Given a diagnostic ID, return a description of the /// issue. const char *Diagnostic::getDescription(unsigned DiagID) const { - if (DiagID < diag::DIAG_START_LEX) + if (DiagID < diag::DIAG_START_DRIVER) return DiagnosticTextCommon[DiagID]; + else if (DiagID < diag::DIAG_START_LEX) + return DiagnosticTextDriver[DiagID - diag::DIAG_START_DRIVER - 1]; else if (DiagID < diag::DIAG_START_PARSE) return DiagnosticTextLex[DiagID - diag::DIAG_START_LEX - 1]; else if (DiagID < diag::DIAG_START_AST) diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index d9ed37b7de..90cf6828e0 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -13,6 +13,7 @@ #include "clang/Driver/Arg.h" #include "clang/Driver/ArgList.h" #include "clang/Driver/Compilation.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/HostInfo.h" #include "clang/Driver/Option.h" #include "clang/Driver/Options.h" @@ -23,8 +24,9 @@ using namespace clang::driver; Driver::Driver(const char *_Name, const char *_Dir, - const char *_DefaultHostTriple) - : Opts(new OptTable()), + const char *_DefaultHostTriple, + Diagnostic &_Diags) + : Opts(new OptTable()), Diags(_Diags), Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple), Host(0), CCCIsCXX(false), CCCEcho(false), @@ -46,7 +48,7 @@ ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) { Arg *A = getOpts().ParseOneArg(*Args, Index, End); if (A) { if (A->getOption().isUnsupported()) { - Diag("unsupported option: ") << A->getOption().getName() << "\n"; + Diag(clang::diag::driver_unsupported_opt) << A->getOption().getName(); continue; } @@ -189,7 +191,7 @@ void Driver::BuildActions(const ArgList &Args, types::ID Ty = types::TY_INVALID; // Infer the input type if necessary. - if (!InputType) { + if (InputType == types::TY_INVALID) { // stdin must be handled specially. if (memcmp(Value, "-", 2) == 0) { // If running with -E, treat as a C input (this changes the @@ -199,7 +201,7 @@ void Driver::BuildActions(const ArgList &Args, // Otherwise emit an error but still use a valid type to // avoid spurious errors (e.g., no inputs). if (!Args.hasArg(options::OPT_E)) - Diag("-E or -x required when input is from standard input"); + Diag(clang::diag::driver_unknown_stdin_type); Ty = types::TY_C; } else { // Otherwise lookup by extension, and fallback to ObjectType @@ -233,7 +235,7 @@ void Driver::BuildActions(const ArgList &Args, // just adds an extra stat to the equation, but this is gcc // compatible. if (memcmp(Value, "-", 2) != 0 && !llvm::sys::Path(Value).exists()) - Diag("no such file or directory: ") << A->getValue(Args) << "\n"; + Diag(clang::diag::driver_no_such_file) << A->getValue(Args); else Inputs.push_back(std::make_pair(Ty, A)); @@ -251,7 +253,7 @@ void Driver::BuildActions(const ArgList &Args, // unknown; but this isn't very important, we might as well be // bug comatible. if (!InputType) { - Diag("language not recognized: ") << A->getValue(Args) << "\n"; + Diag(clang::diag::driver_unknown_language) << A->getValue(Args); InputType = types::TY_Object; } } @@ -286,8 +288,3 @@ HostInfo *Driver::GetHostInfo(const char *Triple) { return new UnknownHostInfo(Arch.c_str(), Platform.c_str(), OS.c_str()); } - -// FIXME: Migrate to a normal diagnostics client. -llvm::raw_ostream &Driver::Diag(const char *Message) const { - return (llvm::errs() << Message); -} diff --git a/tools/driver/Makefile b/tools/driver/Makefile index 60d89204fd..ca2253a9b0 100644 --- a/tools/driver/Makefile +++ b/tools/driver/Makefile @@ -12,8 +12,13 @@ TOOLNAME = clang-driver CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include CXXFLAGS = -fno-rtti -LINK_COMPONENTS := system support -USEDLIBS = clangDriver.a +# FIXME: It is unfortunate we need to pull in the bitcode reader and +# writer just to get the serializer stuff used by clangBasic. +LINK_COMPONENTS := system support bitreader bitwriter + +# FIXME: We shouldn't need clangLex.a here; we do because the +# TextDiagnosticPrinter is pulling it in. :( +USEDLIBS = clangDriver.a clangFrontend.a clangLex.a clangBasic.a # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS = 1 diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp index b9e94b2813..645a3ff11a 100644 --- a/tools/driver/driver.cpp +++ b/tools/driver/driver.cpp @@ -17,15 +17,24 @@ #include "clang/Driver/Option.h" #include "clang/Driver/Options.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" + #include "llvm/ADT/OwningPtr.h" #include "llvm/Config/config.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/Path.h" #include "llvm/System/Signals.h" +using namespace clang; using namespace clang::driver; int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); + llvm::OwningPtr + DiagClient(new TextDiagnosticPrinter(llvm::errs())); + + Diagnostic Diags(DiagClient.get()); + // FIXME: We should use GetMainExecutable here, probably, but we may // want to handle symbolic links slightly differently. The problem // is that the path derived from this will influence search paths. @@ -35,9 +44,14 @@ int main(int argc, const char **argv) { // compiled on. llvm::OwningPtr TheDriver(new Driver(Path.getBasename().c_str(), Path.getDirname().c_str(), - LLVM_HOSTTRIPLE)); - + LLVM_HOSTTRIPLE, + Diags)); + llvm::OwningPtr C(TheDriver->BuildCompilation(argc, argv)); + // If there were errors building the compilation, quit now. + if (Diags.getNumErrors()) + return 1; + return C->Execute(); } -- 2.40.0