23 using namespace clang;
42 if (LangOpts.ObjCAutoRefCount) {
70 if ((isa<ObjCStringLiteral>(Arg) &&
75 (isa<ObjCArrayLiteral>(Arg) &&
80 (isa<ObjCDictionaryLiteral>(Arg) &&
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) {
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)) {
769 if (UOE->getOpcode() == UO_Plus || UOE->getOpcode() == UO_Minus)
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;
807 CallIsUnsigned =
true;
814 CallIsUnsigned =
true;
817 CallIsLongLong =
true;
824 CallIsFloating =
true;
848 if (LitIsFloat && !CallIsFloating)
856 bool isIntZero =
false;
857 if (
const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
858 isIntZero = !IntE->getValue().getBoolValue();
859 if (!
getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
863 if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
870 LitInfo.WithoutSuffRange);
873 if (!LitIsFloat && CallIsFloating)
874 commit.
insert(LitE,
".0");
876 if (CallIsFloating) {
878 commit.
insert(LitE, LitInfo.F);
881 commit.
insert(LitE, LitInfo.U);
884 commit.
insert(LitE, LitInfo.L);
885 else if (CallIsLongLong)
886 commit.
insert(LitE, LitInfo.LL);
895 if (isa<ArraySubscriptExpr>(Expr) ||
896 isa<CallExpr>(Expr) ||
897 isa<DeclRefExpr>(Expr) ||
898 isa<CXXNamedCastExpr>(Expr) ||
899 isa<CXXConstructExpr>(Expr) ||
900 isa<CXXThisExpr>(Expr) ||
901 isa<CXXTypeidExpr>(Expr) ||
902 isa<CXXUnresolvedConstructExpr>(Expr) ||
903 isa<ObjCMessageExpr>(Expr) ||
904 isa<ObjCPropertyRefExpr>(Expr) ||
905 isa<ObjCProtocolExpr>(Expr) ||
906 isa<MemberExpr>(Expr) ||
907 isa<ObjCIvarRefExpr>(Expr) ||
908 isa<ParenExpr>(FullExpr) ||
909 isa<ParenListExpr>(Expr) ||
910 isa<SizeOfPackExpr>(Expr))
917 if (isa<ArraySubscriptExpr>(Expr) ||
918 isa<CallExpr>(Expr) ||
919 isa<DeclRefExpr>(Expr) ||
920 isa<CastExpr>(Expr) ||
921 isa<CXXNewExpr>(Expr) ||
922 isa<CXXConstructExpr>(Expr) ||
923 isa<CXXDeleteExpr>(Expr) ||
924 isa<CXXNoexceptExpr>(Expr) ||
925 isa<CXXPseudoDestructorExpr>(Expr) ||
926 isa<CXXScalarValueInitExpr>(Expr) ||
927 isa<CXXThisExpr>(Expr) ||
928 isa<CXXTypeidExpr>(Expr) ||
929 isa<CXXUnresolvedConstructExpr>(Expr) ||
930 isa<ObjCMessageExpr>(Expr) ||
931 isa<ObjCPropertyRefExpr>(Expr) ||
932 isa<ObjCProtocolExpr>(Expr) ||
933 isa<MemberExpr>(Expr) ||
934 isa<ObjCIvarRefExpr>(Expr) ||
935 isa<ParenExpr>(FullExpr) ||
936 isa<ParenListExpr>(Expr) ||
937 isa<SizeOfPackExpr>(Expr) ||
938 isa<UnaryOperator>(Expr))
950 if (ICE->getCastKind() != CK_CPointerToObjCPointerCast)
971 if (
const ValueDecl *VD = DRE->getDecl())
972 return isa<EnumConstantDecl>(VD);
1000 bool isTruncated = FinalTySize < OrigTySize;
1001 bool needsCast =
false;
1004 switch (ICE->getCastKind()) {
1005 case CK_LValueToRValue:
1007 case CK_UserDefinedConversion:
1010 case CK_IntegralCast: {
1029 case CK_PointerToBoolean:
1030 case CK_IntegralToBoolean:
1031 case CK_IntegralToFloating:
1032 case CK_FloatingToIntegral:
1033 case CK_FloatingToBoolean:
1034 case CK_FloatingCast:
1035 case CK_FloatingComplexToReal:
1036 case CK_FloatingComplexToBoolean:
1037 case CK_IntegralComplexToReal:
1038 case CK_IntegralComplexToBoolean:
1039 case CK_AtomicToNonAtomic:
1040 case CK_AddressSpaceConversion:
1046 case CK_LValueBitCast:
1047 case CK_BaseToDerived:
1048 case CK_DerivedToBase:
1049 case CK_UncheckedDerivedToBase:
1052 case CK_ArrayToPointerDecay:
1053 case CK_FunctionToPointerDecay:
1054 case CK_NullToPointer:
1055 case CK_NullToMemberPointer:
1056 case CK_BaseToDerivedMemberPointer:
1057 case CK_DerivedToBaseMemberPointer:
1058 case CK_MemberPointerToBoolean:
1059 case CK_ReinterpretMemberPointer:
1060 case CK_ConstructorConversion:
1061 case CK_IntegralToPointer:
1062 case CK_PointerToIntegral:
1064 case CK_VectorSplat:
1065 case CK_CPointerToObjCPointerCast:
1066 case CK_BlockPointerToObjCPointerCast:
1067 case CK_AnyPointerToBlockPointerCast:
1068 case CK_ObjCObjectLValueCast:
1069 case CK_FloatingRealToComplex:
1070 case CK_FloatingComplexCast:
1071 case CK_FloatingComplexToIntegralComplex:
1072 case CK_IntegralRealToComplex:
1073 case CK_IntegralComplexCast:
1074 case CK_IntegralComplexToFloatingComplex:
1075 case CK_ARCProduceObject:
1076 case CK_ARCConsumeObject:
1077 case CK_ARCReclaimReturnedObject:
1078 case CK_ARCExtendBlockObject:
1079 case CK_NonAtomicToAtomic:
1080 case CK_CopyAndAutoreleaseBlockObject:
1081 case CK_BuiltinFnToFnPtr:
1082 case CK_ZeroToOCLEvent:
1083 case CK_ZeroToOCLQueue:
1084 case CK_IntToOCLSampler:
1087 case CK_BooleanToSignedIntegral:
1088 llvm_unreachable(
"OpenCL-specific cast in Objective-C?");
1096 "converting to boxing syntax requires casting %0 to %1");
1105 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
1132 StrE = dyn_cast<StringLiteral>(OrigArg->
IgnoreParens())) {
1134 commit.
insert(StrE->getLocStart(),
"@");
1144 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
getName - Get the name of identifier for this declaration as a StringRef.
Smart pointer class that efficiently represents Objective-C method names.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
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
getIdentifier - Get the identifier that names this declaration, if there is one.
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
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.
ObjCMethodDecl - Represents an instance or class method declaration.
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
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Selector getNSStringSelector(NSStringMethodKind MK) const
The Objective-C NSString selectors.
bool insert(SourceLocation loc, StringRef text, bool afterToken=false, bool beforePreviousInsertions=false)
One of these records is kept for each identifier that is lexed.
Represents a class type in Objective C.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool isEnumConstant(const Expr *E)
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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...
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp, [NSNumber numberWithInt:42]];.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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
Gets the interface declaration for this object type, if the base type really is an interface...
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
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
SourceLocation getLocEnd() const LLVM_READONLY
Selector getSetObjectAtIndexedSubscriptSelector() const
Returns selector for "setObject:atIndexedSubscript".
static bool castOperatorNeedsParens(const Expr *FullExpr)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
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
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
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)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > LLVM_ATTRIBUTE_UNUSED has
Matches AST nodes that have child AST nodes that match the provided matcher.
Selector getObjectForKeyedSubscriptSelector() const
Returns selector for "objectForKeyedSubscript:".
bool isNSASCIIStringEncodingConstant(const Expr *E) const
Returns true if the expression.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
SourceLocation getBegin() const
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
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
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
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()))
ASTContext & getASTContext() const
static bool rewriteToArraySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
bool isSentinelNullExpr(const Expr *E)
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)
detail::InMemoryDirectory::const_iterator E
Selector getSetObjectForKeyedSubscriptSelector() const
Returns selector for "setObject:forKeyedSubscript".
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
const T * getAs() const
Member-template getAs<specific type>'.
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.
static bool getLiteralInfo(SourceRange literalRange, bool isFloat, bool isIntZero, ASTContext &Ctx, LiteralInfo &Info)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
bool insertBefore(SourceLocation loc, StringRef text)
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
A reference to a declared variable, function, enum, etc.
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
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
bool isNull() const
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)
SourceLocation getLocStart() const LLVM_READONLY
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
bool isPointerType() const