ExprObjC.h revision 405bad07391494d2eb025f8222c256c66b56e5f8
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#include "clang/Basic/IdentifierTable.h" 19 20namespace clang { 21 class IdentifierInfo; 22 class ASTContext; 23 class ObjCMethodDecl; 24 class ObjCPropertyDecl; 25 26/// ObjCStringLiteral, used for Objective-C string literals 27/// i.e. @"foo". 28class ObjCStringLiteral : public Expr { 29 Stmt *String; 30 SourceLocation AtLoc; 31public: 32 ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) 33 : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {} 34 explicit ObjCStringLiteral(EmptyShell Empty) 35 : Expr(ObjCStringLiteralClass, Empty) {} 36 37 StringLiteral *getString() { return cast<StringLiteral>(String); } 38 const StringLiteral *getString() const { return cast<StringLiteral>(String); } 39 void setString(StringLiteral *S) { String = S; } 40 41 SourceLocation getAtLoc() const { return AtLoc; } 42 void setAtLoc(SourceLocation L) { AtLoc = L; } 43 44 virtual SourceRange getSourceRange() const { 45 return SourceRange(AtLoc, String->getLocEnd()); 46 } 47 48 static bool classof(const Stmt *T) { 49 return T->getStmtClass() == ObjCStringLiteralClass; 50 } 51 static bool classof(const ObjCStringLiteral *) { return true; } 52 53 // Iterators 54 virtual child_iterator child_begin(); 55 virtual child_iterator child_end(); 56}; 57 58/// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type 59/// and behavior as StringLiteral except that the string initializer is obtained 60/// from ASTContext with the encoding type as an argument. 61class ObjCEncodeExpr : public Expr { 62 QualType EncType; 63 SourceLocation AtLoc, RParenLoc; 64public: 65 ObjCEncodeExpr(QualType T, QualType ET, 66 SourceLocation at, SourceLocation rp) 67 : Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {} 68 69 explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} 70 71 72 SourceLocation getAtLoc() const { return AtLoc; } 73 void setAtLoc(SourceLocation L) { AtLoc = L; } 74 SourceLocation getRParenLoc() const { return RParenLoc; } 75 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 76 77 QualType getEncodedType() const { return EncType; } 78 void setEncodedType(QualType T) { EncType = T; } 79 80 81 virtual SourceRange getSourceRange() const { 82 return SourceRange(AtLoc, RParenLoc); 83 } 84 85 static bool classof(const Stmt *T) { 86 return T->getStmtClass() == ObjCEncodeExprClass; 87 } 88 static bool classof(const ObjCEncodeExpr *) { return true; } 89 90 // Iterators 91 virtual child_iterator child_begin(); 92 virtual child_iterator child_end(); 93}; 94 95/// ObjCSelectorExpr used for @selector in Objective-C. 96class ObjCSelectorExpr : public Expr { 97 Selector SelName; 98 SourceLocation AtLoc, RParenLoc; 99public: 100 ObjCSelectorExpr(QualType T, Selector selInfo, 101 SourceLocation at, SourceLocation rp) 102 : Expr(ObjCSelectorExprClass, T), SelName(selInfo), AtLoc(at), RParenLoc(rp){} 103 explicit ObjCSelectorExpr(EmptyShell Empty) 104 : Expr(ObjCSelectorExprClass, Empty) {} 105 106 Selector getSelector() const { return SelName; } 107 void setSelector(Selector S) { SelName = S; } 108 109 SourceLocation getAtLoc() const { return AtLoc; } 110 SourceLocation getRParenLoc() const { return RParenLoc; } 111 void setAtLoc(SourceLocation L) { AtLoc = L; } 112 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 113 114 virtual SourceRange getSourceRange() const { 115 return SourceRange(AtLoc, RParenLoc); 116 } 117 118 /// getNumArgs - Return the number of actual arguments to this call. 119 unsigned getNumArgs() const { return SelName.getNumArgs(); } 120 121 static bool classof(const Stmt *T) { 122 return T->getStmtClass() == ObjCSelectorExprClass; 123 } 124 static bool classof(const ObjCSelectorExpr *) { return true; } 125 126 // Iterators 127 virtual child_iterator child_begin(); 128 virtual child_iterator child_end(); 129}; 130 131/// ObjCProtocolExpr used for protocol expression in Objective-C. This is used 132/// as: @protocol(foo), as in: 133/// obj conformsToProtocol:@protocol(foo)] 134/// The return type is "Protocol*". 135class ObjCProtocolExpr : public Expr { 136 ObjCProtocolDecl *Protocol; 137 SourceLocation AtLoc, RParenLoc; 138public: 139 ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, 140 SourceLocation at, SourceLocation rp) 141 : Expr(ObjCProtocolExprClass, T), Protocol(protocol), 142 AtLoc(at), RParenLoc(rp) {} 143 explicit ObjCProtocolExpr(EmptyShell Empty) 144 : Expr(ObjCProtocolExprClass, Empty) {} 145 146 ObjCProtocolDecl *getProtocol() const { return Protocol; } 147 void setProtocol(ObjCProtocolDecl *P) { Protocol = P; } 148 149 SourceLocation getAtLoc() const { return AtLoc; } 150 SourceLocation getRParenLoc() const { return RParenLoc; } 151 void setAtLoc(SourceLocation L) { AtLoc = L; } 152 void setRParenLoc(SourceLocation L) { RParenLoc = L; } 153 154 virtual SourceRange getSourceRange() const { 155 return SourceRange(AtLoc, RParenLoc); 156 } 157 158 static bool classof(const Stmt *T) { 159 return T->getStmtClass() == ObjCProtocolExprClass; 160 } 161 static bool classof(const ObjCProtocolExpr *) { return true; } 162 163 // Iterators 164 virtual child_iterator child_begin(); 165 virtual child_iterator child_end(); 166}; 167 168/// ObjCIvarRefExpr - A reference to an ObjC instance variable. 169class ObjCIvarRefExpr : public Expr { 170 class ObjCIvarDecl *D; 171 SourceLocation Loc; 172 Stmt *Base; 173 bool IsArrow:1; // True if this is "X->F", false if this is "X.F". 174 bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). 175 176public: 177 ObjCIvarRefExpr(ObjCIvarDecl *d, 178 QualType t, SourceLocation l, Expr *base=0, 179 bool arrow = false, bool freeIvar = false) : 180 Expr(ObjCIvarRefExprClass, t), D(d), 181 Loc(l), Base(base), IsArrow(arrow), 182 IsFreeIvar(freeIvar) {} 183 184 explicit ObjCIvarRefExpr(EmptyShell Empty) 185 : Expr(ObjCIvarRefExprClass, Empty) {} 186 187 ObjCIvarDecl *getDecl() { return D; } 188 const ObjCIvarDecl *getDecl() const { return D; } 189 void setDecl(ObjCIvarDecl *d) { D = d; } 190 191 const Expr *getBase() const { return cast<Expr>(Base); } 192 Expr *getBase() { return cast<Expr>(Base); } 193 void setBase(Expr * base) { Base = base; } 194 195 bool isArrow() const { return IsArrow; } 196 bool isFreeIvar() const { return IsFreeIvar; } 197 void setIsArrow(bool A) { IsArrow = A; } 198 void setIsFreeIvar(bool A) { IsFreeIvar = A; } 199 200 SourceLocation getLocation() const { return Loc; } 201 void setLocation(SourceLocation L) { Loc = L; } 202 203 virtual SourceRange getSourceRange() const { 204 return isFreeIvar() ? SourceRange(Loc) 205 : SourceRange(getBase()->getLocStart(), Loc); 206 } 207 208 static bool classof(const Stmt *T) { 209 return T->getStmtClass() == ObjCIvarRefExprClass; 210 } 211 static bool classof(const ObjCIvarRefExpr *) { return true; } 212 213 // Iterators 214 virtual child_iterator child_begin(); 215 virtual child_iterator child_end(); 216}; 217 218/// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC 219/// property. 220/// 221class ObjCPropertyRefExpr : public Expr { 222private: 223 ObjCPropertyDecl *AsProperty; 224 SourceLocation IdLoc; 225 Stmt *Base; 226public: 227 ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, 228 SourceLocation l, Expr *base) 229 : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) { 230 } 231 232 explicit ObjCPropertyRefExpr(EmptyShell Empty) 233 : Expr(ObjCPropertyRefExprClass, Empty) {} 234 235 ObjCPropertyDecl *getProperty() const { return AsProperty; } 236 void setProperty(ObjCPropertyDecl *D) { AsProperty = D; } 237 238 const Expr *getBase() const { return cast<Expr>(Base); } 239 Expr *getBase() { return cast<Expr>(Base); } 240 void setBase(Expr *base) { Base = base; } 241 242 SourceLocation getLocation() const { return IdLoc; } 243 void setLocation(SourceLocation L) { IdLoc = L; } 244 245 virtual SourceRange getSourceRange() const { 246 return SourceRange(getBase()->getLocStart(), IdLoc); 247 } 248 249 static bool classof(const Stmt *T) { 250 return T->getStmtClass() == ObjCPropertyRefExprClass; 251 } 252 static bool classof(const ObjCPropertyRefExpr *) { return true; } 253 254 // Iterators 255 virtual child_iterator child_begin(); 256 virtual child_iterator child_end(); 257}; 258 259/// ObjCKVCRefExpr - A dot-syntax expression to access "implicit" properties 260/// (i.e. methods following the property naming convention). KVC stands for 261/// Key Value Encoding, a generic concept for accessing or setting a 'Key' 262/// value for an object. 263/// 264class ObjCKVCRefExpr : public Expr { 265 ObjCMethodDecl *Setter; 266 ObjCMethodDecl *Getter; 267 SourceLocation Loc; 268 // FIXME: Swizzle these into a single pointer. 269 Stmt *Base; 270 ObjCInterfaceDecl *ClassProp; 271 SourceLocation ClassLoc; 272 273public: 274 ObjCKVCRefExpr(ObjCMethodDecl *getter, 275 QualType t, 276 ObjCMethodDecl *setter, 277 SourceLocation l, Expr *base) 278 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 279 Getter(getter), Loc(l), Base(base), ClassProp(0), 280 ClassLoc(SourceLocation()) { 281 } 282 ObjCKVCRefExpr(ObjCMethodDecl *getter, 283 QualType t, 284 ObjCMethodDecl *setter, 285 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) 286 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 287 Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) { 288 } 289 explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){} 290 291 ObjCMethodDecl *getGetterMethod() const { return Getter; } 292 ObjCMethodDecl *getSetterMethod() const { return Setter; } 293 ObjCInterfaceDecl *getClassProp() const { return ClassProp; } 294 void setGetterMethod(ObjCMethodDecl *D) { Getter = D; } 295 void setSetterMethod(ObjCMethodDecl *D) { Setter = D; } 296 void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; } 297 298 virtual SourceRange getSourceRange() const { 299 if (Base) 300 return SourceRange(getBase()->getLocStart(), Loc); 301 return SourceRange(ClassLoc, Loc); 302 } 303 const Expr *getBase() const { return cast_or_null<Expr>(Base); } 304 Expr *getBase() { return cast_or_null<Expr>(Base); } 305 void setBase(Expr *base) { Base = base; } 306 307 SourceLocation getLocation() const { return Loc; } 308 void setLocation(SourceLocation L) { Loc = L; } 309 SourceLocation getClassLoc() const { return ClassLoc; } 310 void setClassLoc(SourceLocation L) { ClassLoc = L; } 311 312 static bool classof(const Stmt *T) { 313 return T->getStmtClass() == ObjCKVCRefExprClass; 314 } 315 static bool classof(const ObjCKVCRefExpr *) { return true; } 316 317 // Iterators 318 virtual child_iterator child_begin(); 319 virtual child_iterator child_end(); 320}; 321 322class ObjCMessageExpr : public Expr { 323 // SubExprs - The receiver and arguments of the message expression. 324 Stmt **SubExprs; 325 326 // NumArgs - The number of arguments (not including the receiver) to the 327 // message expression. 328 unsigned NumArgs; 329 330 // A unigue name for this message. 331 Selector SelName; 332 333 // A method prototype for this message (optional). 334 // FIXME: Since method decls contain the selector, and most messages have a 335 // prototype, consider devising a scheme for unifying SelName/MethodProto. 336 ObjCMethodDecl *MethodProto; 337 338 SourceLocation LBracloc, RBracloc; 339 340 // Constants for indexing into SubExprs. 341 enum { RECEIVER=0, ARGS_START=1 }; 342 343 // Bit-swizzling flags. 344 enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 }; 345 unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; } 346 347 // constructor used during deserialization 348 ObjCMessageExpr(Selector selInfo, QualType retType, 349 SourceLocation LBrac, SourceLocation RBrac, 350 Stmt **subexprs, unsigned nargs) 351 : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs), 352 NumArgs(nargs), SelName(selInfo), MethodProto(NULL), 353 LBracloc(LBrac), RBracloc(RBrac) {} 354 355public: 356 /// This constructor is used to represent class messages where the 357 /// ObjCInterfaceDecl* of the receiver is not known. 358 ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, 359 QualType retType, ObjCMethodDecl *methDecl, 360 SourceLocation LBrac, SourceLocation RBrac, 361 Expr **ArgExprs, unsigned NumArgs); 362 363 /// This constructor is used to represent class messages where the 364 /// ObjCInterfaceDecl* of the receiver is known. 365 // FIXME: clsName should be typed to ObjCInterfaceType 366 ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo, 367 QualType retType, ObjCMethodDecl *methDecl, 368 SourceLocation LBrac, SourceLocation RBrac, 369 Expr **ArgExprs, unsigned NumArgs); 370 371 // constructor for instance messages. 372 ObjCMessageExpr(Expr *receiver, Selector selInfo, 373 QualType retType, ObjCMethodDecl *methDecl, 374 SourceLocation LBrac, SourceLocation RBrac, 375 Expr **ArgExprs, unsigned NumArgs); 376 377 explicit ObjCMessageExpr(EmptyShell Empty) 378 : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {} 379 380 ~ObjCMessageExpr() { 381 delete [] SubExprs; 382 } 383 384 /// getReceiver - Returns the receiver of the message expression. 385 /// This can be NULL if the message is for class methods. For 386 /// class methods, use getClassName. 387 /// FIXME: need to handle/detect 'super' usage within a class method. 388 Expr *getReceiver() { 389 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 390 return (x & Flags) == IsInstMeth ? (Expr*) x : 0; 391 } 392 const Expr *getReceiver() const { 393 return const_cast<ObjCMessageExpr*>(this)->getReceiver(); 394 } 395 // FIXME: need setters for different receiver types. 396 void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; } 397 Selector getSelector() const { return SelName; } 398 void setSelector(Selector S) { SelName = S; } 399 400 const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } 401 ObjCMethodDecl *getMethodDecl() { return MethodProto; } 402 void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; } 403 404 typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo; 405 406 /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl* 407 /// and IdentifierInfo* of the invoked class. Both can be NULL if this 408 /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none 409 /// was available when this ObjCMessageExpr object was constructed. 410 ClassInfo getClassInfo() const; 411 void setClassInfo(const ClassInfo &C); 412 413 /// getClassName - For class methods, this returns the invoked class, 414 /// and returns NULL otherwise. For instance methods, use getReceiver. 415 IdentifierInfo *getClassName() const { 416 return getClassInfo().second; 417 } 418 419 /// getNumArgs - Return the number of actual arguments to this call. 420 unsigned getNumArgs() const { return NumArgs; } 421 void setNumArgs(unsigned nArgs) { 422 NumArgs = nArgs; 423 // FIXME: should always allocate SubExprs via the ASTContext's 424 // allocator. 425 if (!SubExprs) 426 SubExprs = new Stmt* [NumArgs + 1]; 427 } 428 429 /// getArg - Return the specified argument. 430 Expr *getArg(unsigned Arg) { 431 assert(Arg < NumArgs && "Arg access out of range!"); 432 return cast<Expr>(SubExprs[Arg+ARGS_START]); 433 } 434 const Expr *getArg(unsigned Arg) const { 435 assert(Arg < NumArgs && "Arg access out of range!"); 436 return cast<Expr>(SubExprs[Arg+ARGS_START]); 437 } 438 /// setArg - Set the specified argument. 439 void setArg(unsigned Arg, Expr *ArgExpr) { 440 assert(Arg < NumArgs && "Arg access out of range!"); 441 SubExprs[Arg+ARGS_START] = ArgExpr; 442 } 443 444 SourceLocation getLeftLoc() const { return LBracloc; } 445 SourceLocation getRightLoc() const { return RBracloc; } 446 447 void setLeftLoc(SourceLocation L) { LBracloc = L; } 448 void setRightLoc(SourceLocation L) { RBracloc = L; } 449 450 void setSourceRange(SourceRange R) { 451 LBracloc = R.getBegin(); 452 RBracloc = R.getEnd(); 453 } 454 virtual SourceRange getSourceRange() const { 455 return SourceRange(LBracloc, RBracloc); 456 } 457 458 static bool classof(const Stmt *T) { 459 return T->getStmtClass() == ObjCMessageExprClass; 460 } 461 static bool classof(const ObjCMessageExpr *) { return true; } 462 463 // Iterators 464 virtual child_iterator child_begin(); 465 virtual child_iterator child_end(); 466 467 typedef ExprIterator arg_iterator; 468 typedef ConstExprIterator const_arg_iterator; 469 470 arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } 471 arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; } 472 const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } 473 const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; } 474}; 475 476/// ObjCSuperExpr - Represents the "super" expression in Objective-C, 477/// which refers to the object on which the current method is executing. 478class ObjCSuperExpr : public Expr { 479 SourceLocation Loc; 480public: 481 ObjCSuperExpr(SourceLocation L, QualType Type) 482 : Expr(ObjCSuperExprClass, Type), Loc(L) { } 483 explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {} 484 485 SourceLocation getLoc() const { return Loc; } 486 void setLoc(SourceLocation L) { Loc = L; } 487 488 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 489 490 static bool classof(const Stmt *T) { 491 return T->getStmtClass() == ObjCSuperExprClass; 492 } 493 static bool classof(const ObjCSuperExpr *) { return true; } 494 495 // Iterators 496 virtual child_iterator child_begin(); 497 virtual child_iterator child_end(); 498}; 499 500} // end namespace clang 501 502#endif 503