Expr.h revision ab18c4c0ac1a46a38aa84c2c8ea485612e21a614
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_InvalidExpression 71 }; 72 isLvalueResult isLvalue() const; 73 74 /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, 75 /// does not have an incomplete type, does not have a const-qualified type, 76 /// and if it is a structure or union, does not have any member (including, 77 /// recursively, any member or element of all contained aggregates or unions) 78 /// with a const-qualified type. 79 enum isModifiableLvalueResult { 80 MLV_Valid, 81 MLV_NotObjectType, 82 MLV_IncompleteVoidType, 83 MLV_InvalidExpression, 84 MLV_IncompleteType, 85 MLV_ConstQualified, 86 MLV_ArrayType 87 }; 88 isModifiableLvalueResult isModifiableLvalue() const; 89 90 bool isNullPointerConstant(ASTContext &Ctx) const; 91 92 /// isIntegerConstantExpr - Return true if this expression is a valid integer 93 /// constant expression, and, if so, return its value in Result. If not a 94 /// valid i-c-e, return false and fill in Loc (if specified) with the location 95 /// of the invalid expression. 96 bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, 97 SourceLocation *Loc = 0, 98 bool isEvaluated = true) const; 99 bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const { 100 llvm::APSInt X(32); 101 return isIntegerConstantExpr(X, Ctx, Loc); 102 } 103 104 virtual void visit(StmtVisitor &Visitor); 105 static bool classof(const Stmt *T) { 106 return T->getStmtClass() >= firstExprConstant && 107 T->getStmtClass() <= lastExprConstant; 108 } 109 static bool classof(const Expr *) { return true; } 110}; 111 112//===----------------------------------------------------------------------===// 113// Primary Expressions. 114//===----------------------------------------------------------------------===// 115 116/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function, 117/// enum, etc. 118class DeclRefExpr : public Expr { 119 Decl *D; // a ValueDecl or EnumConstantDecl 120 SourceLocation Loc; 121public: 122 DeclRefExpr(Decl *d, QualType t, SourceLocation l) : 123 Expr(DeclRefExprClass, t), D(d), Loc(l) {} 124 125 Decl *getDecl() { return D; } 126 const Decl *getDecl() const { return D; } 127 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 128 129 130 virtual void visit(StmtVisitor &Visitor); 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 virtual void visit(StmtVisitor &Visitor); 158 static bool classof(const Stmt *T) { 159 return T->getStmtClass() == PreDefinedExprClass; 160 } 161 static bool classof(const PreDefinedExpr *) { return true; } 162}; 163 164class IntegerLiteral : public Expr { 165 llvm::APInt Value; 166 SourceLocation Loc; 167public: 168 // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, 169 // or UnsignedLongLongTy 170 IntegerLiteral(const llvm::APInt &V, QualType type, SourceLocation l) 171 : Expr(IntegerLiteralClass, type), Value(V), Loc(l) { 172 assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); 173 } 174 const llvm::APInt &getValue() const { return Value; } 175 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 176 177 virtual void visit(StmtVisitor &Visitor); 178 static bool classof(const Stmt *T) { 179 return T->getStmtClass() == IntegerLiteralClass; 180 } 181 static bool classof(const IntegerLiteral *) { return true; } 182}; 183 184class CharacterLiteral : public Expr { 185 unsigned Value; 186 SourceLocation Loc; 187public: 188 // type should be IntTy 189 CharacterLiteral(unsigned value, QualType type, SourceLocation l) 190 : Expr(CharacterLiteralClass, type), Value(value), Loc(l) { 191 } 192 SourceLocation getLoc() const { return Loc; } 193 194 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 195 196 unsigned getValue() const { return Value; } 197 198 virtual void visit(StmtVisitor &Visitor); 199 static bool classof(const Stmt *T) { 200 return T->getStmtClass() == CharacterLiteralClass; 201 } 202 static bool classof(const CharacterLiteral *) { return true; } 203}; 204 205class FloatingLiteral : public Expr { 206 float Value; // FIXME 207 SourceLocation Loc; 208public: 209 FloatingLiteral(float value, QualType type, SourceLocation l) 210 : Expr(FloatingLiteralClass, type), Value(value), Loc(l) {} 211 212 float getValue() const { return Value; } 213 214 virtual SourceRange getSourceRange() const { return SourceRange(Loc); } 215 216 virtual void visit(StmtVisitor &Visitor); 217 static bool classof(const Stmt *T) { 218 return T->getStmtClass() == FloatingLiteralClass; 219 } 220 static bool classof(const FloatingLiteral *) { return true; } 221}; 222 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 virtual void visit(StmtVisitor &Visitor); 244 static bool classof(const Stmt *T) { 245 return T->getStmtClass() == StringLiteralClass; 246 } 247 static bool classof(const StringLiteral *) { return true; } 248}; 249 250/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This 251/// AST node is only formed if full location information is requested. 252class ParenExpr : public Expr { 253 SourceLocation L, R; 254 Expr *Val; 255public: 256 ParenExpr(SourceLocation l, SourceLocation r, Expr *val) 257 : Expr(ParenExprClass, val->getType()), L(l), R(r), Val(val) {} 258 259 const Expr *getSubExpr() const { return Val; } 260 Expr *getSubExpr() { return Val; } 261 SourceRange getSourceRange() const { return SourceRange(L, R); } 262 263 virtual void visit(StmtVisitor &Visitor); 264 static bool classof(const Stmt *T) { 265 return T->getStmtClass() == ParenExprClass; 266 } 267 static bool classof(const ParenExpr *) { return true; } 268}; 269 270 271/// UnaryOperator - This represents the unary-expression's (except sizeof of 272/// types), the postinc/postdec operators from postfix-expression, and various 273/// extensions. 274class UnaryOperator : public Expr { 275public: 276 enum Opcode { 277 PostInc, PostDec, // [C99 6.5.2.4] Postfix increment and decrement operators 278 PreInc, PreDec, // [C99 6.5.3.1] Prefix increment and decrement operators. 279 AddrOf, Deref, // [C99 6.5.3.2] Address and indirection operators. 280 Plus, Minus, // [C99 6.5.3.3] Unary arithmetic operators. 281 Not, LNot, // [C99 6.5.3.3] Unary arithmetic operators. 282 SizeOf, AlignOf, // [C99 6.5.3.4] Sizeof (expr, not type) operator. 283 Real, Imag, // "__real expr"/"__imag expr" Extension. 284 Extension // __extension__ marker. 285 }; 286private: 287 Expr *Val; 288 Opcode Opc; 289 SourceLocation Loc; 290public: 291 292 UnaryOperator(Expr *input, Opcode opc, QualType type, SourceLocation l) 293 : Expr(UnaryOperatorClass, type), Val(input), Opc(opc), Loc(l) {} 294 295 Opcode getOpcode() const { return Opc; } 296 Expr *getSubExpr() const { return Val; } 297 298 /// getOperatorLoc - Return the location of the operator. 299 SourceLocation getOperatorLoc() const { return Loc; } 300 301 /// isPostfix - Return true if this is a postfix operation, like x++. 302 static bool isPostfix(Opcode Op); 303 304 bool isPostfix() const { return isPostfix(Opc); } 305 bool isIncrementDecrementOp() const { return Opc>=PostInc && Opc<=PreDec; } 306 bool isSizeOfAlignOfOp() const { return Opc == SizeOf || Opc == AlignOf; } 307 static bool isArithmeticOp(Opcode Op) { return Op >= Plus && Op <= LNot; } 308 309 /// getDecl - a recursive routine that derives the base decl for an 310 /// expression. For example, it will return the declaration for "s" from 311 /// the following complex expression "s.zz[2].bb.vv". 312 static bool isAddressable(Expr *e); 313 314 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it 315 /// corresponds to, e.g. "sizeof" or "[pre]++" 316 static const char *getOpcodeStr(Opcode Op); 317 318 virtual SourceRange getSourceRange() const { 319 if (isPostfix()) 320 return SourceRange(Val->getLocStart(), Loc); 321 else 322 return SourceRange(Loc, Val->getLocEnd()); 323 } 324 virtual SourceLocation getExprLoc() const { return Loc; } 325 326 virtual void visit(StmtVisitor &Visitor); 327 static bool classof(const Stmt *T) { 328 return T->getStmtClass() == UnaryOperatorClass; 329 } 330 static bool classof(const UnaryOperator *) { return true; } 331}; 332 333/// SizeOfAlignOfTypeExpr - [C99 6.5.3.4] - This is only for sizeof/alignof of 334/// *types*. sizeof(expr) is handled by UnaryOperator. 335class SizeOfAlignOfTypeExpr : public Expr { 336 bool isSizeof; // true if sizeof, false if alignof. 337 QualType Ty; 338 SourceLocation OpLoc, RParenLoc; 339public: 340 SizeOfAlignOfTypeExpr(bool issizeof, QualType argType, QualType resultType, 341 SourceLocation op, SourceLocation rp) : 342 Expr(SizeOfAlignOfTypeExprClass, resultType), 343 isSizeof(issizeof), Ty(argType), OpLoc(op), RParenLoc(rp) {} 344 345 bool isSizeOf() const { return isSizeof; } 346 QualType getArgumentType() const { return Ty; } 347 348 SourceLocation getOperatorLoc() const { return OpLoc; } 349 SourceRange getSourceRange() const { return SourceRange(OpLoc, RParenLoc); } 350 351 virtual void visit(StmtVisitor &Visitor); 352 static bool classof(const Stmt *T) { 353 return T->getStmtClass() == SizeOfAlignOfTypeExprClass; 354 } 355 static bool classof(const SizeOfAlignOfTypeExpr *) { return true; } 356}; 357 358//===----------------------------------------------------------------------===// 359// Postfix Operators. 360//===----------------------------------------------------------------------===// 361 362/// ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting. 363class ArraySubscriptExpr : public Expr { 364 Expr *Base, *Idx; 365 SourceLocation RBracketLoc; 366public: 367 ArraySubscriptExpr(Expr *base, Expr *idx, QualType t, 368 SourceLocation rbracketloc) : 369 Expr(ArraySubscriptExprClass, t), 370 Base(base), Idx(idx), RBracketLoc(rbracketloc) {} 371 372 Expr *getBase() { return Base; } 373 const Expr *getBase() const { return Base; } 374 Expr *getIdx() { return Idx; } 375 const Expr *getIdx() const { return Idx; } 376 377 SourceRange getSourceRange() const { 378 return SourceRange(Base->getLocStart(), RBracketLoc); 379 } 380 virtual SourceLocation getExprLoc() const { return RBracketLoc; } 381 382 virtual void visit(StmtVisitor &Visitor); 383 static bool classof(const Stmt *T) { 384 return T->getStmtClass() == ArraySubscriptExprClass; 385 } 386 static bool classof(const ArraySubscriptExpr *) { return true; } 387}; 388 389 390/// CallExpr - [C99 6.5.2.2] Function Calls. 391/// 392class CallExpr : public Expr { 393 Expr *Fn; 394 Expr **Args; 395 unsigned NumArgs; 396 SourceLocation RParenLoc; 397public: 398 CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t, 399 SourceLocation rparenloc); 400 ~CallExpr() { 401 delete [] Args; 402 } 403 404 const Expr *getCallee() const { return Fn; } 405 Expr *getCallee() { return Fn; } 406 407 /// getNumArgs - Return the number of actual arguments to this call. 408 /// 409 unsigned getNumArgs() const { return NumArgs; } 410 411 /// getArg - Return the specified argument. 412 Expr *getArg(unsigned Arg) { 413 assert(Arg < NumArgs && "Arg access out of range!"); 414 return Args[Arg]; 415 } 416 const Expr *getArg(unsigned Arg) const { 417 assert(Arg < NumArgs && "Arg access out of range!"); 418 return Args[Arg]; 419 } 420 421 /// getNumCommas - Return the number of commas that must have been present in 422 /// this function call. 423 unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; } 424 425 SourceRange getSourceRange() const { 426 return SourceRange(Fn->getLocStart(), RParenLoc); 427 } 428 429 virtual void visit(StmtVisitor &Visitor); 430 static bool classof(const Stmt *T) { 431 return T->getStmtClass() == CallExprClass; 432 } 433 static bool classof(const CallExpr *) { return true; } 434}; 435 436/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. 437/// 438class MemberExpr : public Expr { 439 Expr *Base; 440 FieldDecl *MemberDecl; 441 SourceLocation MemberLoc; 442 bool IsArrow; // True if this is "X->F", false if this is "X.F". 443public: 444 MemberExpr(Expr *base, bool isarrow, FieldDecl *memberdecl, SourceLocation l) 445 : Expr(MemberExprClass, memberdecl->getType()), 446 Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow) {} 447 448 Expr *getBase() const { return Base; } 449 FieldDecl *getMemberDecl() const { return MemberDecl; } 450 bool isArrow() const { return IsArrow; } 451 452 virtual SourceRange getSourceRange() const { 453 return SourceRange(getBase()->getLocStart(), MemberLoc); 454 } 455 virtual SourceLocation getExprLoc() const { return MemberLoc; } 456 457 virtual void visit(StmtVisitor &Visitor); 458 static bool classof(const Stmt *T) { 459 return T->getStmtClass() == MemberExprClass; 460 } 461 static bool classof(const MemberExpr *) { return true; } 462}; 463 464/// CompoundLiteralExpr - [C99 6.5.2.5] 465/// 466class CompoundLiteralExpr : public Expr { 467 Expr *Init; 468public: 469 CompoundLiteralExpr(QualType ty, Expr *init) : 470 Expr(CompoundLiteralExprClass, ty), Init(init) {} 471 472 Expr *getInitializer() const { return Init; } 473 474 virtual SourceRange getSourceRange() const { return SourceRange(); } // FIXME 475 476 virtual void visit(StmtVisitor &Visitor); 477 static bool classof(const Stmt *T) { 478 return T->getStmtClass() == CompoundLiteralExprClass; 479 } 480 static bool classof(const CompoundLiteralExpr *) { return true; } 481}; 482 483/// ImplicitCastExpr - Allows us to explicitly represent implicit type 484/// conversions. For example: converting T[]->T*, void f()->void (*f)(), 485/// float->double, short->int, etc. 486/// 487class ImplicitCastExpr : public Expr { 488 Expr *Op; 489public: 490 ImplicitCastExpr(QualType ty, Expr *op) : 491 Expr(ImplicitCastExprClass, ty), Op(op) {} 492 493 Expr *getSubExpr() { return Op; } 494 const Expr *getSubExpr() const { return Op; } 495 496 virtual SourceRange getSourceRange() const { return Op->getSourceRange(); } 497 498 virtual void visit(StmtVisitor &Visitor); 499 static bool classof(const Stmt *T) { 500 return T->getStmtClass() == ImplicitCastExprClass; 501 } 502 static bool classof(const ImplicitCastExpr *) { return true; } 503}; 504 505/// CastExpr - [C99 6.5.4] Cast Operators. 506/// 507class CastExpr : public Expr { 508 Expr *Op; 509 SourceLocation Loc; // the location of the left paren 510public: 511 CastExpr(QualType ty, Expr *op, SourceLocation l) : 512 Expr(CastExprClass, ty), Op(op), Loc(l) {} 513 514 SourceLocation getLParenLoc() const { return Loc; } 515 516 Expr *getSubExpr() const { return Op; } 517 518 virtual SourceRange getSourceRange() const { 519 return SourceRange(Loc, getSubExpr()->getSourceRange().End()); 520 } 521 virtual void visit(StmtVisitor &Visitor); 522 static bool classof(const Stmt *T) { 523 return T->getStmtClass() == CastExprClass; 524 } 525 static bool classof(const CastExpr *) { return true; } 526}; 527 528class BinaryOperator : public Expr { 529public: 530 enum Opcode { 531 // Operators listed in order of precedence. 532 Mul, Div, Rem, // [C99 6.5.5] Multiplicative operators. 533 Add, Sub, // [C99 6.5.6] Additive operators. 534 Shl, Shr, // [C99 6.5.7] Bitwise shift operators. 535 LT, GT, LE, GE, // [C99 6.5.8] Relational operators. 536 EQ, NE, // [C99 6.5.9] Equality operators. 537 And, // [C99 6.5.10] Bitwise AND operator. 538 Xor, // [C99 6.5.11] Bitwise XOR operator. 539 Or, // [C99 6.5.12] Bitwise OR operator. 540 LAnd, // [C99 6.5.13] Logical AND operator. 541 LOr, // [C99 6.5.14] Logical OR operator. 542 Assign, MulAssign,// [C99 6.5.16] Assignment operators. 543 DivAssign, RemAssign, 544 AddAssign, SubAssign, 545 ShlAssign, ShrAssign, 546 AndAssign, XorAssign, 547 OrAssign, 548 Comma // [C99 6.5.17] Comma operator. 549 }; 550 551 BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy) 552 : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) { 553 assert(!isCompoundAssignmentOp() && 554 "Use ArithAssignBinaryOperator for compound assignments"); 555 } 556 557 Opcode getOpcode() const { return Opc; } 558 Expr *getLHS() const { return LHS; } 559 Expr *getRHS() const { return RHS; } 560 virtual SourceRange getSourceRange() const { 561 return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd()); 562 } 563 564 /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it 565 /// corresponds to, e.g. "<<=". 566 static const char *getOpcodeStr(Opcode Op); 567 568 /// predicates to categorize the respective opcodes. 569 bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; } 570 bool isAdditiveOp() const { return Opc == Add || Opc == Sub; } 571 bool isShiftOp() const { return Opc == Shl || Opc == Shr; } 572 bool isBitwiseOp() const { return Opc >= And && Opc <= Or; } 573 bool isRelationalOp() const { return Opc >= LT && Opc <= GE; } 574 bool isEqualityOp() const { return Opc == EQ || Opc == NE; } 575 bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; } 576 bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; } 577 bool isCompoundAssignmentOp() const { return Opc > Assign && Opc <= OrAssign;} 578 bool isShiftAssignOp() const { return Opc == ShlAssign || Opc == ShrAssign; } 579 580 virtual void visit(StmtVisitor &Visitor); 581 static bool classof(const Stmt *T) { 582 return T->getStmtClass() == BinaryOperatorClass; 583 } 584 static bool classof(const BinaryOperator *) { return true; } 585private: 586 Expr *LHS, *RHS; 587 Opcode Opc; 588protected: 589 BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, bool dead) 590 : Expr(BinaryOperatorClass, ResTy), LHS(lhs), RHS(rhs), Opc(opc) { 591 } 592}; 593 594/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep 595/// track of the type the operation is performed in. Due to the semantics of 596/// these operators, the operands are promoted, the aritmetic performed, an 597/// implicit conversion back to the result type done, then the assignment takes 598/// place. This captures the intermediate type which the computation is done 599/// in. 600class CompoundAssignOperator : public BinaryOperator { 601 QualType ComputationType; 602public: 603 CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, 604 QualType ResType, QualType CompType) 605 : BinaryOperator(lhs, rhs, opc, ResType, true), ComputationType(CompType) { 606 assert(isCompoundAssignmentOp() && 607 "Only should be used for compound assignments"); 608 } 609 610 QualType getComputationType() const { return ComputationType; } 611 612 static bool classof(const CompoundAssignOperator *) { return true; } 613 static bool classof(const BinaryOperator *B) { 614 return B->isCompoundAssignmentOp(); 615 } 616 static bool classof(const Stmt *S) { 617 return isa<BinaryOperator>(S) && classof(cast<BinaryOperator>(S)); 618 } 619}; 620 621/// ConditionalOperator - The ?: operator. Note that LHS may be null when the 622/// GNU "missing LHS" extension is in use. 623/// 624class ConditionalOperator : public Expr { 625 Expr *Cond, *LHS, *RHS; // Left/Middle/Right hand sides. 626public: 627 ConditionalOperator(Expr *cond, Expr *lhs, Expr *rhs, QualType t) 628 : Expr(ConditionalOperatorClass, t), Cond(cond), LHS(lhs), RHS(rhs) {} 629 630 Expr *getCond() const { return Cond; } 631 Expr *getLHS() const { return LHS; } 632 Expr *getRHS() const { return RHS; } 633 634 virtual SourceRange getSourceRange() const { 635 return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd()); 636 } 637 virtual void visit(StmtVisitor &Visitor); 638 static bool classof(const Stmt *T) { 639 return T->getStmtClass() == ConditionalOperatorClass; 640 } 641 static bool classof(const ConditionalOperator *) { return true; } 642}; 643 644/// AddrLabel - The GNU address of label extension, representing &&label. 645class AddrLabel : public Expr { 646 SourceLocation AmpAmpLoc, LabelLoc; 647 LabelStmt *Label; 648public: 649 AddrLabel(SourceLocation AALoc, SourceLocation LLoc, LabelStmt *L, QualType t) 650 : Expr(AddrLabelClass, t), AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} 651 652 virtual SourceRange getSourceRange() const { 653 return SourceRange(AmpAmpLoc, LabelLoc); 654 } 655 656 LabelStmt *getLabel() const { return Label; } 657 658 virtual void visit(StmtVisitor &Visitor); 659 static bool classof(const Stmt *T) { 660 return T->getStmtClass() == AddrLabelClass; 661 } 662 static bool classof(const AddrLabel *) { return true; } 663}; 664 665/// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). 666/// The StmtExpr contains a single CompoundStmt node, which it evaluates and 667/// takes the value of the last subexpression. 668class StmtExpr : public Expr { 669 CompoundStmt *SubStmt; 670 SourceLocation LParenLoc, RParenLoc; 671public: 672 StmtExpr(CompoundStmt *substmt, QualType T, 673 SourceLocation lp, SourceLocation rp) 674 : Expr(StmtExprClass, T), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { 675 } 676 677 CompoundStmt *getSubStmt() { return SubStmt; } 678 const CompoundStmt *getSubStmt() const { return SubStmt; } 679 680 virtual SourceRange getSourceRange() const { 681 return SourceRange(LParenLoc, RParenLoc); 682 } 683 684 virtual void visit(StmtVisitor &Visitor); 685 static bool classof(const Stmt *T) { 686 return T->getStmtClass() == StmtExprClass; 687 } 688 static bool classof(const StmtExpr *) { return true; } 689}; 690 691} // end namespace clang 692 693#endif 694