Stmt.h revision d249e1d1f1498b81314459ceda19d6ff25c278ad
1//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the Stmt interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_STMT_H
15#define LLVM_CLANG_AST_STMT_H
16
17#include "llvm/Support/Casting.h"
18#include "llvm/Support/raw_ostream.h"
19#include "clang/Basic/SourceLocation.h"
20#include "clang/AST/PrettyPrinter.h"
21#include "clang/AST/StmtIterator.h"
22#include "clang/AST/DeclGroup.h"
23#include "llvm/ADT/SmallVector.h"
24#include "llvm/ADT/iterator.h"
25#include "clang/AST/ASTContext.h"
26#include <string>
27using llvm::dyn_cast_or_null;
28
29namespace clang {
30  class ASTContext;
31  class Expr;
32  class Decl;
33  class ParmVarDecl;
34  class QualType;
35  class IdentifierInfo;
36  class SourceManager;
37  class StringLiteral;
38  class SwitchStmt;
39
40  //===----------------------------------------------------------------------===//
41  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
42  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
43  //  references to children (to be compatible with StmtIterator).
44  //===----------------------------------------------------------------------===//
45
46  class Stmt;
47  class Expr;
48
49  class ExprIterator {
50    Stmt** I;
51  public:
52    ExprIterator(Stmt** i) : I(i) {}
53    ExprIterator() : I(0) {}
54    ExprIterator& operator++() { ++I; return *this; }
55    ExprIterator operator-(size_t i) { return I-i; }
56    ExprIterator operator+(size_t i) { return I+i; }
57    Expr* operator[](size_t idx);
58    // FIXME: Verify that this will correctly return a signed distance.
59    signed operator-(const ExprIterator& R) const { return I - R.I; }
60    Expr* operator*() const;
61    Expr* operator->() const;
62    bool operator==(const ExprIterator& R) const { return I == R.I; }
63    bool operator!=(const ExprIterator& R) const { return I != R.I; }
64    bool operator>(const ExprIterator& R) const { return I > R.I; }
65    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
66  };
67
68  class ConstExprIterator {
69    Stmt* const * I;
70  public:
71    ConstExprIterator(Stmt* const* i) : I(i) {}
72    ConstExprIterator() : I(0) {}
73    ConstExprIterator& operator++() { ++I; return *this; }
74    ConstExprIterator operator+(size_t i) { return I+i; }
75    ConstExprIterator operator-(size_t i) { return I-i; }
76    const Expr * operator[](size_t idx) const;
77    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
78    const Expr * operator*() const;
79    const Expr * operator->() const;
80    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
81    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
82    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
83    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
84  };
85
86//===----------------------------------------------------------------------===//
87// AST classes for statements.
88//===----------------------------------------------------------------------===//
89
90/// Stmt - This represents one statement.
91///
92class Stmt {
93public:
94  enum StmtClass {
95    NoStmtClass = 0,
96#define STMT(CLASS, PARENT) CLASS##Class,
97#define FIRST_STMT(CLASS) firstStmtConstant = CLASS##Class,
98#define LAST_STMT(CLASS) lastStmtConstant = CLASS##Class,
99#define FIRST_EXPR(CLASS) firstExprConstant = CLASS##Class,
100#define LAST_EXPR(CLASS) lastExprConstant = CLASS##Class
101#include "clang/AST/StmtNodes.def"
102};
103private:
104  const StmtClass sClass;
105
106  // Make vanilla 'new' and 'delete' illegal for Stmts.
107protected:
108  void* operator new(size_t bytes) throw() {
109    assert(0 && "Stmts cannot be allocated with regular 'new'.");
110    return 0;
111  }
112  void operator delete(void* data) throw() {
113    assert(0 && "Stmts cannot be released with regular 'delete'.");
114  }
115
116public:
117  // Only allow allocation of Stmts using the allocator in ASTContext
118  // or by doing a placement new.
119  void* operator new(size_t bytes, ASTContext& C,
120                     unsigned alignment = 16) throw() {
121    return ::operator new(bytes, C, alignment);
122  }
123
124  void* operator new(size_t bytes, ASTContext* C,
125                     unsigned alignment = 16) throw() {
126    return ::operator new(bytes, *C, alignment);
127  }
128
129  void* operator new(size_t bytes, void* mem) throw() {
130    return mem;
131  }
132
133  void operator delete(void*, ASTContext&, unsigned) throw() { }
134  void operator delete(void*, ASTContext*, unsigned) throw() { }
135  void operator delete(void*, std::size_t) throw() { }
136  void operator delete(void*, void*) throw() { }
137
138public:
139  /// \brief A placeholder type used to construct an empty shell of a
140  /// type, that will be filled in later (e.g., by some
141  /// de-serialization).
142  struct EmptyShell { };
143
144protected:
145  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
146  ///  recursively release child AST nodes.
147  void DestroyChildren(ASTContext& Ctx);
148
149  /// \brief Construct an empty statement.
150  explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC) {
151    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
152  }
153
154public:
155  Stmt(StmtClass SC) : sClass(SC) {
156    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
157  }
158  virtual ~Stmt() {}
159
160  virtual void Destroy(ASTContext &Ctx);
161
162  StmtClass getStmtClass() const { return sClass; }
163  const char *getStmtClassName() const;
164
165  /// SourceLocation tokens are not useful in isolation - they are low level
166  /// value objects created/interpreted by SourceManager. We assume AST
167  /// clients will have a pointer to the respective SourceManager.
168  virtual SourceRange getSourceRange() const = 0;
169  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
170  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
171
172  // global temp stats (until we have a per-module visitor)
173  static void addStmtClass(const StmtClass s);
174  static bool CollectingStats(bool enable=false);
175  static void PrintStats();
176
177  /// dump - This does a local dump of the specified AST fragment.  It dumps the
178  /// specified node and a few nodes underneath it, but not the whole subtree.
179  /// This is useful in a debugger.
180  void dump() const;
181  void dump(SourceManager &SM) const;
182
183  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
184  void dumpAll() const;
185  void dumpAll(SourceManager &SM) const;
186
187  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
188  /// back to its original source language syntax.
189  void dumpPretty() const;
190  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = 0,
191                   const PrintingPolicy &Policy = PrintingPolicy(),
192                   unsigned Indentation = 0) const;
193
194  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
195  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
196  void viewAST() const;
197
198  // Implement isa<T> support.
199  static bool classof(const Stmt *) { return true; }
200
201  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
202  ///  contain implicit control-flow in the order their subexpressions
203  ///  are evaluated.  This predicate returns true if this statement has
204  ///  such implicit control-flow.  Such statements are also specially handled
205  ///  within CFGs.
206  bool hasImplicitControlFlow() const;
207
208  /// Child Iterators: All subclasses must implement child_begin and child_end
209  ///  to permit easy iteration over the substatements/subexpessions of an
210  ///  AST node.  This permits easy iteration over all nodes in the AST.
211  typedef StmtIterator       child_iterator;
212  typedef ConstStmtIterator  const_child_iterator;
213
214  virtual child_iterator child_begin() = 0;
215  virtual child_iterator child_end()   = 0;
216
217  const_child_iterator child_begin() const {
218    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
219  }
220
221  const_child_iterator child_end() const {
222    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
223  }
224};
225
226/// DeclStmt - Adaptor class for mixing declarations with statements and
227/// expressions. For example, CompoundStmt mixes statements, expressions
228/// and declarations (variables, types). Another example is ForStmt, where
229/// the first statement can be an expression or a declaration.
230///
231class DeclStmt : public Stmt {
232  DeclGroupRef DG;
233  SourceLocation StartLoc, EndLoc;
234public:
235  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
236           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
237                                    StartLoc(startLoc), EndLoc(endLoc) {}
238
239  /// \brief Build an empty declaration statement.
240  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
241
242  virtual void Destroy(ASTContext& Ctx);
243
244  /// isSingleDecl - This method returns true if this DeclStmt refers
245  /// to a single Decl.
246  bool isSingleDecl() const {
247    return DG.isSingleDecl();
248  }
249
250  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
251  Decl *getSingleDecl() { return DG.getSingleDecl(); }
252
253  const DeclGroupRef getDeclGroup() const { return DG; }
254  DeclGroupRef getDeclGroup() { return DG; }
255  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
256
257  SourceLocation getStartLoc() const { return StartLoc; }
258  void setStartLoc(SourceLocation L) { StartLoc = L; }
259  SourceLocation getEndLoc() const { return EndLoc; }
260  void setEndLoc(SourceLocation L) { EndLoc = L; }
261
262  SourceRange getSourceRange() const {
263    return SourceRange(StartLoc, EndLoc);
264  }
265
266  static bool classof(const Stmt *T) {
267    return T->getStmtClass() == DeclStmtClass;
268  }
269  static bool classof(const DeclStmt *) { return true; }
270
271  // Iterators over subexpressions.
272  virtual child_iterator child_begin();
273  virtual child_iterator child_end();
274
275  typedef DeclGroupRef::iterator decl_iterator;
276  typedef DeclGroupRef::const_iterator const_decl_iterator;
277
278  decl_iterator decl_begin() { return DG.begin(); }
279  decl_iterator decl_end() { return DG.end(); }
280  const_decl_iterator decl_begin() const { return DG.begin(); }
281  const_decl_iterator decl_end() const { return DG.end(); }
282};
283
284/// NullStmt - This is the null statement ";": C99 6.8.3p3.
285///
286class NullStmt : public Stmt {
287  SourceLocation SemiLoc;
288public:
289  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
290
291  /// \brief Build an empty null statement.
292  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
293
294  NullStmt* Clone(ASTContext &C) const;
295
296  SourceLocation getSemiLoc() const { return SemiLoc; }
297  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
298
299  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
300
301  static bool classof(const Stmt *T) {
302    return T->getStmtClass() == NullStmtClass;
303  }
304  static bool classof(const NullStmt *) { return true; }
305
306  // Iterators
307  virtual child_iterator child_begin();
308  virtual child_iterator child_end();
309};
310
311/// CompoundStmt - This represents a group of statements like { stmt stmt }.
312///
313class CompoundStmt : public Stmt {
314  Stmt** Body;
315  unsigned NumStmts;
316  SourceLocation LBracLoc, RBracLoc;
317public:
318  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned numStmts,
319                             SourceLocation LB, SourceLocation RB)
320  : Stmt(CompoundStmtClass), NumStmts(numStmts), LBracLoc(LB), RBracLoc(RB) {
321    if (NumStmts == 0) {
322      Body = 0;
323      return;
324    }
325
326    Body = new (C) Stmt*[NumStmts];
327    memcpy(Body, StmtStart, numStmts * sizeof(*Body));
328  }
329
330  // \brief Build an empty compound statement.
331  explicit CompoundStmt(EmptyShell Empty)
332    : Stmt(CompoundStmtClass, Empty), Body(0), NumStmts(0) { }
333
334  void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
335
336  bool body_empty() const { return NumStmts == 0; }
337  unsigned size() const { return NumStmts; }
338
339  typedef Stmt** body_iterator;
340  body_iterator body_begin() { return Body; }
341  body_iterator body_end() { return Body + NumStmts; }
342  Stmt *body_back() { return NumStmts ? Body[NumStmts-1] : 0; }
343
344  typedef Stmt* const * const_body_iterator;
345  const_body_iterator body_begin() const { return Body; }
346  const_body_iterator body_end() const { return Body + NumStmts; }
347  const Stmt *body_back() const { return NumStmts ? Body[NumStmts-1] : 0; }
348
349  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
350  reverse_body_iterator body_rbegin() {
351    return reverse_body_iterator(body_end());
352  }
353  reverse_body_iterator body_rend() {
354    return reverse_body_iterator(body_begin());
355  }
356
357  typedef std::reverse_iterator<const_body_iterator>
358          const_reverse_body_iterator;
359
360  const_reverse_body_iterator body_rbegin() const {
361    return const_reverse_body_iterator(body_end());
362  }
363
364  const_reverse_body_iterator body_rend() const {
365    return const_reverse_body_iterator(body_begin());
366  }
367
368  virtual SourceRange getSourceRange() const {
369    return SourceRange(LBracLoc, RBracLoc);
370  }
371
372  SourceLocation getLBracLoc() const { return LBracLoc; }
373  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
374  SourceLocation getRBracLoc() const { return RBracLoc; }
375  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
376
377  static bool classof(const Stmt *T) {
378    return T->getStmtClass() == CompoundStmtClass;
379  }
380  static bool classof(const CompoundStmt *) { return true; }
381
382  // Iterators
383  virtual child_iterator child_begin();
384  virtual child_iterator child_end();
385};
386
387// SwitchCase is the base class for CaseStmt and DefaultStmt,
388class SwitchCase : public Stmt {
389protected:
390  // A pointer to the following CaseStmt or DefaultStmt class,
391  // used by SwitchStmt.
392  SwitchCase *NextSwitchCase;
393
394  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
395
396public:
397  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
398
399  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
400
401  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
402
403  Stmt *getSubStmt() { return v_getSubStmt(); }
404
405  virtual SourceRange getSourceRange() const { return SourceRange(); }
406
407  static bool classof(const Stmt *T) {
408    return T->getStmtClass() == CaseStmtClass ||
409    T->getStmtClass() == DefaultStmtClass;
410  }
411  static bool classof(const SwitchCase *) { return true; }
412protected:
413  virtual Stmt* v_getSubStmt() = 0;
414};
415
416class CaseStmt : public SwitchCase {
417  enum { SUBSTMT, LHS, RHS, END_EXPR };
418  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
419                             // GNU "case 1 ... 4" extension
420  SourceLocation CaseLoc;
421  SourceLocation EllipsisLoc;
422  SourceLocation ColonLoc;
423
424  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
425public:
426  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
427           SourceLocation ellipsisLoc, SourceLocation colonLoc)
428    : SwitchCase(CaseStmtClass) {
429    SubExprs[SUBSTMT] = 0;
430    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
431    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
432    CaseLoc = caseLoc;
433    EllipsisLoc = ellipsisLoc;
434    ColonLoc = colonLoc;
435  }
436
437  /// \brief Build an empty switch case statement.
438  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
439
440  SourceLocation getCaseLoc() const { return CaseLoc; }
441  void setCaseLoc(SourceLocation L) { CaseLoc = L; }
442  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
443  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
444  SourceLocation getColonLoc() const { return ColonLoc; }
445  void setColonLoc(SourceLocation L) { ColonLoc = L; }
446
447  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
448  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
449  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
450
451  const Expr *getLHS() const {
452    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
453  }
454  const Expr *getRHS() const {
455    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
456  }
457  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
458
459  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
460  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
461  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
462
463
464  virtual SourceRange getSourceRange() const {
465    // Handle deeply nested case statements with iteration instead of recursion.
466    const CaseStmt *CS = this;
467    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
468      CS = CS2;
469
470    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
471  }
472  static bool classof(const Stmt *T) {
473    return T->getStmtClass() == CaseStmtClass;
474  }
475  static bool classof(const CaseStmt *) { return true; }
476
477  // Iterators
478  virtual child_iterator child_begin();
479  virtual child_iterator child_end();
480};
481
482class DefaultStmt : public SwitchCase {
483  Stmt* SubStmt;
484  SourceLocation DefaultLoc;
485  SourceLocation ColonLoc;
486  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
487public:
488  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
489    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
490    ColonLoc(CL) {}
491
492  /// \brief Build an empty default statement.
493  explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
494
495  Stmt *getSubStmt() { return SubStmt; }
496  const Stmt *getSubStmt() const { return SubStmt; }
497  void setSubStmt(Stmt *S) { SubStmt = S; }
498
499  SourceLocation getDefaultLoc() const { return DefaultLoc; }
500  void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
501  SourceLocation getColonLoc() const { return ColonLoc; }
502  void setColonLoc(SourceLocation L) { ColonLoc = L; }
503
504  virtual SourceRange getSourceRange() const {
505    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
506  }
507  static bool classof(const Stmt *T) {
508    return T->getStmtClass() == DefaultStmtClass;
509  }
510  static bool classof(const DefaultStmt *) { return true; }
511
512  // Iterators
513  virtual child_iterator child_begin();
514  virtual child_iterator child_end();
515};
516
517class LabelStmt : public Stmt {
518  IdentifierInfo *Label;
519  Stmt *SubStmt;
520  SourceLocation IdentLoc;
521public:
522  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
523    : Stmt(LabelStmtClass), Label(label),
524      SubStmt(substmt), IdentLoc(IL) {}
525
526  // \brief Build an empty label statement.
527  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
528
529  SourceLocation getIdentLoc() const { return IdentLoc; }
530  IdentifierInfo *getID() const { return Label; }
531  void setID(IdentifierInfo *II) { Label = II; }
532  const char *getName() const;
533  Stmt *getSubStmt() { return SubStmt; }
534  const Stmt *getSubStmt() const { return SubStmt; }
535  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
536  void setSubStmt(Stmt *SS) { SubStmt = SS; }
537
538  virtual SourceRange getSourceRange() const {
539    return SourceRange(IdentLoc, SubStmt->getLocEnd());
540  }
541  static bool classof(const Stmt *T) {
542    return T->getStmtClass() == LabelStmtClass;
543  }
544  static bool classof(const LabelStmt *) { return true; }
545
546  // Iterators
547  virtual child_iterator child_begin();
548  virtual child_iterator child_end();
549};
550
551
552/// IfStmt - This represents an if/then/else.
553///
554class IfStmt : public Stmt {
555  enum { COND, THEN, ELSE, END_EXPR };
556  Stmt* SubExprs[END_EXPR];
557  SourceLocation IfLoc;
558  SourceLocation ElseLoc;
559public:
560  IfStmt(SourceLocation IL, Expr *cond, Stmt *then,
561         SourceLocation EL = SourceLocation(), Stmt *elsev = 0)
562    : Stmt(IfStmtClass)  {
563    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
564    SubExprs[THEN] = then;
565    SubExprs[ELSE] = elsev;
566    IfLoc = IL;
567    ElseLoc = EL;
568  }
569
570  /// \brief Build an empty if/then/else statement
571  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
572
573  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
574  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
575  const Stmt *getThen() const { return SubExprs[THEN]; }
576  void setThen(Stmt *S) { SubExprs[THEN] = S; }
577  const Stmt *getElse() const { return SubExprs[ELSE]; }
578  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
579
580  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
581  Stmt *getThen() { return SubExprs[THEN]; }
582  Stmt *getElse() { return SubExprs[ELSE]; }
583
584  SourceLocation getIfLoc() const { return IfLoc; }
585  void setIfLoc(SourceLocation L) { IfLoc = L; }
586  SourceLocation getElseLoc() const { return ElseLoc; }
587  void setElseLoc(SourceLocation L) { ElseLoc = L; }
588
589  virtual SourceRange getSourceRange() const {
590    if (SubExprs[ELSE])
591      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
592    else
593      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
594  }
595
596  static bool classof(const Stmt *T) {
597    return T->getStmtClass() == IfStmtClass;
598  }
599  static bool classof(const IfStmt *) { return true; }
600
601  // Iterators
602  virtual child_iterator child_begin();
603  virtual child_iterator child_end();
604};
605
606/// SwitchStmt - This represents a 'switch' stmt.
607///
608class SwitchStmt : public Stmt {
609  enum { COND, BODY, END_EXPR };
610  Stmt* SubExprs[END_EXPR];
611  // This points to a linked list of case and default statements.
612  SwitchCase *FirstCase;
613  SourceLocation SwitchLoc;
614public:
615  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
616      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
617      SubExprs[BODY] = NULL;
618    }
619
620  /// \brief Build a empty switch statement.
621  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
622
623  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
624  const Stmt *getBody() const { return SubExprs[BODY]; }
625  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
626
627  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
628  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
629  Stmt *getBody() { return SubExprs[BODY]; }
630  void setBody(Stmt *S) { SubExprs[BODY] = S; }
631  SwitchCase *getSwitchCaseList() { return FirstCase; }
632  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
633
634  SourceLocation getSwitchLoc() const { return SwitchLoc; }
635  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
636
637  void setBody(Stmt *S, SourceLocation SL) {
638    SubExprs[BODY] = S;
639    SwitchLoc = SL;
640  }
641  void addSwitchCase(SwitchCase *SC) {
642    assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
643    SC->setNextSwitchCase(FirstCase);
644    FirstCase = SC;
645  }
646  virtual SourceRange getSourceRange() const {
647    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
648  }
649  static bool classof(const Stmt *T) {
650    return T->getStmtClass() == SwitchStmtClass;
651  }
652  static bool classof(const SwitchStmt *) { return true; }
653
654  // Iterators
655  virtual child_iterator child_begin();
656  virtual child_iterator child_end();
657};
658
659
660/// WhileStmt - This represents a 'while' stmt.
661///
662class WhileStmt : public Stmt {
663  enum { COND, BODY, END_EXPR };
664  Stmt* SubExprs[END_EXPR];
665  SourceLocation WhileLoc;
666public:
667  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
668    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
669    SubExprs[BODY] = body;
670    WhileLoc = WL;
671  }
672
673  /// \brief Build an empty while statement.
674  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
675
676  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
677  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
678  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
679  Stmt *getBody() { return SubExprs[BODY]; }
680  const Stmt *getBody() const { return SubExprs[BODY]; }
681  void setBody(Stmt *S) { SubExprs[BODY] = S; }
682
683  SourceLocation getWhileLoc() const { return WhileLoc; }
684  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
685
686  virtual SourceRange getSourceRange() const {
687    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
688  }
689  static bool classof(const Stmt *T) {
690    return T->getStmtClass() == WhileStmtClass;
691  }
692  static bool classof(const WhileStmt *) { return true; }
693
694  // Iterators
695  virtual child_iterator child_begin();
696  virtual child_iterator child_end();
697};
698
699/// DoStmt - This represents a 'do/while' stmt.
700///
701class DoStmt : public Stmt {
702  enum { COND, BODY, END_EXPR };
703  Stmt* SubExprs[END_EXPR];
704  SourceLocation DoLoc;
705  SourceLocation WhileLoc;
706
707public:
708  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL)
709    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL) {
710    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
711    SubExprs[BODY] = body;
712    DoLoc = DL;
713    WhileLoc = WL;
714  }
715
716  /// \brief Build an empty do-while statement.
717  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
718
719  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
720  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
721  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
722  Stmt *getBody() { return SubExprs[BODY]; }
723  const Stmt *getBody() const { return SubExprs[BODY]; }
724  void setBody(Stmt *S) { SubExprs[BODY] = S; }
725
726  SourceLocation getDoLoc() const { return DoLoc; }
727  void setDoLoc(SourceLocation L) { DoLoc = L; }
728  SourceLocation getWhileLoc() const { return WhileLoc; }
729  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
730
731  virtual SourceRange getSourceRange() const {
732    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
733  }
734  static bool classof(const Stmt *T) {
735    return T->getStmtClass() == DoStmtClass;
736  }
737  static bool classof(const DoStmt *) { return true; }
738
739  // Iterators
740  virtual child_iterator child_begin();
741  virtual child_iterator child_end();
742};
743
744
745/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
746/// the init/cond/inc parts of the ForStmt will be null if they were not
747/// specified in the source.
748///
749class ForStmt : public Stmt {
750  enum { INIT, COND, INC, BODY, END_EXPR };
751  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
752  SourceLocation ForLoc;
753  SourceLocation LParenLoc, RParenLoc;
754
755public:
756  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL,
757          SourceLocation LP, SourceLocation RP)
758    : Stmt(ForStmtClass) {
759    SubExprs[INIT] = Init;
760    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
761    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
762    SubExprs[BODY] = Body;
763    ForLoc = FL;
764    LParenLoc = LP;
765    RParenLoc = RP;
766  }
767
768  /// \brief Build an empty for statement.
769  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
770
771  Stmt *getInit() { return SubExprs[INIT]; }
772  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
773  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
774  Stmt *getBody() { return SubExprs[BODY]; }
775
776  const Stmt *getInit() const { return SubExprs[INIT]; }
777  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
778  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
779  const Stmt *getBody() const { return SubExprs[BODY]; }
780
781  void setInit(Stmt *S) { SubExprs[INIT] = S; }
782  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
783  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
784  void setBody(Stmt *S) { SubExprs[BODY] = S; }
785
786  SourceLocation getForLoc() const { return ForLoc; }
787  void setForLoc(SourceLocation L) { ForLoc = L; }
788  SourceLocation getLParenLoc() const { return LParenLoc; }
789  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
790  SourceLocation getRParenLoc() const { return RParenLoc; }
791  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
792
793  virtual SourceRange getSourceRange() const {
794    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
795  }
796  static bool classof(const Stmt *T) {
797    return T->getStmtClass() == ForStmtClass;
798  }
799  static bool classof(const ForStmt *) { return true; }
800
801  // Iterators
802  virtual child_iterator child_begin();
803  virtual child_iterator child_end();
804};
805
806/// GotoStmt - This represents a direct goto.
807///
808class GotoStmt : public Stmt {
809  LabelStmt *Label;
810  SourceLocation GotoLoc;
811  SourceLocation LabelLoc;
812public:
813  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
814    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
815
816  /// \brief Build an empty goto statement.
817  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
818
819  LabelStmt *getLabel() const { return Label; }
820  void setLabel(LabelStmt *S) { Label = S; }
821
822  SourceLocation getGotoLoc() const { return GotoLoc; }
823  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
824  SourceLocation getLabelLoc() const { return LabelLoc; }
825  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
826
827  virtual SourceRange getSourceRange() const {
828    return SourceRange(GotoLoc, LabelLoc);
829  }
830  static bool classof(const Stmt *T) {
831    return T->getStmtClass() == GotoStmtClass;
832  }
833  static bool classof(const GotoStmt *) { return true; }
834
835  // Iterators
836  virtual child_iterator child_begin();
837  virtual child_iterator child_end();
838};
839
840/// IndirectGotoStmt - This represents an indirect goto.
841///
842class IndirectGotoStmt : public Stmt {
843  SourceLocation GotoLoc;
844  SourceLocation StarLoc;
845  Stmt *Target;
846public:
847  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
848                   Expr *target)
849    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
850      Target((Stmt*)target) {}
851
852  /// \brief Build an empty indirect goto statement.
853  explicit IndirectGotoStmt(EmptyShell Empty)
854    : Stmt(IndirectGotoStmtClass, Empty) { }
855
856  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
857  SourceLocation getGotoLoc() const { return GotoLoc; }
858  void setStarLoc(SourceLocation L) { StarLoc = L; }
859  SourceLocation getStarLoc() const { return StarLoc; }
860
861  Expr *getTarget();
862  const Expr *getTarget() const;
863  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
864
865  virtual SourceRange getSourceRange() const {
866    return SourceRange(GotoLoc, Target->getLocEnd());
867  }
868
869  static bool classof(const Stmt *T) {
870    return T->getStmtClass() == IndirectGotoStmtClass;
871  }
872  static bool classof(const IndirectGotoStmt *) { return true; }
873
874  // Iterators
875  virtual child_iterator child_begin();
876  virtual child_iterator child_end();
877};
878
879
880/// ContinueStmt - This represents a continue.
881///
882class ContinueStmt : public Stmt {
883  SourceLocation ContinueLoc;
884public:
885  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
886
887  /// \brief Build an empty continue statement.
888  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
889
890  SourceLocation getContinueLoc() const { return ContinueLoc; }
891  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
892
893  virtual SourceRange getSourceRange() const {
894    return SourceRange(ContinueLoc);
895  }
896
897  ContinueStmt* Clone(ASTContext &C) const;
898
899  static bool classof(const Stmt *T) {
900    return T->getStmtClass() == ContinueStmtClass;
901  }
902  static bool classof(const ContinueStmt *) { return true; }
903
904  // Iterators
905  virtual child_iterator child_begin();
906  virtual child_iterator child_end();
907};
908
909/// BreakStmt - This represents a break.
910///
911class BreakStmt : public Stmt {
912  SourceLocation BreakLoc;
913public:
914  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
915
916  /// \brief Build an empty break statement.
917  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
918
919  SourceLocation getBreakLoc() const { return BreakLoc; }
920  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
921
922  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
923
924  BreakStmt* Clone(ASTContext &C) const;
925
926  static bool classof(const Stmt *T) {
927    return T->getStmtClass() == BreakStmtClass;
928  }
929  static bool classof(const BreakStmt *) { return true; }
930
931  // Iterators
932  virtual child_iterator child_begin();
933  virtual child_iterator child_end();
934};
935
936
937/// ReturnStmt - This represents a return, optionally of an expression:
938///   return;
939///   return 4;
940///
941/// Note that GCC allows return with no argument in a function declared to
942/// return a value, and it allows returning a value in functions declared to
943/// return void.  We explicitly model this in the AST, which means you can't
944/// depend on the return type of the function and the presence of an argument.
945///
946class ReturnStmt : public Stmt {
947  Stmt *RetExpr;
948  SourceLocation RetLoc;
949public:
950  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
951    RetExpr((Stmt*) E), RetLoc(RL) {}
952
953  /// \brief Build an empty return expression.
954  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
955
956  const Expr *getRetValue() const;
957  Expr *getRetValue();
958  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
959
960  SourceLocation getReturnLoc() const { return RetLoc; }
961  void setReturnLoc(SourceLocation L) { RetLoc = L; }
962
963  virtual SourceRange getSourceRange() const;
964
965  static bool classof(const Stmt *T) {
966    return T->getStmtClass() == ReturnStmtClass;
967  }
968  static bool classof(const ReturnStmt *) { return true; }
969
970  // Iterators
971  virtual child_iterator child_begin();
972  virtual child_iterator child_end();
973};
974
975/// AsmStmt - This represents a GNU inline-assembly statement extension.
976///
977class AsmStmt : public Stmt {
978  SourceLocation AsmLoc, RParenLoc;
979  StringLiteral *AsmStr;
980
981  bool IsSimple;
982  bool IsVolatile;
983
984  unsigned NumOutputs;
985  unsigned NumInputs;
986
987  llvm::SmallVector<std::string, 4> Names;
988  llvm::SmallVector<StringLiteral*, 4> Constraints;
989  llvm::SmallVector<Stmt*, 4> Exprs;
990
991  llvm::SmallVector<StringLiteral*, 4> Clobbers;
992public:
993  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
994          unsigned numoutputs, unsigned numinputs,
995          std::string *names, StringLiteral **constraints,
996          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
997          StringLiteral **clobbers, SourceLocation rparenloc);
998
999  /// \brief Build an empty inline-assembly statement.
1000  explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty) { }
1001
1002  SourceLocation getAsmLoc() const { return AsmLoc; }
1003  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1004  SourceLocation getRParenLoc() const { return RParenLoc; }
1005  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1006
1007  bool isVolatile() const { return IsVolatile; }
1008  void setVolatile(bool V) { IsVolatile = V; }
1009  bool isSimple() const { return IsSimple; }
1010  void setSimple(bool V) { IsSimple = false; }
1011
1012  //===--- Asm String Analysis ---===//
1013
1014  const StringLiteral *getAsmString() const { return AsmStr; }
1015  StringLiteral *getAsmString() { return AsmStr; }
1016  void setAsmString(StringLiteral *E) { AsmStr = E; }
1017
1018  /// AsmStringPiece - this is part of a decomposed asm string specification
1019  /// (for use with the AnalyzeAsmString function below).  An asm string is
1020  /// considered to be a concatenation of these parts.
1021  class AsmStringPiece {
1022  public:
1023    enum Kind {
1024      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1025      Operand  // Operand reference, with optional modifier %c4.
1026    };
1027  private:
1028    Kind MyKind;
1029    std::string Str;
1030    unsigned OperandNo;
1031  public:
1032    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
1033    AsmStringPiece(unsigned OpNo, char Modifier)
1034      : MyKind(Operand), Str(), OperandNo(OpNo) {
1035      Str += Modifier;
1036    }
1037
1038    bool isString() const { return MyKind == String; }
1039    bool isOperand() const { return MyKind == Operand; }
1040
1041    const std::string &getString() const {
1042      assert(isString());
1043      return Str;
1044    }
1045
1046    unsigned getOperandNo() const {
1047      assert(isOperand());
1048      return OperandNo;
1049    }
1050
1051    /// getModifier - Get the modifier for this operand, if present.  This
1052    /// returns '\0' if there was no modifier.
1053    char getModifier() const {
1054      assert(isOperand());
1055      return Str[0];
1056    }
1057  };
1058
1059  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1060  /// it into pieces.  If the asm string is erroneous, emit errors and return
1061  /// true, otherwise return false.  This handles canonicalization and
1062  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1063  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1064  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
1065                            ASTContext &C, unsigned &DiagOffs) const;
1066
1067
1068  //===--- Output operands ---===//
1069
1070  unsigned getNumOutputs() const { return NumOutputs; }
1071
1072  const std::string &getOutputName(unsigned i) const {
1073    return Names[i];
1074  }
1075
1076  /// getOutputConstraint - Return the constraint string for the specified
1077  /// output operand.  All output constraints are known to be non-empty (either
1078  /// '=' or '+').
1079  std::string getOutputConstraint(unsigned i) const;
1080
1081  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1082    return Constraints[i];
1083  }
1084  StringLiteral *getOutputConstraintLiteral(unsigned i) {
1085    return Constraints[i];
1086  }
1087
1088
1089  Expr *getOutputExpr(unsigned i);
1090
1091  const Expr *getOutputExpr(unsigned i) const {
1092    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
1093  }
1094
1095  /// isOutputPlusConstraint - Return true if the specified output constraint
1096  /// is a "+" constraint (which is both an input and an output) or false if it
1097  /// is an "=" constraint (just an output).
1098  bool isOutputPlusConstraint(unsigned i) const {
1099    return getOutputConstraint(i)[0] == '+';
1100  }
1101
1102  /// getNumPlusOperands - Return the number of output operands that have a "+"
1103  /// constraint.
1104  unsigned getNumPlusOperands() const;
1105
1106  //===--- Input operands ---===//
1107
1108  unsigned getNumInputs() const { return NumInputs; }
1109
1110  const std::string &getInputName(unsigned i) const {
1111    return Names[i + NumOutputs];
1112  }
1113
1114  /// getInputConstraint - Return the specified input constraint.  Unlike output
1115  /// constraints, these can be empty.
1116  std::string getInputConstraint(unsigned i) const;
1117
1118  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1119    return Constraints[i + NumOutputs];
1120  }
1121  StringLiteral *getInputConstraintLiteral(unsigned i) {
1122    return Constraints[i + NumOutputs];
1123  }
1124
1125
1126  Expr *getInputExpr(unsigned i);
1127
1128  const Expr *getInputExpr(unsigned i) const {
1129    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1130  }
1131
1132  void setOutputsAndInputs(unsigned NumOutputs,
1133                           unsigned NumInputs,
1134                           const std::string *Names,
1135                           StringLiteral **Constraints,
1136                           Stmt **Exprs);
1137
1138  //===--- Other ---===//
1139
1140  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1141  /// translate this into a numeric value needed to reference the same operand.
1142  /// This returns -1 if the operand name is invalid.
1143  int getNamedOperand(const std::string &SymbolicName) const;
1144
1145
1146
1147  unsigned getNumClobbers() const { return Clobbers.size(); }
1148  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1149  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1150  void setClobbers(StringLiteral **Clobbers, unsigned NumClobbers);
1151
1152  virtual SourceRange getSourceRange() const {
1153    return SourceRange(AsmLoc, RParenLoc);
1154  }
1155
1156  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1157  static bool classof(const AsmStmt *) { return true; }
1158
1159  // Input expr iterators.
1160
1161  typedef ExprIterator inputs_iterator;
1162  typedef ConstExprIterator const_inputs_iterator;
1163
1164  inputs_iterator begin_inputs() {
1165    return Exprs.data() + NumOutputs;
1166  }
1167
1168  inputs_iterator end_inputs() {
1169    return Exprs.data() + NumOutputs + NumInputs;
1170  }
1171
1172  const_inputs_iterator begin_inputs() const {
1173    return Exprs.data() + NumOutputs;
1174  }
1175
1176  const_inputs_iterator end_inputs() const {
1177    return Exprs.data() + NumOutputs + NumInputs;
1178  }
1179
1180  // Output expr iterators.
1181
1182  typedef ExprIterator outputs_iterator;
1183  typedef ConstExprIterator const_outputs_iterator;
1184
1185  outputs_iterator begin_outputs() {
1186    return Exprs.data();
1187  }
1188  outputs_iterator end_outputs() {
1189    return Exprs.data() + NumOutputs;
1190  }
1191
1192  const_outputs_iterator begin_outputs() const {
1193    return Exprs.data();
1194  }
1195  const_outputs_iterator end_outputs() const {
1196    return Exprs.data() + NumOutputs;
1197  }
1198
1199  // Input name iterator.
1200
1201  const std::string *begin_output_names() const {
1202    return &Names[0];
1203  }
1204
1205  const std::string *end_output_names() const {
1206    return &Names[0] + NumOutputs;
1207  }
1208
1209  // Child iterators
1210
1211  virtual child_iterator child_begin();
1212  virtual child_iterator child_end();
1213};
1214
1215}  // end namespace clang
1216
1217#endif
1218