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,
"@[]");
464 Objs.push_back(Msg->
getArg(0));
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) {
594 SourceRange ArgRange(Keys.front()->getBeginLoc(), Keys.back()->getEndLoc());
630 if (Vals.size() != Keys.size())
677 StringRef U, F, L, LL;
684 bool isFloat,
bool isIntZero,
699 static bool has(StringRef suff, StringRef &text) {
700 if (text.endswith(suff)) {
701 text = text.substr(0, text.size()-suff.size());
721 }
else if (isFloat &&
Suff::has(
"f", text)) {
723 }
else if (isFloat &&
Suff::has(
"F", text)) {
729 if (!UpperU.hasValue() && !UpperL.hasValue())
730 UpperU = UpperL =
true;
731 else if (UpperU.hasValue() && !UpperL.hasValue())
733 else if (UpperL.hasValue() && !UpperU.hasValue())
736 Info.U = *UpperU ?
"U" :
"u";
737 Info.L = *UpperL ?
"L" :
"l";
738 Info.LL = *UpperL ?
"LL" :
"ll";
739 Info.F = UpperF ?
"F" :
"f";
741 Info.Hex = Info.Octal =
false;
742 if (text.startswith(
"0x"))
744 else if (!isFloat && !isIntZero && text.startswith(
"0"))
748 Info.WithoutSuffRange =
766 const Expr *literalE = Arg;
767 if (
const UnaryOperator *UOE = dyn_cast<UnaryOperator>(literalE)) {
768 if (UOE->getOpcode() == UO_Plus || UOE->getOpcode() == UO_Minus)
769 literalE = UOE->getSubExpr();
774 if (!isa<IntegerLiteral>(literalE) && !isa<FloatingLiteral>(literalE))
785 bool CallIsUnsigned =
false, CallIsLong =
false, CallIsLongLong =
false;
786 bool CallIsFloating =
false, CallIsDouble =
false;
799 CallIsUnsigned =
true;
806 CallIsUnsigned =
true;
813 CallIsUnsigned =
true;
816 CallIsLongLong =
true;
823 CallIsFloating =
true;
847 if (LitIsFloat && !CallIsFloating)
855 bool isIntZero =
false;
856 if (
const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
857 isIntZero = !IntE->getValue().getBoolValue();
858 if (!
getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
862 if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
869 LitInfo.WithoutSuffRange);
872 if (!LitIsFloat && CallIsFloating)
873 commit.
insert(LitE,
".0");
875 if (CallIsFloating) {
877 commit.
insert(LitE, LitInfo.F);
880 commit.
insert(LitE, LitInfo.U);
883 commit.
insert(LitE, LitInfo.L);
884 else if (CallIsLongLong)
885 commit.
insert(LitE, LitInfo.LL);
894 if (isa<ArraySubscriptExpr>(Expr) ||
895 isa<CallExpr>(Expr) ||
896 isa<DeclRefExpr>(Expr) ||
897 isa<CXXNamedCastExpr>(Expr) ||
898 isa<CXXConstructExpr>(Expr) ||
899 isa<CXXThisExpr>(Expr) ||
900 isa<CXXTypeidExpr>(Expr) ||
901 isa<CXXUnresolvedConstructExpr>(Expr) ||
902 isa<ObjCMessageExpr>(Expr) ||
903 isa<ObjCPropertyRefExpr>(Expr) ||
904 isa<ObjCProtocolExpr>(Expr) ||
905 isa<MemberExpr>(Expr) ||
906 isa<ObjCIvarRefExpr>(Expr) ||
907 isa<ParenExpr>(FullExpr) ||
908 isa<ParenListExpr>(Expr) ||
909 isa<SizeOfPackExpr>(Expr))
916 if (isa<ArraySubscriptExpr>(Expr) ||
917 isa<CallExpr>(Expr) ||
918 isa<DeclRefExpr>(Expr) ||
919 isa<CastExpr>(Expr) ||
920 isa<CXXNewExpr>(Expr) ||
921 isa<CXXConstructExpr>(Expr) ||
922 isa<CXXDeleteExpr>(Expr) ||
923 isa<CXXNoexceptExpr>(Expr) ||
924 isa<CXXPseudoDestructorExpr>(Expr) ||
925 isa<CXXScalarValueInitExpr>(Expr) ||
926 isa<CXXThisExpr>(Expr) ||
927 isa<CXXTypeidExpr>(Expr) ||
928 isa<CXXUnresolvedConstructExpr>(Expr) ||
929 isa<ObjCMessageExpr>(Expr) ||
930 isa<ObjCPropertyRefExpr>(Expr) ||
931 isa<ObjCProtocolExpr>(Expr) ||
932 isa<MemberExpr>(Expr) ||
933 isa<ObjCIvarRefExpr>(Expr) ||
934 isa<ParenExpr>(FullExpr) ||
935 isa<ParenListExpr>(Expr) ||
936 isa<SizeOfPackExpr>(Expr) ||
937 isa<UnaryOperator>(Expr))
949 if (ICE->getCastKind() != CK_CPointerToObjCPointerCast)
970 if (
const ValueDecl *VD = DRE->getDecl())
971 return isa<EnumConstantDecl>(VD);
999 bool isTruncated = FinalTySize < OrigTySize;
1000 bool needsCast =
false;
1003 switch (ICE->getCastKind()) {
1004 case CK_LValueToRValue:
1006 case CK_UserDefinedConversion:
1009 case CK_IntegralCast: {
1028 case CK_PointerToBoolean:
1029 case CK_IntegralToBoolean:
1030 case CK_IntegralToFloating:
1031 case CK_FloatingToIntegral:
1032 case CK_FloatingToBoolean:
1033 case CK_FloatingCast:
1034 case CK_FloatingComplexToReal:
1035 case CK_FloatingComplexToBoolean:
1036 case CK_IntegralComplexToReal:
1037 case CK_IntegralComplexToBoolean:
1038 case CK_AtomicToNonAtomic:
1039 case CK_AddressSpaceConversion:
1045 case CK_LValueBitCast:
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:
1085 case CK_BooleanToSignedIntegral:
1086 llvm_unreachable(
"OpenCL-specific cast in Objective-C?");
1088 case CK_FixedPointCast:
1089 case CK_FixedPointToBoolean:
1090 llvm_unreachable(
"Fixed point types are disabled for Objective-C");
1098 "converting to boxing syntax requires casting %0 to %1");
1107 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
1134 StrE = dyn_cast<StringLiteral>(OrigArg->
IgnoreParens())) {
1136 commit.
insert(StrE->getBeginLoc(),
"@");
1146 if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
Selector getObjectAtIndexedSubscriptSelector() const
Returns selector for "objectAtIndexedSubscript:".
The receiver is the instance of the superclass object.
Defines the clang::ASTContext interface.
bool remove(CharSourceRange range)
The receiver is an object instance.
Smart pointer class that efficiently represents Objective-C method names.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Selector getSelector() const
bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
bool insertWrap(StringRef before, CharSourceRange range, StringRef after)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
static CharSourceRange getTokenRange(SourceRange R)
ObjCInterfaceDecl * getReceiverInterface() const
Retrieve the Objective-C interface to which this message is being directed, if known.
static bool rewriteToSubscriptGetCommon(const ObjCMessageExpr *Msg, Commit &commit)
NSNumberLiteralMethodKind
Enumerates the NSNumber methods used to generate literals.
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool insertAfterToken(SourceLocation loc, StringRef text, bool beforePreviousInsertions=false)
bool insertFromRange(SourceLocation loc, CharSourceRange range, bool afterToken=false, bool beforePreviousInsertions=false)
static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
const T * getAs() const
Member-template getAs<specific type>'.
ObjCMethodDecl - Represents an instance or class method declaration.
Defines the clang::Expr interface and subclasses for C++ expressions.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
bool insert(SourceLocation loc, StringRef text, bool afterToken=false, bool beforePreviousInsertions=false)
One of these records is kept for each identifier that is lexed.
Selector getSetObjectForKeyedSubscriptSelector() const
Returns selector for "setObject:forKeyedSubscript".
bool isObjCIdType(QualType T) const
Represents a class type in Objective C.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool isEnumConstant(const Expr *E)
FullExpr - Represents a "full-expression" node.
SourceLocation getBeginLoc() const LLVM_READONLY
Selector getNSStringSelector(NSStringMethodKind MK) const
The Objective-C NSString selectors.
static void objectifyExpr(const Expr *E, Commit &commit)
Adds an explicit cast to 'id' if the type is not objc object.
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]];.
Optional< NSNumberLiteralMethodKind > getNSNumberLiteralMethodKind(Selector Sel) const
Return NSNumberLiteralMethodKind if Sel is such a selector.
bool replace(CharSourceRange range, StringRef text)
static bool rewriteToDictionarySubscriptGet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Concrete class used by the front-end to report problems and issues.
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
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.
Represents an ObjC class declaration.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface...
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 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 ...
static bool castOperatorNeedsParens(const Expr *FullExpr)
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
Represents a character-granular source range.
Selector getNSArraySelector(NSArrayMethodKind MK) const
The Objective-C NSArray selectors.
static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
ASTContext & getASTContext() const
static bool doRewriteToUTF8StringBoxedExpressionHelper(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
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.
An expression that sends a message to the given Objective-C object or class.
static bool subscriptOperatorNeedsParens(const Expr *FullExpr)
SourceLocation getEnd() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
static bool checkForLiteralCreation(const ObjCMessageExpr *Msg, IdentifierInfo *&ClassId, const LangOptions &LangOpts)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isNSUTF8StringEncodingConstant(const Expr *E) const
Returns true if the expression.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getEndLoc() const LLVM_READONLY
static CharSourceRange getCharRange(SourceRange R)
static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap)
unsigned getNumArgs() const
Return the number of actual arguments in this message, not counting the receiver. ...
Encodes a location in the source.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
bool isObjCObjectPointerType() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool isImplicit() const
Indicates whether the message send was implicitly generated by the implementation.
CharacterKind getKind() const
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
const ObjCMethodDecl * getMethodDecl() const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
IdentifierInfo * getNSClassId(NSClassIdKindKind K) const
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
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)
static bool rewriteToArraySubscriptSet(const ObjCInterfaceDecl *IFace, const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
Dataflow Directional Tag Classes.
bool isSentinelNullExpr(const Expr *E)
static bool rewriteToBoolLiteral(const ObjCMessageExpr *Msg, const Expr *Arg, const NSAPI &NS, Commit &commit)
QualType getSuperType() const
Retrieve the type referred to by 'super'.
static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *&IFace, const ObjCMessageExpr *Msg, ASTContext &Ctx, Selector subscriptSel)
bool isBooleanType() const
bool isNSNumberLiteralSelector(NSNumberLiteralMethodKind MK, Selector Sel) const
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit)
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
SourceManager & getSourceManager()
Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const
The Objective-C NSDictionary selectors.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
static void maybePutParensOnReceiver(const Expr *Receiver, Commit &commit)
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...
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.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
bool insertBefore(SourceLocation loc, StringRef text)
Stmt * getParentIgnoreParenCasts(Stmt *) const
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)
bool isPointerType() const
bool isFloatingType() const
A trivial tuple used to represent a source range.
A boolean literal, per ([C++ lex.bool] Boolean literals).
Selector getObjectForKeyedSubscriptSelector() const
Returns selector for "objectForKeyedSubscript:".
The receiver is a superclass.
static bool rewriteToCharLiteral(const ObjCMessageExpr *Msg, const CharacterLiteral *Arg, const NSAPI &NS, Commit &commit)
SourceLocation getBegin() const
const LangOptions & getLangOpts() const
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
bool isNSASCIIStringEncodingConstant(const Expr *E) const
Returns true if the expression.
Selector getSetObjectAtIndexedSubscriptSelector() const
Returns selector for "setObject:atIndexedSubscript".