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