15#ifndef LLVM_CLANG_LIB_SEMA_SEMALIFETIMESAFETY_H
16#define LLVM_CLANG_LIB_SEMA_SEMALIFETIMESAFETY_H
51 constexpr unsigned DiagIDs[] = {
52 diag::warn_lifetime_safety_use_after_scope,
53 diag::warn_lifetime_safety_use_after_scope_moved,
54 diag::warn_lifetime_safety_use_after_free,
55 diag::warn_lifetime_safety_return_stack_addr,
56 diag::warn_lifetime_safety_return_stack_addr_moved,
57 diag::warn_lifetime_safety_invalidation,
58 diag::warn_lifetime_safety_dangling_field,
59 diag::warn_lifetime_safety_dangling_field_moved,
60 diag::warn_lifetime_safety_dangling_global,
61 diag::warn_lifetime_safety_dangling_global_moved,
62 diag::warn_lifetime_safety_noescape_escapes,
63 diag::warn_lifetime_safety_lifetimebound_violation,
64 diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound,
65 diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound,
66 diag::warn_lifetime_safety_invalidated_field,
67 diag::warn_lifetime_safety_invalidated_global,
68 diag::warn_lifetime_safety_cross_tu_param_suggestion,
69 diag::warn_lifetime_safety_intra_tu_param_suggestion,
70 diag::warn_lifetime_safety_cross_tu_this_suggestion,
71 diag::warn_lifetime_safety_intra_tu_this_suggestion,
72 diag::warn_lifetime_safety_inapplicable_lifetimebound};
73 for (
unsigned DiagID : DiagIDs)
81 constexpr unsigned DiagIDs[] = {
82 diag::warn_lifetime_safety_intra_tu_param_suggestion,
83 diag::warn_lifetime_safety_cross_tu_param_suggestion,
84 diag::warn_lifetime_safety_intra_tu_this_suggestion,
85 diag::warn_lifetime_safety_cross_tu_this_suggestion};
86 for (
unsigned DiagID : DiagIDs)
107 unsigned DiagID = MovedExpr
108 ? diag::warn_lifetime_safety_use_after_scope_moved
109 : diag::warn_lifetime_safety_use_after_scope;
110 std::string DestroyedSubject = getDiagSubjectDescription(IssueExpr);
115 S.Diag(MovedExpr->
getExprLoc(), diag::note_lifetime_safety_moved_here)
117 S.Diag(FreeLoc, diag::note_lifetime_safety_destroyed_here)
120 reportAliasingChain(ExprChain);
122 S.Diag(UseExpr->
getExprLoc(), diag::note_lifetime_safety_used_here)
127 const Expr *MovedExpr)
override {
128 unsigned DiagID = MovedExpr
129 ? diag::warn_lifetime_safety_return_stack_addr_moved
130 : diag::warn_lifetime_safety_return_stack_addr;
133 << getDiagSubjectDescription(IssueExpr) << IssueExpr->
getSourceRange();
136 S.Diag(MovedExpr->
getExprLoc(), diag::note_lifetime_safety_moved_here)
138 S.Diag(ReturnExpr->
getExprLoc(), diag::note_lifetime_safety_returned_here)
144 const Expr *MovedExpr,
146 unsigned DiagID = MovedExpr
147 ? diag::warn_lifetime_safety_dangling_field_moved
148 : diag::warn_lifetime_safety_dangling_field;
151 << getDiagSubjectDescription(IssueExpr)
152 << getDiagSubjectDescription(DanglingField)
155 S.Diag(MovedExpr->
getExprLoc(), diag::note_lifetime_safety_moved_here)
158 diag::note_lifetime_safety_dangling_field_here)
164 const Expr *MovedExpr,
166 unsigned DiagID = MovedExpr
167 ? diag::warn_lifetime_safety_dangling_global_moved
168 : diag::warn_lifetime_safety_dangling_global;
171 << getDiagSubjectDescription(IssueExpr)
172 << getDiagSubjectDescription(DanglingGlobal)
175 S.Diag(MovedExpr->
getExprLoc(), diag::note_lifetime_safety_moved_here)
179 diag::note_lifetime_safety_dangling_static_here)
183 diag::note_lifetime_safety_dangling_global_here)
188 const Expr *InvalidationExpr)
override {
190 ? diag::warn_lifetime_safety_use_after_free
191 : diag::warn_lifetime_safety_invalidation;
192 std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
195 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
196 S.Diag(UseExpr->
getExprLoc(), diag::note_lifetime_safety_used_here)
200 const Expr *InvalidationExpr)
override {
203 ? diag::warn_lifetime_safety_use_after_free
204 : diag::warn_lifetime_safety_invalidation;
205 std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
209 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
210 S.Diag(UseExpr->
getExprLoc(), diag::note_lifetime_safety_used_here)
216 const Expr *InvalidationExpr)
override {
217 std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
219 diag::warn_lifetime_safety_invalidated_field)
220 << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
222 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
224 diag::note_lifetime_safety_dangling_field_here)
230 const Expr *InvalidationExpr)
override {
231 std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
233 diag::warn_lifetime_safety_invalidated_field)
234 << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
236 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
238 diag::note_lifetime_safety_dangling_field_here)
244 const Expr *InvalidationExpr)
override {
245 std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
247 diag::warn_lifetime_safety_invalidated_global)
248 << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
250 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
253 diag::note_lifetime_safety_dangling_static_here)
257 diag::note_lifetime_safety_dangling_global_here)
263 const Expr *InvalidationExpr)
override {
264 std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
266 diag::warn_lifetime_safety_invalidated_global)
267 << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
269 reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
272 diag::note_lifetime_safety_dangling_static_here)
276 diag::note_lifetime_safety_dangling_global_here)
285 ? diag::warn_lifetime_safety_cross_tu_param_suggestion
286 : diag::warn_lifetime_safety_intra_tu_param_suggestion;
288 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(ParmToAnnotate);
294 if (
const auto *EscapeExpr =
Target.dyn_cast<
const Expr *>())
295 S.Diag(EscapeExpr->getBeginLoc(),
296 diag::note_lifetime_safety_suggestion_returned_here)
297 << EscapeExpr->getSourceRange();
298 else if (
const auto *EscapeField =
Target.dyn_cast<
const FieldDecl *>())
299 S.Diag(EscapeField->getLocation(),
300 diag::note_lifetime_safety_escapes_to_field_here)
301 << EscapeField->getSourceRange();
305 const ParmVarDecl *ParmWithLifetimebound)
override {
306 const auto *
Attr = ParmWithLifetimebound->
getAttr<LifetimeBoundAttr>();
307 StringRef ParamName = ParmWithLifetimebound->
getName();
308 bool HasName = ParamName.size() > 0;
310 diag::warn_lifetime_safety_lifetimebound_violation)
318 assert(
Attr &&
"Expected lifetimebound attribute");
320 diag::warn_lifetime_safety_lifetimebound_violation)
328 assert(
Attr &&
"Expected lifetimebound attribute");
331 ? diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound
332 : diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound;
334 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(FDecl);
340 if (IsMacro || InsertionPoint.isInvalid())
343 S.Diag(InsertionPoint, DiagID)
346 S.Diag(
Attr->
getLocation(), diag::note_lifetime_safety_lifetimebound_here)
354 const auto *
Attr = PVDDef->
getAttr<LifetimeBoundAttr>();
355 assert(
Attr &&
"Expected lifetimebound attribute");
358 ? diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound
359 : diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound;
361 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(PVDDecl);
367 if (IsMacro || InsertionPoint.isInvalid())
374 S.Diag(
Attr->
getLocation(), diag::note_lifetime_safety_lifetimebound_here)
379 assert(PVD->
hasAttr<LifetimeBoundAttr>() &&
380 "Expected parameter to have lifetimebound attribute");
381 const auto *
Attr = PVD->
getAttr<LifetimeBoundAttr>();
383 diag::warn_lifetime_safety_inapplicable_lifetimebound)
389 const Expr *EscapeExpr)
override {
391 ? diag::warn_lifetime_safety_cross_tu_this_suggestion
392 : diag::warn_lifetime_safety_intra_tu_this_suggestion;
394 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(MD);
396 S.Diag(InsertionPoint, DiagID)
401 diag::note_lifetime_safety_suggestion_returned_here)
406 const Expr *EscapeExpr)
override {
408 diag::warn_lifetime_safety_noescape_escapes)
412 diag::note_lifetime_safety_suggestion_returned_here)
419 diag::warn_lifetime_safety_noescape_escapes)
423 diag::note_lifetime_safety_escapes_to_field_here)
428 const VarDecl *EscapeGlobal)
override {
430 diag::warn_lifetime_safety_noescape_escapes)
434 diag::note_lifetime_safety_escapes_to_static_storage_here)
438 diag::note_lifetime_safety_escapes_to_global_here)
443 S.addLifetimeBoundToImplicitThis(
const_cast<CXXMethodDecl *
>(MD));
447 struct LifetimeBoundMacroCache {
448 bool IsBuilt =
false;
452 void buildLifetimeBoundMacroCache(LifetimeBoundMacroCache &
Cache,
459 for (
const auto &M : PP.
macros()) {
468 const MacroInfo *MI = Def.getMacroInfo();
470 std::equal(Tokens.begin(), Tokens.end(), MI->
tokens_begin())) {
471 Cache.Candidates.push_back(II);
476 Cache.IsBuilt =
true;
479 StringRef getLastCachedMacroWithSpelling(SourceLocation Loc,
480 llvm::ArrayRef<TokenValue> Tokens,
481 LifetimeBoundMacroCache &
Cache) {
485 buildLifetimeBoundMacroCache(
Cache, Tokens);
487 const Preprocessor &PP = S.getPreprocessor();
489 SourceLocation BestLocation;
490 StringRef BestSpelling;
491 for (
const IdentifierInfo *II :
Cache.Candidates) {
492 const MacroDirective *MD = PP.getLocalMacroDirectiveHistory(II);
494 if (!Def || !Def.getMacroInfo())
498 const MacroInfo *MI = Def.getMacroInfo();
499 if (!MI->isObjectLike() || Tokens.size() != MI->getNumTokens() ||
500 !std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin()))
504 SourceLocation Location = Def.getLocation();
505 assert(Location.isInvalid() ||
506 SM.isBeforeInTranslationUnit(Location, Loc));
507 if (BestLocation.isInvalid() ||
508 (Location.isValid() &&
509 SM.isBeforeInTranslationUnit(BestLocation, Location))) {
510 BestLocation = Location;
511 BestSpelling = II->getName();
517 void reportInvalidationSite(
const Expr *InvalidationExpr,
518 StringRef InvalidatedSubject) {
520 ? diag::note_lifetime_safety_freed_here
521 : diag::note_lifetime_safety_invalidated_here;
522 S.Diag(InvalidationExpr->getExprLoc(),
Diag)
523 << InvalidatedSubject << InvalidationExpr->getSourceRange();
526 std::string getLifetimeBoundFixItText(SourceLocation Loc,
bool LeadingSpace,
527 bool AllowGNUAttrMacro =
true) {
528 StringRef Spelling = S.getLangOpts().LifetimeSafetyLifetimeBoundMacro;
529 if (Spelling.empty() && Loc.isValid()) {
530 const Preprocessor &PP = S.getPreprocessor();
531 Spelling = getLastCachedMacroWithSpelling(
533 {tok::l_square, tok::l_square, PP.getIdentifierInfo(
"clang"),
534 tok::coloncolon, PP.getIdentifierInfo(
"lifetimebound"),
535 tok::r_square, tok::r_square},
536 ClangLifetimeBoundMacroCache);
538 if (Spelling.empty() && AllowGNUAttrMacro)
539 Spelling = getLastCachedMacroWithSpelling(
541 {tok::kw___attribute, tok::l_paren, tok::l_paren,
542 PP.getIdentifierInfo(
"lifetimebound"), tok::r_paren, tok::r_paren},
543 GNULifetimeBoundMacroCache);
545 const std::string
Text =
546 Spelling.empty() ?
"[[clang::lifetimebound]]" : Spelling.str();
547 return LeadingSpace ?
" " +
Text :
Text +
" ";
550 std::pair<SourceLocation, std::string>
551 getLifetimeBoundFixIt(
const ParmVarDecl *Decl) {
553 Decl->getEndLoc(), 0, S.getSourceManager(), S.getLangOpts());
554 bool LeadingSpace =
true;
556 if (!
Decl->getIdentifier()) {
559 InsertionPoint =
Decl->getBeginLoc();
560 LeadingSpace =
false;
561 }
else if (
Decl->hasDefaultArg()) {
565 Decl->getLocation(), 0, S.getSourceManager(), S.getLangOpts());
567 return {InsertionPoint,
568 getLifetimeBoundFixItText(InsertionPoint, LeadingSpace)};
571 std::pair<SourceLocation, std::string>
572 getLifetimeBoundFixIt(
const CXXMethodDecl *MD) {
573 const auto MDL = MD->getTypeSourceInfo()->getTypeLoc();
575 MDL.getEndLoc(), 0, S.getSourceManager(), S.getLangOpts());
577 if (
const auto *FPT = MD->getType()->getAs<FunctionProtoType>();
578 FPT && FPT->hasTrailingReturn()) {
583 const auto FTL = MDL.getAs<FunctionTypeLoc>();
590 0, S.getSourceManager(), S.getLangOpts());
592 return {InsertionPoint,
593 getLifetimeBoundFixItText(InsertionPoint,
true,
597 std::string getDiagSubjectDescription(
const ValueDecl *VD) {
599 llvm::raw_string_ostream
OS(Res);
604 }
else if (
const auto *Var = dyn_cast<VarDecl>(VD)) {
605 if (Var->isStaticLocal() || Var->isStaticDataMember())
606 OS <<
"static variable";
607 else if (Var->hasGlobalStorage())
608 OS <<
"global variable";
610 OS <<
"local variable";
615 VD->getNameForDiagnostic(OS, S.getPrintingPolicy(),
false);
620 std::string getDiagSubjectDescription(
const Expr *E) {
621 E = E->IgnoreImpCasts();
623 return "temporary object";
625 return "allocated object";
626 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
627 return getDiagSubjectDescription(DRE->getDecl());
629 if (
const auto *CE = dyn_cast<CallExpr>(E)) {
630 const auto *FD = CE->getDirectCallee();
632 return "result of call";
636 llvm::raw_string_ostream
OS(Name);
637 FD->getNameForDiagnostic(OS, S.getPrintingPolicy(),
639 return "result of call to '" + Name +
"'";
646 bool shouldShowInAliasChain(
const Expr *CurrExpr,
const Expr *LastExpr) {
647 CurrExpr = CurrExpr->IgnoreImpCasts();
648 LastExpr = LastExpr->IgnoreImpCasts();
655 return CurrExpr->getSourceRange() != LastExpr->getSourceRange();
658 void reportAliasingChain(llvm::ArrayRef<const Expr *> OriginExprChain) {
659 if (OriginExprChain.empty())
662 const Expr *LastExpr = OriginExprChain.back();
663 std::string IssueStr = getDiagSubjectDescription(LastExpr);
665 for (
const Expr *CurrExpr : reverse(OriginExprChain.drop_back())) {
666 if (!shouldShowInAliasChain(CurrExpr, LastExpr))
668 S.Diag(CurrExpr->getBeginLoc(),
669 diag::note_lifetime_safety_aliases_storage)
670 << CurrExpr->getSourceRange() << getDiagSubjectDescription(CurrExpr)
676 LifetimeBoundMacroCache ClangLifetimeBoundMacroCache;
677 LifetimeBoundMacroCache GNULifetimeBoundMacroCache;
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::Preprocessor interface.
Attr - This represents one attribute.
SourceLocation getLocation() const
SourceRange getRange() const
Represents a static or instance method of a struct/union/class.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
DeclarationNameInfo getNameInfo() const
One of these records is kept for each identifier that is lexed.
static std::optional< Token > findPreviousToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments)
Finds the token that comes before the given location.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
DefInfo getPreviousDefinition()
Encapsulates changes to the "macros namespace" (the location where the macro name became active,...
const DefInfo findDirectiveAtLoc(SourceLocation L, const SourceManager &SM) const
Find macro definition active in the specified source location.
DefInfo getDefinition()
Traverses the macro directives history and returns the next macro definition directive along with inf...
Encapsulates the data about a macro definition (e.g.
const_tokens_iterator tokens_begin() const
unsigned getNumTokens() const
Return the number of tokens that this macro expands to.
bool isObjectLike() const
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Represents a parameter to a function.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
MacroDirective * getLocalMacroDirectiveHistory(const IdentifierInfo *II) const
Given an identifier, return the latest non-imported macro directive for that identifier.
llvm::iterator_range< macro_iterator > macros(bool IncludeExternalMacros=true) const
SourceManager & getSourceManager() const
Scope - A scope is a transient data structure that is used while parsing the program.
Sema - This implements semantic analysis and AST building for C.
Preprocessor & getPreprocessor() const
DiagnosticsEngine & getDiagnostics() const
const LangOptions & getLangOpts() const
Encodes a location in the source.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a variable declaration or definition.
bool isStaticDataMember() const
Determines whether this is a static data member.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr, const Expr *MovedExpr) override
void reportMisplacedLifetimebound(WarningScope Scope, const ParmVarDecl *PVDDef, const ParmVarDecl *PVDDecl) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const Expr *EscapeExpr) override
void reportUseAfterInvalidation(const ParmVarDecl *PVD, const Expr *UseExpr, const Expr *InvalidationExpr) override
void reportInvalidatedField(const ParmVarDecl *PVD, const FieldDecl *DanglingField, const Expr *InvalidationExpr) override
void reportLifetimeboundViolation(const CXXMethodDecl *MDWithLifetimebound) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const VarDecl *EscapeGlobal) override
void suggestLifetimeboundToImplicitThis(WarningScope Scope, const CXXMethodDecl *MD, const Expr *EscapeExpr) override
void reportInvalidatedGlobal(const ParmVarDecl *PVD, const VarDecl *DanglingGlobal, const Expr *InvalidationExpr) override
LifetimeSafetySemaHelperImpl(Sema &S)
void suggestLifetimeboundToParmVar(WarningScope Scope, const ParmVarDecl *ParmToAnnotate, EscapingTarget Target) override
void reportDanglingGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal, const Expr *MovedExpr, SourceLocation ExpiryLoc) override
void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr, const Expr *MovedExpr, SourceLocation FreeLoc, llvm::ArrayRef< const Expr * > ExprChain) override
void reportInvalidatedField(const Expr *IssueExpr, const FieldDecl *DanglingField, const Expr *InvalidationExpr) override
void reportInapplicableLifetimebound(const ParmVarDecl *PVD) override
void reportDanglingField(const Expr *IssueExpr, const FieldDecl *DanglingField, const Expr *MovedExpr, SourceLocation ExpiryLoc) override
void addLifetimeBoundToImplicitThis(const CXXMethodDecl *MD) override
void reportUseAfterInvalidation(const Expr *IssueExpr, const Expr *UseExpr, const Expr *InvalidationExpr) override
void reportMisplacedLifetimebound(WarningScope Scope, const CXXMethodDecl *FDef, const CXXMethodDecl *FDecl) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const FieldDecl *EscapeField) override
void reportInvalidatedGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal, const Expr *InvalidationExpr) override
void reportLifetimeboundViolation(const ParmVarDecl *ParmWithLifetimebound) override
llvm::PointerUnion< const Expr *, const FieldDecl *, const VarDecl * > EscapingTarget
LifetimeSafetySemaHelper()=default
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
const LifetimeBoundAttr * getDirectImplicitObjectLifetimeBoundAttr(const FunctionDecl *FD)
LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D)
WarningScope
Enum to track functions visible across or within TU.
const LifetimeBoundAttr * getImplicitObjectParamLifetimeBoundAttr(const FunctionDecl *FD)
bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D)
bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D)
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
bool isa(CodeGen::Address addr)
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
bool SuggestAnnotations
Whether to suggest lifetime annotations.
size_t MaxCFGBlocks
Maximum number of CFG blocks to analyze.