23 using namespace clang;
42 if (LangOpts.ObjCAutoRefCount) {
70 if ((isa<ObjCStringLiteral>(Arg) &&
75 (isa<ObjCArrayLiteral>(Arg) &&
80 (isa<ObjCDictionaryLiteral>(Arg) &&
87 Msg->
getArg(0)->getSourceRange());
110 const Expr *Receiver,
112 assert(IFace && Receiver);
149 if (OID->
getName() ==
"NSMapTable" ||
166 if (!MD->isUnavailable())
394 commit.
replace(MsgRange,
"@[]");
416 for (
unsigned i = 0, e = Msg->
getNumArgs() - 1; i != e; ++i)
420 commit.
replace(MsgRange,
"@[]");
462 if (Msg->getNumArgs() != 1)
464 Objs.push_back(Msg->getArg(0));
470 if (Msg->getNumArgs() == 0)
472 const Expr *SentinelExpr = Msg->getArg(Msg->getNumArgs() - 1);
476 for (
unsigned i = 0, e = Msg->getNumArgs() - 1; i != e; ++i)
477 Objs.push_back(Msg->getArg(i));
481 }
else if (
const ObjCArrayLiteral *ArrLit = dyn_cast<ObjCArrayLiteral>(E)) {
482 for (
unsigned i = 0, e = ArrLit->getNumElements(); i != e; ++i)
483 Objs.push_back(ArrLit->getElement(i));
498 commit.
replace(MsgRange,
"@{}");
529 const Expr *SentinelExpr = Msg->
getArg(SentinelIdx);
534 commit.
replace(MsgRange,
"@{}");
538 for (
unsigned i = 0; i < SentinelIdx; i += 2) {
554 Msg->
getArg(SentinelIdx-1)->getLocEnd());
574 if (Vals.size() != Keys.size())
578 commit.
replace(MsgRange,
"@{}");
582 for (
unsigned i = 0, n = Vals.size(); i < n; ++i) {
595 Keys.back()->getLocEnd());
631 if (Vals.size() != Keys.size())
678 StringRef U, F, L, LL;
685 bool isFloat,
bool isIntZero,
700 static bool has(StringRef suff, StringRef &text) {
701 if (text.endswith(suff)) {
702 text = text.substr(0, text.size()-suff.size());
722 }
else if (isFloat &&
Suff::has(
"f", text)) {
724 }
else if (isFloat &&
Suff::has(
"F", text)) {
730 if (!UpperU.hasValue() && !UpperL.hasValue())
731 UpperU = UpperL =
true;
732 else if (UpperU.hasValue() && !UpperL.hasValue())
734 else if (UpperL.hasValue() && !UpperU.hasValue())
737 Info.U = *UpperU ?
"U" :
"u";
738 Info.L = *UpperL ?
"L" :
"l";
739 Info.LL = *UpperL ?
"LL" :
"ll";
740 Info.F = UpperF ?
"F" :
"f";
742 Info.Hex = Info.Octal =
false;
743 if (text.startswith(
"0x"))
745 else if (!isFloat && !isIntZero && text.startswith(
"0"))
749 Info.WithoutSuffRange =
767 const Expr *literalE = Arg;
768 if (
const UnaryOperator *UOE = dyn_cast<UnaryOperator>(literalE)) {
770 literalE = UOE->getSubExpr();
775 if (!isa<IntegerLiteral>(literalE) && !isa<FloatingLiteral>(literalE))
786 bool CallIsUnsigned =
false, CallIsLong =
false, CallIsLongLong =
false;
787 bool CallIsFloating =
false, CallIsDouble =
false;
800 CallIsUnsigned =
true;
806 CallIsUnsigned =
true;
812 CallIsUnsigned =
true;
814 CallIsLongLong =
true;
820 CallIsFloating =
true;
844 if (LitIsFloat && !CallIsFloating)
852 bool isIntZero =
false;
853 if (
const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
854 isIntZero = !IntE->getValue().getBoolValue();
855 if (!
getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
859 if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
866 LitInfo.WithoutSuffRange);
869 if (!LitIsFloat && CallIsFloating)
870 commit.
insert(LitE,
".0");
872 if (CallIsFloating) {
874 commit.
insert(LitE, LitInfo.F);
877 commit.
insert(LitE, LitInfo.U);
880 commit.
insert(LitE, LitInfo.L);
881 else if (CallIsLongLong)
882 commit.
insert(LitE, LitInfo.LL);
891 if (isa<ArraySubscriptExpr>(Expr) ||
892 isa<CallExpr>(Expr) ||
893 isa<DeclRefExpr>(Expr) ||
894 isa<CXXNamedCastExpr>(Expr) ||
895 isa<CXXConstructExpr>(Expr) ||
896 isa<CXXThisExpr>(Expr) ||
897 isa<CXXTypeidExpr>(Expr) ||
898 isa<CXXUnresolvedConstructExpr>(Expr) ||
899 isa<ObjCMessageExpr>(Expr) ||
900 isa<ObjCPropertyRefExpr>(Expr) ||
901 isa<ObjCProtocolExpr>(Expr) ||
902 isa<MemberExpr>(Expr) ||
903 isa<ObjCIvarRefExpr>(Expr) ||
904 isa<ParenExpr>(FullExpr) ||
905 isa<ParenListExpr>(Expr) ||
906 isa<SizeOfPackExpr>(Expr))
913 if (isa<ArraySubscriptExpr>(Expr) ||
914 isa<CallExpr>(Expr) ||
915 isa<DeclRefExpr>(Expr) ||
916 isa<CastExpr>(Expr) ||
917 isa<CXXNewExpr>(Expr) ||
918 isa<CXXConstructExpr>(Expr) ||
919 isa<CXXDeleteExpr>(Expr) ||
920 isa<CXXNoexceptExpr>(Expr) ||
921 isa<CXXPseudoDestructorExpr>(Expr) ||
922 isa<CXXScalarValueInitExpr>(Expr) ||
923 isa<CXXThisExpr>(Expr) ||
924 isa<CXXTypeidExpr>(Expr) ||
925 isa<CXXUnresolvedConstructExpr>(Expr) ||
926 isa<ObjCMessageExpr>(Expr) ||
927 isa<ObjCPropertyRefExpr>(Expr) ||
928 isa<ObjCProtocolExpr>(Expr) ||
929 isa<MemberExpr>(Expr) ||
930 isa<ObjCIvarRefExpr>(Expr) ||
931 isa<ParenExpr>(FullExpr) ||
932 isa<ParenListExpr>(Expr) ||
933 isa<SizeOfPackExpr>(Expr) ||
934 isa<UnaryOperator>(Expr))
967 if (
const ValueDecl *VD = DRE->getDecl())
968 return isa<EnumConstantDecl>(VD);
996 bool isTruncated = FinalTySize < OrigTySize;
997 bool needsCast =
false;
1000 switch (ICE->getCastKind()) {
1087 "converting to boxing syntax requires casting %0 to %1");
1089 << Msg->getSourceRange();
1096 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
1123 StrE = dyn_cast<StringLiteral>(OrigArg->
IgnoreParens())) {
1125 commit.
insert(StrE->getLocStart(),
"@");
1135 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
The receiver is the instance of the superclass object.
Defines the clang::ASTContext interface.
SourceLocation getEnd() const
bool remove(CharSourceRange range)
The receiver is an object instance.
StringRef getName() const
Smart pointer class that efficiently represents Objective-C method names.
bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Selector getObjectAtIndexedSubscriptSelector() const
Returns selector for "objectAtIndexedSubscript:".
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
IdentifierInfo * getIdentifier() const
CharacterKind getKind() const
bool insertWrap(StringRef before, CharSourceRange range, StringRef after)
static CharSourceRange getTokenRange(SourceRange R)
static bool rewriteToSubscriptGetCommon(const ObjCMessageExpr *Msg, Commit &commit)
NSNumberLiteralMethodKind
Enumerates the NSNumber methods used to generate literals.
static bool getNSArrayObjects(const Expr *E, const NSAPI &NS, SmallVectorImpl< const Expr * > &Objs)
If Msg is an NSArray creation message or literal, this gets the objects that were used to create it...
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const
The Objective-C NSDictionary selectors.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool insertAfterToken(SourceLocation loc, StringRef text, bool beforePreviousInsertions=false)
bool isBooleanType() const
bool insertFromRange(SourceLocation loc, CharSourceRange range, bool afterToken=false, bool beforePreviousInsertions=false)
bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, Selector Sel) const
[ARC] Consumes a retainable object pointer that has just been produced, e.g. as the return value of a...
static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CK_Dynamic - A C++ dynamic_cast.
Defines the clang::Expr interface and subclasses for C++ expressions.
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
IdentifierInfo * getNSClassId(NSClassIdKindKind K) const
Expr * IgnoreImpCasts() LLVM_READONLY
Selector getNSStringSelector(NSStringMethodKind MK) const
The Objective-C NSString selectors.
bool insert(SourceLocation loc, StringRef text, bool afterToken=false, bool beforePreviousInsertions=false)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Converts between different integral complex types. _Complex char -> _Complex long long _Complex unsig...
static bool isEnumConstant(const Expr *E)
Converting between two Objective-C object types, which can occur when performing reference binding to...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
[ARC] Causes a value of block type to be copied to the heap, if it is not already there...
static void objectifyExpr(const Expr *E, Commit &commit)
Adds an explicit cast to 'id' if the type is not objc object.
Optional< NSNumberLiteralMethodKind > getNSNumberLiteralMethodKind(Selector Sel) const
Return NSNumberLiteralMethodKind if Sel is such a selector.
static bool rewriteToArraySubscriptGet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Converts a floating point complex to bool by comparing against 0+0i.
bool replace(CharSourceRange range, StringRef text)
static bool rewriteToDictionarySubscriptGet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
const LangOptions & getLangOpts() const
QualType getSuperType() const
Retrieve the type referred to by 'super'.
Concrete class used by the front-end to report problems and issues.
bool isNSUTF8StringEncodingConstant(const Expr *E) const
Returns true if the expression.
Selector getSelector() const
ObjCInterfaceDecl * getInterface() const
Expr * IgnoreParenCasts() LLVM_READONLY
Represents an ObjC class declaration.
static const ObjCInterfaceDecl * maybeAdjustInterfaceForSubscriptingCheck(const ObjCInterfaceDecl *IFace, const Expr *Receiver, ASTContext &Ctx)
Check for classes that accept 'objectForKey:' (or the other selectors that the migrator handles) but ...
DiagnosticsEngine & getDiagnostics() const
Causes a block literal to by copied to the heap and then autoreleased.
Selector getSetObjectAtIndexedSubscriptSelector() const
Returns selector for "setObject:atIndexedSubscript".
static bool castOperatorNeedsParens(const Expr *FullExpr)
QualType getPointeeType() const
Converts between different floating point complex types. _Complex float -> _Complex double...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
const ObjCMethodDecl * getMethodDecl() const
Converts an integral complex to an integral real of the source's element type by discarding the imagi...
Represents a character-granular source range.
static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
static bool doRewriteToUTF8StringBoxedExpressionHelper(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
bool isFloatingType() const
An expression that sends a message to the given Objective-C object or class.
static bool subscriptOperatorNeedsParens(const Expr *FullExpr)
Converts from an integral complex to a floating complex. _Complex unsigned -> _Complex float...
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
static bool checkForLiteralCreation(const ObjCMessageExpr *Msg, IdentifierInfo *&ClassId, const LangOptions &LangOpts)
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
static CharSourceRange getCharRange(SourceRange R)
static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > LLVM_ATTRIBUTE_UNUSED has
Matches the first method of a class or struct that satisfies InnerMatcher.
Selector getObjectForKeyedSubscriptSelector() const
Returns selector for "objectForKeyedSubscript:".
bool isNSASCIIStringEncodingConstant(const Expr *E) const
Returns true if the expression.
Converts from an integral real to an integral complex whose element type matches the source...
SourceLocation getBegin() const
bool isTypeDependent() const
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Selector getNSArraySelector(NSArrayMethodKind MK) const
The Objective-C NSArray selectors.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
static bool rewriteToDictionarySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
Converts a floating point complex to floating point real of the source's element type. Just discards the imaginary component. _Complex long double -> long double.
ASTContext & getASTContext() const
static bool rewriteToArraySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool isSentinelNullExpr(const Expr *E)
Converts an integral complex to bool by comparing against 0+0i.
static bool rewriteToBoolLiteral(const ObjCMessageExpr *Msg, const Expr *Arg, const NSAPI &NS, Commit &commit)
static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *&IFace, const ObjCMessageExpr *Msg, ASTContext &Ctx, Selector subscriptSel)
Selector getSetObjectForKeyedSubscriptSelector() const
Returns selector for "setObject:forKeyedSubscript".
A conversion of a floating point real to a floating point complex of the original type...
[ARC] Reclaim a retainable object pointer object that may have been produced and autoreleased as part...
Expr * IgnoreParenImpCasts() LLVM_READONLY
static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
[ARC] Produces a retainable object pointer so that it may be consumed, e.g. by being passed to a cons...
Converts from T to _Atomic(T).
Converts from a floating complex to an integral complex. _Complex float -> _Complex int...
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
SourceManager & getSourceManager()
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isObjCObjectPointerType() const
static void maybePutParensOnReceiver(const Expr *Receiver, Commit &commit)
Stmt * getParentIgnoreParenCasts(Stmt *) const
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation. If false, it was written explicitly in the source code.
static bool getLiteralInfo(SourceRange literalRange, bool isFloat, bool isIntZero, ASTContext &Ctx, LiteralInfo &Info)
Converts from _Atomic(T) to T.
bool insertBefore(SourceLocation loc, StringRef text)
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
static bool shouldNotRewriteImmediateMessageArgs(const ObjCMessageExpr *Msg, const NSAPI &NS)
Returns true if the immediate message arguments of Msg should not be rewritten because it will interf...
bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange)
const ObjCInterfaceDecl * getObjContainingInterface(const NamedDecl *ND) const
Returns the Objective-C interface that ND belongs to if it is an Objective-C method/property/ivar etc...
bool isObjCIdType(QualType T) const
A trivial tuple used to represent a source range.
A boolean literal, per ([C++ lex.bool] Boolean literals).
bool isSignedIntegerType() const
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
The receiver is a superclass.
static bool rewriteToCharLiteral(const ObjCMessageExpr *Msg, const CharacterLiteral *Arg, const NSAPI &NS, Commit &commit)
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Expr * IgnoreParens() LLVM_READONLY
bool isPointerType() const