;
39structLocalizedState {
41 enum Kind{ NonLocalized, Localized } K;
42LocalizedState(Kind InK) : K(InK) {}
45 boolisLocalized()
const{
returnK == Localized; }
46 boolisNonLocalized()
const{
returnK == NonLocalized; }
48 staticLocalizedState getLocalized() {
returnLocalizedState(Localized); }
49 staticLocalizedState getNonLocalized() {
50 returnLocalizedState(NonLocalized);
54 bool operator==(
constLocalizedState &
X)
const{
returnK ==
X.K; }
57 voidProfile(llvm::FoldingSetNodeID &ID)
const{
ID.AddInteger(K); }
60classNonLocalizedStringChecker
61:
public Checker<check::PreCall, check::PostCall, check::PreObjCMessage,
62check::PostObjCMessage,
63check::PostStmt<ObjCStringLiteral>> {
65 const BugTypeBT{
this,
"Unlocalizable string",
66 "Localizability Issue (Apple)"};
70llvm::DenseMap<Selector, uint8_t>> UIMethods;
72 mutablellvm::SmallSet<std::pair<const IdentifierInfo *, Selector>, 12> LSM;
74 mutablellvm::SmallSet<const IdentifierInfo *, 5> LSF;
77 voidinitLocStringsMethods(
ASTContext&Ctx)
const;
84 boolisAnnotatedAsReturningLocalized(
const Decl*
D)
const;
85 boolisAnnotatedAsTakingLocalized(
const Decl*
D)
const;
87 intargumentNumber = 0)
const;
89 intgetLocalizedArgumentForSelector(
const IdentifierInfo*Receiver,
96 boolIsAggressive =
false;
117NonLocalizedStringBRVisitor(
const MemRegion*NonLocalizedString)
118: NonLocalizedString(NonLocalizedString), Satisfied(
false) {
119assert(NonLocalizedString);
126 void Profile(llvm::FoldingSetNodeID &
ID)
const override{
127 ID.Add(NonLocalizedString);
132#define NEW_RECEIVER(receiver) \ 133 llvm::DenseMap<Selector, uint8_t> &receiver##M = \ 134 UIMethods[&Ctx.Idents.get(#receiver)]; 135#define ADD_NULLARY_METHOD(receiver, method, argument) \ 136 receiver##M.insert( \ 137 {Ctx.Selectors.getNullarySelector(&Ctx.Idents.get(#method)), argument}); 138#define ADD_UNARY_METHOD(receiver, method, argument) \ 139 receiver##M.insert( \ 140 {Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(#method)), argument}); 141#define ADD_METHOD(receiver, method_list, count, argument) \ 142 receiver##M.insert({Ctx.Selectors.getSelector(count, method_list), argument}); 146voidNonLocalizedStringChecker::initUIMethods(
ASTContext&Ctx)
const{
147 if(!UIMethods.empty())
158 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemTag, 3, 0)
162 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemImage, 3, 0)
172 const IdentifierInfo*rowActionWithStyleUITableViewRowAction[] = {
175 ADD_METHOD(UITableViewRowAction, rowActionWithStyleUITableViewRowAction, 3, 1)
187 ADD_METHOD(NSButton, radioButtonWithTitleNSButton, 3, 0)
191 ADD_METHOD(NSButton, buttonWithTitleNSButtonImage, 4, 0)
195 ADD_METHOD(NSButton, checkboxWithTitleNSButton, 3, 0)
199 ADD_METHOD(NSButton, buttonWithTitleNSButtonTarget, 3, 0)
218 ADD_METHOD(NSBrowser, setTitleNSBrowser, 2, 0)
229 ADD_METHOD(UIAlertAction, actionWithTitleUIAlertAction, 3, 0)
235 ADD_METHOD(NSPopUpButton, insertItemWithTitleNSPopUpButton, 2, 0)
241 const IdentifierInfo*rowActionWithStyleNSTableViewRowAction[] = {
244 ADD_METHOD(NSTableViewRowAction, rowActionWithStyleNSTableViewRowAction, 3, 1)
276 ADD_METHOD(NSSegmentedControl, setLabelNSSegmentedControl, 2, 0)
279 ADD_METHOD(NSSegmentedControl, setToolTipNSSegmentedControl, 2, 0)
304 ADD_METHOD(NSMatrix, setToolTipNSMatrix, 2, 0)
320 ADD_METHOD(UIMenuItem, initWithTitleUIMenuItem, 2, 0)
324 const IdentifierInfo*alertControllerWithTitleUIAlertController[] = {
326&Ctx.
Idents.
get(
"preferredStyle")};
327 ADD_METHOD(UIAlertController, alertControllerWithTitleUIAlertController, 3, 1)
332 const IdentifierInfo*initWithTypeUIApplicationShortcutItemIcon[] = {
337initWithTypeUIApplicationShortcutItemIcon, 5, 1)
340 ADD_METHOD(UIApplicationShortcutItem, initWithTypeUIApplicationShortcutItem,
346&Ctx.
Idents.
get(
"cancelButtonTitle"),
347&Ctx.
Idents.
get(
"destructiveButtonTitle"),
348&Ctx.
Idents.
get(
"otherButtonTitles")};
349 ADD_METHOD(UIActionSheet, initWithTitleUIActionSheet, 5, 0)
354 const IdentifierInfo*initWithNameUIAccessibilityCustomAction[] = {
358initWithNameUIAccessibilityCustomAction, 3, 0)
385 ADD_METHOD(NSAttributedString, initWithStringNSAttributedString, 2, 0)
394 ADD_METHOD(UIKeyCommand, keyCommandWithInputUIKeyCommand, 4, 3)
402&Ctx.
Idents.
get(
"alertWithMessageText"), &Ctx.
Idents.
get(
"defaultButton"),
404&Ctx.
Idents.
get(
"informativeTextWithFormat")};
405 ADD_METHOD(NSAlert, alertWithMessageTextNSAlert, 5, 0)
413 ADD_UNARY_METHOD(UIMutableApplicationShortcutItem, setLocalizedSubtitle, 0)
424 ADD_METHOD(NSWindow, minFrameWidthWithTitleNSWindow, 2, 0)
431 const IdentifierInfo*addOptionWithTitleUIDocumentMenuViewController[] = {
435addOptionWithTitleUIDocumentMenuViewController, 4, 0)
446&Ctx.
Idents.
get(
"otherButtonTitles")};
447 ADD_METHOD(UIAlertView, initWithTitleUIAlertView, 5, 0)
477 ADD_METHOD(NSSegmentedCell, setLabelNSSegmentedCell, 2, 0)
480 ADD_METHOD(NSSegmentedCell, setToolTipNSSegmentedCell, 2, 0)
491 ADD_METHOD(NSMenuItem, initWithTitleNSMenuItem, 3, 0)
498 ADD_METHOD(NSPopUpButtonCell, initTextCellNSPopUpButtonCell, 2, 0)
502 ADD_METHOD(NSPopUpButtonCell, insertItemWithTitleNSPopUpButtonCell, 2, 0)
515 ADD_METHOD(NSMenu, insertItemWithTitleNSMenu, 4, 0)
519 ADD_METHOD(NSMenu, addItemWithTitleNSMenu, 3, 0)
535 const IdentifierInfo*actionWithIdentifierNSUserNotificationAction[] = {
538actionWithIdentifierNSUserNotificationAction, 2, 1)
548 ADD_METHOD(UIBarButtonItem, initWithTitleUIBarButtonItem, 4, 0)
554 const IdentifierInfo*insertSegmentWithTitleUISegmentedControl[] = {
557 ADD_METHOD(UISegmentedControl, insertSegmentWithTitleUISegmentedControl, 3, 0)
560 ADD_METHOD(UISegmentedControl, setTitleUISegmentedControl, 2, 0)
564*initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult[] = {
565&Ctx.
Idents.
get(
"initWithItemLoadingToken"),
567 ADD_METHOD(NSAccessibilityCustomRotorItemResult,
568initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult, 2, 1)
572 const IdentifierInfo*contextualActionWithStyleUIContextualAction[] = {
575 ADD_METHOD(UIContextualAction, contextualActionWithStyleUIContextualAction, 3,
580 const IdentifierInfo*initWithLabelNSAccessibilityCustomRotor[] = {
583initWithLabelNSAccessibilityCustomRotor, 2, 0)
591 const IdentifierInfo*initWithNameNSAccessibilityCustomAction[] = {
594initWithNameNSAccessibilityCustomAction, 2, 0)
595 const IdentifierInfo*initWithNameTargetNSAccessibilityCustomAction[] = {
599initWithNameTargetNSAccessibilityCustomAction, 3, 0)
603#define LSF_INSERT(function_name) LSF.insert(&Ctx.Idents.get(function_name)); 604#define LSM_INSERT_NULLARY(receiver, method_name) \ 605 LSM.insert({&Ctx.Idents.get(receiver), Ctx.Selectors.getNullarySelector( \ 606 &Ctx.Idents.get(method_name))}); 607#define LSM_INSERT_UNARY(receiver, method_name) \ 608 LSM.insert({&Ctx.Idents.get(receiver), \ 609 Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(method_name))}); 610#define LSM_INSERT_SELECTOR(receiver, method_list, arguments) \ 611 LSM.insert({&Ctx.Idents.get(receiver), \ 612 Ctx.Selectors.getSelector(arguments, method_list)}); 615voidNonLocalizedStringChecker::initLocStringsMethods(
ASTContext&Ctx)
const{
633 LSF_INSERT(
"CFDateFormatterCreateStringWithDate");
634 LSF_INSERT(
"CFDateFormatterCreateStringWithAbsoluteTime");
635 LSF_INSERT(
"CFNumberFormatterCreateStringWithNumber");
640boolNonLocalizedStringChecker::isAnnotatedAsReturningLocalized(
641 const Decl*
D)
const{
647return Ann->getAnnotation() ==
"returns_localized_nsstring";
653boolNonLocalizedStringChecker::isAnnotatedAsTakingLocalized(
654 const Decl*
D)
const{
660return Ann->getAnnotation() ==
"takes_localized_nsstring";
665boolNonLocalizedStringChecker::hasLocalizedState(
SValS,
669 constLocalizedState *LS =
C.getState()->get<LocalizedMemMap>(mt);
670 if(LS && LS->isLocalized())
678boolNonLocalizedStringChecker::hasNonLocalizedState(
SValS,
682 constLocalizedState *LS =
C.getState()->get<LocalizedMemMap>(mt);
683 if(LS && LS->isNonLocalized())
690voidNonLocalizedStringChecker::setLocalizedState(
const SValS,
695 C.getState()->set<LocalizedMemMap>(mt, LocalizedState::getLocalized());
696 C.addTransition(State);
701voidNonLocalizedStringChecker::setNonLocalizedState(
const SValS,
706mt, LocalizedState::getNonLocalized());
707 C.addTransition(State);
713 returnStringRef(name).contains_insensitive(
"debug");
721 const Decl*
D=
C.getCurrentAnalysisDeclContext()->getDecl();
725 if(
auto*ND = dyn_cast<NamedDecl>(
D)) {
732 if(
auto*CD = dyn_cast<ObjCContainerDecl>(DC)) {
742voidNonLocalizedStringChecker::reportLocalizationError(
751 "UnlocalizedString");
752 ExplodedNode*ErrNode =
C.addTransition(
C.getState(),
C.getPredecessor(), &Tag);
758 autoR = std::make_unique<PathSensitiveBugReport>(
759BT,
"User-facing text should use localized string macro", ErrNode);
760 if(argumentNumber) {
765R->markInteresting(S);
769R->addVisitor(std::make_unique<NonLocalizedStringBRVisitor>(
StringRegion));
771 C.emitReport(std::move(R));
776intNonLocalizedStringChecker::getLocalizedArgumentForSelector(
778 automethod = UIMethods.find(Receiver);
780 if(method == UIMethods.end())
783 autoargumentIterator = method->getSecond().find(S);
785 if(argumentIterator == method->getSecond().end())
788 intargumentNumber = argumentIterator->getSecond();
789 returnargumentNumber;
793voidNonLocalizedStringChecker::checkPreObjCMessage(
const ObjCMethodCall&msg,
795initUIMethods(
C.getASTContext());
804std::string SelectorString = S.getAsString();
805StringRef SelectorName = SelectorString;
806assert(!SelectorName.empty());
808 if(odInfo->
isStr(
"NSString")) {
812 if(!(SelectorName.starts_with(
"drawAtPoint") ||
813SelectorName.starts_with(
"drawInRect") ||
814SelectorName.starts_with(
"drawWithRect")))
819 boolisNonLocalized = hasNonLocalizedState(svTitle,
C);
821 if(isNonLocalized) {
822reportLocalizationError(svTitle, msg,
C);
826 intargumentNumber = getLocalizedArgumentForSelector(odInfo, S);
828 while(argumentNumber < 0 && OD->getSuperClass() !=
nullptr) {
830argumentNumber = getLocalizedArgumentForSelector(
P->getIdentifier(), S);
831 if(argumentNumber >= 0)
834 if(argumentNumber < 0) {
836argumentNumber = getLocalizedArgumentForSelector(OD->
getIdentifier(), S);
840 if(argumentNumber < 0) {
842 if(
const ObjCMethodDecl*OMD = dyn_cast_or_null<ObjCMethodDecl>(
D)) {
843 for(
auto[Idx, FormalParam] : llvm::enumerate(OMD->parameters())) {
844 if(isAnnotatedAsTakingLocalized(FormalParam)) {
845argumentNumber = Idx;
853 if(argumentNumber < 0)
859dyn_cast_or_null<ObjCStringRegion>(svTitle.
getAsRegion())) {
860StringRef stringValue =
861SR->getObjCStringLiteral()->getString()->getString();
862 if((stringValue.trim().size() == 0 && stringValue.size() > 0) ||
865 if(!IsAggressive && llvm::sys::unicode::columnWidthUTF8(stringValue) < 2)
869 boolisNonLocalized = hasNonLocalizedState(svTitle,
C);
871 if(isNonLocalized) {
872reportLocalizationError(svTitle, msg,
C, argumentNumber + 1);
876voidNonLocalizedStringChecker::checkPreCall(
const CallEvent&
Call,
878 const auto*FD = dyn_cast_or_null<FunctionDecl>(
Call.getDecl());
882 autoformals = FD->parameters();
883 for(
unsignedi = 0, ei = std::min(
static_cast<unsigned>(formals.size()),
884 Call.getNumArgs()); i != ei; ++i) {
885 if(isAnnotatedAsTakingLocalized(formals[i])) {
886 autoactual =
Call.getArgSVal(i);
887 if(hasNonLocalizedState(actual,
C)) {
888reportLocalizationError(actual,
Call,
C, i + 1);
907 returnClsName == &Ctx.
Idents.
get(
"NSString") ||
908ClsName == &Ctx.
Idents.
get(
"NSMutableString");
916voidNonLocalizedStringChecker::checkPostCall(
const CallEvent&
Call,
918initLocStringsMethods(
C.getASTContext());
920 if(!
Call.getOriginExpr())
928 for(
unsignedi = 0; i <
Call.getNumArgs(); ++i) {
929 SValargValue =
Call.getArgSVal(i);
930 if(hasLocalizedState(argValue,
C)) {
932setLocalizedState(sv,
C);
945 if(isAnnotatedAsReturningLocalized(
D) || LSF.contains(
Identifier)) {
946setLocalizedState(sv,
C);
948!hasLocalizedState(sv,
C)) {
950setNonLocalizedState(sv,
C);
953dyn_cast_or_null<SymbolicRegion>(sv.
getAsRegion());
955setNonLocalizedState(sv,
C);
962voidNonLocalizedStringChecker::checkPostObjCMessage(
const ObjCMethodCall&msg,
964initLocStringsMethods(
C.getASTContext());
975std::string SelectorName = S.getAsString();
977std::pair<const IdentifierInfo *, Selector> MethodDescription = {odInfo, S};
979 if(LSM.count(MethodDescription) ||
980isAnnotatedAsReturningLocalized(msg.
getDecl())) {
982setLocalizedState(sv,
C);
989 SValsv =
C.getSVal(SL);
990setNonLocalizedState(sv,
C);
994NonLocalizedStringBRVisitor::VisitNode(
const ExplodedNode*Succ,
1004 auto*LiteralExpr = dyn_cast<ObjCStringLiteral>(Point->getStmt());
1009 if(LiteralSVal.
getAsRegion() != NonLocalizedString)
1020 autoPiece = std::make_shared<PathDiagnosticEventPiece>(
1021L,
"Non-localized string literal here");
1022Piece->addRange(LiteralExpr->getSourceRange());
1024 returnstd::move(Piece);
1028classEmptyLocalizationContextChecker
1029:
public Checker<check::ASTDecl<ObjCImplementationDecl>> {
1043: MD(InMD), BR(InBR), Mgr(InMgr),
Checker(
Checker), DCtx(InDCtx) {}
1045 voidVisitStmt(
const Stmt*S) { VisitChildren(S); }
1051 voidVisitChildren(
const Stmt*S) {
1052 for(
const Stmt*Child : S->children()) {
1065voidEmptyLocalizationContextChecker::checkASTDecl(
1072 const Stmt*Body = M->getBody();
1074assert(M->isSynthesizedAccessorStub());
1078MethodCrawler MC(M->getCanonicalDecl(), BR,
this, Mgr, DCtx);
1098voidEmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
1109 if(!(odInfo->
isStr(
"NSBundle") &&
1111 "localizedStringForKey:value:table:")) {
1124std::pair<FileID, unsigned> SLInfo =
1137std::optional<llvm::MemoryBufferRef> BF =
1142 LexerTheLexer(SL, LangOpts, BF->getBufferStart(),
1143BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());
1148 while(!TheLexer.LexFromRawLexer(I)) {
1149 if(I.
getKind() == tok::l_paren)
1151 if(I.
getKind() == tok::r_paren) {
1160 if(Result.getRawIdentifier() ==
"nil") {
1161reportEmptyContextError(ME);
1170StringRef(Result.getLiteralData(), Result.getLength()).trim(
'"');
1172 if((Comment.trim().size() == 0 && Comment.size() > 0) ||
1174reportEmptyContextError(ME);
1178voidEmptyLocalizationContextChecker::MethodCrawler::reportEmptyContextError(
1182 "Localizability Issue (Apple)",
1183 "Localized string macro should include a non-empty " 1184 "comment for translators",
1189classPluralMisuseChecker :
public Checker<check::ASTCodeBody> {
1203 boolInMatchingStatement =
false;
1210 boolVisitIfStmt(
IfStmt*I)
override;
1211 boolEndVisitIfStmt(
IfStmt*I);
1212 boolTraverseIfStmt(
IfStmt*x)
override;
1215 boolVisitCallExpr(
CallExpr*CE)
override;
1219 voidreportPluralMisuseError(
const Stmt*S)
const;
1220 boolisCheckingPlurality(
const Expr*
E)
const;
1227Visitor.TraverseDecl(
const_cast<Decl*
>(
D));
1236boolPluralMisuseChecker::MethodCrawler::isCheckingPlurality(
1241 if(
const VarDecl*VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1242 const Expr*InitExpr = VD->getInit();
1249 if(VD->getName().contains_insensitive(
"plural") ||
1250VD->getName().contains_insensitive(
"singular")) {
1263llvm::APInt
Value= IL->getValue();
1275boolPluralMisuseChecker::MethodCrawler::VisitCallExpr(
CallExpr*CE) {
1276 if(InMatchingStatement) {
1278std::string NormalizedName =
1279StringRef(FD->getNameInfo().getAsString()).lower();
1280 if(NormalizedName.find(
"loc") != std::string::npos) {
1282 if(isa<ObjCStringLiteral>(Arg))
1283reportPluralMisuseError(CE);
1296boolPluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
1304 if(odInfo->
isStr(
"NSBundle") &&
1306 if(InMatchingStatement) {
1307reportPluralMisuseError(ME);
1314boolPluralMisuseChecker::MethodCrawler::TraverseIfStmt(
IfStmt*I) {
1315DynamicRecursiveASTVisitor::TraverseIfStmt(I);
1316 returnEndVisitIfStmt(I);
1322boolPluralMisuseChecker::MethodCrawler::EndVisitIfStmt(
IfStmt*I) {
1323MatchingStatements.pop_back();
1324 if(!MatchingStatements.empty()) {
1325 if(MatchingStatements.back() !=
nullptr) {
1326InMatchingStatement =
true;
1330InMatchingStatement =
false;
1334boolPluralMisuseChecker::MethodCrawler::VisitIfStmt(
IfStmt*I) {
1340MatchingStatements.push_back(I);
1341InMatchingStatement =
true;
1343MatchingStatements.push_back(
nullptr);
1344InMatchingStatement =
false;
1351boolPluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
1353DynamicRecursiveASTVisitor::TraverseConditionalOperator(
C);
1354MatchingStatements.pop_back();
1355 if(!MatchingStatements.empty()) {
1356 if(MatchingStatements.back() !=
nullptr)
1357InMatchingStatement =
true;
1359InMatchingStatement =
false;
1361InMatchingStatement =
false;
1366boolPluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
1370MatchingStatements.push_back(
C);
1371InMatchingStatement =
true;
1373MatchingStatements.push_back(
nullptr);
1374InMatchingStatement =
false;
1379voidPluralMisuseChecker::MethodCrawler::reportPluralMisuseError(
1380 const Stmt*S)
const{
1383 "Localizability Issue (Apple)",
1384 "Plural cases are not supported across all languages. " 1385 "Use a .stringsdict file instead",
1393voidento::registerNonLocalizedStringChecker(
CheckerManager&mgr) {
1394NonLocalizedStringChecker *checker =
1396checker->IsAggressive =
1398checker,
"AggressiveReport");
1401boolento::shouldRegisterNonLocalizedStringChecker(
const CheckerManager&mgr) {
1405voidento::registerEmptyLocalizationContextChecker(
CheckerManager&mgr) {
1409boolento::shouldRegisterEmptyLocalizationContextChecker(
1418boolento::shouldRegisterPluralMisuseChecker(
const CheckerManager&mgr) {
#define LSM_INSERT_SELECTOR(receiver, method_list, arguments)
#define NEW_RECEIVER(receiver)
#define LSM_INSERT_NULLARY(receiver, method_name)
#define LSF_INSERT(function_name)
#define ADD_UNARY_METHOD(receiver, method, argument)
#define ADD_METHOD(receiver, method_list, count, argument)
#define LSM_INSERT_UNARY(receiver, method_name)
static bool isDebuggingContext(CheckerContext &C)
Returns true when, heuristically, the analyzer may be analyzing debugging code.
static bool isDebuggingName(std::string name)
static bool isNSStringType(QualType T, ASTContext &Ctx)
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName, bool SearchInParents=false) const
Interprets an option's string value as a boolean.
A builtin binary operation expression such as "x + y" or "x <= y".
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
ConditionalOperator - The ?: ternary operator.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
DeclContext * getDeclContext()
specific_attr_iterator< T > specific_attr_end() const
specific_attr_iterator< T > specific_attr_begin() const
Recursive AST visitor that supports extension via dynamic dispatch.
This represents one expression.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IfStmt - This represents an if/then/else.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
all_protocol_range all_referenced_protocols() const
ObjCInterfaceDecl * getSuperClass() const
An expression that sends a message to the given Objective-C object or class.
Selector getSelector() const
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
ObjCStringLiteral, used for Objective-C string literals i.e.
std::optional< T > getAs() const
Convert to the specified ProgramPoint type, returning std::nullopt if this ProgramPoint is not of the...
A (possibly-)qualified type.
Smart pointer class that efficiently represents Objective-C method names.
std::string getAsString() const
Derive the full selector name (e.g.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
std::optional< llvm::MemoryBufferRef > getBufferOrNone(FileID FID, SourceLocation Loc=SourceLocation()) const
Return the buffer for the specified FileID.
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceLocation getSpellingLoc() const
This is a discriminated union of FileInfo and ExpansionInfo.
const ExpansionInfo & getExpansion() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Token - This structure provides full information about a lexed token.
tok::TokenKind getKind() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
SourceManager & getSourceManager() override
const SourceManager & getSourceManager() const
BugReporterVisitors are used to add custom diagnostics along a path.
virtual void Profile(llvm::FoldingSetNodeID &ID) const =0
virtual PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR)=0
Return a diagnostic piece which should be associated with the given node.
BugReporter is a utility class for generating PathDiagnostics for analysis.
const SourceManager & getSourceManager()
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges={}, ArrayRef< FixItHint > Fixits={})
Represents an abstract call to a function or method along a particular path.
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
virtual const Expr * getArgExpr(unsigned Index) const
Returns the expression associated with a given argument.
SVal getReturnValue() const
Returns the return value of the call.
virtual SourceRange getSourceRange() const
Returns a source range for the entire call, suitable for outputting in diagnostics.
const AnalyzerOptions & getAnalyzerOptions() const
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
MemRegion - The root abstract class for all memory regions.
Represents any expression that calls an Objective-C method.
const ObjCMethodDecl * getDecl() const override
Returns the declaration of the function or method that will be called.
bool isInstanceMessage() const
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
const ObjCInterfaceDecl * getReceiverInterface() const
Get the interface for the receiver.
Selector getSelector() const
The region associated with an ObjCStringLiteral.
FullSourceLoc asLocation() const
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
const MemRegion * getAsRegion() const
StringRegion - Region associated with a StringLiteral.
SymbolicRegion - A special, "non-concrete" region.
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
bool isAnyIdentifier(TokenKind K)
Return true if this is a raw identifier or an identifier kind.
The JSON file list parser is used to communicate input to InstallAPI.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
const FunctionProtoType * T
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4