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