Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -151,6 +151,10 @@ def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">, HelpText<"Display the list of checker and package options">; +def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">, + HelpText<"Display the list of checker and package options meant for " + "development purposes only">; + def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">, HelpText<"Don't emit errors on invalid analyzer-config inputs">; Index: include/clang/StaticAnalyzer/Checkers/CheckerBase.td =================================================================== --- include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -25,13 +25,22 @@ bits<2> Type = val.Type; } +/// Marks the entry hidden. Hidden entries won't be displayed in +/// -analyzer-checker-option-help. +class HiddenEnum { + bit Val = val; +} +def DontHide : HiddenEnum<0>; +def Hide : HiddenEnum<1>; + /// Describes an option for a checker or a package. class CmdLineOption { + string defaultVal, HiddenEnum isHidden = DontHide> { bits<2> Type = type.Type; - string CmdFlag = cmdFlag; - string Desc = desc; - string DefaultVal = defaultVal; + string CmdFlag = cmdFlag; + string Desc = desc; + string DefaultVal = defaultVal; + bit Hidden = isHidden.Val; } /// Describes a list of package options. Index: include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- include/clang/StaticAnalyzer/Checkers/Checkers.td +++ include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -519,7 +519,8 @@ "for each uninitalized field, as opposed to emitting one " "warning per constructor call, and listing the uninitialized " "fields that belongs to it in notes.", - "false">, + "false", + Hide>, CmdLineOption, + "true", + Hide>, CmdLineOption + "false", + Hide> ]>, Documentation; @@ -1110,67 +1113,83 @@ CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption, + "false", + Hide>, CmdLineOption + "false", + Hide> ]>, Documentation; Index: include/clang/StaticAnalyzer/Core/AnalyzerOptions.h =================================================================== --- include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -224,6 +224,7 @@ unsigned ShowCheckerHelpDeveloper : 1; unsigned ShowEnabledCheckerList : 1; unsigned ShowCheckerOptionList : 1; + unsigned ShowCheckerOptionDeveloperList : 1; unsigned ShowConfigOptionsList : 1; unsigned ShouldEmitErrorsOnInvalidConfigValue : 1; unsigned AnalyzeAll : 1; @@ -287,7 +288,8 @@ AnalyzerOptions() : DisableAllChecks(false), ShowCheckerHelp(false), ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false), - ShowEnabledCheckerList(false), ShowCheckerOptionList(false), + ShowEnabledCheckerList(false), + ShowCheckerOptionList(false), ShowCheckerOptionDeveloperList(false), ShowConfigOptionsList(false), AnalyzeAll(false), AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false), TrimGraph(false), Index: include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -98,11 +98,13 @@ StringRef OptionName; StringRef DefaultValStr; StringRef Description; + bool IsHidden; CmdLineOption(StringRef OptionType, StringRef OptionName, - StringRef DefaultValStr, StringRef Description) + StringRef DefaultValStr, StringRef Description, bool IsHidden) : OptionType(OptionType), OptionName(OptionName), - DefaultValStr(DefaultValStr), Description(Description) { + DefaultValStr(DefaultValStr), Description(Description), + IsHidden(IsHidden) { assert((OptionType == "bool" || OptionType == "string" || OptionType == "int") && @@ -239,7 +241,7 @@ /// non-compatibility mode. void addCheckerOption(StringRef OptionType, StringRef CheckerFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description); + StringRef Description, bool IsHidden = false); /// Adds a package to the registry. void addPackage(StringRef FullName); @@ -255,7 +257,7 @@ /// non-compatibility mode. void addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description); + StringRef Description, bool IsHidden = false); // FIXME: This *really* should be added to the frontend flag descriptions. /// Initializes a CheckerManager by calling the initialization functions for Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -289,6 +289,8 @@ Opts.ShowCheckerHelpDeveloper = Args.hasArg(OPT_analyzer_checker_help_developer); Opts.ShowCheckerOptionList = Args.hasArg(OPT_analyzer_checker_option_help); + Opts.ShowCheckerOptionDeveloperList = + Args.hasArg(OPT_analyzer_checker_option_help_developer); Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help); Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers); Opts.ShouldEmitErrorsOnInvalidConfigValue = Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -249,7 +249,7 @@ } // Honor -analyzer-checker-option-help. - if (Clang->getAnalyzerOpts()->ShowCheckerOptionList) { + if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionDeveloperList) { ento::printCheckerConfigList(llvm::outs(), Clang->getFrontendOpts().Plugins, *Clang->getAnalyzerOpts(), Index: lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -180,12 +180,12 @@ addDependency(FULLNAME, DEPENDENCY); #define GET_CHECKER_OPTIONS -#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \ - addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC); +#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \ + addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN); #define GET_PACKAGE_OPTIONS -#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \ - addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC); +#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \ + addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER_DEPENDENCY @@ -396,10 +396,10 @@ StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description) { + StringRef Description, bool IsHidden) { PackageOptions.emplace_back( - PackageFullName, - CmdLineOption{OptionType, OptionName, DefaultValStr, Description}); + PackageFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, + Description, IsHidden}); } void CheckerRegistry::addChecker(InitializationFunction Rfn, @@ -421,10 +421,10 @@ StringRef CheckerFullName, StringRef OptionName, StringRef DefaultValStr, - StringRef Description) { + StringRef Description, bool IsHidden) { CheckerOptions.emplace_back( - CheckerFullName, - CmdLineOption{OptionType, OptionName, DefaultValStr, Description}); + CheckerFullName, CmdLineOption{OptionType, OptionName, DefaultValStr, + Description, IsHidden}); } void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const { @@ -577,6 +577,9 @@ } for (const std::pair &Entry : OptionMap) { + if (!AnOpts.ShowCheckerOptionDeveloperList && Entry.second.IsHidden) + continue; + const CmdLineOption &Option = Entry.second; std::string FullOption = (Entry.first + ":" + Option.OptionName).str(); Index: test/Analysis/analyzer-checker-option-help.c =================================================================== --- test/Analysis/analyzer-checker-option-help.c +++ test/Analysis/analyzer-checker-option-help.c @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -analyzer-checker-option-help 2>&1 | FileCheck %s +// RUN: %clang_cc1 -analyzer-checker-option-help-developer \ +// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN + // CHECK: OVERVIEW: Clang Static Analyzer Checker and Package Option List // // CHECK: USAGE: -analyzer-config @@ -17,3 +20,6 @@ // CHECK: the first statement in the group is representative // CHECK: for all other statements in the group in // CHECK: terms of complexity. (default: 50) + +// CHECK-NOT: optin.cplusplus.UninitializedObject:NotesAsWarnings +// CHECK-HIDDEN: optin.cplusplus.UninitializedObject:NotesAsWarnings Index: utils/TableGen/ClangSACheckersEmitter.cpp =================================================================== --- utils/TableGen/ClangSACheckersEmitter.cpp +++ utils/TableGen/ClangSACheckersEmitter.cpp @@ -113,6 +113,7 @@ static bool isHidden(const Record *R) { if (R->getValueAsBit("Hidden")) return true; + // Not declared as hidden, check the parent package if it is hidden. if (DefInit *DI = dyn_cast(R->getValueInit("ParentPackage"))) return isHidden(DI->getDef()); @@ -121,21 +122,38 @@ } static void printChecker(llvm::raw_ostream &OS, const Record &R) { - OS << "CHECKER(" << "\""; - OS.write_escaped(getCheckerFullName(&R)) << "\", "; - OS << R.getName() << ", "; - OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; - OS << "\""; - OS.write_escaped(getCheckerDocs(R)); - OS << "\", "; + OS << "CHECKER(" << "\""; + OS.write_escaped(getCheckerFullName(&R)) << "\", "; + OS << R.getName() << ", "; + OS << "\""; + OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; + OS << "\""; + OS.write_escaped(getCheckerDocs(R)); + OS << "\", "; + + if (!isHidden(&R)) + OS << "false"; + else + OS << "true"; - if (!isHidden(&R)) - OS << "false"; - else - OS << "true"; + OS << ")\n"; +} - OS << ")\n"; +static void printOption(llvm::raw_ostream &OS, StringRef FullName, + const Record &R) { + OS << "\""; + OS.write_escaped(getCheckerOptionType(R)) << "\", \""; + OS.write_escaped(FullName) << "\", "; + OS << '\"' << getStringValue(R, "CmdFlag") << "\", "; + OS << '\"'; + OS.write_escaped(getStringValue(R, "Desc")) << "\", "; + OS << '\"'; + OS.write_escaped(getStringValue(R, "DefaultVal")) << "\", "; + + if (!R.getValueAsBit("Hidden")) + OS << "false"; + else + OS << "true"; } namespace clang { @@ -196,14 +214,8 @@ std::vector PackageOptions = Package ->getValueAsListOfDefs("PackageOptions"); for (Record *PackageOpt : PackageOptions) { - OS << "PACKAGE_OPTION(\""; - OS.write_escaped(getCheckerOptionType(*PackageOpt)) << "\", \""; - OS.write_escaped(getPackageFullName(Package)) << "\", "; - OS << '\"' << getStringValue(*PackageOpt, "CmdFlag") << "\", "; - OS << '\"'; - OS.write_escaped(getStringValue(*PackageOpt, "Desc")) << "\", "; - OS << '\"'; - OS.write_escaped(getStringValue(*PackageOpt, "DefaultVal")) << "\""; + OS << "PACKAGE_OPTION("; + printOption(OS, getPackageFullName(Package), *PackageOpt); OS << ")\n"; } } @@ -277,16 +289,9 @@ std::vector CheckerOptions = Checker ->getValueAsListOfDefs("CheckerOptions"); for (Record *CheckerOpt : CheckerOptions) { - OS << "CHECKER_OPTION(\""; - OS << getCheckerOptionType(*CheckerOpt) << "\", \""; - OS.write_escaped(getCheckerFullName(Checker)) << "\", "; - OS << '\"' << getStringValue(*CheckerOpt, "CmdFlag") << "\", "; - OS << '\"'; - OS.write_escaped(getStringValue(*CheckerOpt, "Desc")) << "\", "; - OS << '\"'; - OS.write_escaped(getStringValue(*CheckerOpt, "DefaultVal")) << "\""; - OS << ")"; - OS << '\n'; + OS << "CHECKER_OPTION("; + printOption(OS, getCheckerFullName(Checker), *CheckerOpt); + OS << ")\n"; } } OS << "#endif // GET_CHECKER_OPTIONS\n"