[analyzer] List checker/plugin options in 3 categories: released, alpha, developer

Same patch as D62093, but for checker/plugin options, the only
difference being that options for alpha checkers are implicitly marked
as alpha.

Differential Revision: https://reviews.llvm.org/D62093

llvm-svn: 361566
This commit is contained in:
Kristof Umann 2019-05-23 22:52:09 +00:00
parent 342571e8d6
commit ac95c86511
11 changed files with 238 additions and 65 deletions

View File

@ -151,6 +151,11 @@ def analyzer_config : Separate<["-"], "analyzer-config">,
def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">,
HelpText<"Display the list of checker and package options">;
def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">,
HelpText<"Display the list of in development checker and package options. "
"These are NOT considered safe, they are unstable and will emit "
"incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">;
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">;

View File

@ -21,10 +21,21 @@ def Integer : CmdLineOptionTypeEnum<0>;
def String : CmdLineOptionTypeEnum<1>;
def Boolean : CmdLineOptionTypeEnum<2>;
class Type<CmdLineOptionTypeEnum val> {
bits<2> Type = val.Type;
/// Describes the state of the entry. We wouldn't like to display, for example,
/// developer only entries for a list meant for end users.
class DevelopmentStageEnum<bits<1> val> {
bits<1> Val = val;
}
/// Alpha entries are under development, might be incomplet, inkorrekt and
/// unstable.
def InAlpha : DevelopmentStageEnum<0>;
/// Released entries are stable, produce minimal, if any false positives,
/// and emits reports that explain the occurance of the bug understandably and
/// thoroughly.
def Released : DevelopmentStageEnum<1>;
/// Marks the entry hidden. Hidden entries won't be displayed in
/// -analyzer-checker-option-help.
class HiddenEnum<bit val> {
@ -35,11 +46,13 @@ def Hide : HiddenEnum<1>;
/// Describes an option for a checker or a package.
class CmdLineOption<CmdLineOptionTypeEnum type, string cmdFlag, string desc,
string defaultVal, HiddenEnum isHidden = DontHide> {
string defaultVal, DevelopmentStageEnum stage,
HiddenEnum isHidden = DontHide> {
bits<2> Type = type.Type;
string CmdFlag = cmdFlag;
string Desc = desc;
string DefaultVal = defaultVal;
bits<1> DevelopmentStage = stage.Val;
bit Hidden = isHidden.Val;
}

View File

@ -51,7 +51,8 @@ def Nullability : Package<"nullability">,
"concerned with your custom nullability annotations more "
"than with following nullability specifications of system "
"header functions.",
"false">
"false",
Released>
]>;
def Cplusplus : Package<"cplusplus">;
@ -391,7 +392,8 @@ def DynamicMemoryModeling: Checker<"DynamicMemoryModeling">,
"If set to true, the checker assumes that all the "
"allocating and deallocating functions are annotated with "
"ownership_holds, ownership_takes and ownership_returns.",
"false">
"false",
InAlpha>
]>,
Dependencies<[CStringModeling]>,
Documentation<NotDocumented>,
@ -496,7 +498,8 @@ def MoveChecker: Checker<"Move">,
"user has intentionally asked us to completely eliminate "
"use-after-move in his code. Values: \"KnownsOnly\", "
"\"KnownsAndLocals\", \"All\".",
"KnownsAndLocals">
"KnownsAndLocals",
Released>
]>,
Documentation<HasDocumentation>;
@ -512,7 +515,8 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">,
"If set to false, the checker won't emit warnings "
"for objects that don't have at least one initialized "
"field.",
"false">,
"false",
Released>,
CmdLineOption<Boolean,
"NotesAsWarnings",
"If set to true, the checker will emit a warning "
@ -520,25 +524,29 @@ def UninitializedObjectChecker: Checker<"UninitializedObject">,
"warning per constructor call, and listing the uninitialized "
"fields that belongs to it in notes.",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"CheckPointeeInitialization",
"If set to false, the checker will not analyze "
"the pointee of pointer/reference fields, and will only "
"check whether the object itself is initialized.",
"false">,
"false",
InAlpha>,
CmdLineOption<String,
"IgnoreRecordsWithField",
"If supplied, the checker will not analyze "
"structures that have a field with a name or type name that "
"matches the given pattern.",
"\"\"">,
"\"\"",
Released>,
CmdLineOption<Boolean,
"IgnoreGuardedFields",
"If set to true, the checker will analyze _syntactically_ "
"whether the found uninitialized object is used without a "
"preceding assert call. Defaults to false.",
"false">
"false",
InAlpha>
]>,
Documentation<HasAlphaDocumentation>;
@ -548,7 +556,8 @@ def VirtualCallChecker : Checker<"VirtualCall">,
CmdLineOption<Boolean,
"PureOnly",
"Whether to only report calls to pure virtual methods.",
"false">
"false",
Released>
]>,
Documentation<HasDocumentation>;
@ -651,7 +660,8 @@ def PaddingChecker : Checker<"Padding">,
"AllowedPad",
"Reports are only generated if the excessive padding exceeds "
"'AllowedPad' in bytes.",
"24">
"24",
Released>
]>,
Documentation<NotDocumented>;
@ -768,11 +778,13 @@ def MmapWriteExecChecker : Checker<"MmapWriteExec">,
CmdLineOption<Integer,
"MmapProtExec",
"Specifies the value of PROT_EXEC",
"0x04">,
"0x04",
Released>,
CmdLineOption<Integer,
"MmapProtRead",
"Specifies the value of PROT_READ",
"0x01">
"0x01",
Released>
]>,
Documentation<HasAlphaDocumentation>;
@ -819,7 +831,8 @@ def NumberObjectConversionChecker : Checker<"NumberObjectConversion">,
"Enables detection of more conversion patterns (which are "
"most likely more harmless, and therefore are more likely to "
"produce false positives).",
"false">
"false",
Released>
]>,
Documentation<NotDocumented>;
@ -920,6 +933,7 @@ def RetainCountChecker : Checker<"RetainCount">,
"retain-release rules for Objective-C NSObject instances "
"and CoreFoundation objects.",
"true",
InAlpha,
Hide>,
CmdLineOption<Boolean,
"TrackNSCFStartParam",
@ -928,7 +942,8 @@ def RetainCountChecker : Checker<"RetainCount">,
"elsewhere, but also that it fulfills its own retain count "
"specification with respect to objects that it receives as "
"arguments.",
"false">
"false",
Released>
]>,
Dependencies<[RetainCountBase]>,
Documentation<HasDocumentation>;
@ -1049,6 +1064,7 @@ def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">,
"SymRegion (Non-Aggressive), basically leaving only string "
"literals as NonLocalized.",
"false",
InAlpha,
Hide>
]>,
Documentation<HasDocumentation>;
@ -1114,81 +1130,97 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">,
"PreStmtCastExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PostStmtCastExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PreStmtArraySubscriptExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PostStmtArraySubscriptExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PreStmtCXXNewExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PostStmtCXXNewExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PreStmtOffsetOfExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PostStmtOffsetOfExpr",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PreCall",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"PostCall",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"EndFunction",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"NewAllocator",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"Bind",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"LiveSymbols",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"RegionChanges",
"",
"false",
Released,
Hide>,
CmdLineOption<Boolean,
"*",
"Enables all callbacks.",
"false",
Released,
Hide>
]>,
Documentation<NotDocumented>;
@ -1272,16 +1304,19 @@ def CloneChecker : Checker<"CloneChecker">,
"of a statement. This constraint assumes the first statement "
"in the group is representative for all other statements in "
"the group in terms of complexity.",
"50">,
"50",
Released>,
CmdLineOption<Boolean,
"ReportNormalClones",
"Report all clones, even less suspicious ones.",
"true">,
"true",
Released>,
CmdLineOption<String,
"IgnoredFilesPattern",
"If supplied, the checker wont analyze files with a filename "
"that matches the given pattern.",
"\"\"">
"\"\"",
Released>
]>,
Documentation<HasAlphaDocumentation>;

