summaryrefslogtreecommitdiff
path: root/tools/diagtool
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2012-08-15 20:02:54 +0000
commit56d91b49b13fe55c918afbda19f6165b5fbff87a (patch)
tree9abb1a658a297776086f4e0dfa6ca533de02104e /tools/diagtool
parent41e20f564abdb05101d6b2b29c59459a966c22cc (diff)
Notes
Diffstat (limited to 'tools/diagtool')
-rw-r--r--tools/diagtool/CMakeLists.txt28
-rw-r--r--tools/diagtool/DiagnosticNames.cpp78
-rw-r--r--tools/diagtool/DiagnosticNames.h128
-rw-r--r--tools/diagtool/ListWarnings.cpp37
-rw-r--r--tools/diagtool/Makefile10
-rw-r--r--tools/diagtool/ShowEnabledWarnings.cpp148
-rw-r--r--tools/diagtool/TreeView.cpp135
-rw-r--r--tools/diagtool/diagtool_main.cpp2
8 files changed, 524 insertions, 42 deletions
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index f1fd9de03be0e..a107cbd70bb8c 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -1,24 +1,32 @@
-set( LLVM_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
+ asmparser
support
- )
-
-set( LLVM_USED_LIBS
- clangBasic
- clangLex
- clangSema
+ mc
)
add_clang_executable(diagtool
diagtool_main.cpp
DiagTool.cpp
+ DiagnosticNames.cpp
ListWarnings.cpp
+ ShowEnabledWarnings.cpp
+ TreeView.cpp
)
+add_dependencies(diagtool
+ ClangDiagnosticIndexName
+ )
+
+target_link_libraries(diagtool
+ clangBasic
+ clangLex
+ clangSema
+ clangFrontend
+ )
+
if(UNIX)
set(CLANGXX_LINK_OR_COPY create_symlink)
else()
set(CLANGXX_LINK_OR_COPY copy)
endif()
-
-install(TARGETS diagtool
- RUNTIME DESTINATION bin)
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
new file mode 100644
index 0000000000000..31f352414f902
--- /dev/null
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -0,0 +1,78 @@
+//===- DiagnosticNames.cpp - Defines a table of all builtin diagnostics ----==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagnosticNames.h"
+#include "clang/Basic/AllDiagnostics.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace clang;
+using namespace diagtool;
+
+static const DiagnosticRecord BuiltinDiagnosticsByName[] = {
+#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
+#include "clang/Basic/DiagnosticIndexName.inc"
+#undef DIAG_NAME_INDEX
+};
+
+llvm::ArrayRef<DiagnosticRecord> diagtool::getBuiltinDiagnosticsByName() {
+ return llvm::makeArrayRef(BuiltinDiagnosticsByName);
+}
+
+
+// FIXME: Is it worth having two tables, especially when this one can get
+// out of sync easily?
+static const DiagnosticRecord BuiltinDiagnosticsByID[] = {
+#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \
+ CATEGORY) \
+ { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
+#include "clang/Basic/DiagnosticCommonKinds.inc"
+#include "clang/Basic/DiagnosticDriverKinds.inc"
+#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticSerializationKinds.inc"
+#include "clang/Basic/DiagnosticLexKinds.inc"
+#include "clang/Basic/DiagnosticParseKinds.inc"
+#include "clang/Basic/DiagnosticASTKinds.inc"
+#include "clang/Basic/DiagnosticCommentKinds.inc"
+#include "clang/Basic/DiagnosticSemaKinds.inc"
+#include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#undef DIAG
+};
+
+static bool orderByID(const DiagnosticRecord &Left,
+ const DiagnosticRecord &Right) {
+ return Left.DiagID < Right.DiagID;
+}
+
+const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) {
+ DiagnosticRecord Key = {0, DiagID, 0};
+
+ const DiagnosticRecord *Result =
+ std::lower_bound(BuiltinDiagnosticsByID,
+ llvm::array_endof(BuiltinDiagnosticsByID),
+ Key, orderByID);
+ assert(Result && "diagnostic not found; table may be out of date");
+ return *Result;
+}
+
+
+#define GET_DIAG_ARRAYS
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_ARRAYS
+
+// Second the table of options, sorted by name for fast binary lookup.
+static const GroupRecord OptionTable[] = {
+#define GET_DIAG_TABLE
+#include "clang/Basic/DiagnosticGroups.inc"
+#undef GET_DIAG_TABLE
+};
+
+llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
+ return llvm::makeArrayRef(OptionTable);
+}
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
new file mode 100644
index 0000000000000..9a731587e5e0c
--- /dev/null
+++ b/tools/diagtool/DiagnosticNames.h
@@ -0,0 +1,128 @@
+//===- DiagnosticNames.h - Defines a table of all builtin diagnostics ------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace diagtool {
+
+ struct DiagnosticRecord {
+ const char *NameStr;
+ short DiagID;
+ uint8_t NameLen;
+
+ llvm::StringRef getName() const {
+ return llvm::StringRef(NameStr, NameLen);
+ }
+
+ bool operator<(const DiagnosticRecord &Other) const {
+ return getName() < Other.getName();
+ }
+ };
+
+ /// \brief Get every diagnostic in the system, sorted by name.
+ llvm::ArrayRef<DiagnosticRecord> getBuiltinDiagnosticsByName();
+
+ /// \brief Get a diagnostic by its ID.
+ const DiagnosticRecord &getDiagnosticForID(short DiagID);
+
+
+ struct GroupRecord {
+ // Be safe with the size of 'NameLen' because we don't statically check if
+ // the size will fit in the field; the struct size won't decrease with a
+ // shorter type anyway.
+ size_t NameLen;
+ const char *NameStr;
+ const short *Members;
+ const short *SubGroups;
+
+ llvm::StringRef getName() const {
+ return llvm::StringRef(NameStr, NameLen);
+ }
+
+ template<typename RecordType>
+ class group_iterator {
+ const short *CurrentID;
+
+ friend struct GroupRecord;
+ group_iterator(const short *Start) : CurrentID(Start) {
+ if (CurrentID && *CurrentID == -1)
+ CurrentID = 0;
+ }
+
+ public:
+ typedef RecordType value_type;
+ typedef const value_type & reference;
+ typedef const value_type * pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ inline reference operator*() const;
+ inline pointer operator->() const {
+ return &operator*();
+ }
+
+ inline short getID() const {
+ return *CurrentID;
+ }
+
+ group_iterator &operator++() {
+ ++CurrentID;
+ if (*CurrentID == -1)
+ CurrentID = 0;
+ return *this;
+ }
+
+ bool operator==(group_iterator &Other) const {
+ return CurrentID == Other.CurrentID;
+ }
+
+ bool operator!=(group_iterator &Other) const {
+ return CurrentID != Other.CurrentID;
+ }
+ };
+
+ typedef group_iterator<GroupRecord> subgroup_iterator;
+ subgroup_iterator subgroup_begin() const {
+ return SubGroups;
+ }
+ subgroup_iterator subgroup_end() const {
+ return 0;
+ }
+
+ typedef group_iterator<DiagnosticRecord> diagnostics_iterator;
+ diagnostics_iterator diagnostics_begin() const {
+ return Members;
+ }
+ diagnostics_iterator diagnostics_end() const {
+ return 0;
+ }
+
+ bool operator<(const GroupRecord &Other) const {
+ return getName() < Other.getName();
+ }
+ };
+
+ /// \brief Get every diagnostic group in the system, sorted by name.
+ llvm::ArrayRef<GroupRecord> getDiagnosticGroups();
+
+ template<>
+ inline GroupRecord::subgroup_iterator::reference
+ GroupRecord::subgroup_iterator::operator*() const {
+ return getDiagnosticGroups()[*CurrentID];
+ }
+
+ template<>
+ inline GroupRecord::diagnostics_iterator::reference
+ GroupRecord::diagnostics_iterator::operator*() const {
+ return getDiagnosticForID(*CurrentID);
+ }
+} // end namespace diagtool
+
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index 2bbeca802497d..d554a2ef41ed7 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "DiagTool.h"
+#include "DiagnosticNames.h"
#include "clang/Basic/Diagnostic.h"
#include "llvm/Support/Format.h"
#include "llvm/ADT/StringMap.h"
@@ -24,28 +25,7 @@ DEF_DIAGTOOL("list-warnings",
ListWarnings)
using namespace clang;
-
-namespace {
-struct StaticDiagNameIndexRec {
- const char *NameStr;
- unsigned short DiagID;
- uint8_t NameLen;
-
- StringRef getName() const {
- return StringRef(NameStr, NameLen);
- }
-};
-}
-
-static const StaticDiagNameIndexRec StaticDiagNameIndex[] = {
-#define DIAG_NAME_INDEX(ENUM) { #ENUM, diag::ENUM, STR_SIZE(#ENUM, uint8_t) },
-#include "clang/Basic/DiagnosticIndexName.inc"
-#undef DIAG_NAME_INDEX
- { 0, 0, 0 }
-};
-
-static const unsigned StaticDiagNameIndexSize =
- sizeof(StaticDiagNameIndex)/sizeof(StaticDiagNameIndex[0])-1;
+using namespace diagtool;
namespace {
struct Entry {
@@ -73,9 +53,11 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
std::vector<Entry> Flagged, Unflagged;
llvm::StringMap<std::vector<unsigned> > flagHistogram;
- for (const StaticDiagNameIndexRec *di = StaticDiagNameIndex, *de = StaticDiagNameIndex + StaticDiagNameIndexSize;
+ ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
+
+ for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
+ de = AllDiagnostics.end();
di != de; ++di) {
-
unsigned diagID = di->DiagID;
if (DiagnosticIDs::isBuiltinNote(diagID))
@@ -95,9 +77,6 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
}
}
- std::sort(Flagged.begin(), Flagged.end());
- std::sort(Unflagged.begin(), Unflagged.end());
-
out << "Warnings with flags (" << Flagged.size() << "):\n";
printEntries(Flagged, out);
@@ -119,6 +98,10 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
out << " Average number of diagnostics per flag: "
<< llvm::format("%.4g", avgDiagsPerFlag) << '\n';
+ out << " Number in -Wpedantic (not covered by other -W flags): "
+ << flagHistogram.GetOrCreateValue("pedantic").getValue().size()
+ << '\n';
+
out << '\n';
return 0;
diff --git a/tools/diagtool/Makefile b/tools/diagtool/Makefile
index 6e3bcfc292b1b..b629712e772b2 100644
--- a/tools/diagtool/Makefile
+++ b/tools/diagtool/Makefile
@@ -1,4 +1,4 @@
-##===- tools/driver/Makefile -------------------------------*- Makefile -*-===##
+##===- tools/diagtool/Makefile -----------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -16,9 +16,11 @@ TOOL_NO_EXPORTS := 1
# Don't install this.
NO_INSTALL = 1
-LINK_COMPONENTS := support
-
-USEDLIBS = clangBasic.a
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
+ clangSema.a clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
+ clangBasic.a
include $(CLANG_LEVEL)/Makefile
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
new file mode 100644
index 0000000000000..7162451b4e733
--- /dev/null
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -0,0 +1,148 @@
+//===- 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;
+using namespace diagtool;
+
+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.
+ ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
+ std::vector<PrettyDiag> Active;
+
+ for (ArrayRef<DiagnosticRecord>::iterator I = AllDiagnostics.begin(),
+ E = AllDiagnostics.end();
+ 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));
+ }
+
+ // 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;
+}
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
new file mode 100644
index 0000000000000..9db2c26dd92dc
--- /dev/null
+++ b/tools/diagtool/TreeView.cpp
@@ -0,0 +1,135 @@
+//===- TreeView.cpp - diagtool tool for printing warning flags ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This diagnostic tool
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiagTool.h"
+#include "DiagnosticNames.h"
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/Support/Format.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/Basic/AllDiagnostics.h"
+
+DEF_DIAGTOOL("tree",
+ "Show warning flags in a tree view",
+ TreeView)
+
+using namespace clang;
+using namespace diagtool;
+
+static void printUsage() {
+ llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
+}
+
+static void printGroup(llvm::raw_ostream &out, const GroupRecord &Group,
+ bool FlagsOnly, unsigned Indent = 0) {
+ out.indent(Indent * 2);
+ out << "-W" << Group.getName() << "\n";
+
+ ++Indent;
+ for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
+ E = Group.subgroup_end();
+ I != E; ++I) {
+ printGroup(out, *I, FlagsOnly, Indent);
+ }
+
+ if (!FlagsOnly) {
+ for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
+ E = Group.diagnostics_end();
+ I != E; ++I) {
+ out.indent(Indent * 2);
+ out << I->getName() << "\n";
+ }
+ }
+}
+
+static int showGroup(llvm::raw_ostream &out, StringRef RootGroup,
+ bool FlagsOnly) {
+ ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
+
+ GroupRecord Key = { RootGroup.size(), RootGroup.data(), 0, 0 };
+ const GroupRecord *Found =
+ std::lower_bound(AllGroups.begin(), AllGroups.end(), Key);
+
+ if (Found == AllGroups.end() || Found->getName() != RootGroup) {
+ llvm::errs() << "No such diagnostic group exists\n";
+ return 1;
+ }
+
+ printGroup(out, *Found, FlagsOnly);
+
+ return 0;
+}
+
+static int showAll(llvm::raw_ostream &out, bool FlagsOnly) {
+ ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
+ llvm::DenseSet<unsigned> NonRootGroupIDs;
+
+ for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(),
+ E = AllGroups.end();
+ I != E; ++I) {
+ for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(),
+ SE = I->subgroup_end();
+ SI != SE; ++SI) {
+ NonRootGroupIDs.insert((unsigned)SI.getID());
+ }
+ }
+
+ assert(NonRootGroupIDs.size() < AllGroups.size());
+
+ for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
+ if (!NonRootGroupIDs.count(i))
+ printGroup(out, AllGroups[i], FlagsOnly);
+ }
+
+ return 0;
+}
+
+int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
+ // First check our one flag (--flags-only).
+ bool FlagsOnly = false;
+ if (argc > 0) {
+ StringRef FirstArg(*argv);
+ if (FirstArg.equals("--flags-only")) {
+ FlagsOnly = true;
+ --argc;
+ ++argv;
+ }
+ }
+
+ bool ShowAll = false;
+ StringRef RootGroup;
+
+ switch (argc) {
+ case 0:
+ ShowAll = true;
+ break;
+ case 1:
+ RootGroup = argv[0];
+ if (RootGroup.startswith("-W"))
+ RootGroup = RootGroup.substr(2);
+ if (RootGroup == "everything")
+ ShowAll = true;
+ // FIXME: Handle other special warning flags, like -pedantic.
+ break;
+ default:
+ printUsage();
+ return -1;
+ }
+
+ if (ShowAll)
+ return showAll(out, FlagsOnly);
+
+ return showGroup(out, RootGroup, FlagsOnly);
+}
+
diff --git a/tools/diagtool/diagtool_main.cpp b/tools/diagtool/diagtool_main.cpp
index e34f0dc06c657..4eef54dbfece9 100644
--- a/tools/diagtool/diagtool_main.cpp
+++ b/tools/diagtool/diagtool_main.cpp
@@ -18,7 +18,7 @@ using namespace diagtool;
int main(int argc, char *argv[]) {
if (argc > 1)
if (DiagTool *tool = diagTools->getTool(argv[1]))
- return tool->run(argc - 1, &argv[2], llvm::errs());
+ return tool->run(argc - 2, &argv[2], llvm::outs());
llvm::errs() << "usage: diagtool <command> [<args>]\n\n";
diagTools->printCommands(llvm::errs());