diff options
author | dim <dim@FreeBSD.org> | 2011-02-27 01:32:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-27 01:32:10 +0000 |
commit | b951d621be1d00a520871c689c1cd687b6aa3ae6 (patch) | |
tree | 5c342f2374324ffec4626f558d9aa49f323f90b4 /contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp | |
parent | 4004d6a3076e94bd23e681411c43682267a202fe (diff) | |
parent | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff) | |
download | FreeBSD-src-b951d621be1d00a520871c689c1cd687b6aa3ae6.zip FreeBSD-src-b951d621be1d00a520871c689c1cd687b6aa3ae6.tar.gz |
Update llvm/clang to trunk r126547.
There are several bugfixes in this update, but the most important one is
to ensure __start_ and __stop_ symbols for linker sets and kernel module
metadata are always emitted in object files:
http://llvm.org/bugs/show_bug.cgi?id=9292
Before this fix, if you compiled kernel modules with clang, they would
not be properly processed by kldxref, and if they had any dependencies,
the kernel would fail to load those. Another problem occurred when
attempting to mount a tmpfs filesystem, which would result in 'operation
not supported by device'.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp index 94f200f..5c0c950 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/ClangSACheckerProvider.cpp @@ -16,7 +16,9 @@ #include "ClangSACheckers.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/CheckerProvider.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/DenseSet.h" +#include "map" using namespace clang; using namespace ento; @@ -28,6 +30,7 @@ class ClangSACheckerProvider : public CheckerProvider { public: virtual void registerCheckers(CheckerManager &checkerMgr, CheckerOptInfo *checkOpts, unsigned numCheckOpts); + virtual void printHelp(llvm::raw_ostream &OS); }; } @@ -41,6 +44,7 @@ namespace { struct StaticCheckerInfoRec { const char *FullName; void (*RegFunc)(CheckerManager &mgr); + const char *HelpText; bool Hidden; }; @@ -49,13 +53,16 @@ struct StaticCheckerInfoRec { static const StaticCheckerInfoRec StaticCheckerInfo[] = { #define GET_CHECKERS #define CHECKER(FULLNAME,CLASS,DESCFILE,HELPTEXT,HIDDEN) \ - { FULLNAME, register##CLASS, HIDDEN }, + { FULLNAME, register##CLASS, HELPTEXT, HIDDEN }, #include "Checkers.inc" - { 0, 0, 0} + { 0, 0, 0, 0} #undef CHECKER #undef GET_CHECKERS }; +static const unsigned NumCheckers = sizeof(StaticCheckerInfo) + / sizeof(StaticCheckerInfoRec) - 1; + namespace { struct CheckNameOption { @@ -104,9 +111,10 @@ static void collectCheckers(const CheckNameOption *checkName, // Enable/disable all subgroups along with this one. if (const short *subGroups = checkName->SubGroups) { - for (; *subGroups != -1; ++subGroups) - collectCheckers(&CheckNameTable[*subGroups], enable, checkers, - collectHidden && checkName->Hidden); + for (; *subGroups != -1; ++subGroups) { + const CheckNameOption *sub = &CheckNameTable[*subGroups]; + collectCheckers(sub, enable, checkers, collectHidden && !sub->Hidden); + } } } @@ -135,3 +143,41 @@ void ClangSACheckerProvider::registerCheckers(CheckerManager &checkerMgr, (*I)->RegFunc(checkerMgr); } } + +typedef std::map<std::string, const StaticCheckerInfoRec *> SortedCheckers; + +static void printCheckerOption(llvm::raw_ostream &OS,SortedCheckers &checkers) { + // Find the maximum option length. + unsigned OptionFieldWidth = 0; + for (SortedCheckers::iterator + I = checkers.begin(), E = checkers.end(); I != E; ++I) { + // Limit the amount of padding we are willing to give up for alignment. + unsigned Length = strlen(I->second->FullName); + if (Length <= 30) + OptionFieldWidth = std::max(OptionFieldWidth, Length); + } + + const unsigned InitialPad = 2; + for (SortedCheckers::iterator + I = checkers.begin(), E = checkers.end(); I != E; ++I) { + const std::string &Option = I->first; + int Pad = OptionFieldWidth - int(Option.size()); + OS.indent(InitialPad) << Option; + + // Break on long option names. + if (Pad < 0) { + OS << "\n"; + Pad = OptionFieldWidth + InitialPad; + } + OS.indent(Pad + 1) << I->second->HelpText << '\n'; + } +} + +void ClangSACheckerProvider::printHelp(llvm::raw_ostream &OS) { + // Sort checkers according to their full name. + SortedCheckers checkers; + for (unsigned i = 0; i != NumCheckers; ++i) + checkers[StaticCheckerInfo[i].FullName] = &StaticCheckerInfo[i]; + + printCheckerOption(OS, checkers); +} |