summaryrefslogtreecommitdiff
path: root/tools/diagtool/ShowEnabledWarnings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/diagtool/ShowEnabledWarnings.cpp')
-rw-r--r--tools/diagtool/ShowEnabledWarnings.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
new file mode 100644
index 0000000000..2bc5124e61
--- /dev/null
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -0,0 +1,147 @@
+//===- ShowEnabledWarnings - diagtool tool for printing enabled flags -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagTool.h"
+#include "DiagnosticNames.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
+#include "llvm/Support/TargetSelect.h"
+
+DEF_DIAGTOOL("show-enabled",
+ "Show which warnings are enabled for a given command line",
+ ShowEnabledWarnings)
+
+using namespace clang;
+
+namespace {
+ struct PrettyDiag {
+ StringRef Name;
+ StringRef Flag;
+ DiagnosticsEngine::Level Level;
+
+ PrettyDiag(StringRef name, StringRef flag, DiagnosticsEngine::Level level)
+ : Name(name), Flag(flag), Level(level) {}
+
+ bool operator<(const PrettyDiag &x) const { return Name < x.Name; }
+ };
+}
+
+static void printUsage() {
+ llvm::errs() << "Usage: diagtool show-enabled [<flags>] <single-input.c>\n";
+}
+
+static char getCharForLevel(DiagnosticsEngine::Level Level) {
+ switch (Level) {
+ case DiagnosticsEngine::Ignored: return ' ';
+ case DiagnosticsEngine::Note: return '-';
+ case DiagnosticsEngine::Warning: return 'W';
+ case DiagnosticsEngine::Error: return 'E';
+ case DiagnosticsEngine::Fatal: return 'F';
+ }
+
+ llvm_unreachable("Unknown diagnostic level");
+}
+
+static IntrusiveRefCntPtr<DiagnosticsEngine>
+createDiagnostics(unsigned int argc, char **argv) {
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs());
+
+ // Buffer diagnostics from argument parsing so that we can output them using a
+ // well formed diagnostic object.
+ TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
+ IntrusiveRefCntPtr<DiagnosticsEngine> InterimDiags(
+ new DiagnosticsEngine(DiagIDs, DiagsBuffer));
+
+ // Try to build a CompilerInvocation.
+ OwningPtr<CompilerInvocation> Invocation(
+ createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
+ InterimDiags));
+ if (!Invocation)
+ return NULL;
+
+ // Build the diagnostics parser
+ IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
+ CompilerInstance::createDiagnostics(Invocation->getDiagnosticOpts(),
+ argc, argv);
+ if (!FinalDiags)
+ return NULL;
+
+ // Flush any errors created when initializing everything. This could happen
+ // for invalid command lines, which will probably give non-sensical results.
+ DiagsBuffer->FlushDiagnostics(*FinalDiags);
+
+ return FinalDiags;
+}
+
+int ShowEnabledWarnings::run(unsigned int argc, char **argv, raw_ostream &Out) {
+ // First check our one flag (--levels).
+ bool ShouldShowLevels = true;
+ if (argc > 0) {
+ StringRef FirstArg(*argv);
+ if (FirstArg.equals("--no-levels")) {
+ ShouldShowLevels = false;
+ --argc;
+ ++argv;
+ } else if (FirstArg.equals("--levels")) {
+ ShouldShowLevels = true;
+ --argc;
+ ++argv;
+ }
+ }
+
+ // Create the diagnostic engine.
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags = createDiagnostics(argc, argv);
+ if (!Diags) {
+ printUsage();
+ return EXIT_FAILURE;
+ }
+
+ // Now we have our diagnostics. Iterate through EVERY diagnostic and see
+ // which ones are turned on.
+ // FIXME: It would be very nice to print which flags are turning on which
+ // diagnostics, but this can be done with a diff.
+ std::vector<PrettyDiag> Active;
+
+ for (const diagtool::DiagnosticRecord *I = diagtool::BuiltinDiagnostics,
+ *E = I + diagtool::BuiltinDiagnosticsCount; I != E; ++I) {
+ unsigned DiagID = I->DiagID;
+
+ if (DiagnosticIDs::isBuiltinNote(DiagID))
+ continue;
+
+ if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID))
+ continue;
+
+ DiagnosticsEngine::Level DiagLevel =
+ Diags->getDiagnosticLevel(DiagID, SourceLocation());
+ if (DiagLevel == DiagnosticsEngine::Ignored)
+ continue;
+
+ StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID);
+ Active.push_back(PrettyDiag(I->getName(), WarningOpt, DiagLevel));
+ }
+
+ std::sort(Active.begin(), Active.end());
+
+ // Print them all out.
+ for (std::vector<PrettyDiag>::const_iterator I = Active.begin(),
+ E = Active.end(); I != E; ++I) {
+ if (ShouldShowLevels)
+ Out << getCharForLevel(I->Level) << " ";
+ Out << I->Name;
+ if (!I->Flag.empty())
+ Out << " [-W" << I->Flag << "]";
+ Out << '\n';
+ }
+
+ return EXIT_SUCCESS;
+}