ExprObjC.h revision d7a3fcd48cb308074cc95031252bc64966f0703d
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/// 267class ObjCKVCRefExpr : public Expr { 268 ObjCMethodDecl *Setter; 269 ObjCMethodDecl *Getter; 270 SourceLocation Loc; 271 // FIXME: Swizzle these into a single pointer. 272 Stmt *Base; 273 ObjCInterfaceDecl *ClassProp; 274 SourceLocation ClassLoc; 275 276public: 277 ObjCKVCRefExpr(ObjCMethodDecl *getter, 278 QualType t, 279 ObjCMethodDecl *setter, 280 SourceLocation l, Expr *base) 281 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 282 Getter(getter), Loc(l), Base(base), ClassProp(0), ClassLoc(SourceLocation()) { 283 } 284 ObjCKVCRefExpr(ObjCMethodDecl *getter, 285 QualType t, 286 ObjCMethodDecl *setter, 287 SourceLocation l, ObjCInterfaceDecl *C, SourceLocation CL) 288 : Expr(ObjCKVCRefExprClass, t), Setter(setter), 289 Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) { 290 } 291 292 ObjCMethodDecl *getGetterMethod() const { 293 return Getter; 294 } 295 ObjCMethodDecl *getSetterMethod() const { 296 return Setter; 297 } 298 299 ObjCInterfaceDecl *getClassProp() const { 300 return ClassProp; 301 } 302 303 virtual SourceRange getSourceRange() const { 304 if (Base) 305 return SourceRange(getBase()->getLocStart(), Loc); 306 return SourceRange(ClassLoc, Loc); 307 } 308 const Expr *getBase() const { return cast<Expr>(Base); } 309 Expr *getBase() { return cast<Expr>(Base); } 310 void setBase(Expr * base) { Base = base; } 311 312 SourceLocation getLocation() const { return Loc; } 313 314 static bool classof(const Stmt *T) { 315 return T->getStmtClass() == ObjCKVCRefExprClass; 316 } 317 static bool classof(const ObjCKVCRefExpr *) { return true; } 318 319 // Iterators 320 virtual child_iterator child_begin(); 321 virtual child_iterator child_end(); 322 323 virtual void EmitImpl(llvm::Serializer& S) const; 324 static ObjCKVCRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 325}; 326 327class ObjCMessageExpr : public Expr { 328 // SubExprs - The receiver and arguments of the message expression. 329 Stmt **SubExprs; 330 331 // NumArgs - The number of arguments (not including the receiver) to the 332 // message expression. 333 unsigned NumArgs; 334 335 // A unigue name for this message. 336 Selector SelName; 337 338 // A method prototype for this message (optional). 339 // FIXME: Since method decls contain the selector, and most messages have a 340 // prototype, consider devising a scheme for unifying SelName/MethodProto. 341 ObjCMethodDecl *MethodProto; 342 343 SourceLocation LBracloc, RBracloc; 344 345 // Constants for indexing into SubExprs. 346 enum { RECEIVER=0, ARGS_START=1 }; 347 348 // Bit-swizziling flags. 349 enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 }; 350 unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; } 351 352 // constructor used during deserialization 353 ObjCMessageExpr(Selector selInfo, QualType retType, 354 SourceLocation LBrac, SourceLocation RBrac, 355 Stmt **subexprs, unsigned nargs) 356 : Expr(ObjCMessageExprClass, retType), SubExprs(subexprs), 357 NumArgs(nargs), SelName(selInfo), MethodProto(NULL), 358 LBracloc(LBrac), RBracloc(RBrac) {} 359 360public: 361 /// This constructor is used to represent class messages where the 362 /// ObjCInterfaceDecl* of the receiver is not known. 363 ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, 364 QualType retType, ObjCMethodDecl *methDecl, 365 SourceLocation LBrac, SourceLocation RBrac, 366 Expr **ArgExprs, unsigned NumArgs); 367 368 /// This constructor is used to represent class messages where the 369 /// ObjCInterfaceDecl* of the receiver is known. 370 // FIXME: clsName should be typed to ObjCInterfaceType 371 ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo, 372 QualType retType, ObjCMethodDecl *methDecl, 373 SourceLocation LBrac, SourceLocation RBrac, 374 Expr **ArgExprs, unsigned NumArgs); 375 376 // constructor for instance messages. 377 ObjCMessageExpr(Expr *receiver, Selector selInfo, 378 QualType retType, ObjCMethodDecl *methDecl, 379 SourceLocation LBrac, SourceLocation RBrac, 380 Expr **ArgExprs, unsigned NumArgs); 381 382 ~ObjCMessageExpr() { 383 delete [] SubExprs; 384 } 385 386 /// getReceiver - Returns the receiver of the message expression. 387 /// This can be NULL if the message is for class methods. For 388 /// class methods, use getClassName. 389 /// FIXME: need to handle/detect 'super' usage within a class method. 390 Expr *getReceiver() { 391 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 392 return (x & Flags) == IsInstMeth ? (Expr*) x : 0; 393 } 394 const Expr *getReceiver() const { 395 return const_cast<ObjCMessageExpr*>(this)->getReceiver(); 396 } 397 398 Selector getSelector() const { return SelName; } 399 400 const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } 401 ObjCMethodDecl *getMethodDecl() { return MethodProto; } 402 403 typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo; 404 405 /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl* 406 /// and IdentifierInfo* of the invoked class. Both can be NULL if this 407 /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none 408 /// was available when this ObjCMessageExpr object was constructed. 409 ClassInfo getClassInfo() const; 410 411 /// getClassName - For class methods, this returns the invoked class, 412 /// and returns NULL otherwise. For instance methods, use getReceiver. 413 IdentifierInfo *getClassName() const { 414 return getClassInfo().second; 415 } 416 417 418 /// getNumArgs - Return the number of actual arguments to this call. 419 unsigned getNumArgs() const { return NumArgs; } 420 421 /// getArg - Return the specified argument. 422 Expr *getArg(unsigned Arg) { 423 assert(Arg < NumArgs && "Arg access out of range!"); 424 return cast<Expr>(SubExprs[Arg+ARGS_START]); 425 } 426 const Expr *getArg(unsigned Arg) const { 427 assert(Arg < NumArgs && "Arg access out of range!"); 428 return cast<Expr>(SubExprs[Arg+ARGS_START]); 429 } 430 /// setArg - Set the specified argument. 431 void setArg(unsigned Arg, Expr *ArgExpr) { 432 assert(Arg < NumArgs && "Arg access out of range!"); 433 SubExprs[Arg+ARGS_START] = ArgExpr; 434 } 435 436 virtual SourceRange getSourceRange() const { 437 return SourceRange(LBracloc, RBracloc); 438 } 439 440 static bool classof(const Stmt *T) { 441 return T->getStmtClass() == ObjCMessageExprClass; 442 } 443 static bool classof(const ObjCMessageExpr *) { return true; } 444 445 // Iterators 446 virtual child_iterator child_begin(); 447 virtual child_iterator child_end(); 448 449 typedef ExprIterator arg_iterator; 450 typedef ConstExprIterator const_arg_iterator; 451 452 arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } 453 arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; } 454 const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } 455 const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; } 456 457 // Serialization. 458 virtual void EmitImpl(llvm::Serializer& S) const; 459 static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 460}; 461 462/// ObjCSuperExpr - Represents the "super" expression in Objective-C, 463/// which refers to the object on which the current method is executing. 464class ObjCSuperExpr : public Expr { 465 SourceLocation Loc; 466public: 467 ObjCSuperExpr(SourceLocation L, QualType Type) 468 : Expr(ObjCSuperExprClass, Type), Loc(L) { } 469 470 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 471 472 static bool classof(const Stmt *T) { 473 return T->getStmtClass() == ObjCSuperExprClass; 474 } 475 static bool classof(const ObjCSuperExpr *) { return true; } 476 477 // Iterators 478 virtual child_iterator child_begin(); 479 virtual child_iterator child_end(); 480 481 virtual void EmitImpl(llvm::Serializer& S) const; 482 static ObjCSuperExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 483}; 484 485} // end namespace clang 486 487#endif 488