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