32 #include "llvm/Support/Unicode.h"
33 #include "llvm/ADT/StringSet.h"
35 using namespace clang;
39 struct LocalizedState {
41 enum Kind { NonLocalized, Localized } K;
42 LocalizedState(
Kind InK) : K(InK) {}
45 bool isLocalized()
const {
return K == Localized; }
46 bool isNonLocalized()
const {
return K == NonLocalized; }
48 static LocalizedState getLocalized() {
return LocalizedState(Localized); }
49 static LocalizedState getNonLocalized() {
50 return LocalizedState(NonLocalized);
54 bool operator==(
const LocalizedState &
X)
const {
return K == X.K; }
57 void Profile(llvm::FoldingSetNodeID &
ID)
const { ID.AddInteger(K); }
60 class NonLocalizedStringChecker
61 :
public Checker<check::PostCall, check::PreObjCMessage,
62 check::PostObjCMessage,
63 check::PostStmt<ObjCStringLiteral>> {
65 mutable std::unique_ptr<BugType> BT;
69 llvm::DenseMap<Selector, uint8_t>> UIMethods;
71 mutable llvm::SmallSet<std::pair<const IdentifierInfo *, Selector>, 12> LSM;
73 mutable llvm::SmallSet<const IdentifierInfo *, 5> LSF;
76 void initLocStringsMethods(
ASTContext &Ctx)
const;
83 bool isAnnotatedAsLocalized(
const Decl *D)
const;
87 int getLocalizedArgumentForSelector(
const IdentifierInfo *Receiver,
91 NonLocalizedStringChecker();
109 NonLocalizedStringChecker::NonLocalizedStringChecker() {
110 BT.reset(
new BugType(
this,
"Unlocalizable string",
111 "Localizability Issue (Apple)"));
115 class NonLocalizedStringBRVisitor final
122 NonLocalizedStringBRVisitor(
const MemRegion *NonLocalizedString)
123 : NonLocalizedString(NonLocalizedString), Satisfied(
false) {
124 assert(NonLocalizedString);
132 void Profile(llvm::FoldingSetNodeID &
ID)
const override {
133 ID.Add(NonLocalizedString);
138 #define NEW_RECEIVER(receiver) \
139 llvm::DenseMap<Selector, uint8_t> &receiver##M = \
140 UIMethods.insert({&Ctx.Idents.get(#receiver), \
141 llvm::DenseMap<Selector, uint8_t>()}) \
143 #define ADD_NULLARY_METHOD(receiver, method, argument) \
144 receiver##M.insert( \
145 {Ctx.Selectors.getNullarySelector(&Ctx.Idents.get(#method)), argument});
146 #define ADD_UNARY_METHOD(receiver, method, argument) \
147 receiver##M.insert( \
148 {Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(#method)), argument});
149 #define ADD_METHOD(receiver, method_list, count, argument) \
150 receiver##M.insert({Ctx.Selectors.getSelector(count, method_list), argument});
154 void NonLocalizedStringChecker::initUIMethods(
ASTContext &Ctx)
const {
155 if (!UIMethods.empty())
166 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemTag, 3, 0)
170 ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemImage, 3, 0)
183 ADD_METHOD(UITableViewRowAction, rowActionWithStyleUITableViewRowAction, 3, 1)
210 ADD_METHOD(NSBrowser, setTitleNSBrowser, 2, 0)
221 ADD_METHOD(UIAlertAction, actionWithTitleUIAlertAction, 3, 0)
227 ADD_METHOD(NSPopUpButton, insertItemWithTitleNSPopUpButton, 2, 0)
236 ADD_METHOD(NSTableViewRowAction, rowActionWithStyleNSTableViewRowAction, 3, 1)
268 ADD_METHOD(NSSegmentedControl, setLabelNSSegmentedControl, 2, 0)
290 ADD_METHOD(NSMatrix, setToolTipNSMatrix, 2, 0)
306 ADD_METHOD(UIMenuItem, initWithTitleUIMenuItem, 2, 0)
313 ADD_METHOD(UIAlertController, alertControllerWithTitleUIAlertController, 3, 1)
323 initWithTypeUIApplicationShortcutItemIcon, 5, 1)
326 ADD_METHOD(UIApplicationShortcutItem, initWithTypeUIApplicationShortcutItem,
333 &Ctx.
Idents.
get(
"destructiveButtonTitle"),
335 ADD_METHOD(UIActionSheet, initWithTitleUIActionSheet, 5, 0)
347 initWithNameUIAccessibilityCustomAction, 3, 0)
371 ADD_METHOD(NSAttributedString, initWithStringNSAttributedString, 2, 0)
380 ADD_METHOD(UIKeyCommand, keyCommandWithInputUIKeyCommand, 4, 3)
390 &Ctx.
Idents.
get(
"informativeTextWithFormat")};
391 ADD_METHOD(NSAlert, alertWithMessageTextNSAlert, 5, 0)
410 ADD_METHOD(NSWindow, minFrameWidthWithTitleNSWindow, 2, 0)
417 IdentifierInfo *addOptionWithTitleUIDocumentMenuViewController[] = {
421 addOptionWithTitleUIDocumentMenuViewController, 4, 0)
433 ADD_METHOD(UIAlertView, initWithTitleUIAlertView, 5, 0)
463 ADD_METHOD(NSSegmentedCell, setLabelNSSegmentedCell, 2, 0)
466 ADD_METHOD(NSSegmentedCell, setToolTipNSSegmentedCell, 2, 0)
477 ADD_METHOD(NSMenuItem, initWithTitleNSMenuItem, 3, 0)
484 ADD_METHOD(NSPopUpButtonCell, initTextCellNSPopUpButtonCell, 2, 0)
488 ADD_METHOD(NSPopUpButtonCell, insertItemWithTitleNSPopUpButtonCell, 2, 0)
501 ADD_METHOD(NSMenu, insertItemWithTitleNSMenu, 4, 0)
505 ADD_METHOD(NSMenu, addItemWithTitleNSMenu, 3, 0)
521 IdentifierInfo *actionWithIdentifierNSUserNotificationAction[] = {
524 actionWithIdentifierNSUserNotificationAction, 2, 1)
537 ADD_METHOD(UIBarButtonItem, initWithTitleUIBarButtonItem, 4, 0)
546 ADD_METHOD(UISegmentedControl, insertSegmentWithTitleUISegmentedControl, 3, 0)
549 ADD_METHOD(UISegmentedControl, setTitleUISegmentedControl, 2, 0)
552 #define LSF_INSERT(function_name) LSF.insert(&Ctx.Idents.get(function_name));
553 #define LSM_INSERT_NULLARY(receiver, method_name) \
554 LSM.insert({&Ctx.Idents.get(receiver), Ctx.Selectors.getNullarySelector( \
555 &Ctx.Idents.get(method_name))});
556 #define LSM_INSERT_UNARY(receiver, method_name) \
557 LSM.insert({&Ctx.Idents.get(receiver), \
558 Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(method_name))});
559 #define LSM_INSERT_SELECTOR(receiver, method_list, arguments) \
560 LSM.insert({&Ctx.Idents.get(receiver), \
561 Ctx.Selectors.getSelector(arguments, method_list)});
564 void NonLocalizedStringChecker::initLocStringsMethods(
ASTContext &Ctx)
const {
582 LSF_INSERT(
"CFDateFormatterCreateStringWithDate");
583 LSF_INSERT(
"CFDateFormatterCreateStringWithAbsoluteTime");
584 LSF_INSERT(
"CFNumberFormatterCreateStringWithNumber");
589 bool NonLocalizedStringChecker::isAnnotatedAsLocalized(
const Decl *D)
const {
593 D->specific_attr_begin<AnnotateAttr>(),
594 D->specific_attr_end<AnnotateAttr>(), [](
const AnnotateAttr *Ann) {
595 return Ann->getAnnotation() ==
"returns_localized_nsstring";
600 bool NonLocalizedStringChecker::hasLocalizedState(
SVal S,
604 const LocalizedState *LS = C.
getState()->get<LocalizedMemMap>(mt);
605 if (LS && LS->isLocalized())
613 bool NonLocalizedStringChecker::hasNonLocalizedState(
SVal S,
617 const LocalizedState *LS = C.
getState()->get<LocalizedMemMap>(mt);
618 if (LS && LS->isNonLocalized())
625 void NonLocalizedStringChecker::setLocalizedState(
const SVal S,
630 C.
getState()->set<LocalizedMemMap>(mt, LocalizedState::getLocalized());
636 void NonLocalizedStringChecker::setNonLocalizedState(
const SVal S,
641 mt, LocalizedState::getNonLocalized());
648 return StringRef(name).lower().find(
"debug") != StringRef::npos;
660 if (
auto *ND = dyn_cast<NamedDecl>(D)) {
667 if (
auto *CD = dyn_cast<ObjCContainerDecl>(DC)) {
677 void NonLocalizedStringChecker::reportLocalizationError(
679 int argumentNumber)
const {
688 "UnlocalizedString");
695 std::unique_ptr<BugReport> R(
new BugReport(
696 *BT,
"User-facing text should use localized string macro", ErrNode));
697 if (argumentNumber) {
698 R->addRange(M.
getArgExpr(argumentNumber - 1)->getSourceRange());
702 R->markInteresting(S);
706 R->addVisitor(llvm::make_unique<NonLocalizedStringBRVisitor>(StringRegion));
713 int NonLocalizedStringChecker::getLocalizedArgumentForSelector(
715 auto method = UIMethods.find(Receiver);
717 if (method == UIMethods.end())
720 auto argumentIterator = method->getSecond().find(S);
722 if (argumentIterator == method->getSecond().end())
725 int argumentNumber = argumentIterator->getSecond();
726 return argumentNumber;
730 void NonLocalizedStringChecker::checkPreObjCMessage(
const ObjCMethodCall &msg,
742 StringRef SelectorName = SelectorString;
743 assert(!SelectorName.empty());
745 if (odInfo->
isStr(
"NSString")) {
749 if (!(SelectorName.startswith(
"drawAtPoint") ||
750 SelectorName.startswith(
"drawInRect") ||
751 SelectorName.startswith(
"drawWithRect")))
756 bool isNonLocalized = hasNonLocalizedState(svTitle, C);
758 if (isNonLocalized) {
759 reportLocalizationError(svTitle, msg, C);
763 int argumentNumber = getLocalizedArgumentForSelector(odInfo, S);
765 while (argumentNumber < 0 && OD->getSuperClass() !=
nullptr) {
766 for (
const auto *
P : OD->all_referenced_protocols()) {
767 argumentNumber = getLocalizedArgumentForSelector(
P->getIdentifier(),
S);
768 if (argumentNumber >= 0)
771 if (argumentNumber < 0) {
772 OD = OD->getSuperClass();
773 argumentNumber = getLocalizedArgumentForSelector(OD->getIdentifier(),
S);
777 if (argumentNumber < 0)
780 SVal svTitle = msg.getArgSVal(argumentNumber);
783 dyn_cast_or_null<ObjCStringRegion>(svTitle.
getAsRegion())) {
784 StringRef stringValue =
785 SR->getObjCStringLiteral()->getString()->getString();
786 if ((stringValue.trim().size() == 0 && stringValue.size() > 0) ||
789 if (!IsAggressive && llvm::sys::unicode::columnWidthUTF8(stringValue) < 2)
793 bool isNonLocalized = hasNonLocalizedState(svTitle, C);
795 if (isNonLocalized) {
796 reportLocalizationError(svTitle, msg, C, argumentNumber + 1);
813 return ClsName == &Ctx.
Idents.
get(
"NSString") ||
814 ClsName == &Ctx.
Idents.
get(
"NSMutableString");
822 void NonLocalizedStringChecker::checkPostCall(
const CallEvent &Call,
834 for (
unsigned i = 0; i < Call.
getNumArgs(); ++i) {
836 if (hasLocalizedState(argValue, C)) {
838 setLocalizedState(sv, C);
851 if (isAnnotatedAsLocalized(D) || LSF.count(Identifier) != 0) {
852 setLocalizedState(sv, C);
854 !hasLocalizedState(sv, C)) {
856 setNonLocalizedState(sv, C);
859 dyn_cast_or_null<SymbolicRegion>(sv.
getAsRegion());
861 setNonLocalizedState(sv, C);
868 void NonLocalizedStringChecker::checkPostObjCMessage(
const ObjCMethodCall &msg,
883 std::pair<const IdentifierInfo *, Selector> MethodDescription = {odInfo, S};
885 if (LSM.count(MethodDescription) || isAnnotatedAsLocalized(msg.
getDecl())) {
886 SVal sv = msg.getReturnValue();
887 setLocalizedState(sv, C);
895 setNonLocalizedState(sv, C);
899 NonLocalizedStringBRVisitor::VisitNode(
const ExplodedNode *Succ,
906 if (!Point.hasValue())
915 if (LiteralSVal.
getAsRegion() != NonLocalizedString)
927 "Non-localized string literal here");
928 Piece->addRange(LiteralExpr->getSourceRange());
934 class EmptyLocalizationContextChecker
935 :
public Checker<check::ASTDecl<ObjCImplementationDecl>> {
949 : MD(InMD), BR(InBR), Mgr(InMgr), Checker(Checker), DCtx(InDCtx) {}
951 void VisitStmt(
const Stmt *S) { VisitChildren(S); }
957 void VisitChildren(
const Stmt *S) {
958 for (
const Stmt *Child : S->children()) {
971 void EmptyLocalizationContextChecker::checkASTDecl(
978 const Stmt *Body = M->getBody();
981 MethodCrawler MC(M->getCanonicalDecl(), BR,
this, Mgr, DCtx);
1001 void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
1010 if (!(odInfo->
isStr(
"NSBundle") &&
1012 "localizedStringForKey:value:table:")) {
1025 std::pair<FileID, unsigned> SLInfo =
1040 BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());
1045 while (!TheLexer.LexFromRawLexer(I)) {
1046 if (I.getKind() == tok::l_paren)
1048 if (I.getKind() == tok::r_paren) {
1058 reportEmptyContextError(ME);
1069 if ((Comment.trim().size() == 0 && Comment.size() > 0) ||
1071 reportEmptyContextError(ME);
1075 void EmptyLocalizationContextChecker::MethodCrawler::reportEmptyContextError(
1079 "Localizability Issue (Apple)",
1080 "Localized string macro should include a non-empty "
1081 "comment for translators",
1086 class PluralMisuseChecker :
public Checker<check::ASTCodeBody> {
1100 bool InMatchingStatement =
false;
1105 : BR(InBR), Checker(Checker), AC(InAC) {}
1107 bool VisitIfStmt(
const IfStmt *I);
1108 bool EndVisitIfStmt(
IfStmt *I);
1109 bool TraverseIfStmt(
IfStmt *x);
1112 bool VisitCallExpr(
const CallExpr *CE);
1116 void reportPluralMisuseError(
const Stmt *S)
const;
1117 bool isCheckingPlurality(
const Expr *
E)
const;
1124 Visitor.TraverseDecl(const_cast<Decl *>(D));
1133 bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
1134 const Expr *Condition)
const {
1137 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Condition)) {
1138 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1139 const Expr *InitExpr = VD->getInit();
1146 if (VD->getName().lower().find(
"plural") != StringRef::npos ||
1147 VD->getName().lower().find(
"singular") != StringRef::npos) {
1151 }
else if (
const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
1160 llvm::APInt
Value = IL->getValue();
1161 if (Value == 1 || Value == 2) {
1172 bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(
const CallExpr *CE) {
1173 if (InMatchingStatement) {
1175 std::string NormalizedName =
1176 StringRef(FD->getNameInfo().getAsString()).lower();
1177 if (NormalizedName.find(
"loc") != std::string::npos) {
1179 if (isa<ObjCStringLiteral>(Arg))
1180 reportPluralMisuseError(CE);
1193 bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
1201 if (odInfo->
isStr(
"NSBundle") &&
1203 if (InMatchingStatement) {
1204 reportPluralMisuseError(ME);
1211 bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(
IfStmt *I) {
1213 return EndVisitIfStmt(I);
1219 bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(
IfStmt *I) {
1220 MatchingStatements.pop_back();
1221 if (!MatchingStatements.empty()) {
1222 if (MatchingStatements.back() !=
nullptr) {
1223 InMatchingStatement =
true;
1227 InMatchingStatement =
false;
1231 bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(
const IfStmt *I) {
1233 if (isCheckingPlurality(Condition)) {
1234 MatchingStatements.push_back(I);
1235 InMatchingStatement =
true;
1237 MatchingStatements.push_back(
nullptr);
1238 InMatchingStatement =
false;
1245 bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
1248 MatchingStatements.pop_back();
1249 if (!MatchingStatements.empty()) {
1250 if (MatchingStatements.back() !=
nullptr)
1251 InMatchingStatement =
true;
1253 InMatchingStatement =
false;
1255 InMatchingStatement =
false;
1260 bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
1263 if (isCheckingPlurality(Condition)) {
1264 MatchingStatements.push_back(C);
1265 InMatchingStatement =
true;
1267 MatchingStatements.push_back(
nullptr);
1268 InMatchingStatement =
false;
1273 void PluralMisuseChecker::MethodCrawler::reportPluralMisuseError(
1274 const Stmt *S)
const {
1277 "Localizability Issue (Apple)",
1278 "Plural cases are not supported accross all languages. "
1279 "Use a .stringsdict file instead",
1287 void ento::registerNonLocalizedStringChecker(
CheckerManager &mgr) {
1288 NonLocalizedStringChecker *checker =
1290 checker->IsAggressive =
1294 void ento::registerEmptyLocalizationContextChecker(
CheckerManager &mgr) {
virtual SVal getArgSVal(unsigned Index) const
Returns the value of a given argument at the time of the call.
#define NEW_RECEIVER(receiver)
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.
#define ADD_METHOD(receiver, method_list, count, argument)
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
REGISTER_MAP_WITH_PROGRAMSTATE(LocalizedMemMap, const MemRegion *, LocalizedState) NonLocalizedStringChecker
const ExpansionInfo & getExpansion() const
static bool isDebuggingName(std::string name)
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
SourceRange getSourceRange() const override
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...
Represents any expression that calls an Objective-C method.
SVal getReceiverSVal() const
Returns the value of the receiver at the time of this call.
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.
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.
detail::InMemoryDirectory::const_iterator I
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 LSM_INSERT_NULLARY(receiver, method_name)
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.
An expression that sends a message to the given Objective-C object or class.
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.
#define ADD_UNARY_METHOD(receiver, method, argument)
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.
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.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Selector getSelector() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
#define LSF_INSERT(function_name)
const FileInfo & getFile() const
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.
const ObjCMethodDecl * getDecl() const override
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.
ASTContext & getASTContext()
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
const ContentCache * getContentCache() const
detail::InMemoryDirectory::const_iterator E
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()
#define LSM_INSERT_UNARY(receiver, method_name)
const Expr * getArgExpr(unsigned Index) const override
AnalysisDeclContext * getCurrentAnalysisDeclContext() const
virtual unsigned getNumArgs() const =0
Returns the number of arguments (explicit and implicit).
const Expr * getCond() const
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.
unsigned getLength() const
#define LSM_INSERT_SELECTOR(receiver, method_list, arguments)
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.