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