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