View File

@ -222,9 +222,12 @@ public:
unsigned ShowCheckerHelp : 1;
unsigned ShowCheckerHelpAlpha : 1;
unsigned ShowCheckerHelpDeveloper : 1;
unsigned ShowEnabledCheckerList : 1;
unsigned ShowCheckerOptionList : 1;
unsigned ShowCheckerOptionAlphaList : 1;
unsigned ShowCheckerOptionDeveloperList : 1;
unsigned ShowEnabledCheckerList : 1;
unsigned ShowConfigOptionsList : 1;
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
@ -288,8 +291,8 @@ public:
AnalyzerOptions()
: DisableAllChecks(false), ShowCheckerHelp(false),
ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
ShowEnabledCheckerList(false),
ShowCheckerOptionList(false), ShowCheckerOptionDeveloperList(false),
ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
ShowConfigOptionsList(false), AnalyzeAll(false),
AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),

View File

@ -98,13 +98,15 @@ public:
StringRef OptionName;
StringRef DefaultValStr;
StringRef Description;
StringRef DevelopmentStatus;
bool IsHidden;
CmdLineOption(StringRef OptionType, StringRef OptionName,
StringRef DefaultValStr, StringRef Description, bool IsHidden)
StringRef DefaultValStr, StringRef Description,
StringRef DevelopmentStatus, bool IsHidden)
: OptionType(OptionType), OptionName(OptionName),
DefaultValStr(DefaultValStr), Description(Description),
IsHidden(IsHidden) {
DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) {
assert((OptionType == "bool" || OptionType == "string" ||
OptionType == "int") &&
@ -120,6 +122,10 @@ public:
"Invalid value for integer command line option! Maybe incorrect "
"parameters to the addCheckerOption or addPackageOption method?");
(void)Tmp;
assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" ||
DevelopmentStatus == "released") &&
"Invalid development status!");
}
};
@ -241,7 +247,8 @@ public:
/// non-compatibility mode.
void addCheckerOption(StringRef OptionType, StringRef CheckerFullName,
StringRef OptionName, StringRef DefaultValStr,
StringRef Description, bool IsHidden = false);
StringRef Description, StringRef DevelopmentStatus,
bool IsHidden = false);
/// Adds a package to the registry.
void addPackage(StringRef FullName);
@ -257,7 +264,8 @@ public:
/// non-compatibility mode.
void addPackageOption(StringRef OptionType, StringRef PackageFullName,
StringRef OptionName, StringRef DefaultValStr,
StringRef Description, bool IsHidden = false);
StringRef Description, StringRef DevelopmentStatus,
bool IsHidden = false);
// FIXME: This *really* should be added to the frontend flag descriptions.
/// Initializes a CheckerManager by calling the initialization functions for

