diff options
Diffstat (limited to 'utils/TableGen/ClangSACheckersEmitter.cpp')
-rw-r--r-- | utils/TableGen/ClangSACheckersEmitter.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp index e01d55c527..57850a4387 100644 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ b/utils/TableGen/ClangSACheckersEmitter.cpp @@ -57,6 +57,40 @@ static std::string getStringValue(const Record &R, StringRef field) { return std::string(); } +// Calculates the integer value representing the BitsInit object +static inline uint64_t getValueFromBitsInit(const BitsInit *B, const Record &R) { + assert(B->getNumBits() <= sizeof(uint64_t) * 8 && "BitInits' too long!"); + + uint64_t Value = 0; + for (unsigned i = 0, e = B->getNumBits(); i != e; ++i) { + const auto *Bit = dyn_cast<BitInit>(B->getBit(i)); + if (Bit) + Value |= uint64_t(Bit->getValue()) << i; + else + PrintFatalError(R.getLoc(), + "missing Documentation for " + getCheckerFullName(&R)); + } + return Value; +} + +static std::string getCheckerDocs(const Record &R) { + StringRef LandingPage; + if (BitsInit *BI = R.getValueAsBitsInit("Documentation")) { + uint64_t V = getValueFromBitsInit(BI, R); + if (V == 1) + LandingPage = "available_checks.html"; + else if (V == 2) + LandingPage = "alpha_checks.html"; + } + + if (LandingPage.empty()) + return ""; + + return (llvm::Twine("https://clang-analyzer.llvm.org/") + LandingPage + "#" + + getCheckerFullName(&R)) + .str(); +} + namespace clang { void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { std::vector<Record*> checkers = Records.getAllDerivedDefinitions("Checker"); @@ -64,6 +98,9 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { using SortedRecords = llvm::StringMap<const Record *>; + OS << "// This file is automatically generated. Do not edit this file by " + "hand.\n"; + OS << "\n#ifdef GET_PACKAGES\n"; { SortedRecords sortedPackages; @@ -89,7 +126,10 @@ void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS) { OS.write_escaped(getCheckerFullName(&R)) << "\", "; OS << R.getName() << ", "; OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << '\"'; + OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; + OS << "\""; + OS.write_escaped(getCheckerDocs(R)); + OS << "\""; OS << ")\n"; } OS << "#endif // GET_CHECKERS\n\n"; |