//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the ExprObjC interface and subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H #include "clang/AST/Expr.h" #include "clang/Basic/IdentifierTable.h" namespace clang { class IdentifierInfo; class ASTContext; class ObjCMethodDecl; class ObjCPropertyDecl; /// ObjCStringLiteral, used for Objective-C string literals /// i.e. @"foo". class ObjCStringLiteral : public Expr { Stmt *String; SourceLocation AtLoc; public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) : Expr(ObjCStringLiteralClass, T, false, false), String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} StringLiteral *getString() { return cast(String); } const StringLiteral *getString() const { return cast(String); } void setString(StringLiteral *S) { String = S; } SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, String->getLocEnd()); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } static bool classof(const ObjCStringLiteral *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// 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. class ObjCEncodeExpr : public Expr { TypeSourceInfo *EncodedType; SourceLocation AtLoc, RParenLoc; public: ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, SourceLocation rp) : Expr(ObjCEncodeExprClass, T, EncodedType->getType()->isDependentType(), EncodedType->getType()->isDependentType()), EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } QualType getEncodedType() const { return EncodedType->getType(); } TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { EncodedType = EncType; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCEncodeExprClass; } static bool classof(const ObjCEncodeExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCSelectorExpr used for @selector in Objective-C. class ObjCSelectorExpr : public Expr { Selector SelName; SourceLocation AtLoc, RParenLoc; public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) : Expr(ObjCSelectorExprClass, T, false, false), SelName(selInfo), AtLoc(at), RParenLoc(rp){} explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} Selector getSelector() const { return SelName; } void setSelector(Selector S) { SelName = S; } SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); } /// getNumArgs - Return the number of actual arguments to this call. unsigned getNumArgs() const { return SelName.getNumArgs(); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSelectorExprClass; } static bool classof(const ObjCSelectorExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCProtocolExpr used for protocol expression in Objective-C. This is used /// as: @protocol(foo), as in: /// obj conformsToProtocol:@protocol(foo)] /// The return type is "Protocol*". class ObjCProtocolExpr : public Expr { ObjCProtocolDecl *TheProtocol; SourceLocation AtLoc, RParenLoc; public: ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation rp) : Expr(ObjCProtocolExprClass, T, false, false), TheProtocol(protocol), AtLoc(at), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} ObjCProtocolDecl *getProtocol() const { return TheProtocol; } void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } SourceLocation getAtLoc() const { return AtLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(AtLoc, RParenLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCProtocolExprClass; } static bool classof(const ObjCProtocolExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCIvarRefExpr - A reference to an ObjC instance variable. class ObjCIvarRefExpr : public Expr { class ObjCIvarDecl *D; SourceLocation Loc; Stmt *Base; 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). public: ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, Expr *base, bool arrow = false, bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false, base->isValueDependent()), D(d), Loc(l), Base(base), IsArrow(arrow), IsFreeIvar(freeIvar) {} explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} ObjCIvarDecl *getDecl() { return D; } const ObjCIvarDecl *getDecl() const { return D; } void setDecl(ObjCIvarDecl *d) { D = d; } const Expr *getBase() const { return cast(Base); } Expr *getBase() { return cast(Base); } void setBase(Expr * base) { Base = base; } bool isArrow() const { return IsArrow; } bool isFreeIvar() const { return IsFreeIvar; } void setIsArrow(bool A) { IsArrow = A; } void setIsFreeIvar(bool A) { IsFreeIvar = A; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } virtual SourceRange getSourceRange() const { return isFreeIvar() ? SourceRange(Loc) : SourceRange(getBase()->getLocStart(), Loc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } static bool classof(const ObjCIvarRefExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC /// property. /// class ObjCPropertyRefExpr : public Expr { private: ObjCPropertyDecl *AsProperty; SourceLocation IdLoc; Stmt *Base; public: ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, SourceLocation l, Expr *base) : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false, base->isValueDependent()), AsProperty(PD), IdLoc(l), Base(base) { } explicit ObjCPropertyRefExpr(EmptyShell Empty) : Expr(ObjCPropertyRefExprClass, Empty) {} ObjCPropertyDecl *getProperty() const { return AsProperty; } void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } const Expr *getBase() const { return cast(Base); } Expr *getBase() { return cast(Base); } void setBase(Expr *base) { Base = base; } SourceLocation getLocation() const { return IdLoc; } void setLocation(SourceLocation L) { IdLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(getBase()->getLocStart(), IdLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCPropertyRefExprClass; } static bool classof(const ObjCPropertyRefExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCImplicitSetterGetterRefExpr - A dot-syntax expression to access two /// methods; one to set a value to an 'ivar' (Setter) and the other to access /// an 'ivar' (Setter). /// An example for use of this AST is: /// @code /// @interface Test { } /// - (Test *)crash; /// - (void)setCrash: (Test*)value; /// @end /// void foo(Test *p1, Test *p2) /// { /// p2.crash = p1.crash; // Uses ObjCImplicitSetterGetterRefExpr AST /// } /// @endcode class ObjCImplicitSetterGetterRefExpr : public Expr { /// Setter - Setter method user declared for setting its 'ivar' to a value ObjCMethodDecl *Setter; /// Getter - Getter method user declared for accessing 'ivar' it controls. ObjCMethodDecl *Getter; /// Location of the member in the dot syntax notation. This is location /// of the getter method. SourceLocation MemberLoc; // FIXME: Swizzle these into a single pointer. Stmt *Base; ObjCInterfaceDecl *InterfaceDecl; /// Location of the receiver class in the dot syntax notation /// used to call a class method setter/getter. SourceLocation ClassLoc; public: ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, ObjCMethodDecl *setter, SourceLocation l, Expr *base) : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false, base->isValueDependent()), Setter(setter), Getter(getter), MemberLoc(l), Base(base), InterfaceDecl(0), ClassLoc(SourceLocation()) { } ObjCImplicitSetterGetterRefExpr(ObjCMethodDecl *getter, QualType t, ObjCMethodDecl *setter, SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false), Setter(setter), Getter(getter), MemberLoc(l), Base(0), InterfaceDecl(C), ClassLoc(CL) { } explicit ObjCImplicitSetterGetterRefExpr(EmptyShell Empty) : Expr(ObjCImplicitSetterGetterRefExprClass, Empty){} ObjCMethodDecl *getGetterMethod() const { return Getter; } ObjCMethodDecl *getSetterMethod() const { return Setter; } ObjCInterfaceDecl *getInterfaceDecl() const { return InterfaceDecl; } void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } void setInterfaceDecl(ObjCInterfaceDecl *D) { InterfaceDecl = D; } virtual SourceRange getSourceRange() const { if (Base) return SourceRange(getBase()->getLocStart(), MemberLoc); return SourceRange(ClassLoc, MemberLoc); } const Expr *getBase() const { return cast_or_null(Base); } Expr *getBase() { return cast_or_null(Base); } void setBase(Expr *base) { Base = base; } SourceLocation getLocation() const { return MemberLoc; } void setLocation(SourceLocation L) { MemberLoc = L; } SourceLocation getClassLoc() const { return ClassLoc; } void setClassLoc(SourceLocation L) { ClassLoc = L; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCImplicitSetterGetterRefExprClass; } static bool classof(const ObjCImplicitSetterGetterRefExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// \brief An expression that sends a message to the given Objective-C /// object or class. /// /// The following contains two message send expressions: /// /// \code /// [[NSString alloc] initWithString:@"Hello"] /// \endcode /// /// The innermost message send invokes the "alloc" class method on the /// NSString class, while the outermost message send invokes the /// "initWithString" instance method on the object returned from /// NSString's "alloc". In all, an Objective-C message send can take /// on four different (although related) forms: /// /// 1. Send to an object instance. /// 2. Send to a class. /// 3. Send to the superclass instance of the current class. /// 4. Send to the superclass of the current class. /// /// All four kinds of message sends are modeled by the ObjCMessageExpr /// class, and can be distinguished via \c getReceiverKind(). Example: /// class ObjCMessageExpr : public Expr { /// \brief The number of arguments in the message send, not /// including the receiver. unsigned NumArgs : 16; /// \brief The kind of message send this is, which is one of the /// ReceiverKind values. /// /// We pad this out to a byte to avoid excessive masking and shifting. unsigned Kind : 8; /// \brief Whether we have an actual method prototype in \c /// SelectorOrMethod. /// /// When non-zero, we have a method declaration; otherwise, we just /// have a selector. unsigned HasMethod : 8; /// \brief When the message expression is a send to 'super', this is /// the location of the 'super' keyword. SourceLocation SuperLoc; /// \brief Stores either the selector that this message is sending /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer /// referring to the method that we type-checked against. uintptr_t SelectorOrMethod; /// \brief The source locations of the open and close square /// brackets ('[' and ']', respectively). SourceLocation LBracLoc, RBracLoc; ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), HasMethod(0), SelectorOrMethod(0) { } ObjCMessageExpr(QualType T, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); ObjCMessageExpr(QualType T, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); ObjCMessageExpr(QualType T, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); /// \brief Retrieve the pointer value of the message receiver. void *getReceiverPointer() const { return *const_cast( reinterpret_cast(this + 1)); } /// \brief Set the pointer value of the message receiver. void setReceiverPointer(void *Value) { *reinterpret_cast(this + 1) = Value; } public: /// \brief The kind of receiver this message is sending to. enum ReceiverKind { /// \brief The receiver is a class. Class = 0, /// \brief The receiver is an object instance. Instance, /// \brief The receiver is a superclass. SuperClass, /// \brief The receiver is the instance of the superclass object. SuperInstance }; /// \brief Create a message send to super. /// /// \param Context The ASTContext in which this expression will be created. /// /// \param T The result type of this message. /// /// \param LBrac The location of the open square bracket '['. /// /// \param SuperLoc The location of the "super" keyword. /// /// \param IsInstanceSuper Whether this is an instance "super" /// message (otherwise, it's a class "super" message). /// /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message /// send was type-checked. May be NULL. /// /// \param Args The message send arguments. /// /// \param NumArgs The number of arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. static ObjCMessageExpr *Create(ASTContext &Context, QualType T, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, QualType SuperType, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); /// \brief Create a class message send. /// /// \param Context The ASTContext in which this expression will be created. /// /// \param T The result type of this message. /// /// \param LBrac The location of the open square bracket '['. /// /// \param Receiver The type of the receiver, including /// source-location information. /// /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message /// send was type-checked. May be NULL. /// /// \param Args The message send arguments. /// /// \param NumArgs The number of arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. static ObjCMessageExpr *Create(ASTContext &Context, QualType T, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); /// \brief Create an instance message send. /// /// \param Context The ASTContext in which this expression will be created. /// /// \param T The result type of this message. /// /// \param LBrac The location of the open square bracket '['. /// /// \param Receiver The expression used to produce the object that /// will receive this message. /// /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message /// send was type-checked. May be NULL. /// /// \param Args The message send arguments. /// /// \param NumArgs The number of arguments. /// /// \param RBracLoc The location of the closing square bracket ']'. static ObjCMessageExpr *Create(ASTContext &Context, QualType T, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc); /// \brief Create an empty Objective-C message expression, to be /// filled in by subsequent calls. /// /// \param Context The context in which the message send will be created. /// /// \param NumArgs The number of message arguments, not including /// the receiver. static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs); /// \brief Determine the kind of receiver that this message is being /// sent to. ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; } /// \brief Determine whether this is an instance message to either a /// computed object or to super. bool isInstanceMessage() const { return getReceiverKind() == Instance || getReceiverKind() == SuperInstance; } /// \brief Determine whether this is an class message to either a /// specified class or to super. bool isClassMessage() const { return getReceiverKind() == Class || getReceiverKind() == SuperClass; } /// \brief Returns the receiver of an instance message. /// /// \brief Returns the object expression for an instance message, or /// NULL for a message that is not an instance message. Expr *getInstanceReceiver() { if (getReceiverKind() == Instance) return static_cast(getReceiverPointer()); return 0; } const Expr *getInstanceReceiver() const { return const_cast(this)->getInstanceReceiver(); } /// \brief Turn this message send into an instance message that /// computes the receiver object with the given expression. void setInstanceReceiver(Expr *rec) { Kind = Instance; setReceiverPointer(rec); } /// \brief Returns the type of a class message send, or NULL if the /// message is not a class message. QualType getClassReceiver() const { if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) return TSInfo->getType(); return QualType(); } /// \brief Returns a type-source information of a class message /// send, or NULL if the message is not a class message. TypeSourceInfo *getClassReceiverTypeInfo() const { if (getReceiverKind() == Class) return reinterpret_cast(getReceiverPointer()); return 0; } void setClassReceiver(TypeSourceInfo *TSInfo) { Kind = Class; setReceiverPointer(TSInfo); } /// \brief Retrieve the location of the 'super' keyword for a class /// or instance message to 'super', otherwise an invalid source location. SourceLocation getSuperLoc() const { if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) return SuperLoc; return SourceLocation(); } /// \brief Retrieve the Objective-C interface to which this message /// is being directed, if known. /// /// This routine cross-cuts all of the different kinds of message /// sends to determine what the underlying (statically known) type /// of the receiver will be; use \c getReceiverKind() to determine /// whether the message is a class or an instance method, whether it /// is a send to super or not, etc. /// /// \returns The Objective-C interface if known, otherwise NULL. ObjCInterfaceDecl *getReceiverInterface() const; /// \brief Retrieve the type referred to by 'super'. /// /// The returned type will either be an ObjCInterfaceType (for an /// class message to super) or an ObjCObjectPointerType that refers /// to a class (for an instance message to super); QualType getSuperType() const { if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass) return QualType::getFromOpaquePtr(getReceiverPointer()); return QualType(); } void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) { Kind = IsInstanceSuper? SuperInstance : SuperClass; SuperLoc = Loc; setReceiverPointer(T.getAsOpaquePtr()); } Selector getSelector() const; void setSelector(Selector S) { HasMethod = false; SelectorOrMethod = reinterpret_cast(S.getAsOpaquePtr()); } const ObjCMethodDecl *getMethodDecl() const { if (HasMethod) return reinterpret_cast(SelectorOrMethod); return 0; } ObjCMethodDecl *getMethodDecl() { if (HasMethod) return reinterpret_cast(SelectorOrMethod); return 0; } void setMethodDecl(ObjCMethodDecl *MD) { HasMethod = true; SelectorOrMethod = reinterpret_cast(MD); } /// \brief Return the number of actual arguments in this message, /// not counting the receiver. unsigned getNumArgs() const { return NumArgs; } /// \brief Retrieve the arguments to this message, not including the /// receiver. Stmt **getArgs() { return reinterpret_cast(this + 1) + 1; } const Stmt * const *getArgs() const { return reinterpret_cast(this + 1) + 1; } /// getArg - Return the specified argument. Expr *getArg(unsigned Arg) { assert(Arg < NumArgs && "Arg access out of range!"); return cast(getArgs()[Arg]); } const Expr *getArg(unsigned Arg) const { assert(Arg < NumArgs && "Arg access out of range!"); return cast(getArgs()[Arg]); } /// setArg - Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); getArgs()[Arg] = ArgExpr; } SourceLocation getLeftLoc() const { return LBracLoc; } SourceLocation getRightLoc() const { return RBracLoc; } void setLeftLoc(SourceLocation L) { LBracLoc = L; } void setRightLoc(SourceLocation L) { RBracLoc = L; } void setSourceRange(SourceRange R) { LBracLoc = R.getBegin(); RBracLoc = R.getEnd(); } virtual SourceRange getSourceRange() const { return SourceRange(LBracLoc, RBracLoc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCMessageExprClass; } static bool classof(const ObjCMessageExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; arg_iterator arg_begin() { return getArgs(); } arg_iterator arg_end() { return getArgs() + NumArgs; } const_arg_iterator arg_begin() const { return getArgs(); } const_arg_iterator arg_end() const { return getArgs() + NumArgs; } }; /// ObjCSuperExpr - Represents the "super" expression in Objective-C, /// which refers to the object on which the current method is executing. /// /// FIXME: This class is intended for removal, once its remaining /// clients have been altered to represent "super" internally. class ObjCSuperExpr : public Expr { SourceLocation Loc; public: ObjCSuperExpr(SourceLocation L, QualType Type) : Expr(ObjCSuperExprClass, Type, false, false), Loc(L) { } explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {} SourceLocation getLoc() const { return Loc; } void setLoc(SourceLocation L) { Loc = L; } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCSuperExprClass; } static bool classof(const ObjCSuperExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. /// (similiar in spirit to MemberExpr). class ObjCIsaExpr : public Expr { /// Base - the expression for the base object pointer. Stmt *Base; /// IsaMemberLoc - This is the location of the 'isa'. SourceLocation IsaMemberLoc; /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow; public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty) : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false, base->isValueDependent()), Base(base), IsaMemberLoc(l), IsArrow(isarrow) {} /// \brief Build an empty expression. explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast(Base); } bool isArrow() const { return IsArrow; } void setArrow(bool A) { IsArrow = A; } /// getMemberLoc - Return the location of the "member", in X->F, it is the /// location of 'F'. SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; } void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; } virtual SourceRange getSourceRange() const { return SourceRange(getBase()->getLocStart(), IsaMemberLoc); } virtual SourceLocation getExprLoc() const { return IsaMemberLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } static bool classof(const ObjCIsaExpr *) { return true; } // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); }; } // end namespace clang #endif