Go to the documentation of this file.
22 using namespace clang;
41 if (LangOpts.ObjCAutoRefCount) {
69 if ((isa<ObjCStringLiteral>(Arg) &&
74 (isa<ObjCArrayLiteral>(Arg) &&
79 (isa<ObjCDictionaryLiteral>(Arg) &&
109 const Expr *Receiver,
111 assert(IFace && Receiver);
148 if (OID->
getName() ==
"NSMapTable" ||
165 if (!MD->isUnavailable())
393 commit.
replace(MsgRange,
"@[]");
415 for (
unsigned i = 0, e = Msg->
getNumArgs() - 1; i != e; ++i)
419 commit.
replace(MsgRange,
"@[]");
461 if (Msg->getNumArgs() != 1)
463 Objs.push_back(Msg->getArg(0));
469 if (Msg->getNumArgs() == 0)
471 const Expr *SentinelExpr = Msg->getArg(Msg->getNumArgs() - 1);
475 for (
unsigned i = 0, e = Msg->getNumArgs() - 1; i != e; ++i)
476 Objs.push_back(Msg->getArg(i));
480 }
else if (
const ObjCArrayLiteral *ArrLit = dyn_cast<ObjCArrayLiteral>(E)) {
481 for (
unsigned i = 0, e = ArrLit->getNumElements(); i != e; ++i)
482 Objs.push_back(ArrLit->getElement(i));
497 commit.
replace(MsgRange,
"@{}");
528 const Expr *SentinelExpr = Msg->
getArg(SentinelIdx);
533 commit.
replace(MsgRange,
"@{}");
537 for (
unsigned i = 0; i < SentinelIdx; i += 2) {
573 if (Vals.size() != Keys.size())
577 commit.
replace(MsgRange,
"@{}");
581 for (
unsigned i = 0, n = Vals.size(); i < n; ++i) {
593 SourceRange ArgRange(Keys.front()->getBeginLoc(), Keys.back()->getEndLoc());
629 if (Vals.size() != Keys.size())
676 StringRef
U, F, L, LL;
683 bool isFloat,
bool isIntZero,
698 static bool has(StringRef suff, StringRef &
text) {
699 if (
text.endswith(suff)) {
728 if (!UpperU.hasValue() && !UpperL.hasValue())
729 UpperU = UpperL =
true;
730 else if (UpperU.hasValue() && !UpperL.hasValue())
732 else if (UpperL.hasValue() && !UpperU.hasValue())
735 Info.U = *UpperU ?
"U" :
"u";
736 Info.L = *UpperL ?
"L" :
"l";
737 Info.LL = *UpperL ?
"LL" :
"ll";
738 Info.F = UpperF ?
"F" :
"f";
740 Info.Hex = Info.Octal =
false;
741 if (
text.startswith(
"0x"))
743 else if (!isFloat && !isIntZero &&
text.startswith(
"0"))
747 Info.WithoutSuffRange =
765 const Expr *literalE = Arg;
766 if (
const UnaryOperator *UOE = dyn_cast<UnaryOperator>(literalE)) {
767 if (UOE->getOpcode() == UO_Plus || UOE->getOpcode() == UO_Minus)
768 literalE = UOE->getSubExpr();
773 if (!isa<IntegerLiteral>(literalE) && !isa<FloatingLiteral>(literalE))
784 bool CallIsUnsigned =
false, CallIsLong =
false, CallIsLongLong =
false;
785 bool CallIsFloating =
false, CallIsDouble =
false;
798 CallIsUnsigned =
true;
805 CallIsUnsigned =
true;
812 CallIsUnsigned =
true;
815 CallIsLongLong =
true;
822 CallIsFloating =
true;
846 if (LitIsFloat && !CallIsFloating)
854 bool isIntZero =
false;
855 if (
const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
856 isIntZero = !IntE->getValue().getBoolValue();
857 if (!
getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
861 if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
868 LitInfo.WithoutSuffRange);
871 if (!LitIsFloat && CallIsFloating)
872 commit.
insert(LitE,
".0");
874 if (CallIsFloating) {
876 commit.
insert(LitE, LitInfo.F);
879 commit.
insert(LitE, LitInfo.U);
882 commit.
insert(LitE, LitInfo.L);
883 else if (CallIsLongLong)
884 commit.
insert(LitE, LitInfo.LL);
893 if (isa<ArraySubscriptExpr>(
Expr) ||
894 isa<CallExpr>(
Expr) ||
895 isa<DeclRefExpr>(
Expr) ||
896 isa<CXXNamedCastExpr>(
Expr) ||
897 isa<CXXConstructExpr>(
Expr) ||
898 isa<CXXThisExpr>(
Expr) ||
899 isa<CXXTypeidExpr>(
Expr) ||
900 isa<CXXUnresolvedConstructExpr>(
Expr) ||
901 isa<ObjCMessageExpr>(
Expr) ||
902 isa<ObjCPropertyRefExpr>(
Expr) ||
903 isa<ObjCProtocolExpr>(
Expr) ||
904 isa<MemberExpr>(
Expr) ||
905 isa<ObjCIvarRefExpr>(
Expr) ||
907 isa<ParenListExpr>(
Expr) ||
908 isa<SizeOfPackExpr>(
Expr))
915 if (isa<ArraySubscriptExpr>(
Expr) ||
916 isa<CallExpr>(
Expr) ||
917 isa<DeclRefExpr>(
Expr) ||
918 isa<CastExpr>(
Expr) ||
919 isa<CXXNewExpr>(
Expr) ||
920 isa<CXXConstructExpr>(
Expr) ||
921 isa<CXXDeleteExpr>(
Expr) ||
922 isa<CXXNoexceptExpr>(
Expr) ||
923 isa<CXXPseudoDestructorExpr>(
Expr) ||
924 isa<CXXScalarValueInitExpr>(
Expr) ||
925 isa<CXXThisExpr>(
Expr) ||
926 isa<CXXTypeidExpr>(
Expr) ||
927 isa<CXXUnresolvedConstructExpr>(
Expr) ||
928 isa<ObjCMessageExpr>(
Expr) ||
929 isa<ObjCPropertyRefExpr>(
Expr) ||
930 isa<ObjCProtocolExpr>(
Expr) ||
931 isa<MemberExpr>(
Expr) ||
932 isa<ObjCIvarRefExpr>(
Expr) ||
934 isa<ParenListExpr>(
Expr) ||
935 isa<SizeOfPackExpr>(
Expr) ||
936 isa<UnaryOperator>(
Expr))
948 if (ICE->getCastKind() != CK_CPointerToObjCPointerCast)
969 if (
const ValueDecl *VD = DRE->getDecl())
970 return isa<EnumConstantDecl>(VD);
998 bool isTruncated = FinalTySize < OrigTySize;
999 bool needsCast =
false;
1002 switch (ICE->getCastKind()) {
1003 case CK_LValueToRValue:
1005 case CK_UserDefinedConversion:
1008 case CK_IntegralCast: {
1027 case CK_PointerToBoolean:
1028 case CK_IntegralToBoolean:
1029 case CK_IntegralToFloating:
1030 case CK_FloatingToIntegral:
1031 case CK_FloatingToBoolean:
1032 case CK_FloatingCast:
1033 case CK_FloatingComplexToReal:
1034 case CK_FloatingComplexToBoolean:
1035 case CK_IntegralComplexToReal:
1036 case CK_IntegralComplexToBoolean:
1037 case CK_AtomicToNonAtomic:
1038 case CK_AddressSpaceConversion:
1044 case CK_LValueBitCast:
1045 case CK_LValueToRValueBitCast:
1046 case CK_BaseToDerived:
1047 case CK_DerivedToBase:
1048 case CK_UncheckedDerivedToBase:
1051 case CK_ArrayToPointerDecay:
1052 case CK_FunctionToPointerDecay:
1053 case CK_NullToPointer:
1054 case CK_NullToMemberPointer:
1055 case CK_BaseToDerivedMemberPointer:
1056 case CK_DerivedToBaseMemberPointer:
1057 case CK_MemberPointerToBoolean:
1058 case CK_ReinterpretMemberPointer:
1059 case CK_ConstructorConversion:
1060 case CK_IntegralToPointer:
1061 case CK_PointerToIntegral:
1063 case CK_VectorSplat:
1064 case CK_CPointerToObjCPointerCast:
1065 case CK_BlockPointerToObjCPointerCast:
1066 case CK_AnyPointerToBlockPointerCast:
1067 case CK_ObjCObjectLValueCast:
1068 case CK_FloatingRealToComplex:
1069 case CK_FloatingComplexCast:
1070 case CK_FloatingComplexToIntegralComplex:
1071 case CK_IntegralRealToComplex:
1072 case CK_IntegralComplexCast:
1073 case CK_IntegralComplexToFloatingComplex:
1074 case CK_ARCProduceObject:
1075 case CK_ARCConsumeObject:
1076 case CK_ARCReclaimReturnedObject:
1077 case CK_ARCExtendBlockObject:
1078 case CK_NonAtomicToAtomic:
1079 case CK_CopyAndAutoreleaseBlockObject:
1080 case CK_BuiltinFnToFnPtr:
1081 case CK_ZeroToOCLOpaqueType:
1082 case CK_IntToOCLSampler:
1086 case CK_BooleanToSignedIntegral:
1087 llvm_unreachable(
"OpenCL-specific cast in Objective-C?");
1089 case CK_FloatingToFixedPoint:
1090 case CK_FixedPointToFloating:
1091 case CK_FixedPointCast:
1092 case CK_FixedPointToBoolean:
1093 case CK_FixedPointToIntegral:
1094 case CK_IntegralToFixedPoint:
1095 llvm_unreachable(
"Fixed point types are disabled for Objective-C");
1103 "converting to boxing syntax requires casting %0 to %1");
1112 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
1139 StrE = dyn_cast<StringLiteral>(OrigArg->
IgnoreParens())) {
1141 commit.
insert(StrE->getBeginLoc(),
"@");
1151 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
@ SuperInstance
The receiver is the instance of the superclass object.
Represents an ObjC class declaration.
static bool castOperatorNeedsParens(const Expr *FullExpr)
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
@ NSStr_stringWithCString
A boolean literal, per ([C++ lex.bool] Boolean literals).
static bool getLiteralInfo(SourceRange literalRange, bool isFloat, bool isIntZero, ASTContext &Ctx, LiteralInfo &Info)
static bool rewriteToArraySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Optional< NSNumberLiteralMethodKind > getNSNumberLiteralMethodKind(Selector Sel) const
Return NSNumberLiteralMethodKind if Sel is such a selector.
A trivial tuple used to represent a source range.
@ NSDict_initWithObjectsAndKeys
bool insertWrap(StringRef before, CharSourceRange range, StringRef after)
bool insertFromRange(SourceLocation loc, CharSourceRange range, bool afterToken=false, bool beforePreviousInsertions=false)
static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, Selector Sel) const
Selector getSelector() const
IdentifierInfo * getNSClassId(NSClassIdKindKind K) const
Stmt * getParentIgnoreParenCasts(Stmt *) const
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
SourceLocation getBegin() const
static bool rewriteToDictionarySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool insert(SourceLocation loc, StringRef text, bool afterToken=false, bool beforePreviousInsertions=false)
@ NSNumberWithUnsignedLongLong
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
@ NSStr_stringWithCStringEncoding
A (possibly-)qualified type.
bool replace(CharSourceRange range, StringRef text)
bool isFloatingType() const
Concrete class used by the front-end to report problems and issues.
static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
@ NSMutableDict_setObjectForKey
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
static bool subscriptOperatorNeedsParens(const Expr *FullExpr)
bool insertAfterToken(SourceLocation loc, StringRef text, bool beforePreviousInsertions=false)
@ SuperClass
The receiver is a superclass.
Selector getNSArraySelector(NSArrayMethodKind MK) const
The Objective-C NSArray selectors.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceManager & getSourceManager()
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
ASTContext & getASTContext() const
static bool rewriteToArraySubscriptGet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Represents a class type in Objective C.
FullExpr - Represents a "full-expression" node.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
@ NSNumberWithUnsignedInteger
@ NSStr_initWithUTF8String
static CharSourceRange getCharRange(SourceRange R)
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
@ NSDict_dictionaryWithObjectForKey
bool isNSUTF8StringEncodingConstant(const Expr *E) const
Returns true if the expression.
@ NSMutableArr_replaceObjectAtIndex
SourceLocation getEnd() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
@ NSDict_initWithObjectsForKeys
const T * getAs() const
Member-template getAs<specific type>'.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
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 ...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
SourceLocation getEndLoc() const LLVM_READONLY
@ NSNumberWithUnsignedShort
@ Class
The receiver is a class.
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...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
StringLiteral - This represents a string literal expression, e.g.
@ NSDict_dictionaryWithObjectsAndKeys
static bool checkForLiteralCreation(const ObjCMessageExpr *Msg, IdentifierInfo *&ClassId, const LangOptions &LangOpts)
static bool rewriteToCharLiteral(const ObjCMessageExpr *Msg, const CharacterLiteral *Arg, const NSAPI &NS, Commit &commit)
@ NSNumberWithUnsignedInt
static void objectifyExpr(const Expr *E, Commit &commit)
Adds an explicit cast to 'id' if the type is not objc object.
static bool rewriteToSubscriptGetCommon(const ObjCMessageExpr *Msg, Commit &commit)
An expression that sends a message to the given Objective-C object or class.
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const
The Objective-C NSDictionary selectors.
@ NSNumberWithUnsignedLong
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Selector getObjectForKeyedSubscriptSelector() const
Returns selector for "objectForKeyedSubscript:".
bool isObjCObjectPointerType() const
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool isNSASCIIStringEncodingConstant(const Expr *E) const
Returns true if the expression.
Selector getSetObjectAtIndexedSubscriptSelector() const
Returns selector for "setObject:atIndexedSubscript".
Selector getObjectAtIndexedSubscriptSelector() const
Returns selector for "objectAtIndexedSubscript:".
@ NSStr_stringWithUTF8String
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)
@ NSDict_dictionaryWithObjectsForKeys
bool isPointerType() const
NSNumberLiteralMethodKind
Enumerates the NSNumber methods used to generate literals.
bool isObjCIdType(QualType T) const
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
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.
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *&IFace, const ObjCMessageExpr *Msg, ASTContext &Ctx, Selector subscriptSel)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
@ NSDict_dictionaryWithDictionary
Represents a character-granular source range.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
One of these records is kept for each identifier that is lexed.
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 isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
Selector getSetObjectForKeyedSubscriptSelector() const
Returns selector for "setObject:forKeyedSubscript".
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool isBooleanType() const
Selector getNSStringSelector(NSStringMethodKind MK) const
The Objective-C NSString selectors.
ObjCMethodDecl - Represents an instance or class method declaration.
@ NSNumberWithUnsignedChar
PointerType - C99 6.7.5.1 - Pointer Declarators.
@ Instance
The receiver is an object instance.
@ NSDict_initWithDictionary
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Smart pointer class that efficiently represents Objective-C method names.
bool isSentinelNullExpr(const Expr *E)
static bool isEnumConstant(const Expr *E)
bool insertBefore(SourceLocation loc, StringRef text)
static void maybePutParensOnReceiver(const Expr *Receiver, Commit &commit)
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
static bool rewriteToDictionarySubscriptGet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
QualType getSuperType() const
Retrieve the type referred to by 'super'.
bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
static bool doRewriteToUTF8StringBoxedExpressionHelper(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
This represents one expression.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
A reference to a declared variable, function, enum, etc.
bool remove(CharSourceRange range)
const LangOptions & getLangOpts() const
bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange)
DiagnosticsEngine & getDiagnostics() const
CharacterKind getKind() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.