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