ExprObjC.h revision 4df728e368fa1f65ffc57572fed613dcca5b4fe8
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 enum { RECEIVER=0, ARGS_START=1 }; 229 230 // Bit-swizziling flags. 231 enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 }; 232 233 Stmt **SubExprs; 234 235 unsigned NumArgs; 236 237 // A unigue name for this message. 238 Selector SelName; 239 240 // A method prototype for this message (optional). 241 // FIXME: Since method decls contain the selector, and most messages have a 242 // prototype, consider devising a scheme for unifying SelName/MethodProto. 243 ObjCMethodDecl *MethodProto; 244 245 SourceLocation LBracloc, RBracloc; 246 247 // constructor used during deserialization 248 ObjCMessageExpr(Selector selInfo, QualType retType, 249 SourceLocation LBrac, SourceLocation RBrac, 250 Expr **ArgExprs, unsigned nargs) 251 : Expr(ObjCMessageExprClass, retType), NumArgs(nargs), SelName(selInfo), 252 MethodProto(NULL), LBracloc(LBrac), RBracloc(RBrac) {} 253 254public: 255 /// This constructor is used to represent class messages where the 256 /// ObjCInterfaceDecl* of the receiver is not known. 257 ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, 258 QualType retType, ObjCMethodDecl *methDecl, 259 SourceLocation LBrac, SourceLocation RBrac, 260 Expr **ArgExprs, unsigned NumArgs); 261 262 /// This constructor is used to represent class messages where the 263 /// ObjCInterfaceDecl* of the receiver is known. 264 // FIXME: clsName should be typed to ObjCInterfaceType 265 ObjCMessageExpr(ObjCInterfaceDecl *cls, Selector selInfo, 266 QualType retType, ObjCMethodDecl *methDecl, 267 SourceLocation LBrac, SourceLocation RBrac, 268 Expr **ArgExprs, unsigned NumArgs); 269 270 // constructor for instance messages. 271 ObjCMessageExpr(Expr *receiver, Selector selInfo, 272 QualType retType, ObjCMethodDecl *methDecl, 273 SourceLocation LBrac, SourceLocation RBrac, 274 Expr **ArgExprs, unsigned NumArgs); 275 276 ~ObjCMessageExpr() { 277 delete [] SubExprs; 278 } 279 280 /// getReceiver - Returns the receiver of the message expression. 281 /// This can be NULL if the message is for class methods. For 282 /// class methods, use getClassName. 283 Expr *getReceiver() { 284 uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; 285 return (x & Flags) == IsInstMeth ? (Expr*) x : 0; 286 } 287 const Expr *getReceiver() const { 288 return const_cast<ObjCMessageExpr*>(this)->getReceiver(); 289 } 290 291 Selector getSelector() const { return SelName; } 292 293 const ObjCMethodDecl *getMethodDecl() const { return MethodProto; } 294 ObjCMethodDecl *getMethodDecl() { return MethodProto; } 295 296 typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo; 297 298 /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl* 299 /// and IdentifierInfo* of the invoked class. Both can be NULL if this 300 /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none 301 /// was available when this ObjCMessageExpr object was constructed. 302 ClassInfo getClassInfo() const; 303 304 /// getClassName - For class methods, this returns the invoked class, 305 /// and returns NULL otherwise. For instance methods, use getReceiver. 306 IdentifierInfo *getClassName() const { 307 return getClassInfo().second; 308 } 309 310 311 /// getNumArgs - Return the number of actual arguments to this call. 312 unsigned getNumArgs() const { return NumArgs; } 313 314 /// getArg - Return the specified argument. 315 Expr *getArg(unsigned Arg) { 316 assert(Arg < NumArgs && "Arg access out of range!"); 317 return cast<Expr>(SubExprs[Arg+ARGS_START]); 318 } 319 const Expr *getArg(unsigned Arg) const { 320 assert(Arg < NumArgs && "Arg access out of range!"); 321 return cast<Expr>(SubExprs[Arg+ARGS_START]); 322 } 323 /// setArg - Set the specified argument. 324 void setArg(unsigned Arg, Expr *ArgExpr) { 325 assert(Arg < NumArgs && "Arg access out of range!"); 326 SubExprs[Arg+ARGS_START] = ArgExpr; 327 } 328 329 virtual SourceRange getSourceRange() const { 330 return SourceRange(LBracloc, RBracloc); 331 } 332 333 static bool classof(const Stmt *T) { 334 return T->getStmtClass() == ObjCMessageExprClass; 335 } 336 static bool classof(const ObjCMessageExpr *) { return true; } 337 338 // Iterators 339 virtual child_iterator child_begin(); 340 virtual child_iterator child_end(); 341 342 typedef ExprIterator arg_iterator; 343 typedef ConstExprIterator const_arg_iterator; 344 345 arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } 346 arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; } 347 const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } 348 const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; } 349 350 // Serialization. 351 virtual void EmitImpl(llvm::Serializer& S) const; 352 static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 353}; 354 355/// ObjCSuperRefExpr - A reference to super. 356class ObjCSuperRefExpr : public Expr { 357 SourceLocation Loc; 358public: 359 ObjCSuperRefExpr(QualType t, SourceLocation l) : 360 Expr(ObjCSuperRefExprClass, t), Loc(l) {} 361 362 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 363 364 static bool classof(const Stmt *T) { 365 return T->getStmtClass() == ObjCSuperRefExprClass; 366 } 367 static bool classof(const ObjCSuperRefExpr *) { return true; } 368 369 // Iterators 370 virtual child_iterator child_begin(); 371 virtual child_iterator child_end(); 372 373 virtual void EmitImpl(llvm::Serializer& S) const; 374 static ObjCSuperRefExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); 375}; 376 377} // end namespace clang 378 379#endif 380