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