diff options
Diffstat (limited to 'include/clang/AST/ExprObjC.h')
-rw-r--r-- | include/clang/AST/ExprObjC.h | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h new file mode 100644 index 0000000..51b9961 --- /dev/null +++ b/include/clang/AST/ExprObjC.h @@ -0,0 +1,494 @@ +//===--- 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), 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), 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), 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 *Protocol; + SourceLocation AtLoc, RParenLoc; +public: + ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, + SourceLocation at, SourceLocation rp) + : Expr(ObjCProtocolExprClass, T), Protocol(protocol), + AtLoc(at), RParenLoc(rp) {} + explicit ObjCProtocolExpr(EmptyShell Empty) + : Expr(ObjCProtocolExprClass, Empty) {} + + ObjCProtocolDecl *getProtocol() const { return Protocol; } + void setProtocol(ObjCProtocolDecl *P) { Protocol = 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), 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), 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(); +}; + +/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties +/// (i.e. methods following the property naming convention). KVC stands for +/// Key Value Encoding, a generic concept for accessing or setting a 'Key' +/// value for an object. +/// +class ObjCKVCRefExpr : public Expr { + ObjCMethodDecl *Setter; + ObjCMethodDecl *Getter; + SourceLocation Loc; + // FIXME: Swizzle these into a single pointer. + Stmt *Base; + ObjCInterfaceDecl *ClassProp; + SourceLocation ClassLoc; + +public: + ObjCKVCRefExpr(ObjCMethodDecl *getter, + QualType t, + ObjCMethodDecl *setter, + SourceLocation l, Expr *base) + : Expr(ObjCKVCRefExprClass, t), Setter(setter), + Getter(getter), Loc(l), Base(base), ClassProp(0), + ClassLoc(SourceLocation()) { + } + ObjCKVCRefExpr(ObjCMethodDecl *getter, + QualType t, + ObjCMethodDecl *setter, + SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) + : Expr(ObjCKVCRefExprClass, t), Setter(setter), + Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) { + } + explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){} + + ObjCMethodDecl *getGetterMethod() const { return Getter; } + ObjCMethodDecl *getSetterMethod() const { return Setter; } + ObjCInterfaceDecl *getClassProp() const { return ClassProp; } + void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } + void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } + void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; } + + virtual SourceRange getSourceRange() const { + if (Base) + return SourceRange(getBase()->getLocStart(), Loc); + return SourceRange(ClassLoc, Loc); + } + 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 Loc; } + void setLocation(SourceLocation L) { Loc = L; } + SourceLocation getClassLoc() const { return ClassLoc; } + void setClassLoc(SourceLocation L) { ClassLoc = L; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCKVCRefExprClass; + } + static bool classof(const ObjCKVCRefExpr *) { 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(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(ObjCInterfaceDecl *cls, Selector selInfo, + QualType retType, ObjCMethodDecl *methDecl, + SourceLocation LBrac, SourceLocation RBrac, + Expr **ArgExprs, unsigned NumArgs); + + // constructor for instance messages. + ObjCMessageExpr(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) {} + + ~ObjCMessageExpr() { + delete [] SubExprs; + } + + /// 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), 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(); +}; + +} // end namespace clang + +#endif |