View File

@ -288,9 +288,13 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
Opts.ShowCheckerHelpAlpha = Args.hasArg(OPT_analyzer_checker_help_alpha);
Opts.ShowCheckerHelpDeveloper =
Args.hasArg(OPT_analyzer_checker_help_developer);
Opts.ShowCheckerOptionList = Args.hasArg(OPT_analyzer_checker_option_help);
Opts.ShowCheckerOptionAlphaList =
Args.hasArg(OPT_analyzer_checker_option_help_alpha);
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 =

View File

@ -249,7 +249,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
}
// Honor -analyzer-checker-option-help.
if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionDeveloperList) {
if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
AnOpts.ShowCheckerOptionDeveloperList) {
ento::printCheckerConfigList(llvm::outs(),
Clang->getFrontendOpts().Plugins,
*Clang->getAnalyzerOpts(),

View File

@ -180,12 +180,12 @@ CheckerRegistry::CheckerRegistry(
addDependency(FULLNAME, DEPENDENCY);
#define GET_CHECKER_OPTIONS
#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \
addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN);
#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \
addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN);
#define GET_PACKAGE_OPTIONS
#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, IS_HIDDEN) \
addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, IS_HIDDEN);
#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \
addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN);
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER_DEPENDENCY
@ -396,10 +396,12 @@ void CheckerRegistry::addPackageOption(StringRef OptionType,
StringRef PackageFullName,
StringRef OptionName,
StringRef DefaultValStr,
StringRef Description, bool IsHidden) {
StringRef Description,
StringRef DevelopmentStatus,
bool IsHidden) {
PackageOptions.emplace_back(
PackageFullName, CmdLineOption{OptionType, OptionName, DefaultValStr,
Description, IsHidden});
Description, DevelopmentStatus, IsHidden});
}
void CheckerRegistry::addChecker(InitializationFunction Rfn,
@ -421,10 +423,12 @@ void CheckerRegistry::addCheckerOption(StringRef OptionType,
StringRef CheckerFullName,
StringRef OptionName,
StringRef DefaultValStr,
StringRef Description, bool IsHidden) {
StringRef Description,
StringRef DevelopmentStatus,
bool IsHidden) {
CheckerOptions.emplace_back(
CheckerFullName, CmdLineOption{OptionType, OptionName, DefaultValStr,
Description, IsHidden});
Description, DevelopmentStatus, IsHidden});
}
void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {
@ -576,10 +580,14 @@ void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const {
}
}
auto Print = [] (llvm::raw_ostream &Out, StringRef FullOption, StringRef Desc) {
AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc},
/*InitialPad*/ 2,
/*EntryWidth*/ 50,
/*MinLineWidth*/ 90);
Out << "\n\n";
};
for (const std::pair<StringRef, const CmdLineOption &> &Entry : OptionMap) {
if (!AnOpts.ShowCheckerOptionDeveloperList && Entry.second.IsHidden)
continue;
const CmdLineOption &Option = Entry.second;
std::string FullOption = (Entry.first + ":" + Option.OptionName).str();
@ -588,10 +596,25 @@ void CheckerRegistry::printCheckerOptionList(raw_ostream &Out) const {
(Option.DefaultValStr.empty() ? "\"\"" : Option.DefaultValStr) + ")")
.str();
AnalyzerOptions::printFormattedEntry(Out, {FullOption, Desc},
/*InitialPad*/ 2,
/*EntryWidth*/ 50,
/*MinLineWidth*/ 90);
Out << "\n\n";
// The list of these if branches is significant, we wouldn't like to
// display hidden alpha checker options for
// -analyzer-checker-option-help-alpha.
if (Option.IsHidden) {
if (AnOpts.ShowCheckerOptionDeveloperList)
Print(Out, FullOption, Desc);
continue;
}
if (Option.DevelopmentStatus == "alpha" ||
Entry.first.startswith("alpha")) {
if (AnOpts.ShowCheckerOptionAlphaList)
Print(Out, FullOption,
llvm::Twine("(Enable only for development!) " + Desc).str());
continue;
}
if (AnOpts.ShowCheckerOptionList)
Print(Out, FullOption, Desc);
}
}

