1//===- TreeView.cpp - diagtool tool for printing warning flags ------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This diagnostic tool 11// 12//===----------------------------------------------------------------------===// 13 14#include "DiagTool.h" 15#include "DiagnosticNames.h" 16#include "clang/Basic/Diagnostic.h" 17#include "llvm/Support/Format.h" 18#include "llvm/ADT/StringMap.h" 19#include "llvm/ADT/DenseSet.h" 20#include "clang/AST/ASTDiagnostic.h" 21#include "clang/Basic/AllDiagnostics.h" 22 23DEF_DIAGTOOL("tree", 24 "Show warning flags in a tree view", 25 TreeView) 26 27using namespace clang; 28using namespace diagtool; 29 30static void printUsage() { 31 llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n"; 32} 33 34static void printGroup(llvm::raw_ostream &out, const GroupRecord &Group, 35 bool FlagsOnly, unsigned Indent = 0) { 36 out.indent(Indent * 2); 37 out << "-W" << Group.getName() << "\n"; 38 39 ++Indent; 40 for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(), 41 E = Group.subgroup_end(); 42 I != E; ++I) { 43 printGroup(out, *I, FlagsOnly, Indent); 44 } 45 46 if (!FlagsOnly) { 47 for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(), 48 E = Group.diagnostics_end(); 49 I != E; ++I) { 50 out.indent(Indent * 2); 51 out << I->getName() << "\n"; 52 } 53 } 54} 55 56static int showGroup(llvm::raw_ostream &out, StringRef RootGroup, 57 bool FlagsOnly) { 58 ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups(); 59 60 GroupRecord Key = { RootGroup.size(), RootGroup.data(), 0, 0 }; 61 const GroupRecord *Found = 62 std::lower_bound(AllGroups.begin(), AllGroups.end(), Key); 63 64 if (Found == AllGroups.end() || Found->getName() != RootGroup) { 65 llvm::errs() << "No such diagnostic group exists\n"; 66 return 1; 67 } 68 69 printGroup(out, *Found, FlagsOnly); 70 71 return 0; 72} 73 74static int showAll(llvm::raw_ostream &out, bool FlagsOnly) { 75 ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups(); 76 llvm::DenseSet<unsigned> NonRootGroupIDs; 77 78 for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(), 79 E = AllGroups.end(); 80 I != E; ++I) { 81 for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(), 82 SE = I->subgroup_end(); 83 SI != SE; ++SI) { 84 NonRootGroupIDs.insert((unsigned)SI.getID()); 85 } 86 } 87 88 assert(NonRootGroupIDs.size() < AllGroups.size()); 89 90 for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) { 91 if (!NonRootGroupIDs.count(i)) 92 printGroup(out, AllGroups[i], FlagsOnly); 93 } 94 95 return 0; 96} 97 98int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) { 99 // First check our one flag (--flags-only). 100 bool FlagsOnly = false; 101 if (argc > 0) { 102 StringRef FirstArg(*argv); 103 if (FirstArg.equals("--flags-only")) { 104 FlagsOnly = true; 105 --argc; 106 ++argv; 107 } 108 } 109 110 bool ShowAll = false; 111 StringRef RootGroup; 112 113 switch (argc) { 114 case 0: 115 ShowAll = true; 116 break; 117 case 1: 118 RootGroup = argv[0]; 119 if (RootGroup.startswith("-W")) 120 RootGroup = RootGroup.substr(2); 121 if (RootGroup == "everything") 122 ShowAll = true; 123 // FIXME: Handle other special warning flags, like -pedantic. 124 break; 125 default: 126 printUsage(); 127 return -1; 128 } 129 130 if (ShowAll) 131 return showAll(out, FlagsOnly); 132 133 return showGroup(out, RootGroup, FlagsOnly); 134} 135 136