| //===--- 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<StringLiteral>(String); } |
| const StringLiteral *getString() const { return cast<StringLiteral>(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 { |
| QualType EncType; |
| SourceLocation AtLoc, RParenLoc; |
| public: |
| ObjCEncodeExpr(QualType T, QualType ET, |
| SourceLocation at, SourceLocation rp) |
| : Expr(ObjCEncodeExprClass, T, ET->isDependentType(), |
| ET->isDependentType()), EncType(ET), 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 EncType; } |
| void setEncodedType(QualType T) { EncType = T; } |
| |
| |
| 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=0, |
| bool arrow = false, bool freeIvar = false) : |
| Expr(ObjCIvarRefExprClass, t, false, false), 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<Expr>(Base); } |
| Expr *getBase() { return cast<Expr>(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, false, false), 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<Expr>(Base); } |
| Expr *getBase() { return cast<Expr>(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, false, false), |
| 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<Expr>(Base); } |
| Expr *getBase() { return cast_or_null<Expr>(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(); |
| }; |
| |
| class ObjCMessageExpr : public Expr { |
| // SubExprs - The receiver and arguments of the message expression. |
| Stmt **SubExprs; |
| |
| // NumArgs - The number of arguments (not including the receiver) to the |
| // message expression. |
| unsigned NumArgs; |
| |
| // A unigue name for this message. |
| Selector SelName; |
| |
| // A method prototype for this message (optional). |
| // FIXME: Since method decls contain the selector, and most messages have a |
| // prototype, consider devising a scheme for unifying SelName/MethodProto. |
| ObjCMethodDecl *MethodProto; |
| |
| SourceLocation LBracloc, RBracloc; |
| |
| // Constants for indexing into SubExprs. |
| enum { RECEIVER=0, ARGS_START=1 }; |
| |
| // Bit-swizzling flags. |
| enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 }; |
| unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; } |
| |
| public: |
| /// This constructor is used to represent class messages where the |
| /// ObjCInterfaceDecl* of the receiver is not known. |
| ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo, |
| QualType retType, ObjCMethodDecl *methDecl, |
| SourceLocation LBrac, SourceLocation RBrac, |
| Expr **ArgExprs, unsigned NumArgs); |
| |
| /// This constructor is used to represent class messages where the |
| /// ObjCInterfaceDecl* of the receiver is known. |
| // FIXME: clsName should be typed to ObjCInterfaceType |
| ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo, |
| QualType retType, ObjCMethodDecl *methDecl, |
| SourceLocation LBrac, SourceLocation RBrac, |
| Expr **ArgExprs, unsigned NumArgs); |
| |
| // constructor for instance messages. |
| ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo, |
| QualType retType, ObjCMethodDecl *methDecl, |
| SourceLocation LBrac, SourceLocation RBrac, |
| Expr **ArgExprs, unsigned NumArgs); |
| |
| explicit ObjCMessageExpr(EmptyShell Empty) |
| : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {} |
| |
| virtual void DoDestroy(ASTContext &C); |
| |
| /// getReceiver - Returns the receiver of the message expression. |
| /// This can be NULL if the message is for class methods. For |
| /// class methods, use getClassName. |
| /// FIXME: need to handle/detect 'super' usage within a class method. |
| Expr *getReceiver() { |
| uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; |
| return (x & Flags) == IsInstMeth ? (Expr*) x : 0; |
| } |
| const Expr *getReceiver() const { |
| return const_cast<ObjCMessageExpr*>(this)->getReceiver(); |
| } |
| // FIXME: need setters for different receiver types. |
| void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; } |
| Selector getSelector() const { return SelName; } |
| void setSelector(Selector S) { SelName = S; } |
| |
| const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } |
| ObjCMethodDecl *getMethodDecl() { return MethodProto; } |
| void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; } |
| |
| typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo; |
| |
| /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl* |
| /// and IdentifierInfo* of the invoked class. Both can be NULL if this |
| /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none |
| /// was available when this ObjCMessageExpr object was constructed. |
| ClassInfo getClassInfo() const; |
| void setClassInfo(const ClassInfo &C); |
| |
| /// getClassName - For class methods, this returns the invoked class, |
| /// and returns NULL otherwise. For instance methods, use getReceiver. |
| IdentifierInfo *getClassName() const { |
| return getClassInfo().second; |
| } |
| |
| /// getNumArgs - Return the number of actual arguments to this call. |
| unsigned getNumArgs() const { return NumArgs; } |
| void setNumArgs(unsigned nArgs) { |
| NumArgs = nArgs; |
| // FIXME: should always allocate SubExprs via the ASTContext's |
| // allocator. |
| if (!SubExprs) |
| SubExprs = new Stmt* [NumArgs + 1]; |
| } |
| |
| /// getArg - Return the specified argument. |
| Expr *getArg(unsigned Arg) { |
| assert(Arg < NumArgs && "Arg access out of range!"); |
| return cast<Expr>(SubExprs[Arg+ARGS_START]); |
| } |
| const Expr *getArg(unsigned Arg) const { |
| assert(Arg < NumArgs && "Arg access out of range!"); |
| return cast<Expr>(SubExprs[Arg+ARGS_START]); |
| } |
| /// setArg - Set the specified argument. |
| void setArg(unsigned Arg, Expr *ArgExpr) { |
| assert(Arg < NumArgs && "Arg access out of range!"); |
| SubExprs[Arg+ARGS_START] = 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 &SubExprs[ARGS_START]; } |
| arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; } |
| const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } |
| const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; } |
| }; |
| |
| /// ObjCSuperExpr - Represents the "super" expression in Objective-C, |
| /// which refers to the object on which the current method is executing. |
| 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, false, false), |
| 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<Expr>(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 |