diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-04-14 14:01:31 +0000 |
commit | dbe13110f59f48b4dbb7552b3ac2935acdeece7f (patch) | |
tree | be1815eb79b42ff482a8562b13c2dcbf0c5dcbee /include/clang/AST/ExprObjC.h | |
parent | 9da628931ebf2609493570f87824ca22402cc65f (diff) | |
download | src-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.tar.gz src-dbe13110f59f48b4dbb7552b3ac2935acdeece7f.zip |
Vendor import of clang trunk r154661:vendor/clang/clang-trunk-r154661
Notes
Notes:
svn path=/vendor/clang/dist/; revision=234287
svn path=/vendor/clang/clang-trunk-r154661/; revision=234288; tag=vendor/clang/clang-trunk-r154661
Diffstat (limited to 'include/clang/AST/ExprObjC.h')
-rw-r--r-- | include/clang/AST/ExprObjC.h | 517 |
1 files changed, 478 insertions, 39 deletions
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 55726eb4ae65..4bfd12c06930 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -18,6 +18,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" +#include "llvm/Support/Compiler.h" namespace clang { class IdentifierInfo; @@ -43,7 +44,7 @@ public: SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, String->getLocEnd()); } @@ -56,6 +57,281 @@ public: child_range children() { return child_range(&String, &String+1); } }; +/// ObjCBoolLiteralExpr - Objective-C Boolean Literal. +/// +class ObjCBoolLiteralExpr : public Expr { + bool Value; + SourceLocation Loc; +public: + ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : + Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + false, false), Value(val), Loc(l) {} + + explicit ObjCBoolLiteralExpr(EmptyShell Empty) + : Expr(ObjCBoolLiteralExprClass, Empty) { } + + bool getValue() const { return Value; } + void setValue(bool V) { Value = V; } + + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); } + + SourceLocation getLocation() const { return Loc; } + void setLocation(SourceLocation L) { Loc = L; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCBoolLiteralExprClass; + } + static bool classof(const ObjCBoolLiteralExpr *) { return true; } + + // Iterators + child_range children() { return child_range(); } +}; + +/// ObjCNumericLiteral - used for objective-c numeric literals; +/// as in: @42 or @true (c++/objc++) or @__yes (c/objc) +class ObjCNumericLiteral : public Expr { + /// Number - expression AST node for the numeric literal + Stmt *Number; + ObjCMethodDecl *ObjCNumericLiteralMethod; + SourceLocation AtLoc; +public: + ObjCNumericLiteral(Stmt *NL, QualType T, ObjCMethodDecl *method, + SourceLocation L) + : Expr(ObjCNumericLiteralClass, T, VK_RValue, OK_Ordinary, + false, false, false, false), Number(NL), + ObjCNumericLiteralMethod(method), AtLoc(L) {} + explicit ObjCNumericLiteral(EmptyShell Empty) + : Expr(ObjCNumericLiteralClass, Empty) {} + + Expr *getNumber() { return cast<Expr>(Number); } + const Expr *getNumber() const { return cast<Expr>(Number); } + + ObjCMethodDecl *getObjCNumericLiteralMethod() const { + return ObjCNumericLiteralMethod; + } + + SourceLocation getAtLoc() const { return AtLoc; } + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(AtLoc, Number->getSourceRange().getEnd()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCNumericLiteralClass; + } + static bool classof(const ObjCNumericLiteral *) { return true; } + + // Iterators + child_range children() { return child_range(&Number, &Number+1); } + + friend class ASTStmtReader; +}; + +/// ObjCArrayLiteral - used for objective-c array containers; as in: +/// @[@"Hello", NSApp, [NSNumber numberWithInt:42]]; +class ObjCArrayLiteral : public Expr { + unsigned NumElements; + SourceRange Range; + ObjCMethodDecl *ArrayWithObjectsMethod; + + ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements, + QualType T, ObjCMethodDecl * Method, + SourceRange SR); + + explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) + : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} + +public: + static ObjCArrayLiteral *Create(ASTContext &C, + llvm::ArrayRef<Expr *> Elements, + QualType T, ObjCMethodDecl * Method, + SourceRange SR); + + static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements); + + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCArrayLiteralClass; + } + static bool classof(const ObjCArrayLiteral *) { return true; } + + /// \brief Retrieve elements of array of literals. + Expr **getElements() { return reinterpret_cast<Expr **>(this + 1); } + + /// \brief Retrieve elements of array of literals. + const Expr * const *getElements() const { + return reinterpret_cast<const Expr * const*>(this + 1); + } + + /// getNumElements - Return number of elements of objective-c array literal. + unsigned getNumElements() const { return NumElements; } + + /// getExpr - Return the Expr at the specified index. + Expr *getElement(unsigned Index) { + assert((Index < NumElements) && "Arg access out of range!"); + return cast<Expr>(getElements()[Index]); + } + const Expr *getElement(unsigned Index) const { + assert((Index < NumElements) && "Arg access out of range!"); + return cast<Expr>(getElements()[Index]); + } + + ObjCMethodDecl *getArrayWithObjectsMethod() const { + return ArrayWithObjectsMethod; + } + + // Iterators + child_range children() { + return child_range((Stmt **)getElements(), + (Stmt **)getElements() + NumElements); + } + + friend class ASTStmtReader; +}; + +/// \brief An element in an Objective-C dictionary literal. +/// +struct ObjCDictionaryElement { + /// \brief The key for the dictionary element. + Expr *Key; + + /// \brief The value of the dictionary element. + Expr *Value; + + /// \brief The location of the ellipsis, if this is a pack expansion. + SourceLocation EllipsisLoc; + + /// \brief The number of elements this pack expansion will expand to, if + /// this is a pack expansion and is known. + llvm::Optional<unsigned> NumExpansions; + + /// \brief Determines whether this dictionary element is a pack expansion. + bool isPackExpansion() const { return EllipsisLoc.isValid(); } +}; + +/// ObjCDictionaryLiteral - AST node to represent objective-c dictionary +/// literals; as in: @{@"name" : NSUserName(), @"date" : [NSDate date] }; +class ObjCDictionaryLiteral : public Expr { + /// \brief Key/value pair used to store the key and value of a given element. + /// + /// Objects of this type are stored directly after the expression. + struct KeyValuePair { + Expr *Key; + Expr *Value; + }; + + /// \brief Data that describes an element that is a pack expansion, used if any + /// of the elements in the dictionary literal are pack expansions. + struct ExpansionData { + /// \brief The location of the ellipsis, if this element is a pack + /// expansion. + SourceLocation EllipsisLoc; + + /// \brief If non-zero, the number of elements that this pack + /// expansion will expand to (+1). + unsigned NumExpansionsPlusOne; + }; + + /// \brief The number of elements in this dictionary literal. + unsigned NumElements : 31; + + /// \brief Determine whether this dictionary literal has any pack expansions. + /// + /// If the dictionary literal has pack expansions, then there will + /// be an array of pack expansion data following the array of + /// key/value pairs, which provide the locations of the ellipses (if + /// any) and number of elements in the expansion (if known). If + /// there are no pack expansions, we optimize away this storage. + unsigned HasPackExpansions : 1; + + SourceRange Range; + ObjCMethodDecl *DictWithObjectsMethod; + + ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, + bool HasPackExpansions, + QualType T, ObjCMethodDecl *method, + SourceRange SR); + + explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, + bool HasPackExpansions) + : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), + HasPackExpansions(HasPackExpansions) {} + + KeyValuePair *getKeyValues() { + return reinterpret_cast<KeyValuePair *>(this + 1); + } + + const KeyValuePair *getKeyValues() const { + return reinterpret_cast<const KeyValuePair *>(this + 1); + } + + ExpansionData *getExpansionData() { + if (!HasPackExpansions) + return 0; + + return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements); + } + + const ExpansionData *getExpansionData() const { + if (!HasPackExpansions) + return 0; + + return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements); + } + +public: + static ObjCDictionaryLiteral *Create(ASTContext &C, + ArrayRef<ObjCDictionaryElement> VK, + bool HasPackExpansions, + QualType T, ObjCMethodDecl *method, + SourceRange SR); + + static ObjCDictionaryLiteral *CreateEmpty(ASTContext &C, + unsigned NumElements, + bool HasPackExpansions); + + /// getNumElements - Return number of elements of objective-c dictionary + /// literal. + unsigned getNumElements() const { return NumElements; } + + ObjCDictionaryElement getKeyValueElement(unsigned Index) const { + assert((Index < NumElements) && "Arg access out of range!"); + const KeyValuePair &KV = getKeyValues()[Index]; + ObjCDictionaryElement Result = { KV.Key, KV.Value, SourceLocation(), + llvm::Optional<unsigned>() }; + if (HasPackExpansions) { + const ExpansionData &Expansion = getExpansionData()[Index]; + Result.EllipsisLoc = Expansion.EllipsisLoc; + if (Expansion.NumExpansionsPlusOne > 0) + Result.NumExpansions = Expansion.NumExpansionsPlusOne - 1; + } + return Result; + } + + ObjCMethodDecl *getDictWithObjectsMethod() const + { return DictWithObjectsMethod; } + + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCDictionaryLiteralClass; + } + static bool classof(const ObjCDictionaryLiteral *) { return true; } + + // Iterators + child_range children() { + // Note: we're taking advantage of the layout of the KeyValuePair struct + // here. If that struct changes, this code will need to change as well. + return child_range(reinterpret_cast<Stmt **>(this + 1), + reinterpret_cast<Stmt **>(this + 1) + NumElements * 2); + } + + friend class ASTStmtReader; + friend class ASTStmtWriter; +}; + + /// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type /// and behavior as StringLiteral except that the string initializer is obtained /// from ASTContext with the encoding type as an argument. @@ -87,7 +363,7 @@ public: EncodedType = EncType; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, RParenLoc); } @@ -121,7 +397,7 @@ public: void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, RParenLoc); } @@ -161,7 +437,7 @@ public: void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(AtLoc, RParenLoc); } @@ -176,9 +452,9 @@ public: /// ObjCIvarRefExpr - A reference to an ObjC instance variable. class ObjCIvarRefExpr : public Expr { - class ObjCIvarDecl *D; - SourceLocation Loc; + ObjCIvarDecl *D; Stmt *Base; + SourceLocation Loc; bool IsArrow:1; // True if this is "X->F", false if this is "X.F". bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). @@ -190,7 +466,7 @@ public: /*TypeDependent=*/false, base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), - D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} + D(d), Base(base), Loc(l), IsArrow(arrow), IsFreeIvar(freeIvar) {} explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} @@ -211,7 +487,7 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return isFreeIvar() ? SourceRange(Loc) : SourceRange(getBase()->getLocStart(), Loc); } @@ -227,7 +503,6 @@ public: /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC /// property. -/// class ObjCPropertyRefExpr : public Expr { private: /// If the bool is true, this is an implicit property reference; the @@ -235,7 +510,23 @@ private: /// if the bool is false, this is an explicit property reference; /// the pointer is an ObjCPropertyDecl and Setter is always null. llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter; - ObjCMethodDecl *Setter; + + /// \brief Indicates whether the property reference will result in a message + /// to the getter, the setter, or both. + /// This applies to both implicit and explicit property references. + enum MethodRefFlags { + MethodRef_None = 0, + MethodRef_Getter = 0x1, + MethodRef_Setter = 0x2 + }; + + /// \brief Contains the Setter method pointer and MethodRefFlags bit flags. + llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags; + + // FIXME: Maybe we should store the property identifier here, + // because it's not rederivable from the other data when there's an + // implicit property with no getter (because the 'foo' -> 'setFoo:' + // transformation is lossy on the first character). SourceLocation IdLoc; @@ -253,8 +544,9 @@ public: /*TypeDependent=*/false, base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), Setter(0), + PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), IdLoc(l), ReceiverLoc(), Receiver(base) { + assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, @@ -263,8 +555,9 @@ public: : Expr(ObjCPropertyRefExprClass, t, VK, OK, /*TypeDependent=*/false, false, st->isInstantiationDependentType(), st->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), Setter(0), + PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { + assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, @@ -273,8 +566,9 @@ public: : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, Base->isValueDependent(), Base->isInstantiationDependent(), Base->containsUnexpandedParameterPack()), - PropertyOrGetter(Getter, true), Setter(Setter), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { + assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, @@ -282,8 +576,9 @@ public: SourceLocation IdLoc, SourceLocation SuperLoc, QualType SuperTy) : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), - PropertyOrGetter(Getter, true), Setter(Setter), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { + assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, @@ -291,8 +586,9 @@ public: SourceLocation IdLoc, SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), - PropertyOrGetter(Getter, true), Setter(Setter), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { + assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } explicit ObjCPropertyRefExpr(EmptyShell Empty) @@ -313,7 +609,7 @@ public: ObjCMethodDecl *getImplicitPropertySetter() const { assert(isImplicitProperty()); - return Setter; + return SetterAndMethodRefFlags.getPointer(); } Selector getGetterSelector() const { @@ -328,6 +624,28 @@ public: return getExplicitProperty()->getSetterName(); } + /// \brief True if the property reference will result in a message to the + /// getter. + /// This applies to both implicit and explicit property references. + bool isMessagingGetter() const { + return SetterAndMethodRefFlags.getInt() & MethodRef_Getter; + } + + /// \brief True if the property reference will result in a message to the + /// setter. + /// This applies to both implicit and explicit property references. + bool isMessagingSetter() const { + return SetterAndMethodRefFlags.getInt() & MethodRef_Setter; + } + + void setIsMessagingGetter(bool val = true) { + setMethodRefFlag(MethodRef_Getter, val); + } + + void setIsMessagingSetter(bool val = true) { + setMethodRefFlag(MethodRef_Setter, val); + } + const Expr *getBase() const { return cast<Expr>(Receiver.get<Stmt*>()); } @@ -348,14 +666,15 @@ public: if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl()) ResultType = Getter->getResultType(); else - ResultType = getType(); + ResultType = PDecl->getType(); } else { const ObjCMethodDecl *Getter = getImplicitPropertyGetter(); - ResultType = Getter->getResultType(); // with reference! + if (Getter) + ResultType = Getter->getResultType(); // with reference! } return ResultType; } - + QualType getSetterArgType() const { QualType ArgType; if (isImplicitProperty()) { @@ -381,7 +700,7 @@ public: bool isSuperReceiver() const { return Receiver.is<const Type*>(); } bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange((isObjectReceiver() ? getBase()->getLocStart() : getReceiverLocation()), IdLoc); @@ -403,15 +722,19 @@ public: private: friend class ASTStmtReader; - void setExplicitProperty(ObjCPropertyDecl *D) { + friend class ASTStmtWriter; + void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { PropertyOrGetter.setPointer(D); PropertyOrGetter.setInt(false); - Setter = 0; + SetterAndMethodRefFlags.setPointer(0); + SetterAndMethodRefFlags.setInt(methRefFlags); } - void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) { + void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, + unsigned methRefFlags) { PropertyOrGetter.setPointer(Getter); PropertyOrGetter.setInt(true); - this->Setter = Setter; + SetterAndMethodRefFlags.setPointer(Setter); + SetterAndMethodRefFlags.setInt(methRefFlags); } void setBase(Expr *Base) { Receiver = Base; } void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } @@ -419,7 +742,98 @@ private: void setLocation(SourceLocation L) { IdLoc = L; } void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; } + + void setMethodRefFlag(MethodRefFlags flag, bool val) { + unsigned f = SetterAndMethodRefFlags.getInt(); + if (val) + f |= flag; + else + f &= ~flag; + SetterAndMethodRefFlags.setInt(f); + } }; + +/// ObjCSubscriptRefExpr - used for array and dictionary subscripting. +/// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; +/// +class ObjCSubscriptRefExpr : public Expr { + // Location of ']' in an indexing expression. + SourceLocation RBracket; + // array/dictionary base expression. + // for arrays, this is a numeric expression. For dictionaries, this is + // an objective-c object pointer expression. + enum { BASE, KEY, END_EXPR }; + Stmt* SubExprs[END_EXPR]; + + ObjCMethodDecl *GetAtIndexMethodDecl; + + // For immutable objects this is null. When ObjCSubscriptRefExpr is to read + // an indexed object this is null too. + ObjCMethodDecl *SetAtIndexMethodDecl; + +public: + + ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, + ExprValueKind VK, ExprObjectKind OK, + ObjCMethodDecl *getMethod, + ObjCMethodDecl *setMethod, SourceLocation RB) + : Expr(ObjCSubscriptRefExprClass, T, VK, OK, + base->isTypeDependent() || key->isTypeDependent(), + base->isValueDependent() || key->isValueDependent(), + base->isInstantiationDependent() || key->isInstantiationDependent(), + (base->containsUnexpandedParameterPack() || + key->containsUnexpandedParameterPack())), + RBracket(RB), + GetAtIndexMethodDecl(getMethod), + SetAtIndexMethodDecl(setMethod) + {SubExprs[BASE] = base; SubExprs[KEY] = key;} + + explicit ObjCSubscriptRefExpr(EmptyShell Empty) + : Expr(ObjCSubscriptRefExprClass, Empty) {} + + static ObjCSubscriptRefExpr *Create(ASTContext &C, + Expr *base, + Expr *key, QualType T, + ObjCMethodDecl *getMethod, + ObjCMethodDecl *setMethod, + SourceLocation RB); + + SourceLocation getRBracket() const { return RBracket; } + void setRBracket(SourceLocation RB) { RBracket = RB; } + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(SubExprs[BASE]->getLocStart(), RBracket); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCSubscriptRefExprClass; + } + static bool classof(const ObjCSubscriptRefExpr *) { return true; } + + Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } + void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } + + Expr *getKeyExpr() const { return cast<Expr>(SubExprs[KEY]); } + void setKeyExpr(Stmt *S) { SubExprs[KEY] = S; } + + ObjCMethodDecl *getAtIndexMethodDecl() const { + return GetAtIndexMethodDecl; + } + + ObjCMethodDecl *setAtIndexMethodDecl() const { + return SetAtIndexMethodDecl; + } + + bool isArraySubscriptRefExpr() const { + return getKeyExpr()->getType()->isIntegralOrEnumerationType(); + } + + child_range children() { + return child_range(SubExprs, SubExprs+END_EXPR); + } +private: + friend class ASTStmtReader; +}; + /// \brief An expression that sends a message to the given Objective-C /// object or class. @@ -477,7 +891,11 @@ class ObjCMessageExpr : public Expr { /// \brief Whether this message send is a "delegate init call", /// i.e. a call of an init method on self from within an init method. unsigned IsDelegateInitCall : 1; - + + /// \brief Whether this message send was implicitly generated by + /// the implementation rather than explicitly written by the user. + unsigned IsImplicit : 1; + /// \brief Whether the locations of the selector identifiers are in a /// "standard" position, a enum SelectorLocationsKind. unsigned SelLocsKind : 2; @@ -492,7 +910,7 @@ class ObjCMessageExpr : public Expr { ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), - HasMethod(0), IsDelegateInitCall(0) { + HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) { setNumArgs(NumArgs); } @@ -506,7 +924,8 @@ class ObjCMessageExpr : public Expr { SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, @@ -515,7 +934,8 @@ class ObjCMessageExpr : public Expr { SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); ObjCMessageExpr(QualType T, ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, @@ -524,7 +944,8 @@ class ObjCMessageExpr : public Expr { SelectorLocationsKind SelLocsK, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); void initArgsAndSelLocs(ArrayRef<Expr *> Args, ArrayRef<SourceLocation> SelLocs, @@ -625,7 +1046,8 @@ public: ArrayRef<SourceLocation> SelLocs, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); /// \brief Create a class message send. /// @@ -660,7 +1082,8 @@ public: ArrayRef<SourceLocation> SelLocs, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); /// \brief Create an instance message send. /// @@ -695,7 +1118,8 @@ public: ArrayRef<SourceLocation> SeLocs, ObjCMethodDecl *Method, ArrayRef<Expr *> Args, - SourceLocation RBracLoc); + SourceLocation RBracLoc, + bool isImplicit); /// \brief Create an empty Objective-C message expression, to be /// filled in by subsequent calls. @@ -708,6 +1132,11 @@ public: unsigned NumArgs, unsigned NumStoredSelLocs); + /// \brief Indicates whether the message send was implicitly + /// generated by the implementation. If false, it was written explicitly + /// in the source code. + bool isImplicit() const { return IsImplicit; } + /// \brief Determine the kind of receiver that this message is being /// sent to. ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } @@ -877,7 +1306,11 @@ public: SourceLocation getLeftLoc() const { return LBracLoc; } SourceLocation getRightLoc() const { return RBracLoc; } - SourceLocation getSelectorStartLoc() const { return getSelectorLoc(0); } + SourceLocation getSelectorStartLoc() const { + if (isImplicit()) + return getLocStart(); + return getSelectorLoc(0); + } SourceLocation getSelectorLoc(unsigned Index) const { assert(Index < getNumSelectorLocs() && "Index out of range!"); if (hasStandardSelLocs()) @@ -892,6 +1325,8 @@ public: void getSelectorLocs(SmallVectorImpl<SourceLocation> &SelLocs) const; unsigned getNumSelectorLocs() const { + if (isImplicit()) + return 0; Selector Sel = getSelector(); if (Sel.isUnarySelector()) return 1; @@ -902,7 +1337,7 @@ public: LBracLoc = R.getBegin(); RBracLoc = R.getEnd(); } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(LBracLoc, RBracLoc); } @@ -965,11 +1400,11 @@ public: SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getBase()->getLocStart(), IsaMemberLoc); } - SourceLocation getExprLoc() const { return IsaMemberLoc; } + SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; @@ -1038,8 +1473,12 @@ public: child_range children() { return child_range(&Operand, &Operand+1); } // Source locations are determined by the subexpression. - SourceRange getSourceRange() const { return Operand->getSourceRange(); } - SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); } + SourceRange getSourceRange() const LLVM_READONLY { + return Operand->getSourceRange(); + } + SourceLocation getExprLoc() const LLVM_READONLY { + return getSubExpr()->getExprLoc(); + } static bool classof(const Stmt *s) { return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass; @@ -1086,7 +1525,7 @@ public: /// \brief The location of the bridge keyword. SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } - SourceRange getSourceRange() const { + SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(LParenLoc, getSubExpr()->getLocEnd()); } |