View File

@ -1,25 +1,87 @@
// RUN: %clang_cc1 -analyzer-checker-option-help 2>&1 | FileCheck %s
// RUN: %clang_cc1 -analyzer-checker-option-help \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE
// RUN: %clang_cc1 -analyzer-checker-option-help-alpha \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-ALPHA
// RUN: %clang_cc1 -analyzer-checker-option-help-developer \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-HIDDEN
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER
// CHECK: OVERVIEW: Clang Static Analyzer Checker and Package Option List
//
// CHECK: USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
//
// CHECK: -analyzer-config OPTION1=VALUE, -analyzer-config
// CHECK-SAME: OPTION2=VALUE, ...
//
// CHECK: OPTIONS:
//
// CHECK: alpha.clone.CloneChecker:MinimumCloneComplexity
// CHECK-SAME: (int) Ensures that every clone has at least
// CHECK: the given complexity. Complexity is here
// CHECK: defined as the total amount of children
// CHECK: of a statement. This constraint assumes
// CHECK: the first statement in the group is representative
// CHECK: for all other statements in the group in
// CHECK: terms of complexity. (default: 50)
// RUN: %clang_cc1 -analyzer-checker-option-help-developer \
// RUN: -analyzer-checker-option-help-alpha \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-DEVELOPER-ALPHA
// CHECK-NOT: optin.cplusplus.UninitializedObject:NotesAsWarnings
// CHECK-HIDDEN: optin.cplusplus.UninitializedObject:NotesAsWarnings
// RUN: %clang_cc1 -analyzer-checker-option-help \
// RUN: -analyzer-checker-option-help-alpha \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA
// RUN: %clang_cc1 -analyzer-checker-option-help \
// RUN: -analyzer-checker-option-help-developer \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-DEVELOPER
// RUN: %clang_cc1 -analyzer-checker-option-help \
// RUN: -analyzer-checker-option-help-alpha \
// RUN: -analyzer-checker-option-help-developer \
// RUN: 2>&1 | FileCheck %s -check-prefix=CHECK-STABLE-ALPHA-DEVELOPER
// CHECK-STABLE: OVERVIEW: Clang Static Analyzer Checker and Package Option List
//
// CHECK-STABLE: USAGE: -analyzer-config <OPTION1=VALUE,OPTION2=VALUE,...>
//
// CHECK-STABLE: -analyzer-config OPTION1=VALUE, -analyzer-config
// CHECK-STABLE-SAME: OPTION2=VALUE, ...
//
// CHECK-STABLE: OPTIONS:
//
// CHECK-STABLE: cplusplus.Move:WarnOn
// CHECK-STABLE-SAME: (string) In non-aggressive mode, only warn
// CHECK-STABLLE: on use-after-move of local variables (or
// CHECK-STABLLE: local rvalue references) and of STL objects.
// CHECK-STABLLE: The former is possible because local variables
// CHECK-STABLLE: (or local rvalue references) are not tempting
// CHECK-STABLLE: their user to re-use the storage. The latter
// CHECK-STABLLE: is possible because STL objects are known
// CHECK-STABLLE: to end up in a valid but unspecified state
// CHECK-STABLLE: after the move and their state-reset methods
// CHECK-STABLLE: are also known, which allows us to predict
// CHECK-STABLLE: precisely when use-after-move is invalid.
// CHECK-STABLLE: Some STL objects are known to conform to
// CHECK-STABLLE: additional contracts after move, so they
// CHECK-STABLLE: are not tracked. However, smart pointers
// CHECK-STABLLE: specifically are tracked because we can
// CHECK-STABLLE: perform extra checking over them. In aggressive
// CHECK-STABLLE: mode, warn on any use-after-move because
// CHECK-STABLLE: the user has intentionally asked us to completely
// CHECK-STABLLE: eliminate use-after-move in his code. Values:
// CHECK-STABLLE: "KnownsOnly", "KnownsAndLocals", "All".
// CHECK-STABLLE: (default: KnownsAndLocals)
// CHECK-STABLE-NOT: debug.AnalysisOrder:*
// CHECK-DEVELOPER: debug.AnalysisOrder:*
// CHECK-ALPHA-NOT: debug.AnalysisOrder:*
// CHECK-STABLE-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-DEVELOPER-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-STABLE: optin.performance.Padding:AllowedPad
// CHECK-DEVELOPER-NOT: optin.performance.Padding:AllowedPad
// CHECK-ALPHA-NOT: optin.performance.Padding:AllowedPad
// CHECK-STABLE-ALPHA-NOT: debug.AnalysisOrder:*
// CHECK-DEVELOPER-ALPHA: debug.AnalysisOrder:*
// CHECK-STABLE-DEVELOPER: debug.AnalysisOrder:*
// CHECK-STABLE-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-DEVELOPER-ALPHA: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-STABLE-DEVELOPER-NOT: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-STABLE-ALPHA: optin.performance.Padding:AllowedPad
// CHECK-DEVELOPER-ALPHA-NOT: optin.performance.Padding:AllowedPad
// CHECK-STABLE-DEVELOPER: optin.performance.Padding:AllowedPad
// CHECK-STABLE-ALPHA-DEVELOPER: debug.AnalysisOrder:*
// CHECK-STABLE-ALPHA-DEVELOPER: optin.cplusplus.UninitializedObject:IgnoreGuardedFields
// CHECK-STABLE-ALPHA-DEVELOPER: optin.performance.Padding:AllowedPad

