10832f82f763185767d63ae4bf05021c5630c155fJordan Rose//===- ShowEnabledWarnings - diagtool tool for printing enabled flags -----===// 20832f82f763185767d63ae4bf05021c5630c155fJordan Rose// 30832f82f763185767d63ae4bf05021c5630c155fJordan Rose// The LLVM Compiler Infrastructure 40832f82f763185767d63ae4bf05021c5630c155fJordan Rose// 50832f82f763185767d63ae4bf05021c5630c155fJordan Rose// This file is distributed under the University of Illinois Open Source 60832f82f763185767d63ae4bf05021c5630c155fJordan Rose// License. See LICENSE.TXT for details. 70832f82f763185767d63ae4bf05021c5630c155fJordan Rose// 80832f82f763185767d63ae4bf05021c5630c155fJordan Rose//===----------------------------------------------------------------------===// 90832f82f763185767d63ae4bf05021c5630c155fJordan Rose 100832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "DiagTool.h" 110832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "DiagnosticNames.h" 120832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "clang/Basic/LLVM.h" 130832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "clang/Frontend/CompilerInstance.h" 140832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "clang/Frontend/TextDiagnosticBuffer.h" 150832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "clang/Frontend/TextDiagnosticPrinter.h" 160832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "clang/Frontend/Utils.h" 170832f82f763185767d63ae4bf05021c5630c155fJordan Rose#include "llvm/Support/TargetSelect.h" 180832f82f763185767d63ae4bf05021c5630c155fJordan Rose 190832f82f763185767d63ae4bf05021c5630c155fJordan RoseDEF_DIAGTOOL("show-enabled", 200832f82f763185767d63ae4bf05021c5630c155fJordan Rose "Show which warnings are enabled for a given command line", 210832f82f763185767d63ae4bf05021c5630c155fJordan Rose ShowEnabledWarnings) 220832f82f763185767d63ae4bf05021c5630c155fJordan Rose 230832f82f763185767d63ae4bf05021c5630c155fJordan Roseusing namespace clang; 24e7427636767501903cfa51ccecafa7a4795a23c2Jordan Roseusing namespace diagtool; 250832f82f763185767d63ae4bf05021c5630c155fJordan Rose 260832f82f763185767d63ae4bf05021c5630c155fJordan Rosenamespace { 270832f82f763185767d63ae4bf05021c5630c155fJordan Rose struct PrettyDiag { 280832f82f763185767d63ae4bf05021c5630c155fJordan Rose StringRef Name; 290832f82f763185767d63ae4bf05021c5630c155fJordan Rose StringRef Flag; 300832f82f763185767d63ae4bf05021c5630c155fJordan Rose DiagnosticsEngine::Level Level; 310832f82f763185767d63ae4bf05021c5630c155fJordan Rose 320832f82f763185767d63ae4bf05021c5630c155fJordan Rose PrettyDiag(StringRef name, StringRef flag, DiagnosticsEngine::Level level) 330832f82f763185767d63ae4bf05021c5630c155fJordan Rose : Name(name), Flag(flag), Level(level) {} 340832f82f763185767d63ae4bf05021c5630c155fJordan Rose 350832f82f763185767d63ae4bf05021c5630c155fJordan Rose bool operator<(const PrettyDiag &x) const { return Name < x.Name; } 360832f82f763185767d63ae4bf05021c5630c155fJordan Rose }; 370832f82f763185767d63ae4bf05021c5630c155fJordan Rose} 380832f82f763185767d63ae4bf05021c5630c155fJordan Rose 390832f82f763185767d63ae4bf05021c5630c155fJordan Rosestatic void printUsage() { 400832f82f763185767d63ae4bf05021c5630c155fJordan Rose llvm::errs() << "Usage: diagtool show-enabled [<flags>] <single-input.c>\n"; 410832f82f763185767d63ae4bf05021c5630c155fJordan Rose} 420832f82f763185767d63ae4bf05021c5630c155fJordan Rose 430832f82f763185767d63ae4bf05021c5630c155fJordan Rosestatic char getCharForLevel(DiagnosticsEngine::Level Level) { 440832f82f763185767d63ae4bf05021c5630c155fJordan Rose switch (Level) { 450832f82f763185767d63ae4bf05021c5630c155fJordan Rose case DiagnosticsEngine::Ignored: return ' '; 460832f82f763185767d63ae4bf05021c5630c155fJordan Rose case DiagnosticsEngine::Note: return '-'; 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines case DiagnosticsEngine::Remark: return 'R'; 480832f82f763185767d63ae4bf05021c5630c155fJordan Rose case DiagnosticsEngine::Warning: return 'W'; 490832f82f763185767d63ae4bf05021c5630c155fJordan Rose case DiagnosticsEngine::Error: return 'E'; 500832f82f763185767d63ae4bf05021c5630c155fJordan Rose case DiagnosticsEngine::Fatal: return 'F'; 510832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 520832f82f763185767d63ae4bf05021c5630c155fJordan Rose 530832f82f763185767d63ae4bf05021c5630c155fJordan Rose llvm_unreachable("Unknown diagnostic level"); 540832f82f763185767d63ae4bf05021c5630c155fJordan Rose} 550832f82f763185767d63ae4bf05021c5630c155fJordan Rose 560832f82f763185767d63ae4bf05021c5630c155fJordan Rosestatic IntrusiveRefCntPtr<DiagnosticsEngine> 570832f82f763185767d63ae4bf05021c5630c155fJordan RosecreateDiagnostics(unsigned int argc, char **argv) { 580832f82f763185767d63ae4bf05021c5630c155fJordan Rose IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs()); 590832f82f763185767d63ae4bf05021c5630c155fJordan Rose 600832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Buffer diagnostics from argument parsing so that we can output them using a 610832f82f763185767d63ae4bf05021c5630c155fJordan Rose // well formed diagnostic object. 620832f82f763185767d63ae4bf05021c5630c155fJordan Rose TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; 630832f82f763185767d63ae4bf05021c5630c155fJordan Rose IntrusiveRefCntPtr<DiagnosticsEngine> InterimDiags( 6402c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer)); 650832f82f763185767d63ae4bf05021c5630c155fJordan Rose 660832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Try to build a CompilerInvocation. 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<CompilerInvocation> Invocation( 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc), 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines InterimDiags)); 700832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (!Invocation) 71ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return nullptr; 720832f82f763185767d63ae4bf05021c5630c155fJordan Rose 730832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Build the diagnostics parser 740832f82f763185767d63ae4bf05021c5630c155fJordan Rose IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags = 75d47afb96a3f988e6d21a92fe4dfe875ab227c7c0Sean Silva CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts()); 760832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (!FinalDiags) 77ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return nullptr; 78ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 790832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Flush any errors created when initializing everything. This could happen 800832f82f763185767d63ae4bf05021c5630c155fJordan Rose // for invalid command lines, which will probably give non-sensical results. 810832f82f763185767d63ae4bf05021c5630c155fJordan Rose DiagsBuffer->FlushDiagnostics(*FinalDiags); 820832f82f763185767d63ae4bf05021c5630c155fJordan Rose 830832f82f763185767d63ae4bf05021c5630c155fJordan Rose return FinalDiags; 840832f82f763185767d63ae4bf05021c5630c155fJordan Rose} 850832f82f763185767d63ae4bf05021c5630c155fJordan Rose 860832f82f763185767d63ae4bf05021c5630c155fJordan Roseint ShowEnabledWarnings::run(unsigned int argc, char **argv, raw_ostream &Out) { 870832f82f763185767d63ae4bf05021c5630c155fJordan Rose // First check our one flag (--levels). 880832f82f763185767d63ae4bf05021c5630c155fJordan Rose bool ShouldShowLevels = true; 890832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (argc > 0) { 900832f82f763185767d63ae4bf05021c5630c155fJordan Rose StringRef FirstArg(*argv); 910832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (FirstArg.equals("--no-levels")) { 920832f82f763185767d63ae4bf05021c5630c155fJordan Rose ShouldShowLevels = false; 930832f82f763185767d63ae4bf05021c5630c155fJordan Rose --argc; 940832f82f763185767d63ae4bf05021c5630c155fJordan Rose ++argv; 950832f82f763185767d63ae4bf05021c5630c155fJordan Rose } else if (FirstArg.equals("--levels")) { 960832f82f763185767d63ae4bf05021c5630c155fJordan Rose ShouldShowLevels = true; 970832f82f763185767d63ae4bf05021c5630c155fJordan Rose --argc; 980832f82f763185767d63ae4bf05021c5630c155fJordan Rose ++argv; 990832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 1000832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 1010832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1020832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Create the diagnostic engine. 1030832f82f763185767d63ae4bf05021c5630c155fJordan Rose IntrusiveRefCntPtr<DiagnosticsEngine> Diags = createDiagnostics(argc, argv); 1040832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (!Diags) { 1050832f82f763185767d63ae4bf05021c5630c155fJordan Rose printUsage(); 1060832f82f763185767d63ae4bf05021c5630c155fJordan Rose return EXIT_FAILURE; 1070832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 1080832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1090832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Now we have our diagnostics. Iterate through EVERY diagnostic and see 1100832f82f763185767d63ae4bf05021c5630c155fJordan Rose // which ones are turned on. 1110832f82f763185767d63ae4bf05021c5630c155fJordan Rose // FIXME: It would be very nice to print which flags are turning on which 1120832f82f763185767d63ae4bf05021c5630c155fJordan Rose // diagnostics, but this can be done with a diff. 113e7427636767501903cfa51ccecafa7a4795a23c2Jordan Rose ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName(); 1140832f82f763185767d63ae4bf05021c5630c155fJordan Rose std::vector<PrettyDiag> Active; 1150832f82f763185767d63ae4bf05021c5630c155fJordan Rose 116e7427636767501903cfa51ccecafa7a4795a23c2Jordan Rose for (ArrayRef<DiagnosticRecord>::iterator I = AllDiagnostics.begin(), 117e7427636767501903cfa51ccecafa7a4795a23c2Jordan Rose E = AllDiagnostics.end(); 118e7427636767501903cfa51ccecafa7a4795a23c2Jordan Rose I != E; ++I) { 1190832f82f763185767d63ae4bf05021c5630c155fJordan Rose unsigned DiagID = I->DiagID; 1200832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1210832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (DiagnosticIDs::isBuiltinNote(DiagID)) 1220832f82f763185767d63ae4bf05021c5630c155fJordan Rose continue; 1230832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1240832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID)) 1250832f82f763185767d63ae4bf05021c5630c155fJordan Rose continue; 1260832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1270832f82f763185767d63ae4bf05021c5630c155fJordan Rose DiagnosticsEngine::Level DiagLevel = 1280832f82f763185767d63ae4bf05021c5630c155fJordan Rose Diags->getDiagnosticLevel(DiagID, SourceLocation()); 1290832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (DiagLevel == DiagnosticsEngine::Ignored) 1300832f82f763185767d63ae4bf05021c5630c155fJordan Rose continue; 1310832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1320832f82f763185767d63ae4bf05021c5630c155fJordan Rose StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID); 1330832f82f763185767d63ae4bf05021c5630c155fJordan Rose Active.push_back(PrettyDiag(I->getName(), WarningOpt, DiagLevel)); 1340832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 1350832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1360832f82f763185767d63ae4bf05021c5630c155fJordan Rose // Print them all out. 1370832f82f763185767d63ae4bf05021c5630c155fJordan Rose for (std::vector<PrettyDiag>::const_iterator I = Active.begin(), 1380832f82f763185767d63ae4bf05021c5630c155fJordan Rose E = Active.end(); I != E; ++I) { 1390832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (ShouldShowLevels) 1400832f82f763185767d63ae4bf05021c5630c155fJordan Rose Out << getCharForLevel(I->Level) << " "; 1410832f82f763185767d63ae4bf05021c5630c155fJordan Rose Out << I->Name; 1420832f82f763185767d63ae4bf05021c5630c155fJordan Rose if (!I->Flag.empty()) 1430832f82f763185767d63ae4bf05021c5630c155fJordan Rose Out << " [-W" << I->Flag << "]"; 1440832f82f763185767d63ae4bf05021c5630c155fJordan Rose Out << '\n'; 1450832f82f763185767d63ae4bf05021c5630c155fJordan Rose } 1460832f82f763185767d63ae4bf05021c5630c155fJordan Rose 1470832f82f763185767d63ae4bf05021c5630c155fJordan Rose return EXIT_SUCCESS; 1480832f82f763185767d63ae4bf05021c5630c155fJordan Rose} 149