[cfe-commits] r69136 - /cfe/trunk/tools/clang-cc/Warnings.cpp

Chris Lattner sabre at nondot.org
Tue Apr 14 21:27:38 PDT 2009


Author: lattner
Date: Tue Apr 14 23:27:38 2009
New Revision: 69136

URL: http://llvm.org/viewvc/llvm-project?rev=69136&view=rev
Log:
refactor a bunch of the warning parsing stuff to simplify it.  This removes the
-Wfoo=ignore syntax.  GCC supports -Wno-foo, no need to invent our own stuff.

Modified:
    cfe/trunk/tools/clang-cc/Warnings.cpp

Modified: cfe/trunk/tools/clang-cc/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/Warnings.cpp?rev=69136&r1=69135&r2=69136&view=diff

==============================================================================
--- cfe/trunk/tools/clang-cc/Warnings.cpp (original)
+++ cfe/trunk/tools/clang-cc/Warnings.cpp Tue Apr 14 23:27:38 2009
@@ -16,22 +16,13 @@
 // 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
-//
 // 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-cc.h"
 #include "clang/Basic/Diagnostic.h"
@@ -43,80 +34,23 @@
 #include <algorithm>
 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) {
-          fprintf(stderr, "Illegal warning option value: %s\n",
-                  ArgValue.substr(Eq+1).c_str());
-          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);
+// This gets all -W options, including -Werror, -W[no-]system-headers, etc.  The
+// driver has stripped off -Wa,foo etc.
+static llvm::cl::list<std::string>
+OptWarnings("W", llvm::cl::Prefix);
 
 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>
-OptWarnInSystemHeaders("Wsystem-headers",
-           llvm::cl::desc("Do not suppress warnings issued in system headers"));
 
 namespace {
   struct WarningOption {
     const char *Name;
     const diag::kind *Members;
-    size_t NumMembers;
+    unsigned NumMembers;
   };
 }
-#define DIAGS(a) a, (sizeof(a) / sizeof(a[0]))
+#define DIAGS(a) a, unsigned(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 };
@@ -174,6 +108,7 @@
   Diags.setIgnoreAllWarnings(OptNoWarnings);
   Diags.setWarnOnExtensions(OptPedantic);
   Diags.setErrorOnExtensions(OptPedanticErrors);
+  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
 
   // Set some defaults that are currently set manually. This, too, should
   // be in the tablegen stuff later.
@@ -189,48 +124,67 @@
   Diags.setDiagnosticMapping(diag::err_template_recursion_depth_exceeded, 
                              diag::MAP_FATAL);
   Diags.setDiagnosticMapping(diag::warn_missing_prototype, diag::MAP_IGNORE);
-  Diags.setSuppressSystemWarnings(!OptWarnInSystemHeaders);
-
-  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;
+  
+  // FIXME: -W -> -Wextra in driver.
+  // -fdiagnostics-show-option
+
+  for (unsigned i = 0, e = OptWarnings.size(); i != e; ++i) {
+    const std::string &Opt = OptWarnings[i];
+    const char *OptStart = &Opt[0];
+    const char *OptEnd = OptStart+Opt.size();
+    assert(*OptEnd == 0 && "Expect null termination for lower-bound search");
+    
+    // Check to see if this warning starts with "no-", if so, this is a negative
+    // form of the option.
+    bool isPositive = true;
+    if (OptEnd-OptStart > 3 && memcmp(OptStart, "no-", 3) == 0) {
+      isPositive = false;
+      OptStart += 3;
+    }
 
-      case diag::MAP_ERROR:
-        Diags.setIgnoreAllWarnings(false);
+    // -Wsystem-headers is a special case, not driven by the option table.
+    if (OptEnd-OptStart == 14 && memcmp(OptStart, "system-headers", 14) == 0) {
+      Diags.setSuppressSystemWarnings(!isPositive);
+      continue;
+    }
+    
+    // -Werror/-Wno-error is a special case, not controlled by the option table.
+    // It also has the "specifier" form of -Werror=foo.
+    if (OptEnd-OptStart >= 5 && memcmp(OptStart, "error", 5) == 0) {
+      const char *Specifier = 0;
+      if (OptEnd-OptStart != 5) {  // Specifier must be present.
+        if (OptStart[5] != '=' || OptEnd-OptStart == 6) {
+          fprintf(stderr, "Unknown warning option: -W%s\n", Opt.c_str());
+          return true;
+        }
+        Specifier = OptStart+6;
+      }
+      
+      if (Specifier == 0) {
         Diags.setWarningsAsErrors(true);
-        break;
+        continue;
       }
-      continue;
+      
+      // FIXME: specifier not implemented yet
+      fprintf(stderr, "specifier in -W%s not supported yet\n", Opt.c_str());
+      return true;
     }
-    WarningOption Key = { it->Name.c_str(), 0, 0 };
+    
+    WarningOption Key = { OptStart, 0, 0 };
     const WarningOption *Found =
       std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
                        WarningOptionCompare);
     if (Found == OptionTable + OptionTableSize ||
         strcmp(Found->Name, Key.Name) != 0) {
-      fprintf(stderr, "Unknown warning option: -W%s\n", Key.Name);
+      fprintf(stderr, "Unknown warning option: -W%s\n", Opt.c_str());
       return true;
     }
 
+    diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
+    
     // Option exists.
-    for (size_t i = 0, e = Found->NumMembers; i != e; ++i)
-      Diags.setDiagnosticMapping(Found->Members[i], it->Mapping);
+    for (unsigned i = 0, e = Found->NumMembers; i != e; ++i)
+      Diags.setDiagnosticMapping(Found->Members[i], Mapping);
   }
   return false;
 }





More information about the cfe-commits mailing list