diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-12-20 20:20:20 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-12-20 20:20:20 +0000 |
commit | 2f234cbfb05549c62130bf53fc500c0c612f4f7b (patch) | |
tree | 754c224411ed11eb80ee79838ee8b38675d27eb2 /clang/lib/StaticAnalyzer | |
parent | ed414847bc80916af4361ad703ab542fe2d2577b (diff) | |
download | bcm5719-llvm-2f234cbfb05549c62130bf53fc500c0c612f4f7b.tar.gz bcm5719-llvm-2f234cbfb05549c62130bf53fc500c0c612f4f7b.zip |
Allow direct navigation to static analysis checker documentation through SARIF exports.
This adds anchors to all of the documented checks so that you can directly link to a check by a stable name. This is useful because the SARIF file format has a field for specifying a URI to documentation for a rule and some viewers, like CodeSonar, make use of this information. These links are then exposed through the SARIF exporter.
llvm-svn: 349812
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 2 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp | 21 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp | 14 |
3 files changed, 27 insertions, 10 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index d9b63c209d4..0588c2bd3d3 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -34,7 +34,7 @@ std::vector<StringRef> AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) { static const StringRef StaticAnalyzerChecks[] = { #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ FULLNAME, #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER diff --git a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp index 36046f0cfd1..9e9690ca0b3 100644 --- a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp @@ -257,7 +257,7 @@ static json::Object createResult(const PathDiagnostic &Diag, json::Array &Files, static StringRef getRuleDescription(StringRef CheckName) { return llvm::StringSwitch<StringRef>(CheckName) #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ .Case(FULLNAME, HELPTEXT) #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER @@ -265,12 +265,29 @@ static StringRef getRuleDescription(StringRef CheckName) { ; } +static StringRef getRuleHelpURIStr(StringRef CheckName) { + return llvm::StringSwitch<StringRef>(CheckName) +#define GET_CHECKERS +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ + .Case(FULLNAME, DOC_URI) +#include "clang/StaticAnalyzer/Checkers/Checkers.inc" +#undef CHECKER +#undef GET_CHECKERS + ; +} + static json::Object createRule(const PathDiagnostic &Diag) { StringRef CheckName = Diag.getCheckName(); - return json::Object{ + json::Object Ret{ {"fullDescription", createMessage(getRuleDescription(CheckName))}, {"name", createMessage(CheckName)}, {"id", CheckName}}; + + std::string RuleURI = getRuleHelpURIStr(CheckName); + if (!RuleURI.empty()) + Ret["helpURI"] = RuleURI; + + return Ret; } static json::Array createRules(std::vector<const PathDiagnostic *> &Diags, diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index 86cf62a1636..620c0e58890 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -42,8 +42,8 @@ static bool isCompatibleAPIVersion(const char *versionString) { CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags) : Diags(diags) { #define GET_CHECKERS -#define CHECKER(FULLNAME, CLASS, HELPTEXT) \ - addChecker(register##CLASS, FULLNAME, HELPTEXT); +#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ + addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS @@ -115,7 +115,7 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( for (const std::pair<std::string, bool> &opt : Opts.CheckersControlList) { // Use a binary search to find the possible start of the package. - CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, ""); + CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.first, "", ""); auto firstRelatedChecker = std::lower_bound(Checkers.cbegin(), end, packageInfo, checkerNameLT); @@ -147,13 +147,13 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers( return enabledCheckers; } -void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name, - StringRef desc) { - Checkers.push_back(CheckerInfo(fn, name, desc)); +void CheckerRegistry::addChecker(InitializationFunction Fn, StringRef Name, + StringRef Desc, StringRef DocsUri) { + Checkers.emplace_back(Fn, Name, Desc, DocsUri); // Record the presence of the checker in its packages. StringRef packageName, leafName; - std::tie(packageName, leafName) = name.rsplit(PackageSeparator); + std::tie(packageName, leafName) = Name.rsplit(PackageSeparator); while (!leafName.empty()) { Packages[packageName] += 1; std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator); |