ExprObjC.h revision f494b579b22f9950f5af021f0bf9879a91bb8b41
1//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the ExprObjC interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_EXPROBJC_H 15#define LLVM_CLANG_AST_EXPROBJC_H 16 17#include "clang/AST/Expr.h" 18 19namespace clang { 20 class IdentifierInfo; 21 class Selector; 22 class ASTContext; 23 24/// ObjCStringLiteral, used for Objective-C string literals 25/// i.e. @"foo". 26class ObjCStringLiteral : public Expr { 27 StringLiteral *String; 28 SourceLocation AtLoc; 29public: 30 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 31 : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {} 32 33 StringLiteral* getString() { return String; } 34 35 const StringLiteral* getString() const { return String; } 36 37 SourceLocation getAtLoc() const { return AtLoc; } 38 39 virtual SourceRange getSourceRange() const { 40 return SourceRange(AtLoc, String->getLocEnd()); 41 } 42 43 static bool classof(const Stmt *T) { 44 return T->getStmtClass() == ObjCStringLiteralClass; 45 } 46 static bool classof(const ObjCStringLiteral *) { return true; } 47 48 // Iterators 49 virtual child_iterator child_begin(); 50 virtual child_iterator child_end(); 51 52 virtual void EmitImpl(llvm::Serializer& S) const; 53 static ObjCStringLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C); 54}; 55 56/// ObjCEncodeExpr, used for @encode in Objective-C. 57class ObjCEncodeExpr : public Expr { 58 QualType EncType; 59 SourceLocation AtLoc, RParenLoc; 60public: 61 ObjCEncodeExpr(QualType T, QualType ET, 62 SourceLocation at, SourceLocation rp) 63 : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {} 64 65 SourceLocation getAtLoc() const { return AtLoc; } 66 SourceLocation getRParenLoc() const { return RParenLoc; } 67 68 virtual SourceRange getSourceRange() const { 69 return SourceRange(AtLoc, RParenLoc); 70 } 71 72 QualType getEncodedType() const { return EncType; } 73 74 static bool classof(const Stmt *T) { 75 return T->getStmtClass() == ObjCEncodeExprClass; 76 } 77 static bool classof(const ObjCEncodeExpr *) { return true; } 78 79 // Iterators 80 virtual child_iterator child_begin(); 81 virtual child_iterator child_end(); 82 83 virtual void EmitImpl(llvm::Serializer& S) const; 84 static ObjCEncodeExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 85}; 86 87/// ObjCSelectorExpr used for @selector in Objective-C. 88class ObjCSelectorExpr : public Expr { 89 Selector SelName; 90 SourceLocation AtLoc, RParenLoc; 91public: 92 ObjCSelectorExpr(QualType T, Selector selInfo, 93 SourceLocation at, SourceLocation rp) 94 : Expr(ObjCSelectorExprClass, T), SelName(selInfo), 95 AtLoc(at), RParenLoc(rp) {} 96 97 Selector getSelector() const { return SelName; } 98 99 SourceLocation getAtLoc() const { return AtLoc; } 100 SourceLocation getRParenLoc() const { return RParenLoc; } 101 102 virtual SourceRange getSourceRange() const { 103 return SourceRange(AtLoc, RParenLoc); 104 } 105 106 /// getNumArgs - Return the number of actual arguments to this call. 107 unsigned getNumArgs() const { return SelName.getNumArgs(); } 108 109 static bool classof(const Stmt *T) { 110 return T->getStmtClass() == ObjCSelectorExprClass; 111 } 112 static bool classof(const ObjCSelectorExpr *) { return true; } 113 114 // Iterators 115 virtual child_iterator child_begin(); 116 virtual child_iterator child_end(); 117 118 virtual void EmitImpl(llvm::Serializer& S) const; 119 static ObjCSelectorExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 120}; 121 122/// ObjCProtocolExpr used for protocol in Objective-C. 123class ObjCProtocolExpr : public Expr { 124 ObjCProtocolDecl *Protocol; 125 SourceLocation AtLoc, RParenLoc; 126public: 127 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 128 SourceLocation at, SourceLocation rp) 129 : Expr(ObjCProtocolExprClass, T), Protocol(protocol), 130 AtLoc(at), RParenLoc(rp) {} 131 132 ObjCProtocolDecl *getProtocol() const { return Protocol; } 133 134 SourceLocation getAtLoc() const { return AtLoc; } 135 SourceLocation getRParenLoc() const { return RParenLoc; } 136 137 virtual SourceRange getSourceRange() const { 138 return SourceRange(AtLoc, RParenLoc); 139 } 140 141 static bool classof(const Stmt *T) { 142 return T->getStmtClass() == ObjCProtocolExprClass; 143 } 144 static bool classof(const ObjCProtocolExpr *) { return true; } 145 146 // Iterators 147 virtual child_iterator child_begin(); 148 virtual child_iterator child_end(); 149}; 150 151/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 152class ObjCIvarRefExpr : public Expr { 153 class ObjCIvarDecl *D; 154 SourceLocation Loc; 155 Expr *Base; 156 bool IsArrow:1; // True if this is "X->F", false if this is "X.F". 157 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). 158 159public: 160 ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, Expr *base=0, 161 bool arrow = false, bool freeIvar = false) : 162 Expr(ObjCIvarRefExprClass, t), D(d), Loc(l), Base(base), IsArrow(arrow), 163 IsFreeIvar(freeIvar) {} 164 165 ObjCIvarDecl *getDecl() { return D; } 166 const ObjCIvarDecl *getDecl() const { return D; } 167 virtual SourceRange getSourceRange() const { 168 return isFreeIvar() ? SourceRange(Loc) 169 : SourceRange(getBase()->getLocStart(), Loc); 170 } 171 const Expr *getBase() const { return Base; } 172 Expr *getBase() { return Base; } 173 void setBase(Expr * base) { Base = base; } 174 bool isArrow() const { return IsArrow; } 175 bool isFreeIvar() const { return IsFreeIvar; } 176 177 SourceLocation getLocation() const { return Loc; } 178 179 static bool classof(const Stmt *T) { 180 return T->getStmtClass() == ObjCIvarRefExprClass; 181 } 182 static bool classof(const ObjCIvarRefExpr *) { return true; } 183 184 // Iterators 185 virtual child_iterator child_begin(); 186 virtual child_iterator child_end(); 187 188 virtual void EmitImpl(llvm::Serializer& S) const; 189 static ObjCIvarRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 190}; 191 192class ObjCMessageExpr : public Expr { 193 enum { RECEIVER=0, ARGS_START=1 }; 194 195 Expr **SubExprs; 196 197 unsigned NumArgs; 198 199 // A unigue name for this message. 200 Selector SelName; 201 202 // A method prototype for this message (optional). 203 // FIXME: Since method decls contain the selector, and most messages have a 204 // prototype, consider devising a scheme for unifying SelName/MethodProto. 205 ObjCMethodDecl *MethodProto; 206 207 SourceLocation LBracloc, RBracloc; 208 209 // constructor used during deserialization 210 ObjCMessageExpr(Selector selInfo, QualType retType, 211 SourceLocation LBrac, SourceLocation RBrac, 212 Expr **ArgExprs, unsigned nargs) 213 : Expr(ObjCMessageExprClass, retType), NumArgs(nargs), SelName(selInfo), 214 MethodProto(NULL), LBracloc(LBrac), RBracloc(RBrac) {} 215 216public: 217 // constructor for class messages. 218 // FIXME: clsName should be typed to ObjCInterfaceType 219 ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, 220 QualType retType, ObjCMethodDecl *methDecl, 221 SourceLocation LBrac, SourceLocation RBrac, 222 Expr **ArgExprs, unsigned NumArgs); 223 // constructor for instance messages. 224 ObjCMessageExpr(Expr *receiver, Selector selInfo, 225 QualType retType, ObjCMethodDecl *methDecl, 226 SourceLocation LBrac, SourceLocation RBrac, 227 Expr **ArgExprs, unsigned NumArgs); 228 229 ~ObjCMessageExpr() { 230 delete [] SubExprs; 231 } 232 233 /// getReceiver - Returns the receiver of the message expression. 234 /// This can be NULL if the message is for instance methods. For 235 /// instance methods, use getClassName. 236 Expr *getReceiver() { 237 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 238 return x & 0x1 ? NULL : (Expr*) x; 239 } 240 const Expr *getReceiver() const { 241 return const_cast<ObjCMessageExpr*>(this)->getReceiver(); 242 } 243 244 Selector getSelector() const { return SelName; } 245 246 const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } 247 ObjCMethodDecl *getMethodDecl() { return MethodProto; } 248 249 /// getClassName - For instance methods, this returns the invoked class, 250 /// and returns NULL otherwise. For regular methods, use getReceiver. 251 IdentifierInfo *getClassName() { 252 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 253 return x & 0x1 ? (IdentifierInfo*) (x & ~0x1) : NULL; 254 } 255 const IdentifierInfo *getClassName() const { 256 return const_cast<ObjCMessageExpr*>(this)->getClassName(); 257 } 258 259 /// getNumArgs - Return the number of actual arguments to this call. 260 unsigned getNumArgs() const { return NumArgs; } 261 262 /// getArg - Return the specified argument. 263 Expr *getArg(unsigned Arg) { 264 assert(Arg < NumArgs && "Arg access out of range!"); 265 return SubExprs[Arg+ARGS_START]; 266 } 267 const Expr *getArg(unsigned Arg) const { 268 assert(Arg < NumArgs && "Arg access out of range!"); 269 return SubExprs[Arg+ARGS_START]; 270 } 271 /// setArg - Set the specified argument. 272 void setArg(unsigned Arg, Expr *ArgExpr) { 273 assert(Arg < NumArgs && "Arg access out of range!"); 274 SubExprs[Arg+ARGS_START] = ArgExpr; 275 } 276 277 virtual SourceRange getSourceRange() const { 278 return SourceRange(LBracloc, RBracloc); 279 } 280 281 static bool classof(const Stmt *T) { 282 return T->getStmtClass() == ObjCMessageExprClass; 283 } 284 static bool classof(const ObjCMessageExpr *) { return true; } 285 286 // Iterators 287 virtual child_iterator child_begin(); 288 virtual child_iterator child_end(); 289 290 typedef Expr** arg_iterator; 291 typedef const Expr* const* const_arg_iterator; 292 293 arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } 294 arg_iterator arg_end() { return arg_begin() + NumArgs; } 295 const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } 296 const_arg_iterator arg_end() const { return arg_begin() + NumArgs; } 297 298 // Serialization. 299 virtual void EmitImpl(llvm::Serializer& S) const; 300 static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 301}; 302 303} // end namespace clang 304 305#endif 306