Expr.h revision 5508518a2702b00be3b15a26d772bde968972f54
1//===--- Expr.h - Classes for representing expressions ----------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the Expr interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_EXPR_H 15#define LLVM_CLANG_AST_EXPR_H 16 17#include "clang/AST/Stmt.h" 18#include "clang/AST/Type.h" 19#include "clang/AST/Decl.h" 20#include "llvm/ADT/APSInt.h" 21 22namespace clang { 23 class IdentifierInfo; 24 class Decl; 25 class ASTContext; 26 27/// Expr - This represents one expression. Note that Expr's are subclasses of 28/// Stmt. This allows an expression to be transparently used any place a Stmt 29/// is required. 30/// 31class Expr : public Stmt { 32 QualType TR; 33protected: 34 Expr(StmtClass SC, QualType T) : Stmt(SC), TR(T) {} 35 ~Expr() {} 36public: 37 QualType getType() const { return TR; } 38 void setType(QualType t) { TR = t; } 39 40 /// SourceLocation tokens are not useful in isolation - they are low level 41 /// value objects created/interpreted by SourceManager. We assume AST 42 /// clients will have a pointer to the respective SourceManager. 43 virtual SourceRange getSourceRange() const = 0; 44 SourceLocation getLocStart() const { return getSourceRange().Begin(); } 45 SourceLocation getLocEnd() const { return getSourceRange().End(); } 46 47 /// getExprLoc - Return the preferred location for the arrow when diagnosing 48 /// a problem with a generic expression. 49 virtual SourceLocation getExprLoc() const { return getLocStart(); } 50 51 /// hasLocalSideEffect - Return true if this immediate expression has side 52 /// effects, not counting any sub-expressions. 53 bool hasLocalSideEffect() const; 54 55 /// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or 56 /// incomplete type other than void. Nonarray expressions that can be lvalues: 57 /// - name, where name must be a variable 58 /// - e[i] 59 /// - (e), where e must be an lvalue 60 /// - e.name, where e must be an lvalue 61 /// - e->name 62 /// - *e, the type of e cannot be a function type 63 /// - string-constant 64 /// - reference type [C++ [expr]] 65 /// 66 enum isLvalueResult { 67 LV_Valid, 68 LV_NotObjectType, 69 LV_IncompleteVoidType, 70 LV_DuplicateVectorComponents, 71 LV_InvalidExpression 72 }; 73 isLvalueResult isLvalue() const; 74 75 /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, 76 /// does not have an incomplete type, does not have a const-qualified type, 77 /// and if it is a structure or union, does not have any member (including, 78 /// recursively, any member or element of all contained aggregates or unions) 79 /// with a const-qualified type. 80 enum isModifiableLvalueResult { 81 MLV_Valid, 82 MLV_NotObjectType, 83 MLV_IncompleteVoidType, 84 MLV_DuplicateVectorComponents, 85 MLV_InvalidExpression, 86 MLV_IncompleteType, 87 MLV_ConstQualified, 88 MLV_ArrayType 89 }; 90 isModifiableLvalueResult isModifiableLvalue() const; 91 92 bool isNullPointerConstant(ASTContext &Ctx) const; 93 94 /// isIntegerConstantExpr - Return true if this expression is a valid integer 95 /// constant expression, and, if so, return its value in Result. If not a 96 /// valid i-c-e, return false and fill in Loc (if specified) with the location 97 /// of the invalid expression. 98 bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, 99 SourceLocation *Loc = 0, 100 bool isEvaluated = true) const; 101 bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const { 102 llvm::APSInt X(32); 103 return isIntegerConstantExpr(X, Ctx, Loc); 104 } 105 106 static bool classof(const Stmt *T) { 107 return T->getStmtClass() >= firstExprConstant && 108 T->getStmtClass() <= lastExprConstant; 109 } 110 static bool classof(const Expr *) { return true; } 111}; 112 113//===----------------------------------------------------------------------===// 114// Primary Expressions. 115//===----------------------------------------------------------------------===// 116 117/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function, 118/// enum, etc. 119class DeclRefExpr : public Expr { 120 Decl *D; // a ValueDecl or EnumConstantDecl 121 SourceLocation Loc; 122public: 123 DeclRefExpr(Decl *d, QualType t, SourceLocation l) : 124 Expr(DeclRefExprClass, t), D(d), Loc(l) {} 125 126 Decl *getDecl() { return D; } 127 const Decl *getDecl() const { return D; } 128 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 129 130 131 static bool classof(const Stmt *T) { 132 return T->getStmtClass() == DeclRefExprClass; 133 } 134 static bool classof(const DeclRefExpr *) { return true; } 135}; 136 137/// PreDefinedExpr - [C99 6.4.2.2] - A pre-defined identifier such as __func__. 138class PreDefinedExpr : public Expr { 139public: 140 enum IdentType { 141 Func, 142 Function, 143 PrettyFunction 144 }; 145 146private: 147 SourceLocation Loc; 148 IdentType Type; 149public: 150 PreDefinedExpr(SourceLocation l, QualType type, IdentType IT) 151 : Expr(PreDefinedExprClass, type), Loc(l), Type(IT) {} 152 153 IdentType getIdentType() const { return Type; } 154 155 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 156 157 static bool classof(const Stmt *T) { 158 return T->getStmtClass() == PreDefinedExprClass; 159 } 160 static bool classof(const PreDefinedExpr *) { return true; } 161}; 162 163class IntegerLiteral : public Expr { 164 llvm::APInt Value; 165 SourceLocation Loc; 166public: 167 // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, 168 // or UnsignedLongLongTy 169 IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l) 170 : Expr(IntegerLiteralClass, type), Value(V), Loc(l) { 171 assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); 172 } 173 const llvm::APInt &getValue() const { return Value; } 174 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 175 176 static bool classof(const Stmt *T) { 177 return T->getStmtClass() == IntegerLiteralClass; 178 } 179 static bool classof(const IntegerLiteral *) { return true; } 180}; 181 182class CharacterLiteral : public Expr { 183 unsigned Value; 184 SourceLocation Loc; 185public: 186 // type should be IntTy 187 CharacterLiteral(unsigned value, QualType type, SourceLocation l) 188 : Expr(CharacterLiteralClass, type), Value(value), Loc(l) { 189 } 190 SourceLocation getLoc() const { return Loc; } 191 192 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 193 194 unsigned getValue() const { return Value; } 195 196 static bool classof(const Stmt *T) { 197 return T->getStmtClass() == CharacterLiteralClass; 198 } 199 static bool classof(const CharacterLiteral *) { return true; } 200}; 201 202class FloatingLiteral : public Expr { 203 float Value; // FIXME 204 SourceLocation Loc; 205public: 206 FloatingLiteral(float value, QualType type, SourceLocation l) 207 : Expr(FloatingLiteralClass, type), Value(value), Loc(l) {} 208 209 float getValue() const { return Value; } 210 211 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 212 213 static bool classof(const Stmt *T) { 214 return T->getStmtClass() == FloatingLiteralClass; 215 } 216 static bool classof(const FloatingLiteral *) { return true; } 217}; 218 219/// StringLiteral - This represents a string literal expression, e.g. "foo" 220/// or L"bar" (wide strings). The actual string is returned by getStrData() 221/// is NOT null-terminated, and the length of the string is determined by 222/// calling getByteLength(). 223class StringLiteral : public Expr { 224 const char *StrData; 225 unsigned ByteLength; 226 bool IsWide; 227 // if the StringLiteral was composed using token pasting, both locations 228 // are needed. If not (the common case), firstTokLoc == lastTokLoc. 229 // FIXME: if space becomes an issue, we should create a sub-class. 230 SourceLocation firstTokLoc, lastTokLoc; 231public: 232 StringLiteral(const char *strData, unsigned byteLength, bool Wide, 233 QualType t, SourceLocation b, SourceLocation e); 234 virtual ~StringLiteral(); 235 236 const char *getStrData() const { return StrData; } 237 unsigned getByteLength() const { return ByteLength; } 238 bool isWide() const { return IsWide; } 239 240 virtual SourceRange getSourceRange() const { 241 return SourceRange(firstTokLoc,lastTokLoc); 242 } 243 static bool classof(const Stmt *T) { 244 return T->getStmtClass() == StringLiteralClass; 245 } 246 static bool classof(const StringLiteral *) { return true; } 247}; 248 249/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This 250/// AST node is only formed if full location information is requested. 251class ParenExpr : public Expr { 252 SourceLocation L, R; 253 Expr *Val; 254public: 255 ParenExpr(SourceLocation l, SourceLocation r, Expr *val) 256 : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {} 257 258 const Expr *getSubExpr() const { return Val; } 259 Expr *getSubExpr() { return Val; } 260 SourceRange getSourceRange() const { return SourceRange(L, R); } 261 262 static bool classof(const Stmt *T) { 263 return T->getStmtClass() == ParenExprClass; 264 } 265 static bool classof(const ParenExpr *) { return true; } 266}; 267 268 269/// UnaryOperator - This represents the unary-expression's (except sizeof of 270/// types), the postinc/postdec operators from postfix-expression, and various 271/// extensions. 272class UnaryOperator : public Expr { 273public: 274 enum Opcode { 275 PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators 276 PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators. 277 AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators. 278 Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators. 279 Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators. 280 SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator. 281 Real, Imag, // "__real expr"/"__imag expr" Extension. 282 Extension // __extension__ marker. 283 }; 284private: 285 Expr *Val; 286 Opcode Opc; 287 SourceLocation Loc; 288public: 289 290 UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l) 291 : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {} 292 293 Opcode getOpcode() const { return Opc; } 294 Expr *getSubExpr() const { return Val; } 295 296 /// getOperatorLoc - Return the location of the operator. 297 SourceLocation getOperatorLoc() const { return Loc; } 298 299 /// isPostfix - Return true if this is a postfix operation, like x++. 300 static bool isPostfix(Opcode Op); 301 302 bool isPostfix() const { return isPostfix(Opc); } 303 bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; } 304 bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; } 305 static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; } 306 307 /// getDecl - a recursive routine that derives the base decl for an 308 /// expression. For example, it will return the declaration for "s" from 309 /// the following complex expression "s.zz[2].bb.vv". 310 static bool isAddressable(Expr *e); 311 312 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it 313 /// corresponds to, e.g. "sizeof" or "[pre]++" 314 static const char *getOpcodeStr(Opcode Op); 315 316 virtual SourceRange getSourceRange() const { 317 if (isPostfix()) 318 return SourceRange(Val->getLocStart(), Loc); 319 else 320 return SourceRange(Loc, Val->getLocEnd()); 321 } 322 virtual SourceLocation getExprLoc() const { return Loc; } 323 324 static bool classof(const Stmt *T) { 325 return T->getStmtClass() == UnaryOperatorClass; 326 } 327 static bool classof(const UnaryOperator *) { return true; } 328}; 329 330/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of 331/// *types*. sizeof(expr) is handled by UnaryOperator. 332class SizeOfAlignOfTypeExpr : public Expr { 333 bool isSizeof; // true if sizeof, false if alignof. 334 QualType Ty; 335 SourceLocation OpLoc, RParenLoc; 336public: 337 SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType, 338 SourceLocation op, SourceLocation rp) : 339 Expr(SizeOfAlignOfTypeExprClass, resultType), 340 isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {} 341 342 bool isSizeOf() const { return isSizeof; } 343 QualType getArgumentType() const { return Ty; } 344 345 SourceLocation getOperatorLoc() const { return OpLoc; } 346 SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); } 347 348 static bool classof(const Stmt *T) { 349 return T->getStmtClass() == SizeOfAlignOfTypeExprClass; 350 } 351 static bool classof(const SizeOfAlignOfTypeExpr *) { return true; } 352}; 353 354//===----------------------------------------------------------------------===// 355// Postfix Operators. 356//===----------------------------------------------------------------------===// 357 358/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting. 359class ArraySubscriptExpr : public Expr { 360 Expr *LHS, *RHS; 361 SourceLocation RBracketLoc; 362public: 363 ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, 364 SourceLocation rbracketloc) : 365 Expr(ArraySubscriptExprClass, t), 366 LHS(lhs), RHS(rhs), RBracketLoc(rbracketloc) {} 367 368 /// An array access can be written A[4] or 4[A] (both are equivalent). 369 /// - getBase() and getIdx() always present the normalized view: A[4]. 370 /// In this case getBase() returns "A" and getIdx() returns "4". 371 /// - getLHS() and getRHS() present the syntactic view. e.g. for 372 /// 4[A] getLHS() returns "4". 373 374 Expr *getBase() { return (LHS->getType()->isIntegerType()) ? RHS : LHS; } 375 const Expr *getBase() const { 376 return (LHS->getType()->isIntegerType()) ? RHS : LHS; 377 } 378 379 Expr *getIdx() { return (LHS->getType()->isIntegerType()) ? LHS : RHS; } 380 const Expr *getIdx() const { 381 return (LHS->getType()->isIntegerType()) ? LHS : RHS; 382 } 383 384 Expr *getLHS() { return LHS; } 385 const Expr *getLHS() const { return LHS; } 386 387 Expr *getRHS() { return RHS; } 388 const Expr *getRHS() const { return RHS; } 389 390 SourceRange getSourceRange() const { 391 return SourceRange(LHS->getLocStart(), RBracketLoc); 392 } 393 virtual SourceLocation getExprLoc() const { return RBracketLoc; } 394 395 static bool classof(const Stmt *T) { 396 return T->getStmtClass() == ArraySubscriptExprClass; 397 } 398 static bool classof(const ArraySubscriptExpr *) { return true; } 399}; 400 401 402/// CallExpr - [C99 6.5.2.2] Function Calls. 403/// 404class CallExpr : public Expr { 405 Expr *Fn; 406 Expr **Args; 407 unsigned NumArgs; 408 SourceLocation RParenLoc; 409public: 410 CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t, 411 SourceLocation rparenloc); 412 ~CallExpr() { 413 delete [] Args; 414 } 415 416 const Expr *getCallee() const { return Fn; } 417 Expr *getCallee() { return Fn; } 418 419 /// getNumArgs - Return the number of actual arguments to this call. 420 /// 421 unsigned getNumArgs() const { return NumArgs; } 422 423 /// getArg - Return the specified argument. 424 Expr *getArg(unsigned Arg) { 425 assert(Arg < NumArgs && "Arg access out of range!"); 426 return Args[Arg]; 427 } 428 const Expr *getArg(unsigned Arg) const { 429 assert(Arg < NumArgs && "Arg access out of range!"); 430 return Args[Arg]; 431 } 432 433 /// getNumCommas - Return the number of commas that must have been present in 434 /// this function call. 435 unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; } 436 437 bool isBuiltinClassifyType(llvm::APSInt &Result) const; 438 439 SourceRange getSourceRange() const { 440 return SourceRange(Fn->getLocStart(), RParenLoc); 441 } 442 443 static bool classof(const Stmt *T) { 444 return T->getStmtClass() == CallExprClass; 445 } 446 static bool classof(const CallExpr *) { return true; } 447}; 448 449/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. 450/// 451class MemberExpr : public Expr { 452 Expr *Base; 453 FieldDecl *MemberDecl; 454 SourceLocation MemberLoc; 455 bool IsArrow; // True if this is "X->F", false if this is "X.F". 456public: 457 MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l) 458 : Expr(MemberExprClass, memberdecl->getType()), 459 Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {} 460 461 Expr *getBase() const { return Base; } 462 FieldDecl *getMemberDecl() const { return MemberDecl; } 463 bool isArrow() const { return IsArrow; } 464 465 virtual SourceRange getSourceRange() const { 466 return SourceRange(getBase()->getLocStart(), MemberLoc); 467 } 468 virtual SourceLocation getExprLoc() const { return MemberLoc; } 469 470 static bool classof(const Stmt *T) { 471 return T->getStmtClass() == MemberExprClass; 472 } 473 static bool classof(const MemberExpr *) { return true; } 474}; 475 476/// OCUVectorElementExpr - This represents access to specific elements of a 477/// vector, and may occur on the left hand side or right hand side. For example 478/// the following is legal: "V.xy = V.zw" if V is a 4 element ocu vector. 479/// 480class OCUVectorElementExpr : public Expr { 481 Expr *Base; 482 IdentifierInfo &Accessor; 483 SourceLocation AccessorLoc; 484public: 485 enum ElementType { 486 Point, // xywz 487 Color, // rgba 488 Texture // stpq 489 }; 490 OCUVectorElementExpr(QualType ty, Expr *base, IdentifierInfo &accessor, 491 SourceLocation loc) 492 : Expr(OCUVectorElementExprClass, ty), 493 Base(base), Accessor(accessor), AccessorLoc(loc) {} 494 495 const Expr *getBase() const { return Base; } 496 Expr *getBase() { return Base; } 497 498 IdentifierInfo &getAccessor() const { return Accessor; } 499 500 /// getNumElements - Get the number of components being selected. 501 unsigned getNumElements() const; 502 503 /// getElementType - Determine whether the components of this access are 504 /// "point" "color" or "texture" elements. 505 ElementType getElementType() const; 506 507 /// containsDuplicateElements - Return true if any element access is 508 /// repeated. 509 bool containsDuplicateElements() const; 510 511 /// getEncodedElementAccess - Encode the elements accessed into a bit vector. 512 /// The encoding currently uses 2-bit bitfields, but clients should use the 513 /// accessors below to access them. 514 /// 515 unsigned getEncodedElementAccess() const; 516 517 /// getAccessedFieldNo - Given an encoded value and a result number, return 518 /// the input field number being accessed. 519 static unsigned getAccessedFieldNo(unsigned Idx, unsigned EncodedVal) { 520 return (EncodedVal >> (Idx*2)) & 3; 521 } 522 523 virtual SourceRange getSourceRange() const { 524 return SourceRange(getBase()->getLocStart(), AccessorLoc); 525 } 526 static bool classof(const Stmt *T) { 527 return T->getStmtClass() == OCUVectorElementExprClass; 528 } 529 static bool classof(const OCUVectorElementExpr *) { return true; } 530}; 531 532/// CompoundLiteralExpr - [C99 6.5.2.5] 533/// 534class CompoundLiteralExpr : public Expr { 535 Expr *Init; 536public: 537 CompoundLiteralExpr(QualType ty, Expr *init) : 538 Expr(CompoundLiteralExprClass, ty), Init(init) {} 539 540 const Expr *getInitializer() const { return Init; } 541 Expr *getInitializer() { return Init; } 542 543 virtual SourceRange getSourceRange() const { return Init->getSourceRange(); } 544 545 static bool classof(const Stmt *T) { 546 return T->getStmtClass() == CompoundLiteralExprClass; 547 } 548 static bool classof(const CompoundLiteralExpr *) { return true; } 549}; 550 551/// ImplicitCastExpr - Allows us to explicitly represent implicit type 552/// conversions. For example: converting T[]->T*, void f()->void (*f)(), 553/// float->double, short->int, etc. 554/// 555class ImplicitCastExpr : public Expr { 556 Expr *Op; 557public: 558 ImplicitCastExpr(QualType ty, Expr *op) : 559 Expr(ImplicitCastExprClass, ty), Op(op) {} 560 561 Expr *getSubExpr() { return Op; } 562 const Expr *getSubExpr() const { return Op; } 563 564 virtual SourceRange getSourceRange() const { return Op->getSourceRange(); } 565 566 static bool classof(const Stmt *T) { 567 return T->getStmtClass() == ImplicitCastExprClass; 568 } 569 static bool classof(const ImplicitCastExpr *) { return true; } 570}; 571 572/// CastExpr - [C99 6.5.4] Cast Operators. 573/// 574class CastExpr : public Expr { 575 Expr *Op; 576 SourceLocation Loc; // the location of the left paren 577public: 578 CastExpr(QualType ty, Expr *op, SourceLocation l) : 579 Expr(CastExprClass, ty), Op(op), Loc(l) {} 580 581 SourceLocation getLParenLoc() const { return Loc; } 582 583 Expr *getSubExpr() const { return Op; } 584 585 virtual SourceRange getSourceRange() const { 586 return SourceRange(Loc, getSubExpr()->getSourceRange().End()); 587 } 588 static bool classof(const Stmt *T) { 589 return T->getStmtClass() == CastExprClass; 590 } 591 static bool classof(const CastExpr *) { return true; } 592}; 593 594class BinaryOperator : public Expr { 595public: 596 enum Opcode { 597 // Operators listed in order of precedence. 598 // Note that additions to this should also update the StmtVisitor class. 599 Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators. 600 Add, Sub, // [C99 6.5.6] Additive operators. 601 Shl, Shr, // [C99 6.5.7] Bitwise shift operators. 602 LT, GT, LE, GE, // [C99 6.5.8] Relational operators. 603 EQ, NE, // [C99 6.5.9] Equality operators. 604 And, // [C99 6.5.10] Bitwise AND operator. 605 Xor, // [C99 6.5.11] Bitwise XOR operator. 606 Or, // [C99 6.5.12] Bitwise OR operator. 607 LAnd, // [C99 6.5.13] Logical AND operator. 608 LOr, // [C99 6.5.14] Logical OR operator. 609 Assign, MulAssign,// [C99 6.5.16] Assignment operators. 610 DivAssign, RemAssign, 611 AddAssign, SubAssign, 612 ShlAssign, ShrAssign, 613 AndAssign, XorAssign, 614 OrAssign, 615 Comma // [C99 6.5.17] Comma operator. 616 }; 617 618 BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy) 619 : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) { 620 assert(!isCompoundAssignmentOp() && 621 "Use ArithAssignBinaryOperator for compound assignments"); 622 } 623 624 Opcode getOpcode() const { return Opc; } 625 Expr *getLHS() const { return LHS; } 626 Expr *getRHS() const { return RHS; } 627 virtual SourceRange getSourceRange() const { 628 return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd()); 629 } 630 631 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it 632 /// corresponds to, e.g. "<<=". 633 static const char *getOpcodeStr(Opcode Op); 634 635 /// predicates to categorize the respective opcodes. 636 bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; } 637 bool isAdditiveOp() const { return Opc == Add || Opc == Sub; } 638 bool isShiftOp() const { return Opc == Shl || Opc == Shr; } 639 bool isBitwiseOp() const { return Opc >= And && Opc <= Or; } 640 bool isRelationalOp() const { return Opc >= LT && Opc <= GE; } 641 bool isEqualityOp() const { return Opc == EQ || Opc == NE; } 642 bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; } 643 bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; } 644 bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;} 645 bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; } 646 647 static bool classof(const Stmt *T) { 648 return T->getStmtClass() == BinaryOperatorClass; 649 } 650 static bool classof(const BinaryOperator *) { return true; } 651private: 652 Expr *LHS, *RHS; 653 Opcode Opc; 654protected: 655 BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, bool dead) 656 : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) { 657 } 658}; 659 660/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep 661/// track of the type the operation is performed in. Due to the semantics of 662/// these operators, the operands are promoted, the aritmetic performed, an 663/// implicit conversion back to the result type done, then the assignment takes 664/// place. This captures the intermediate type which the computation is done 665/// in. 666class CompoundAssignOperator : public BinaryOperator { 667 QualType ComputationType; 668public: 669 CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, 670 QualType ResType, QualType CompType) 671 : BinaryOperator(lhs, rhs, opc, ResType, true), ComputationType(CompType) { 672 assert(isCompoundAssignmentOp() && 673 "Only should be used for compound assignments"); 674 } 675 676 QualType getComputationType() const { return ComputationType; } 677 678 static bool classof(const CompoundAssignOperator *) { return true; } 679 static bool classof(const BinaryOperator *B) { 680 return B->isCompoundAssignmentOp(); 681 } 682 static bool classof(const Stmt *S) { 683 return isa<BinaryOperator>(S) && classof(cast<BinaryOperator>(S)); 684 } 685}; 686 687/// ConditionalOperator - The ?: operator. Note that LHS may be null when the 688/// GNU "missing LHS" extension is in use. 689/// 690class ConditionalOperator : public Expr { 691 Expr *Cond, *LHS, *RHS; // Left/Middle/Right hand sides. 692public: 693 ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs, QualType t) 694 : Expr(ConditionalOperatorClass, t), Cond(cond), LHS(lhs), RHS(rhs) {} 695 696 Expr *getCond() const { return Cond; } 697 Expr *getLHS() const { return LHS; } 698 Expr *getRHS() const { return RHS; } 699 700 virtual SourceRange getSourceRange() const { 701 return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd()); 702 } 703 static bool classof(const Stmt *T) { 704 return T->getStmtClass() == ConditionalOperatorClass; 705 } 706 static bool classof(const ConditionalOperator *) { return true; } 707}; 708 709/// AddrLabelExpr - The GNU address of label extension, representing &&label. 710class AddrLabelExpr : public Expr { 711 SourceLocation AmpAmpLoc, LabelLoc; 712 LabelStmt *Label; 713public: 714 AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, 715 QualType t) 716 : Expr(AddrLabelExprClass, t), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} 717 718 virtual SourceRange getSourceRange() const { 719 return SourceRange(AmpAmpLoc, LabelLoc); 720 } 721 722 LabelStmt *getLabel() const { return Label; } 723 724 static bool classof(const Stmt *T) { 725 return T->getStmtClass() == AddrLabelExprClass; 726 } 727 static bool classof(const AddrLabelExpr *) { return true; } 728}; 729 730/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). 731/// The StmtExpr contains a single CompoundStmt node, which it evaluates and 732/// takes the value of the last subexpression. 733class StmtExpr : public Expr { 734 CompoundStmt *SubStmt; 735 SourceLocation LParenLoc, RParenLoc; 736public: 737 StmtExpr(CompoundStmt *substmt, QualType T, 738 SourceLocation lp, SourceLocation rp) : 739 Expr(StmtExprClass, T), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } 740 741 CompoundStmt *getSubStmt() { return SubStmt; } 742 const CompoundStmt *getSubStmt() const { return SubStmt; } 743 744 virtual SourceRange getSourceRange() const { 745 return SourceRange(LParenLoc, RParenLoc); 746 } 747 748 static bool classof(const Stmt *T) { 749 return T->getStmtClass() == StmtExprClass; 750 } 751 static bool classof(const StmtExpr *) { return true; } 752}; 753 754/// TypesCompatibleExpr - GNU builtin-in function __builtin_type_compatible_p. 755/// This AST node represents a function that returns 1 if two *types* (not 756/// expressions) are compatible. The result of this built-in function can be 757/// used in integer constant expressions. 758class TypesCompatibleExpr : public Expr { 759 QualType Type1; 760 QualType Type2; 761 SourceLocation BuiltinLoc, RParenLoc; 762public: 763 TypesCompatibleExpr(QualType ReturnType, SourceLocation BLoc, 764 QualType t1, QualType t2, SourceLocation RP) : 765 Expr(TypesCompatibleExprClass, ReturnType), Type1(t1), Type2(t2), 766 BuiltinLoc(BLoc), RParenLoc(RP) {} 767 768 QualType getArgType1() const { return Type1; } 769 QualType getArgType2() const { return Type2; } 770 771 int typesAreCompatible() const { return Type::typesAreCompatible(Type1,Type2); } 772 773 virtual SourceRange getSourceRange() const { 774 return SourceRange(BuiltinLoc, RParenLoc); 775 } 776 static bool classof(const Stmt *T) { 777 return T->getStmtClass() == TypesCompatibleExprClass; 778 } 779 static bool classof(const TypesCompatibleExpr *) { return true; } 780}; 781 782/// ChooseExpr - GNU builtin-in function __builtin_choose_expr. 783/// This AST node is similar to the conditional operator (?:) in C, with 784/// the following exceptions: 785/// - the test expression much be a constant expression. 786/// - the expression returned has it's type unaltered by promotion rules. 787/// - does not evaluate the expression that was not chosen. 788class ChooseExpr : public Expr { 789 Expr *Cond, *LHS, *RHS; // First, second, and third arguments. 790 SourceLocation BuiltinLoc, RParenLoc; 791public: 792 ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, 793 SourceLocation RP) 794 : Expr(ChooseExprClass, t), 795 Cond(cond), LHS(lhs), RHS(rhs), BuiltinLoc(BLoc), RParenLoc(RP) {} 796 797 Expr *getCond() { return Cond; } 798 Expr *getLHS() { return LHS; } 799 Expr *getRHS() { return RHS; } 800 801 const Expr *getCond() const { return Cond; } 802 const Expr *getLHS() const { return LHS; } 803 const Expr *getRHS() const { return RHS; } 804 805 virtual SourceRange getSourceRange() const { 806 return SourceRange(BuiltinLoc, RParenLoc); 807 } 808 static bool classof(const Stmt *T) { 809 return T->getStmtClass() == ChooseExprClass; 810 } 811 static bool classof(const ChooseExpr *) { return true; } 812}; 813 814/// ObjCStringLiteral, used for Objective-C string literals 815/// i.e. @"foo". 816class ObjCStringLiteral : public Expr { 817 StringLiteral *String; 818public: 819 ObjCStringLiteral(StringLiteral *SL, QualType T) 820 : Expr(ObjCStringLiteralClass, T), String(SL) {} 821 822 StringLiteral* getString() { return String; } 823 824 const StringLiteral* getString() const { return String; } 825 826 virtual SourceRange getSourceRange() const { 827 return String->getSourceRange(); 828 } 829 830 static bool classof(const Stmt *T) { 831 return T->getStmtClass() == ObjCStringLiteralClass; 832 } 833 static bool classof(const ObjCStringLiteral *) { return true; } 834}; 835 836} // end namespace clang 837 838#endif 839