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