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