View File

@ -36,7 +36,8 @@ extern "C" void clang_registerCheckers(CheckerRegistry &registry) {
/*CheckerFullName*/ "example.MyChecker",
/*OptionName*/ "ExampleOption",
/*DefaultValStr*/ "false",
/*Description*/ "This is an example checker opt.");
/*Description*/ "This is an example checker opt.",
/*DevelopmentStage*/ "released");
}
extern "C" const char clang_analyzerAPIVersionString[] =

View File

@ -110,6 +110,22 @@ static std::string getCheckerOptionType(const Record &R) {
return "";
}
static std::string getDevelopmentStage(const Record &R) {
if (BitsInit *BI = R.getValueAsBitsInit("DevelopmentStage")) {
switch(getValueFromBitsInit(BI, R)) {
case 0:
return "alpha";
case 1:
return "released";
}
}
PrintFatalError(R.getLoc(),
"unable to parse command line option type for "
+ getCheckerFullName(&R));
return "";
}
static bool isHidden(const Record *R) {
if (R->getValueAsBit("Hidden"))
return true;
@ -149,6 +165,8 @@ static void printOption(llvm::raw_ostream &OS, StringRef FullName,
OS.write_escaped(getStringValue(R, "Desc")) << "\", ";
OS << '\"';
OS.write_escaped(getStringValue(R, "DefaultVal")) << "\", ";
OS << '\"';
OS << getDevelopmentStage(R) << "\", ";
if (!R.getValueAsBit("Hidden"))
OS << "false";