32 #include "llvm/Support/Unicode.h" 34 using namespace clang;
38 struct LocalizedState {
40 enum Kind { NonLocalized, Localized } K;
41 LocalizedState(
Kind InK) : K(InK) {}
44 bool isLocalized()
const {
return K == Localized; }
45 bool isNonLocalized()
const {
return K == NonLocalized; }
47 static LocalizedState getLocalized() {
return LocalizedState(Localized); }
48 static LocalizedState getNonLocalized() {
49 return LocalizedState(NonLocalized);
53 bool operator==(
const LocalizedState &
X)
const {
return K == X.K; }
56 void Profile(llvm::FoldingSetNodeID &
ID)
const { ID.AddInteger(K); }
59 class NonLocalizedStringChecker
60 :
public Checker<check::PostCall, check::PreObjCMessage,
61 check::PostObjCMessage,
62 check::PostStmt<ObjCStringLiteral>> {
64 mutable std::unique_ptr<BugType> BT;
68 llvm::DenseMap<Selector, uint8_t>> UIMethods;
70 mutable llvm::SmallSet<std::pair<const IdentifierInfo *, Selector>, 12> LSM;
72 mutable llvm::SmallSet<const IdentifierInfo *, 5> LSF;
75 void initLocStringsMethods(
ASTContext &Ctx)
const;
82 bool isAnnotatedAsLocalized(
const Decl *D)
const;
86 int getLocalizedArgumentForSelector(
const IdentifierInfo *Receiver,
90 NonLocalizedStringChecker();
108 NonLocalizedStringChecker::NonLocalizedStringChecker() {
109 BT.reset(
new BugType(
this,
"Unlocalizable string",
110 "Localizability Issue (Apple)"));
114 class NonLocalizedStringBRVisitor final
121 NonLocalizedStringBRVisitor(
const MemRegion *NonLocalizedString)
122 : NonLocalizedString(NonLocalizedString), Satisfied(
false) {
123 assert(NonLocalizedString);
131 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
132 ID.Add(NonLocalizedString);
137 #define NEW_RECEIVER(receiver) \ 138 llvm::DenseMap<Selector, uint8_t> &receiver##M = \ 139 UIMethods.insert({&Ctx.Idents.get(#receiver), \ 140 llvm::DenseMap<Selector, uint8_t>()}) \ 142 #define ADD_NULLARY_METHOD(receiver, method, argument) \ 143 receiver##M.insert( \ 144 {Ctx.Selectors.getNullarySelector(&Ctx.Idents.get(#method)), argument}); 145 #define ADD_UNARY_METHOD(receiver, method, argument) \ 146 receiver##M.insert( \ 147 {Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(#method)), argument}); 148 #define ADD_METHOD(receiver, method_list, count, argument) \ 149 receiver##M.insert({Ctx.Selectors.getSelector(count, method_list), argument}); 153 void NonLocalizedStringChecker::initUIMethods(
ASTContext &Ctx)
const {
154 if (!UIMethods.empty())
165 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemTag, 3, 0)
169 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemImage, 3, 0)
182 ADD_METHOD(UITableViewRowAction, rowActionWithStyleUITableViewRowAction, 3, 1)
194 ADD_METHOD(NSButton, radioButtonWithTitleNSButton, 3, 0)
198 ADD_METHOD(NSButton, buttonWithTitleNSButtonImage, 4, 0)
202 ADD_METHOD(NSButton, checkboxWithTitleNSButton, 3, 0)
206 ADD_METHOD(NSButton, buttonWithTitleNSButtonTarget, 3, 0)
225 ADD_METHOD(NSBrowser, setTitleNSBrowser, 2, 0)
236 ADD_METHOD(UIAlertAction, actionWithTitleUIAlertAction, 3, 0)
242 ADD_METHOD(NSPopUpButton, insertItemWithTitleNSPopUpButton, 2, 0)
251 ADD_METHOD(NSTableViewRowAction, rowActionWithStyleNSTableViewRowAction, 3, 1)
283 ADD_METHOD(NSSegmentedControl, setLabelNSSegmentedControl, 2, 0)
308 ADD_METHOD(NSMatrix, setToolTipNSMatrix, 2, 0)
324 ADD_METHOD(UIMenuItem, initWithTitleUIMenuItem, 2, 0)
331 ADD_METHOD(UIAlertController, alertControllerWithTitleUIAlertController, 3, 1)
341 initWithTypeUIApplicationShortcutItemIcon, 5, 1)
344 ADD_METHOD(UIApplicationShortcutItem, initWithTypeUIApplicationShortcutItem,
351 &Ctx.
Idents.
get(
"destructiveButtonTitle"),
353 ADD_METHOD(UIActionSheet, initWithTitleUIActionSheet, 5, 0)
362 initWithNameUIAccessibilityCustomAction, 3, 0)
389 ADD_METHOD(NSAttributedString, initWithStringNSAttributedString, 2, 0)
398 ADD_METHOD(UIKeyCommand, keyCommandWithInputUIKeyCommand, 4, 3)
408 &Ctx.
Idents.
get(
"informativeTextWithFormat")};
409 ADD_METHOD(NSAlert, alertWithMessageTextNSAlert, 5, 0)
428 ADD_METHOD(NSWindow, minFrameWidthWithTitleNSWindow, 2, 0)
435 IdentifierInfo *addOptionWithTitleUIDocumentMenuViewController[] = {
439 addOptionWithTitleUIDocumentMenuViewController, 4, 0)
451 ADD_METHOD(UIAlertView, initWithTitleUIAlertView, 5, 0)
481 ADD_METHOD(NSSegmentedCell, setLabelNSSegmentedCell, 2, 0)
484 ADD_METHOD(NSSegmentedCell, setToolTipNSSegmentedCell, 2, 0)
495 ADD_METHOD(NSMenuItem, initWithTitleNSMenuItem, 3, 0)
502 ADD_METHOD(NSPopUpButtonCell, initTextCellNSPopUpButtonCell, 2, 0)
506 ADD_METHOD(NSPopUpButtonCell, insertItemWithTitleNSPopUpButtonCell, 2, 0)
519 ADD_METHOD(NSMenu, insertItemWithTitleNSMenu, 4, 0)
523 ADD_METHOD(NSMenu, addItemWithTitleNSMenu, 3, 0)
539 IdentifierInfo *actionWithIdentifierNSUserNotificationAction[] = {
542 actionWithIdentifierNSUserNotificationAction, 2, 1)
552 ADD_METHOD(UIBarButtonItem, initWithTitleUIBarButtonItem, 4, 0)
561 ADD_METHOD(UISegmentedControl, insertSegmentWithTitleUISegmentedControl, 3, 0)
564 ADD_METHOD(UISegmentedControl, setTitleUISegmentedControl, 2, 0)
567 #define LSF_INSERT(function_name) LSF.insert(&Ctx.Idents.get(function_name)); 568 #define LSM_INSERT_NULLARY(receiver, method_name) \ 569 LSM.insert({&Ctx.Idents.get(receiver), Ctx.Selectors.getNullarySelector( \ 570 &Ctx.Idents.get(method_name))}); 571 #define LSM_INSERT_UNARY(receiver, method_name) \ 572 LSM.insert({&Ctx.Idents.get(receiver), \ 573 Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(method_name))}); 574 #define LSM_INSERT_SELECTOR(receiver, method_list, arguments) \ 575 LSM.insert({&Ctx.Idents.get(receiver), \ 576 Ctx.Selectors.getSelector(arguments, method_list)}); 579 void NonLocalizedStringChecker::initLocStringsMethods(
ASTContext &Ctx)
const {
597 LSF_INSERT(
"CFDateFormatterCreateStringWithDate");
598 LSF_INSERT(
"CFDateFormatterCreateStringWithAbsoluteTime");
599 LSF_INSERT(
"CFNumberFormatterCreateStringWithNumber");
604 bool NonLocalizedStringChecker::isAnnotatedAsLocalized(
const Decl *D)
const {
608 D->specific_attr_begin<AnnotateAttr>(),
609 D->specific_attr_end<AnnotateAttr>(), [](
const AnnotateAttr *Ann) {
610 return Ann->getAnnotation() ==
"returns_localized_nsstring";
615 bool NonLocalizedStringChecker::hasLocalizedState(
SVal S,
619 const LocalizedState *LS = C.
getState()->get<LocalizedMemMap>(mt);
620 if (LS && LS->isLocalized())
628 bool NonLocalizedStringChecker::hasNonLocalizedState(
SVal S,
632 const LocalizedState *LS = C.
getState()->get<LocalizedMemMap>(mt);
633 if (LS && LS->isNonLocalized())
640 void NonLocalizedStringChecker::setLocalizedState(
const SVal S,
645 C.
getState()->set<LocalizedMemMap>(mt, LocalizedState::getLocalized());
651 void NonLocalizedStringChecker::setNonLocalizedState(
const SVal S,
656 mt, LocalizedState::getNonLocalized());
663 return StringRef(name).lower().find(
"debug") != StringRef::npos;
675 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
682 if (
auto *CD = dyn_cast<ObjCContainerDecl>(DC)) {
692 void NonLocalizedStringChecker::reportLocalizationError(
694 int argumentNumber)
const {
703 "UnlocalizedString");
710 std::unique_ptr<BugReport> R(
new BugReport(
711 *BT,
"User-facing text should use localized string macro", ErrNode));
712 if (argumentNumber) {
713 R->addRange(M.
getArgExpr(argumentNumber - 1)->getSourceRange());
717 R->markInteresting(S);
721 R->addVisitor(llvm::make_unique<NonLocalizedStringBRVisitor>(StringRegion));
728 int NonLocalizedStringChecker::getLocalizedArgumentForSelector(
730 auto method = UIMethods.find(Receiver);
732 if (method == UIMethods.end())
735 auto argumentIterator = method->getSecond().find(S);
737 if (argumentIterator == method->getSecond().end())
740 int argumentNumber = argumentIterator->getSecond();
741 return argumentNumber;
745 void NonLocalizedStringChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
757 StringRef SelectorName = SelectorString;
758 assert(!SelectorName.empty());
760 if (odInfo->
isStr(
"NSString")) {
764 if (!(SelectorName.startswith(
"drawAtPoint") ||
765 SelectorName.startswith(
"drawInRect") ||
766 SelectorName.startswith(
"drawWithRect")))
771 bool isNonLocalized = hasNonLocalizedState(svTitle, C);
773 if (isNonLocalized) {
774 reportLocalizationError(svTitle, msg, C);
778 int argumentNumber = getLocalizedArgumentForSelector(odInfo, S);
780 while (argumentNumber < 0 && OD->getSuperClass() !=
nullptr) {
781 for (
const auto *
P : OD->all_referenced_protocols()) {
782 argumentNumber = getLocalizedArgumentForSelector(
P->getIdentifier(), S);
783 if (argumentNumber >= 0)
786 if (argumentNumber < 0) {
787 OD = OD->getSuperClass();
788 argumentNumber = getLocalizedArgumentForSelector(OD->getIdentifier(), S);
792 if (argumentNumber < 0)
795 SVal svTitle = msg.getArgSVal(argumentNumber);
798 dyn_cast_or_null<ObjCStringRegion>(svTitle.
getAsRegion())) {
799 StringRef stringValue =
800 SR->getObjCStringLiteral()->getString()->getString();
801 if ((stringValue.trim().size() == 0 && stringValue.size() > 0) ||
804 if (!IsAggressive && llvm::sys::unicode::columnWidthUTF8(stringValue) < 2)
808 bool isNonLocalized = hasNonLocalizedState(svTitle, C);
810 if (isNonLocalized) {
811 reportLocalizationError(svTitle, msg, C, argumentNumber + 1);
828 return ClsName == &Ctx.
Idents.
get(
"NSString") ||
829 ClsName == &Ctx.
Idents.
get(
"NSMutableString");
837 void NonLocalizedStringChecker::checkPostCall(
const CallEvent &Call,
849 for (
unsigned i = 0; i < Call.
getNumArgs(); ++i) {
851 if (hasLocalizedState(argValue, C)) {
853 setLocalizedState(sv, C);
866 if (isAnnotatedAsLocalized(D) || LSF.count(Identifier) != 0) {
867 setLocalizedState(sv, C);
869 !hasLocalizedState(sv, C)) {
871 setNonLocalizedState(sv, C);
874 dyn_cast_or_null<SymbolicRegion>(sv.
getAsRegion());
876 setNonLocalizedState(sv, C);
883 void NonLocalizedStringChecker::checkPostObjCMessage(
const ObjCMethodCall &msg,
898 std::pair<const IdentifierInfo *, Selector> MethodDescription = {odInfo, S};
900 if (LSM.count(MethodDescription) || isAnnotatedAsLocalized(msg.
getDecl())) {
901 SVal sv = msg.getReturnValue();
902 setLocalizedState(sv, C);
910 setNonLocalizedState(sv, C);
914 NonLocalizedStringBRVisitor::VisitNode(
const ExplodedNode *Succ,
921 if (!Point.hasValue())
930 if (LiteralSVal.
getAsRegion() != NonLocalizedString)
942 "Non-localized string literal here");
943 Piece->addRange(LiteralExpr->getSourceRange());
949 class EmptyLocalizationContextChecker
950 :
public Checker<check::ASTDecl<ObjCImplementationDecl>> {
964 : MD(InMD), BR(InBR), Mgr(InMgr), Checker(Checker), DCtx(InDCtx) {}
966 void VisitStmt(
const Stmt *S) { VisitChildren(S); }
972 void VisitChildren(
const Stmt *S) {
973 for (
const Stmt *Child : S->children()) {
986 void EmptyLocalizationContextChecker::checkASTDecl(
993 const Stmt *Body = M->getBody();
996 MethodCrawler MC(M->getCanonicalDecl(), BR,
this, Mgr, DCtx);
1016 void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
1027 if (!(odInfo->
isStr(
"NSBundle") &&
1029 "localizedStringForKey:value:table:")) {
1042 std::pair<FileID, unsigned> SLInfo =
1055 bool Invalid =
false;
1056 llvm::MemoryBuffer *BF =
1062 BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());
1067 while (!TheLexer.LexFromRawLexer(I)) {
1068 if (I.getKind() == tok::l_paren)
1070 if (I.getKind() == tok::r_paren) {
1080 reportEmptyContextError(ME);
1091 if ((Comment.trim().size() == 0 && Comment.size() > 0) ||
1093 reportEmptyContextError(ME);
1097 void EmptyLocalizationContextChecker::MethodCrawler::reportEmptyContextError(
1101 "Localizability Issue (Apple)",
1102 "Localized string macro should include a non-empty " 1103 "comment for translators",
1108 class PluralMisuseChecker :
public Checker<check::ASTCodeBody> {
1122 bool InMatchingStatement =
false;
1127 : BR(InBR), Checker(Checker), AC(InAC) {}
1129 bool VisitIfStmt(
const IfStmt *I);
1130 bool EndVisitIfStmt(
IfStmt *I);
1131 bool TraverseIfStmt(
IfStmt *
x);
1138 void reportPluralMisuseError(
const Stmt *S)
const;
1139 bool isCheckingPlurality(
const Expr *E)
const;
1146 Visitor.TraverseDecl(const_cast<Decl *>(D));
1155 bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
1156 const Expr *Condition)
const {
1159 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Condition)) {
1160 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1161 const Expr *InitExpr = VD->getInit();
1168 if (VD->getName().lower().find(
"plural") != StringRef::npos ||
1169 VD->getName().lower().find(
"singular") != StringRef::npos) {
1173 }
else if (
const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
1182 llvm::APInt
Value = IL->getValue();
1183 if (Value == 1 || Value == 2) {
1194 bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(
const CallExpr *CE) {
1195 if (InMatchingStatement) {
1197 std::string NormalizedName =
1198 StringRef(FD->getNameInfo().getAsString()).lower();
1199 if (NormalizedName.find(
"loc") != std::string::npos) {
1201 if (isa<ObjCStringLiteral>(Arg))
1202 reportPluralMisuseError(CE);
1215 bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
1223 if (odInfo->
isStr(
"NSBundle") &&
1225 if (InMatchingStatement) {
1226 reportPluralMisuseError(ME);
1233 bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(
IfStmt *I) {
1235 return EndVisitIfStmt(I);
1241 bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(
IfStmt *I) {
1242 MatchingStatements.pop_back();
1243 if (!MatchingStatements.empty()) {
1244 if (MatchingStatements.back() !=
nullptr) {
1245 InMatchingStatement =
true;
1249 InMatchingStatement =
false;
1253 bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(
const IfStmt *I) {
1255 if (isCheckingPlurality(Condition)) {
1256 MatchingStatements.push_back(I);
1257 InMatchingStatement =
true;
1259 MatchingStatements.push_back(
nullptr);
1260 InMatchingStatement =
false;
1267 bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
1270 MatchingStatements.pop_back();
1271 if (!MatchingStatements.empty()) {
1272 if (MatchingStatements.back() !=
nullptr)
1273 InMatchingStatement =
true;
1275 InMatchingStatement =
false;
1277 InMatchingStatement =
false;
1282 bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
1285 if (isCheckingPlurality(Condition)) {
1286 MatchingStatements.push_back(C);
1287 InMatchingStatement =
true;
1289 MatchingStatements.push_back(
nullptr);
1290 InMatchingStatement =
false;
1295 void PluralMisuseChecker::MethodCrawler::reportPluralMisuseError(
1296 const Stmt *S)
const {
1299 "Localizability Issue (Apple)",
1300 "Plural cases are not supported accross all languages. " 1301 "Use a .stringsdict file instead",
1309 void ento::registerNonLocalizedStringChecker(
CheckerManager &mgr) {
1310 NonLocalizedStringChecker *checker =
1312 checker->IsAggressive =
1316 void ento::registerEmptyLocalizationContextChecker(
CheckerManager &mgr) {
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Lexer - This provides a simple interface that turns a text buffer into a stream of tokens...
Smart pointer class that efficiently represents Objective-C method names.
This is a discriminated union of FileInfo and ExpansionInfo.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
bool isInstanceMessage() const
bool operator==(CanQual< T > x, CanQual< U > y)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
void VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred, ExplodedNodeSet &Dst)
VisitCall - Transfer function for function calls.
IfStmt - This represents an if/then/else.
A helper class which wraps a boolean value set to false by default.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
const SrcMgr::SLocEntry & getSLocEntry(FileID FID, bool *Invalid=nullptr) const
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
REGISTER_MAP_WITH_PROGRAMSTATE(LocalizedMemMap, const MemRegion *, LocalizedState) NonLocalizedStringChecker
#define NEW_RECEIVER(receiver)
const ExpansionInfo & getExpansion() const
static bool isDebuggingName(std::string name)
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
static bool isDebuggingContext(CheckerContext &C)
Returns true when, heuristically, the analyzer may be analyzing debugging code.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token...
ObjCMethodDecl - Represents an instance or class method declaration.
ExplodedNode * getPredecessor()
Returns the previous node in the exploded graph, which includes the state of the program before the c...
FullSourceLoc asLocation() const
const ObjCInterfaceDecl * getReceiverInterface() const
Get the interface for the receiver.
One of these records is kept for each identifier that is lexed.
The region associated with an ObjCStringLiteral.
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 or method under analysis.
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
const Expr * getOriginExpr() const
Returns the expression whose value will be the result of this call.
Token - This structure provides full information about a lexed token.
method_range methods() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
#define LSM_INSERT_UNARY(receiver, method_name)
Represents any expression that calls an Objective-C method.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
const Expr * getArgExpr(unsigned Index) const override
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
A builtin binary operation expression such as "x + y" or "x <= y".
Selector getSelector() const
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.
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
tok::TokenKind getKind() const
const Decl * getDecl() const
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
Represents an ObjC class declaration.
AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)
const LocationContext * getLocationContext() const
StringRef getRawIdentifier() const
getRawIdentifier - For a raw identifier token (i.e., an identifier lexed in raw mode), returns a reference to the text substring in the buffer if known.
ConditionalOperator - The ?: ternary operator.
#define ADD_METHOD(receiver, method_list, count, argument)
ID
Defines the set of possible language-specific address spaces.
SymbolicRegion - A special, "non-concrete" region.
Expr - This represents one expression.
const ProgramStateRef & getState() const
const ProgramStateRef & getState() const
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
void Visit(const Stmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst)
Visit - Transfer function logic for all statements.
An expression that sends a message to the given Objective-C object or class.
#define ADD_UNARY_METHOD(receiver, method, argument)
The result type of a method or function.
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as a boolean.
llvm::PointerUnion< const LocationContext *, AnalysisDeclContext * > LocationOrAnalysisDeclContext
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
const char * getLiteralData() const
getLiteralData - For a literal token (numeric constant, string, etc), this returns a pointer to the s...
BugReporter is a utility class for generating PathDiagnostics for analysis.
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
CHECKER * registerChecker()
Used to register checkers.
static bool isNSStringType(QualType T, ASTContext &Ctx)
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
bool isValid() const
Return true if this is a valid SourceLocation object.
const ObjCMethodDecl * getDecl() const override
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Selector getSelector() const
#define LSF_INSERT(function_name)
std::string getAsString() const
Derive the full selector name (e.g.
SourceLocation getBegin() const
const IdentifierInfo * getCalleeIdentifier() const
Returns the name of the callee, if its name is a simple identifier.
SourceManager & getSourceManager() override
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
/file This file defines classes for searching and anlyzing source code clones.
ASTContext & getASTContext()
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
#define LSM_INSERT_NULLARY(receiver, method_name)
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
#define LSM_INSERT_SELECTOR(receiver, method_list, arguments)
const MemRegion * getAsRegion() const
Represents an abstract call to a function or method along a particular path.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
AnalyzerOptions & getAnalyzerOptions()
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Represents a pointer to an Objective C object.
QualType getResultType() const
Returns the result type, adjusted for references.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
const T * getAs() const
Member-template getAs<specific type>'.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
SourceManager & getSourceManager()
AnalysisDeclContext * getCurrentAnalysisDeclContext() const
const Expr * getCond() const
SourceRange getSourceRange() const override
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
StringRegion - Region associated with a StringLiteral.
A reference to a declared variable, function, enum, etc.
IRgen optimization opportunities The common pattern of short x
unsigned getLength() const
A trivial tuple used to represent a source range.
Tag that can use a checker name as a message provider (see SimpleProgramPointTag).
This class provides an interface through which checkers can create individual bug reports...
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
SVal getReturnValue() const
Returns the return value of the call.
bool isAnyIdentifier(TokenKind K)
Return true if this is a raw identifier or an identifier kind.
SourceManager & getSourceManager()
SourceLocation getSpellingLoc() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.