[cfe-commits] r66276 - in /cfe/trunk/Driver: CMakeLists.txt Warnings.cpp clang.cpp clang.h
Sebastian Redl
sebastian.redl at getdesigned.at
Fri Mar 6 09:41:35 PST 2009
Author: cornedbee
Date: Fri Mar 6 11:41:35 2009
New Revision: 66276
URL: http://llvm.org/viewvc/llvm-project?rev=66276&view=rev
Log:
Implement the machinery that can process TableGenerated warning options.
Manually write a table and some ad-hoc code to provide feature parity with the current code.
Added:
cfe/trunk/Driver/Warnings.cpp
Modified:
cfe/trunk/Driver/CMakeLists.txt
cfe/trunk/Driver/clang.cpp
cfe/trunk/Driver/clang.h
Modified: cfe/trunk/Driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/CMakeLists.txt?rev=66276&r1=66275&r2=66276&view=diff
==============================================================================
--- cfe/trunk/Driver/CMakeLists.txt (original)
+++ cfe/trunk/Driver/CMakeLists.txt Fri Mar 6 11:41:35 2009
@@ -37,4 +37,5 @@
RewriteObjC.cpp
RewriteTest.cpp
SerializationTest.cpp
+ Warnings.cpp
)
Added: cfe/trunk/Driver/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Warnings.cpp?rev=66276&view=auto
==============================================================================
--- cfe/trunk/Driver/Warnings.cpp (added)
+++ cfe/trunk/Driver/Warnings.cpp Fri Mar 6 11:41:35 2009
@@ -0,0 +1,217 @@
+//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line warning options handler.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is responsible for handling all warning options. This includes
+// a number of -Wfoo options and their variants, which are driven by TableGen-
+// generated data, and the special cases -pedantic, -pedantic-errors, -w and
+// -Werror.
+//
+// Warning options control the handling of the warnings that Clang emits. There
+// are three possible reactions to any given warning:
+// ignore: Do nothing
+// warn: Emit a message, but don't fail the compilation
+// error: Emit a message and fail the compilation
+//
+// Clang is parsed warning options. Each warning option controls any number of
+// actual warnings.
+// Given a warning option 'foo', the following are valid:
+// -Wfoo=ignore -> Ignore the controlled warnings.
+// -Wfoo=warn -> Warn about the controlled warnings.
+// -Wfoo=error -> Fail on the controlled warnings.
+// -Wfoo -> alias of -Wfoo=warn
+// -Wno-foo -> alias of -Wfoo=ignore
+// -Werror=foo -> alias of -Wfoo=error
+//
+// Because of this complex handling of options, the default parser is replaced.
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "llvm/Support/CommandLine.h"
+#include <vector>
+#include <string>
+#include <utility>
+#include <algorithm>
+#include <string.h>
+
+using namespace clang;
+
+namespace {
+ struct ParsedOption {
+ std::string Name;
+ diag::Mapping Mapping;
+
+ ParsedOption() {}
+ // Used by -Werror, implicitly.
+ ParsedOption(const std::string& name) : Name(name), Mapping(diag::MAP_ERROR)
+ {}
+ };
+
+ typedef std::vector<ParsedOption> OptionsList;
+
+ OptionsList Options;
+
+ struct WarningParser : public llvm::cl::basic_parser<ParsedOption> {
+ diag::Mapping StrToMapping(const std::string &S) {
+ if (S == "ignore")
+ return diag::MAP_IGNORE;
+ if (S == "warn")
+ return diag::MAP_WARNING;
+ if (S == "error")
+ return diag::MAP_ERROR;
+ return diag::MAP_DEFAULT;
+ }
+ bool parse(llvm::cl::Option &O, const char *ArgName,
+ const std::string &ArgValue, ParsedOption &Val)
+ {
+ size_t Eq = ArgValue.find("=");
+ if (Eq == std::string::npos) {
+ // Could be -Wfoo or -Wno-foo
+ if (ArgValue.compare(0, 3, "no-") == 0) {
+ Val.Name = ArgValue.substr(3);
+ Val.Mapping = diag::MAP_IGNORE;
+ } else {
+ Val.Name = ArgValue;
+ Val.Mapping = diag::MAP_WARNING;
+ }
+ } else {
+ Val.Name = ArgValue.substr(0, Eq);
+ Val.Mapping = StrToMapping(ArgValue.substr(Eq+1));
+ if (Val.Mapping == diag::MAP_DEFAULT)
+ return true;
+ }
+ return false;
+ }
+ };
+}
+
+static llvm::cl::list<ParsedOption, OptionsList, WarningParser>
+OptWarnings("W", llvm::cl::location(Options), llvm::cl::Prefix);
+
+static llvm::cl::list<ParsedOption, OptionsList, llvm::cl::parser<std::string> >
+OptWError("Werror", llvm::cl::location(Options), llvm::cl::CommaSeparated,
+ llvm::cl::ValueOptional);
+
+static llvm::cl::opt<bool> OptPedantic("pedantic");
+static llvm::cl::opt<bool> OptPedanticErrors("pedantic-errors");
+static llvm::cl::opt<bool> OptNoWarnings("w");
+static llvm::cl::opt<bool>
+OptSuppressSystemWarnings("suppress-system-warnings",
+ llvm::cl::desc("Suppress warnings issued in system headers"),
+ llvm::cl::init(true));
+
+namespace {
+ struct WarningOption {
+ const char *Name;
+ const diag::kind *Members;
+ size_t NumMembers;
+ };
+ bool operator <(const WarningOption& lhs, const WarningOption& rhs) {
+ return strcmp(lhs.Name, rhs.Name) < 0;
+ }
+}
+#define DIAGS(a) a, (sizeof(a) / sizeof(a[0]))
+// These tables will be TableGenerated later.
+// First the table sets describing the diagnostics controlled by each option.
+static const diag::kind UnusedMacrosDiags[] = { diag::pp_macro_not_used };
+static const diag::kind FloatEqualDiags[] = { diag::warn_floatingpoint_eq };
+static const diag::kind ReadOnlySetterAttrsDiags[] = {
+ diag::warn_objc_property_attr_mutually_exclusive
+};
+static const diag::kind FormatNonLiteralDiags[] = {
+ diag::warn_printf_not_string_constant
+};
+static const diag::kind UndefDiags[] = { diag::warn_pp_undef_identifier };
+static const diag::kind ImplicitFunctionDeclarationDiags[] = {
+ diag::ext_implicit_function_decl, diag::warn_implicit_function_decl
+};
+// Hmm ... this option is currently actually completely ignored.
+//static const diag::kind StrictSelectorMatchDiags[] = { };
+// Second the table of options. MUST be sorted by name! Binary lookup is done.
+static const WarningOption OptionTable[] = {
+ { "float-equal", DIAGS(FloatEqualDiags) },
+ { "format-nonliteral", DIAGS(FormatNonLiteralDiags) },
+ { "implicit-function-declaration", DIAGS(ImplicitFunctionDeclarationDiags) },
+ { "readonly-setter-attrs", DIAGS(ReadOnlySetterAttrsDiags) },
+ { "undef", DIAGS(UndefDiags) },
+ { "unused-macros", DIAGS(UnusedMacrosDiags) },
+// { "strict-selector-match", DIAGS(StrictSelectorMatchDiags) }
+};
+static const size_t OptionTableSize =
+ sizeof(OptionTable) / sizeof(OptionTable[0]);
+
+namespace clang {
+
+bool ProcessWarningOptions(Diagnostic &Diags) {
+ // FIXME: These should be mapped to group options.
+ Diags.setIgnoreAllWarnings(OptNoWarnings);
+ Diags.setWarnOnExtensions(OptPedantic);
+ Diags.setErrorOnExtensions(OptPedanticErrors);
+
+ // Set some defaults that are currently set manually. This, too, should
+ // be in the tablegen stuff later.
+ Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
+ Diags.setDiagnosticMapping(diag::warn_floatingpoint_eq, diag::MAP_IGNORE);
+ Diags.setDiagnosticMapping(diag::warn_objc_property_attr_mutually_exclusive,
+ diag::MAP_IGNORE);
+ Diags.setDiagnosticMapping(diag::warn_pp_undef_identifier, diag::MAP_IGNORE);
+ Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
+ diag::MAP_IGNORE);
+
+ Diags.setDiagnosticMapping(diag::err_pp_file_not_found, diag::MAP_FATAL);
+ Diags.setSuppressSystemWarnings(OptSuppressSystemWarnings);
+
+ for (OptionsList::iterator it = Options.begin(), e = Options.end();
+ it != e; ++it) {
+ if (it->Name.empty()) {
+ // Empty string is "everything". This way, -Werror does the right thing.
+ // FIXME: These flags do not participate in proper option overriding.
+ switch(it->Mapping) {
+ default:
+ assert(false && "Illegal mapping");
+ break;
+
+ case diag::MAP_IGNORE:
+ Diags.setIgnoreAllWarnings(true);
+ Diags.setWarningsAsErrors(false);
+ break;
+
+ case diag::MAP_WARNING:
+ Diags.setIgnoreAllWarnings(false);
+ Diags.setWarningsAsErrors(false);
+ break;
+
+ case diag::MAP_ERROR:
+ Diags.setIgnoreAllWarnings(false);
+ Diags.setWarningsAsErrors(true);
+ break;
+ }
+ continue;
+ }
+ WarningOption Key = { it->Name.c_str(), 0, 0 };
+ const WarningOption *Found = std::lower_bound(OptionTable,
+ OptionTable + OptionTableSize,
+ Key);
+ if (Found == OptionTable + OptionTableSize ||
+ strcmp(Found->Name, Key.Name) != 0)
+ return true;
+
+ // Option exists.
+ for (size_t i = 0; i < Found->NumMembers; ++i) {
+ Diags.setDiagnosticMapping(Found->Members[i], it->Mapping);
+ }
+ }
+ return false;
+}
+
+}
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=66276&r1=66275&r2=66276&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Fri Mar 6 11:41:35 2009
@@ -679,101 +679,6 @@
}
//===----------------------------------------------------------------------===//
-// Our DiagnosticClient implementation
-//===----------------------------------------------------------------------===//
-
-// FIXME: Werror should take a list of things, -Werror=foo,bar
-static llvm::cl::opt<bool>
-WarningsAsErrors("Werror", llvm::cl::desc("Treat all warnings as errors"));
-
-static llvm::cl::opt<bool>
-SilenceWarnings("w", llvm::cl::desc("Do not emit any warnings"));
-
-static llvm::cl::opt<bool>
-WarnOnExtensions("pedantic", llvm::cl::init(false),
- llvm::cl::desc("Issue a warning on uses of GCC extensions"));
-
-static llvm::cl::opt<bool>
-ErrorOnExtensions("pedantic-errors",
- llvm::cl::desc("Issue an error on uses of GCC extensions"));
-
-static llvm::cl::opt<bool>
-SuppressSystemWarnings("suppress-system-warnings",
- llvm::cl::desc("Suppress warnings issued in system headers"),
- llvm::cl::init(true));
-
-static llvm::cl::opt<bool>
-WarnUnusedMacros("Wunused-macros",
- llvm::cl::desc("Warn for unused macros in the main translation unit"));
-
-static llvm::cl::opt<bool>
-WarnFloatEqual("Wfloat-equal",
- llvm::cl::desc("Warn about equality comparisons of floating point values"));
-
-static llvm::cl::opt<bool>
-WarnPropertyReadonlyAttrs("Wreadonly-setter-attrs",
- llvm::cl::desc("Warn about readonly properties with writable attributes"));
-
-static llvm::cl::opt<bool>
-WarnNoFormatNonLiteral("Wno-format-nonliteral",
- llvm::cl::desc("Do not warn about non-literal format strings"));
-
-static llvm::cl::opt<bool>
-WarnUndefMacros("Wundef",
- llvm::cl::desc("Warn on use of undefined macros in #if's"));
-
-static llvm::cl::opt<bool>
-WarnImplicitFunctionDeclaration("Wimplicit-function-declaration",
- llvm::cl::desc("Warn about uses of implicitly defined functions"));
-
-static llvm::cl::opt<bool>
-WarnNoStrictSelectorMatch("Wno-strict-selector-match",
- llvm::cl::desc("Do not warn about duplicate methods that have the same size"
- " and alignment"),
- llvm::cl::init(true));
-
-/// InitializeDiagnostics - Initialize the diagnostic object, based on the
-/// current command line option settings.
-static void InitializeDiagnostics(Diagnostic &Diags) {
- Diags.setIgnoreAllWarnings(SilenceWarnings);
- Diags.setWarningsAsErrors(WarningsAsErrors);
- Diags.setWarnOnExtensions(WarnOnExtensions);
- Diags.setErrorOnExtensions(ErrorOnExtensions);
-
- // Suppress warnings in system headers unless requested not to.
- Diags.setSuppressSystemWarnings(SuppressSystemWarnings);
-
- // Silence the "macro is not used" warning unless requested.
- if (!WarnUnusedMacros)
- Diags.setDiagnosticMapping(diag::pp_macro_not_used, diag::MAP_IGNORE);
-
- // Silence "floating point comparison" warnings unless requested.
- if (!WarnFloatEqual)
- Diags.setDiagnosticMapping(diag::warn_floatingpoint_eq, diag::MAP_IGNORE);
-
- if (!WarnPropertyReadonlyAttrs)
- Diags.setDiagnosticMapping(diag::warn_objc_property_attr_mutually_exclusive,
- diag::MAP_IGNORE);
-
- // Silence "format string is not a string literal" warnings if requested
- if (WarnNoFormatNonLiteral)
- Diags.setDiagnosticMapping(diag::warn_printf_not_string_constant,
- diag::MAP_IGNORE);
- if (!WarnUndefMacros)
- Diags.setDiagnosticMapping(diag::warn_pp_undef_identifier,diag::MAP_IGNORE);
-
- if (WarnImplicitFunctionDeclaration)
- Diags.setDiagnosticMapping(diag::ext_implicit_function_decl,
- diag::MAP_WARNING);
- else
- Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
- diag::MAP_IGNORE);
-
-
- Diags.setDiagnosticMapping(diag::err_pp_file_not_found, diag::MAP_FATAL);
-}
-
-//===----------------------------------------------------------------------===//
// Target Triple Processing.
//===----------------------------------------------------------------------===//
@@ -1599,7 +1504,11 @@
// Configure our handling of diagnostics.
llvm::OwningPtr<DiagnosticClient> DiagClient(TextDiagClient);
Diagnostic Diags(DiagClient.get());
- InitializeDiagnostics(Diags);
+ if (ProcessWarningOptions(Diags)) {
+ fprintf(stderr, "Error in warning options.\n");
+ return 1;
+ }
+ //InitializeDiagnostics(Diags);
// -I- is a deprecated GCC feature, scan for it and reject it.
for (unsigned i = 0, e = I_dirs.size(); i != e; ++i) {
Modified: cfe/trunk/Driver/clang.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.h?rev=66276&r1=66275&r2=66276&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.h (original)
+++ cfe/trunk/Driver/clang.h Fri Mar 6 11:41:35 2009
@@ -26,6 +26,10 @@
class IdentifierTable;
class SourceManager;
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+bool ProcessWarningOptions(Diagnostic &Diags);
+
/// DoPrintPreprocessedInput - Implement -E mode.
void DoPrintPreprocessedInput(Preprocessor &PP, const std::string& OutFile);
More information about the cfe-commits
mailing list