diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-06-01 21:23:17 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-06-01 21:23:17 +0000 |
commit | f11b0f9a4e8d79f1bf59f4271f96d28b55bcc067 (patch) | |
tree | 7bbeae13ab6fe02559808068b24312466fa216e0 /tools/diagtool | |
parent | 39876df44d4aec9cbcb30bdfd6a0bc26867a2e75 (diff) |
[diagtool] Add 'show-enabled', which displays which warnings are enabled.
show-enabled uses the command line you give it to build a CompilerInstance,
so any flags you pass will be processed as if running clang proper.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157842 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/diagtool')
-rw-r--r-- | tools/diagtool/CMakeLists.txt | 4 | ||||
-rw-r--r-- | tools/diagtool/DiagnosticNames.cpp | 25 | ||||
-rw-r--r-- | tools/diagtool/DiagnosticNames.h | 28 | ||||
-rw-r--r-- | tools/diagtool/ListWarnings.cpp | 27 | ||||
-rw-r--r-- | tools/diagtool/Makefile | 4 | ||||
-rw-r--r-- | tools/diagtool/ShowEnabledWarnings.cpp | 146 |
6 files changed, 208 insertions, 26 deletions
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt index f1fd9de03b..6263cb10a5 100644 --- a/tools/diagtool/CMakeLists.txt +++ b/tools/diagtool/CMakeLists.txt @@ -1,17 +1,21 @@ set( LLVM_LINK_COMPONENTS support + ${LLVM_TARGETS_TO_BUILD} ) set( LLVM_USED_LIBS clangBasic clangLex clangSema + clangFrontend ) add_clang_executable(diagtool diagtool_main.cpp DiagTool.cpp + DiagnosticNames.cpp ListWarnings.cpp + ShowEnabledWarnings.cpp ) if(UNIX) diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp new file mode 100644 index 0000000000..dd86c287ac --- /dev/null +++ b/tools/diagtool/DiagnosticNames.cpp @@ -0,0 +1,25 @@ +//===- 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" + +using namespace clang; + +const diagtool::DiagnosticRecord diagtool::BuiltinDiagnostics[] = { +#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 } +}; + +const size_t diagtool::BuiltinDiagnosticsCount = + sizeof(diagtool::BuiltinDiagnostics) / + sizeof(diagtool::BuiltinDiagnostics[0]) - 1; + diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h new file mode 100644 index 0000000000..ac1934aac1 --- /dev/null +++ b/tools/diagtool/DiagnosticNames.h @@ -0,0 +1,28 @@ +//===- 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/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace diagtool { + struct DiagnosticRecord { + const char *NameStr; + unsigned short DiagID; + uint8_t NameLen; + + llvm::StringRef getName() const { + return llvm::StringRef(NameStr, NameLen); + } + }; + + extern const DiagnosticRecord BuiltinDiagnostics[]; + extern const size_t BuiltinDiagnosticsCount; + +} // end namespace diagtool + diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp index 2bbeca8024..6c59338eef 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" @@ -26,28 +27,6 @@ DEF_DIAGTOOL("list-warnings", 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; - -namespace { struct Entry { llvm::StringRef DiagName; llvm::StringRef Flag; @@ -73,8 +52,8 @@ 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; - di != de; ++di) { + for (const diagtool::DiagnosticRecord *di = diagtool::BuiltinDiagnostics, + *de = di + diagtool::BuiltinDiagnosticsCount; di != de; ++di) { unsigned diagID = di->DiagID; diff --git a/tools/diagtool/Makefile b/tools/diagtool/Makefile index 6e3bcfc292..2f9706ef25 100644 --- a/tools/diagtool/Makefile +++ b/tools/diagtool/Makefile @@ -16,9 +16,9 @@ TOOL_NO_EXPORTS := 1 # Don't install this. NO_INSTALL = 1 -LINK_COMPONENTS := support +LINK_COMPONENTS := support $(TARGETS_TO_BUILD) -USEDLIBS = clangBasic.a +USEDLIBS = clangBasic.a clangFrontend.a include $(CLANG_LEVEL)/Makefile diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp new file mode 100644 index 0000000000..b220003e93 --- /dev/null +++ b/tools/diagtool/ShowEnabledWarnings.cpp @@ -0,0 +1,146 @@ +//===- 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 "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 char getFlagForLevel(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'; + } +} + +static CompilerInstance *createCompiler(unsigned int argc, char **argv) { + // First, build a compiler instance! + OwningPtr<CompilerInstance> Clang(new CompilerInstance()); + IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs()); + + // Initialize targets first. This may be necessary if any warnings are + // selectively enabled. + llvm::InitializeAllTargets(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllAsmParsers(); + + // Buffer diagnostics from argument parsing so that we can output them using a + // well formed diagnostic object. + TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer; + DiagnosticsEngine Diags(DiagIDs, DiagsBuffer); + + bool Success; + Success = CompilerInvocation::CreateFromArgs(Clang->getInvocation(), + argv, argv+argc, Diags); + + // We are skipping cc1's usual search for a resource directory. + // This is not likely to affect warning output. + + // Create the actual diagnostics engine. + Clang->createDiagnostics(argc, argv); + if (!Clang->hasDiagnostics()) + 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(Clang->getDiagnostics()); + if (!Success) + return NULL; + + return Clang.take(); +} + +int ShowEnabledWarnings::run(unsigned int argc, char **argv, raw_ostream &Out) { + // First check our one flag (--flags). + bool ShouldShowFlags = true; + if (argc > 0) { + StringRef FirstArg(*argv); + if (FirstArg.equals("--no-flags")) { + ShouldShowFlags = false; + --argc; + ++argv; + } else if (FirstArg.equals("--flags")) { + ShouldShowFlags = true; + --argc; + ++argv; + } + } + + // Create the compiler instance. + OwningPtr<CompilerInstance> Clang(createCompiler(argc, argv)); + if (!Clang) + return EXIT_FAILURE; + + DiagnosticsEngine &Diags = Clang->getDiagnostics(); + + // 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 (ShouldShowFlags) + Out << getFlagForLevel(I->Level) << " "; + Out << I->Name; + if (!I->Flag.empty()) + Out << " [-W" << I->Flag << "]"; + Out << '\n'; + } + + return EXIT_SUCCESS; +} |