Stmt.h revision f2cad8633e46cce12fc3d77c0bd451ffd7264baf
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/StmtIterator.h"
21#include "clang/AST/DeclGroup.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/iterator.h"
24#include "llvm/Bitcode/SerializationFwd.h"
25#include <string>
26
27using llvm::dyn_cast_or_null;
28
29namespace clang {
30  class ASTContext;
31  class Expr;
32  class Decl;
33  class ScopedDecl;
34  class IdentifierInfo;
35  class SourceManager;
36  class StringLiteral;
37  class SwitchStmt;
38  class PrinterHelper;
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
106protected:
107  /// DestroyChildren - Invoked by destructors of subclasses of Stmt to
108  ///  recursively release child AST nodes.
109  void DestroyChildren(ASTContext& Ctx);
110
111public:
112  Stmt(StmtClass SC) : sClass(SC) {
113    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
114  }
115  virtual ~Stmt() {}
116
117  virtual void Destroy(ASTContext& Ctx);
118
119  StmtClass getStmtClass() const { return sClass; }
120  const char *getStmtClassName() const;
121
122  /// SourceLocation tokens are not useful in isolation - they are low level
123  /// value objects created/interpreted by SourceManager. We assume AST
124  /// clients will have a pointer to the respective SourceManager.
125  virtual SourceRange getSourceRange() const = 0;
126  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
127  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
128
129  // global temp stats (until we have a per-module visitor)
130  static void addStmtClass(const StmtClass s);
131  static bool CollectingStats(bool enable=false);
132  static void PrintStats();
133
134  /// dump - This does a local dump of the specified AST fragment.  It dumps the
135  /// specified node and a few nodes underneath it, but not the whole subtree.
136  /// This is useful in a debugger.
137  void dump() const;
138  void dump(SourceManager &SM) const;
139
140  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
141  void dumpAll() const;
142  void dumpAll(SourceManager &SM) const;
143
144  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
145  /// back to its original source language syntax.
146  void dumpPretty() const;
147  void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL) const;
148
149  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
150  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
151  void viewAST() const;
152
153  // Implement isa<T> support.
154  static bool classof(const Stmt *) { return true; }
155
156  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
157  ///  contain implicit control-flow in the order their subexpressions
158  ///  are evaluated.  This predicate returns true if this statement has
159  ///  such implicit control-flow.  Such statements are also specially handled
160  ///  within CFGs.
161  bool hasImplicitControlFlow() const;
162
163  /// Child Iterators: All subclasses must implement child_begin and child_end
164  ///  to permit easy iteration over the substatements/subexpessions of an
165  ///  AST node.  This permits easy iteration over all nodes in the AST.
166  typedef StmtIterator       child_iterator;
167  typedef ConstStmtIterator  const_child_iterator;
168
169  virtual child_iterator child_begin() = 0;
170  virtual child_iterator child_end()   = 0;
171
172  const_child_iterator child_begin() const {
173    return const_child_iterator(const_cast<Stmt*>(this)->child_begin());
174  }
175
176  const_child_iterator child_end() const {
177    return const_child_iterator(const_cast<Stmt*>(this)->child_end());
178  }
179
180  void Emit(llvm::Serializer& S) const;
181  static Stmt* Create(llvm::Deserializer& D, ASTContext& C);
182
183  virtual void EmitImpl(llvm::Serializer& S) const {
184    // This method will eventually be a pure-virtual function.
185    assert (false && "Not implemented.");
186  }
187};
188
189/// DeclStmt - Adaptor class for mixing declarations with statements and
190/// expressions. For example, CompoundStmt mixes statements, expressions
191/// and declarations (variables, types). Another example is ForStmt, where
192/// the first statement can be an expression or a declaration.
193///
194class DeclStmt : public Stmt {
195protected:
196  DeclGroupOwningRef DG;
197  SourceLocation StartLoc, EndLoc;
198public:
199  DeclStmt(DeclGroupOwningRef& dg, SourceLocation startLoc,
200           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
201                                    StartLoc(startLoc), EndLoc(endLoc) {}
202
203  virtual void Destroy(ASTContext& Ctx);
204
205  // hasSolitaryDecl - This method returns true if this DeclStmt refers
206  // to a single Decl.
207  bool hasSolitaryDecl() const {
208    return DG.hasSolitaryDecl();
209  }
210
211  const ScopedDecl* getSolitaryDecl() const {
212    assert (hasSolitaryDecl() &&
213            "Caller assumes this DeclStmt points to one Decl*");
214    return llvm::cast<ScopedDecl>(*DG.begin());
215  }
216
217  ScopedDecl* getSolitaryDecl() {
218    assert (hasSolitaryDecl() &&
219            "Caller assumes this DeclStmt points to one Decl*");
220    return llvm::cast<ScopedDecl>(*DG.begin());
221  }
222
223  SourceLocation getStartLoc() const { return StartLoc; }
224  SourceLocation getEndLoc() const { return EndLoc; }
225
226  SourceRange getSourceRange() const {
227    return SourceRange(StartLoc, EndLoc);
228  }
229
230  static bool classof(const Stmt *T) {
231    return T->getStmtClass() == DeclStmtClass;
232  }
233  static bool classof(const DeclStmt *) { return true; }
234
235  // Iterators over subexpressions.
236  virtual child_iterator child_begin();
237  virtual child_iterator child_end();
238
239  class decl_iterator {
240    DeclGroupRef::iterator I;
241  public:
242    decl_iterator(DeclGroupRef::iterator i) : I(i) {}
243    decl_iterator& operator++() { ++I; return *this; }
244    bool operator==(const decl_iterator& R) const {
245      return R.I == I;
246    }
247    bool operator!=(const decl_iterator& R) const {
248      return R.I != I;
249    }
250    ScopedDecl* operator*() const {
251      return llvm::cast<ScopedDecl>(*I);
252    }
253  };
254
255  class const_decl_iterator {
256    DeclGroupRef::const_iterator I;
257  public:
258    const_decl_iterator(DeclGroupRef::const_iterator i) : I(i) {}
259    const_decl_iterator& operator++() { ++I; return *this; }
260    bool operator==(const const_decl_iterator& R) const {
261      return R.I == I;
262    }
263    bool operator!=(const const_decl_iterator& R) const {
264      return R.I != I;
265    }
266    ScopedDecl* operator*() const {
267      return llvm::cast<ScopedDecl>(*I);
268    }
269  };
270
271  decl_iterator decl_begin() { return DG.begin(); }
272  decl_iterator decl_end() { return DG.end(); }
273  const_decl_iterator decl_begin() const { return DG.begin(); }
274  const_decl_iterator decl_end() const { return DG.end(); }
275
276  // Serialization.
277  virtual void EmitImpl(llvm::Serializer& S) const;
278  static DeclStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
279};
280
281/// NullStmt - This is the null statement ";": C99 6.8.3p3.
282///
283class NullStmt : public Stmt {
284  SourceLocation SemiLoc;
285public:
286  NullStmt(SourceLocation L) : Stmt(NullStmtClass), SemiLoc(L) {}
287
288  SourceLocation getSemiLoc() const { return SemiLoc; }
289
290  virtual SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
291
292  static bool classof(const Stmt *T) {
293    return T->getStmtClass() == NullStmtClass;
294  }
295  static bool classof(const NullStmt *) { return true; }
296
297  // Iterators
298  virtual child_iterator child_begin();
299  virtual child_iterator child_end();
300
301  virtual void EmitImpl(llvm::Serializer& S) const;
302  static NullStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
303};
304
305/// CompoundStmt - This represents a group of statements like { stmt stmt }.
306///
307class CompoundStmt : public Stmt {
308  llvm::SmallVector<Stmt*, 16> Body;
309  SourceLocation LBracLoc, RBracLoc;
310public:
311  CompoundStmt(Stmt **StmtStart, unsigned NumStmts,
312               SourceLocation LB, SourceLocation RB)
313    : Stmt(CompoundStmtClass), Body(StmtStart, StmtStart+NumStmts),
314      LBracLoc(LB), RBracLoc(RB) {}
315
316  bool body_empty() const { return Body.empty(); }
317
318  typedef llvm::SmallVector<Stmt*, 16>::iterator body_iterator;
319  body_iterator body_begin() { return Body.begin(); }
320  body_iterator body_end() { return Body.end(); }
321  Stmt *body_back() { return Body.back(); }
322
323  typedef llvm::SmallVector<Stmt*, 16>::const_iterator const_body_iterator;
324  const_body_iterator body_begin() const { return Body.begin(); }
325  const_body_iterator body_end() const { return Body.end(); }
326  const Stmt *body_back() const { return Body.back(); }
327
328  typedef llvm::SmallVector<Stmt*, 16>::reverse_iterator reverse_body_iterator;
329  reverse_body_iterator body_rbegin() { return Body.rbegin(); }
330  reverse_body_iterator body_rend() { return Body.rend(); }
331
332  typedef llvm::SmallVector<Stmt*, 16>::const_reverse_iterator
333    const_reverse_body_iterator;
334  const_reverse_body_iterator body_rbegin() const { return Body.rbegin(); }
335  const_reverse_body_iterator body_rend() const { return Body.rend(); }
336
337  void push_back(Stmt *S) { Body.push_back(S); }
338
339  virtual SourceRange getSourceRange() const {
340    return SourceRange(LBracLoc, RBracLoc);
341  }
342
343  SourceLocation getLBracLoc() const { return LBracLoc; }
344  SourceLocation getRBracLoc() const { return RBracLoc; }
345
346  static bool classof(const Stmt *T) {
347    return T->getStmtClass() == CompoundStmtClass;
348  }
349  static bool classof(const CompoundStmt *) { return true; }
350
351  // Iterators
352  virtual child_iterator child_begin();
353  virtual child_iterator child_end();
354
355  virtual void EmitImpl(llvm::Serializer& S) const;
356  static CompoundStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
357};
358
359// SwitchCase is the base class for CaseStmt and DefaultStmt,
360class SwitchCase : public Stmt {
361protected:
362  // A pointer to the following CaseStmt or DefaultStmt class,
363  // used by SwitchStmt.
364  SwitchCase *NextSwitchCase;
365
366  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
367
368public:
369  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
370
371  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
372
373  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
374
375  virtual Stmt* v_getSubStmt() = 0;
376  Stmt *getSubStmt() { return v_getSubStmt(); }
377
378  virtual SourceRange getSourceRange() const { return SourceRange(); }
379
380  static bool classof(const Stmt *T) {
381    return T->getStmtClass() == CaseStmtClass ||
382    T->getStmtClass() == DefaultStmtClass;
383  }
384  static bool classof(const SwitchCase *) { return true; }
385};
386
387class CaseStmt : public SwitchCase {
388  enum { SUBSTMT, LHS, RHS, END_EXPR };
389  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
390                             // GNU "case 1 ... 4" extension
391  SourceLocation CaseLoc;
392public:
393  CaseStmt(Expr *lhs, Expr *rhs, Stmt *substmt, SourceLocation caseLoc)
394    : SwitchCase(CaseStmtClass) {
395    SubExprs[SUBSTMT] = substmt;
396    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
397    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
398    CaseLoc = caseLoc;
399  }
400
401  SourceLocation getCaseLoc() const { return CaseLoc; }
402
403  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
404  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
405  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
406  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
407  const Expr *getLHS() const {
408    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
409  }
410  const Expr *getRHS() const {
411    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
412  }
413  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
414
415  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
416  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
417  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
418
419
420  virtual SourceRange getSourceRange() const {
421    return SourceRange(CaseLoc, SubExprs[SUBSTMT]->getLocEnd());
422  }
423  static bool classof(const Stmt *T) {
424    return T->getStmtClass() == CaseStmtClass;
425  }
426  static bool classof(const CaseStmt *) { return true; }
427
428  // Iterators
429  virtual child_iterator child_begin();
430  virtual child_iterator child_end();
431
432  virtual void EmitImpl(llvm::Serializer& S) const;
433  static CaseStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
434};
435
436class DefaultStmt : public SwitchCase {
437  Stmt* SubStmt;
438  SourceLocation DefaultLoc;
439public:
440  DefaultStmt(SourceLocation DL, Stmt *substmt) :
441    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL) {}
442
443  Stmt *getSubStmt() { return SubStmt; }
444  virtual Stmt* v_getSubStmt() { return getSubStmt(); }
445  const Stmt *getSubStmt() const { return SubStmt; }
446
447  SourceLocation getDefaultLoc() const { return DefaultLoc; }
448
449  virtual SourceRange getSourceRange() const {
450    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
451  }
452  static bool classof(const Stmt *T) {
453    return T->getStmtClass() == DefaultStmtClass;
454  }
455  static bool classof(const DefaultStmt *) { return true; }
456
457  // Iterators
458  virtual child_iterator child_begin();
459  virtual child_iterator child_end();
460
461  virtual void EmitImpl(llvm::Serializer& S) const;
462  static DefaultStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
463};
464
465class LabelStmt : public Stmt {
466  IdentifierInfo *Label;
467  Stmt *SubStmt;
468  SourceLocation IdentLoc;
469public:
470  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt)
471    : Stmt(LabelStmtClass), Label(label),
472      SubStmt(substmt), IdentLoc(IL) {}
473
474  SourceLocation getIdentLoc() const { return IdentLoc; }
475  IdentifierInfo *getID() const { return Label; }
476  const char *getName() const;
477  Stmt *getSubStmt() { return SubStmt; }
478  const Stmt *getSubStmt() const { return SubStmt; }
479
480  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
481  void setSubStmt(Stmt *SS) { SubStmt = SS; }
482
483  virtual SourceRange getSourceRange() const {
484    return SourceRange(IdentLoc, SubStmt->getLocEnd());
485  }
486  static bool classof(const Stmt *T) {
487    return T->getStmtClass() == LabelStmtClass;
488  }
489  static bool classof(const LabelStmt *) { return true; }
490
491  // Iterators
492  virtual child_iterator child_begin();
493  virtual child_iterator child_end();
494
495  virtual void EmitImpl(llvm::Serializer& S) const;
496  static LabelStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
497};
498
499
500/// IfStmt - This represents an if/then/else.
501///
502class IfStmt : public Stmt {
503  enum { COND, THEN, ELSE, END_EXPR };
504  Stmt* SubExprs[END_EXPR];
505  SourceLocation IfLoc;
506public:
507  IfStmt(SourceLocation IL, Expr *cond, Stmt *then, Stmt *elsev = 0)
508    : Stmt(IfStmtClass)  {
509    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
510    SubExprs[THEN] = then;
511    SubExprs[ELSE] = elsev;
512    IfLoc = IL;
513  }
514
515  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
516  const Stmt *getThen() const { return SubExprs[THEN]; }
517  const Stmt *getElse() const { return SubExprs[ELSE]; }
518
519  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
520  Stmt *getThen() { return SubExprs[THEN]; }
521  Stmt *getElse() { return SubExprs[ELSE]; }
522
523  virtual SourceRange getSourceRange() const {
524    if (SubExprs[ELSE])
525      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
526    else
527      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
528  }
529
530  static bool classof(const Stmt *T) {
531    return T->getStmtClass() == IfStmtClass;
532  }
533  static bool classof(const IfStmt *) { return true; }
534
535  // Iterators
536  virtual child_iterator child_begin();
537  virtual child_iterator child_end();
538
539  virtual void EmitImpl(llvm::Serializer& S) const;
540  static IfStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
541};
542
543/// SwitchStmt - This represents a 'switch' stmt.
544///
545class SwitchStmt : public Stmt {
546  enum { COND, BODY, END_EXPR };
547  Stmt* SubExprs[END_EXPR];
548  // This points to a linked list of case and default statements.
549  SwitchCase *FirstCase;
550  SourceLocation SwitchLoc;
551public:
552  SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
553      SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
554      SubExprs[BODY] = NULL;
555    }
556
557  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
558  const Stmt *getBody() const { return SubExprs[BODY]; }
559  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
560
561  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
562  Stmt *getBody() { return SubExprs[BODY]; }
563  SwitchCase *getSwitchCaseList() { return FirstCase; }
564
565  void setBody(Stmt *S, SourceLocation SL) {
566    SubExprs[BODY] = S;
567    SwitchLoc = SL;
568  }
569  void addSwitchCase(SwitchCase *SC) {
570    if (FirstCase)
571      SC->setNextSwitchCase(FirstCase);
572
573    FirstCase = SC;
574  }
575  virtual SourceRange getSourceRange() const {
576    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
577  }
578  static bool classof(const Stmt *T) {
579    return T->getStmtClass() == SwitchStmtClass;
580  }
581  static bool classof(const SwitchStmt *) { return true; }
582
583  // Iterators
584  virtual child_iterator child_begin();
585  virtual child_iterator child_end();
586
587  virtual void EmitImpl(llvm::Serializer& S) const;
588  static SwitchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
589};
590
591
592/// WhileStmt - This represents a 'while' stmt.
593///
594class WhileStmt : public Stmt {
595  enum { COND, BODY, END_EXPR };
596  Stmt* SubExprs[END_EXPR];
597  SourceLocation WhileLoc;
598public:
599  WhileStmt(Expr *cond, Stmt *body, SourceLocation WL) : Stmt(WhileStmtClass) {
600    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
601    SubExprs[BODY] = body;
602    WhileLoc = WL;
603  }
604
605  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
606  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
607  Stmt *getBody() { return SubExprs[BODY]; }
608  const Stmt *getBody() const { return SubExprs[BODY]; }
609
610  virtual SourceRange getSourceRange() const {
611    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
612  }
613  static bool classof(const Stmt *T) {
614    return T->getStmtClass() == WhileStmtClass;
615  }
616  static bool classof(const WhileStmt *) { return true; }
617
618  // Iterators
619  virtual child_iterator child_begin();
620  virtual child_iterator child_end();
621
622  virtual void EmitImpl(llvm::Serializer& S) const;
623  static WhileStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
624};
625
626/// DoStmt - This represents a 'do/while' stmt.
627///
628class DoStmt : public Stmt {
629  enum { COND, BODY, END_EXPR };
630  Stmt* SubExprs[END_EXPR];
631  SourceLocation DoLoc;
632public:
633  DoStmt(Stmt *body, Expr *cond, SourceLocation DL)
634    : Stmt(DoStmtClass), DoLoc(DL) {
635    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
636    SubExprs[BODY] = body;
637    DoLoc = DL;
638  }
639
640  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
641  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
642  Stmt *getBody() { return SubExprs[BODY]; }
643  const Stmt *getBody() const { return SubExprs[BODY]; }
644
645  virtual SourceRange getSourceRange() const {
646    return SourceRange(DoLoc, SubExprs[BODY]->getLocEnd());
647  }
648  static bool classof(const Stmt *T) {
649    return T->getStmtClass() == DoStmtClass;
650  }
651  static bool classof(const DoStmt *) { return true; }
652
653  // Iterators
654  virtual child_iterator child_begin();
655  virtual child_iterator child_end();
656
657  virtual void EmitImpl(llvm::Serializer& S) const;
658  static DoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
659};
660
661
662/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
663/// the init/cond/inc parts of the ForStmt will be null if they were not
664/// specified in the source.
665///
666class ForStmt : public Stmt {
667  enum { INIT, COND, INC, BODY, END_EXPR };
668  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
669  SourceLocation ForLoc;
670public:
671  ForStmt(Stmt *Init, Expr *Cond, Expr *Inc, Stmt *Body, SourceLocation FL)
672    : Stmt(ForStmtClass) {
673    SubExprs[INIT] = Init;
674    SubExprs[COND] = reinterpret_cast<Stmt*>(Cond);
675    SubExprs[INC] = reinterpret_cast<Stmt*>(Inc);
676    SubExprs[BODY] = Body;
677    ForLoc = FL;
678  }
679
680  Stmt *getInit() { return SubExprs[INIT]; }
681  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
682  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
683  Stmt *getBody() { return SubExprs[BODY]; }
684
685  const Stmt *getInit() const { return SubExprs[INIT]; }
686  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
687  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
688  const Stmt *getBody() const { return SubExprs[BODY]; }
689
690  virtual SourceRange getSourceRange() const {
691    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
692  }
693  static bool classof(const Stmt *T) {
694    return T->getStmtClass() == ForStmtClass;
695  }
696  static bool classof(const ForStmt *) { return true; }
697
698  // Iterators
699  virtual child_iterator child_begin();
700  virtual child_iterator child_end();
701
702  virtual void EmitImpl(llvm::Serializer& S) const;
703  static ForStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
704};
705
706/// GotoStmt - This represents a direct goto.
707///
708class GotoStmt : public Stmt {
709  LabelStmt *Label;
710  SourceLocation GotoLoc;
711  SourceLocation LabelLoc;
712public:
713  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
714    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
715
716  LabelStmt *getLabel() const { return Label; }
717
718  virtual SourceRange getSourceRange() const {
719    return SourceRange(GotoLoc, LabelLoc);
720  }
721  static bool classof(const Stmt *T) {
722    return T->getStmtClass() == GotoStmtClass;
723  }
724  static bool classof(const GotoStmt *) { return true; }
725
726  // Iterators
727  virtual child_iterator child_begin();
728  virtual child_iterator child_end();
729
730  virtual void EmitImpl(llvm::Serializer& S) const;
731  static GotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
732};
733
734/// IndirectGotoStmt - This represents an indirect goto.
735///
736class IndirectGotoStmt : public Stmt {
737  Stmt *Target;
738  // FIXME: Add location information (e.g. SourceLocation objects).
739  //        When doing so, update the serialization routines.
740public:
741  IndirectGotoStmt(Expr *target) : Stmt(IndirectGotoStmtClass),
742                                   Target((Stmt*)target){}
743
744  Expr *getTarget();
745  const Expr *getTarget() const;
746
747  virtual SourceRange getSourceRange() const { return SourceRange(); }
748
749  static bool classof(const Stmt *T) {
750    return T->getStmtClass() == IndirectGotoStmtClass;
751  }
752  static bool classof(const IndirectGotoStmt *) { return true; }
753
754  // Iterators
755  virtual child_iterator child_begin();
756  virtual child_iterator child_end();
757
758  virtual void EmitImpl(llvm::Serializer& S) const;
759  static IndirectGotoStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
760};
761
762
763/// ContinueStmt - This represents a continue.
764///
765class ContinueStmt : public Stmt {
766  SourceLocation ContinueLoc;
767public:
768  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
769
770  virtual SourceRange getSourceRange() const {
771    return SourceRange(ContinueLoc);
772  }
773  static bool classof(const Stmt *T) {
774    return T->getStmtClass() == ContinueStmtClass;
775  }
776  static bool classof(const ContinueStmt *) { return true; }
777
778  // Iterators
779  virtual child_iterator child_begin();
780  virtual child_iterator child_end();
781
782  virtual void EmitImpl(llvm::Serializer& S) const;
783  static ContinueStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
784};
785
786/// BreakStmt - This represents a break.
787///
788class BreakStmt : public Stmt {
789  SourceLocation BreakLoc;
790public:
791  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
792
793  virtual SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
794
795  static bool classof(const Stmt *T) {
796    return T->getStmtClass() == BreakStmtClass;
797  }
798  static bool classof(const BreakStmt *) { return true; }
799
800  // Iterators
801  virtual child_iterator child_begin();
802  virtual child_iterator child_end();
803
804  virtual void EmitImpl(llvm::Serializer& S) const;
805  static BreakStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
806};
807
808
809/// ReturnStmt - This represents a return, optionally of an expression:
810///   return;
811///   return 4;
812///
813/// Note that GCC allows return with no argument in a function declared to
814/// return a value, and it allows returning a value in functions declared to
815/// return void.  We explicitly model this in the AST, which means you can't
816/// depend on the return type of the function and the presence of an argument.
817///
818class ReturnStmt : public Stmt {
819  Stmt *RetExpr;
820  SourceLocation RetLoc;
821public:
822  ReturnStmt(SourceLocation RL, Expr *E = 0) : Stmt(ReturnStmtClass),
823    RetExpr((Stmt*) E), RetLoc(RL) {}
824
825  const Expr *getRetValue() const;
826  Expr *getRetValue();
827
828  virtual SourceRange getSourceRange() const;
829
830  static bool classof(const Stmt *T) {
831    return T->getStmtClass() == ReturnStmtClass;
832  }
833  static bool classof(const ReturnStmt *) { return true; }
834
835  // Iterators
836  virtual child_iterator child_begin();
837  virtual child_iterator child_end();
838
839  virtual void EmitImpl(llvm::Serializer& S) const;
840  static ReturnStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
841};
842
843/// AsmStmt - This represents a GNU inline-assembly statement extension.
844///
845class AsmStmt : public Stmt {
846  SourceLocation AsmLoc, RParenLoc;
847  StringLiteral *AsmStr;
848
849  bool IsSimple;
850  bool IsVolatile;
851
852  unsigned NumOutputs;
853  unsigned NumInputs;
854
855  llvm::SmallVector<std::string, 4> Names;
856  llvm::SmallVector<StringLiteral*, 4> Constraints;
857  llvm::SmallVector<Stmt*, 4> Exprs;
858
859  llvm::SmallVector<StringLiteral*, 4> Clobbers;
860public:
861  AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
862          unsigned numoutputs, unsigned numinputs,
863          std::string *names, StringLiteral **constraints,
864          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
865          StringLiteral **clobbers, SourceLocation rparenloc);
866
867  bool isVolatile() const { return IsVolatile; }
868  bool isSimple() const { return IsSimple; }
869
870  unsigned getNumOutputs() const { return NumOutputs; }
871
872  const std::string &getOutputName(unsigned i) const {
873    return Names[i];
874  }
875
876  const StringLiteral *getOutputConstraint(unsigned i) const {
877    return Constraints[i];
878  }
879
880  StringLiteral *getOutputConstraint(unsigned i)
881    { return Constraints[i]; }
882
883  const Expr *getOutputExpr(unsigned i) const;
884  Expr *getOutputExpr(unsigned i);
885
886  unsigned getNumInputs() const { return NumInputs; }
887
888  const std::string &getInputName(unsigned i) const {
889    return Names[i + NumOutputs];
890  }
891  StringLiteral *getInputConstraint(unsigned i) {
892    return Constraints[i + NumOutputs];
893  }
894  const StringLiteral *getInputConstraint(unsigned i) const {
895    return Constraints[i + NumOutputs];
896  }
897
898  Expr *getInputExpr(unsigned i);
899  const Expr *getInputExpr(unsigned i) const;
900
901  const StringLiteral *getAsmString() const { return AsmStr; }
902  StringLiteral *getAsmString() { return AsmStr; }
903
904  unsigned getNumClobbers() const { return Clobbers.size(); }
905  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
906  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
907
908  virtual SourceRange getSourceRange() const {
909    return SourceRange(AsmLoc, RParenLoc);
910  }
911
912  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
913  static bool classof(const AsmStmt *) { return true; }
914
915  // Input expr iterators.
916
917  typedef ExprIterator inputs_iterator;
918  typedef ConstExprIterator const_inputs_iterator;
919
920  inputs_iterator begin_inputs() {
921    return &Exprs[0] + NumOutputs;
922  }
923
924  inputs_iterator end_inputs() {
925    return  &Exprs[0] + NumOutputs + NumInputs;
926  }
927
928  const_inputs_iterator begin_inputs() const {
929    return &Exprs[0] + NumOutputs;
930  }
931
932  const_inputs_iterator end_inputs() const {
933    return  &Exprs[0] + NumOutputs + NumInputs;}
934
935  // Output expr iterators.
936
937  typedef ExprIterator outputs_iterator;
938  typedef ConstExprIterator const_outputs_iterator;
939
940  outputs_iterator begin_outputs() { return &Exprs[0]; }
941  outputs_iterator end_outputs() { return &Exprs[0] + NumOutputs; }
942
943  const_outputs_iterator begin_outputs() const { return &Exprs[0]; }
944  const_outputs_iterator end_outputs() const { return &Exprs[0] + NumOutputs; }
945
946  // Child iterators
947
948  virtual child_iterator child_begin();
949  virtual child_iterator child_end();
950
951  virtual void EmitImpl(llvm::Serializer& S) const;
952  static AsmStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
953};
954
955/// ObjCForCollectionStmt - This represents Objective-c's collection statement;
956/// represented as 'for (element 'in' collection-expression)' stmt.
957///
958class ObjCForCollectionStmt : public Stmt {
959  enum { ELEM, COLLECTION, BODY, END_EXPR };
960  Stmt* SubExprs[END_EXPR]; // SubExprs[ELEM] is an expression or declstmt.
961  SourceLocation ForLoc;
962  SourceLocation RParenLoc;
963public:
964  ObjCForCollectionStmt(Stmt *Elem, Expr *Collect, Stmt *Body,
965                        SourceLocation FCL, SourceLocation RPL);
966
967  Stmt *getElement() { return SubExprs[ELEM]; }
968  Expr *getCollection() {
969    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
970  }
971  Stmt *getBody() { return SubExprs[BODY]; }
972
973  const Stmt *getElement() const { return SubExprs[ELEM]; }
974  const Expr *getCollection() const {
975    return reinterpret_cast<Expr*>(SubExprs[COLLECTION]);
976  }
977  const Stmt *getBody() const { return SubExprs[BODY]; }
978
979  SourceLocation getRParenLoc() const { return RParenLoc; }
980
981  virtual SourceRange getSourceRange() const {
982    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
983  }
984  static bool classof(const Stmt *T) {
985    return T->getStmtClass() == ObjCForCollectionStmtClass;
986  }
987  static bool classof(const ObjCForCollectionStmt *) { return true; }
988
989  // Iterators
990  virtual child_iterator child_begin();
991  virtual child_iterator child_end();
992
993  virtual void EmitImpl(llvm::Serializer& S) const;
994  static ObjCForCollectionStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
995};
996
997/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
998class ObjCAtCatchStmt : public Stmt {
999private:
1000  enum { SELECTOR, BODY, NEXT_CATCH, END_EXPR };
1001  Stmt *SubExprs[END_EXPR];
1002  SourceLocation AtCatchLoc, RParenLoc;
1003
1004  // Used by deserialization.
1005  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc)
1006  : Stmt(ObjCAtCatchStmtClass), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) {}
1007
1008public:
1009  ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
1010                  Stmt *catchVarStmtDecl, Stmt *atCatchStmt, Stmt *atCatchList);
1011
1012  const Stmt *getCatchBody() const { return SubExprs[BODY]; }
1013  Stmt *getCatchBody() { return SubExprs[BODY]; }
1014
1015  const ObjCAtCatchStmt *getNextCatchStmt() const {
1016    return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1017  }
1018  ObjCAtCatchStmt *getNextCatchStmt() {
1019    return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
1020  }
1021
1022  const Stmt *getCatchParamStmt() const { return SubExprs[SELECTOR]; }
1023  Stmt *getCatchParamStmt() { return SubExprs[SELECTOR]; }
1024
1025  SourceLocation getRParenLoc() const { return RParenLoc; }
1026
1027  virtual SourceRange getSourceRange() const {
1028    return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
1029  }
1030
1031  bool hasEllipsis() const { return getCatchParamStmt() == 0; }
1032
1033  static bool classof(const Stmt *T) {
1034    return T->getStmtClass() == ObjCAtCatchStmtClass;
1035  }
1036  static bool classof(const ObjCAtCatchStmt *) { return true; }
1037
1038  virtual child_iterator child_begin();
1039  virtual child_iterator child_end();
1040
1041  virtual void EmitImpl(llvm::Serializer& S) const;
1042  static ObjCAtCatchStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1043};
1044
1045/// ObjCAtFinallyStmt - This represent objective-c's @finally Statement
1046class ObjCAtFinallyStmt : public Stmt {
1047  Stmt *AtFinallyStmt;
1048  SourceLocation AtFinallyLoc;
1049public:
1050  ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt)
1051  : Stmt(ObjCAtFinallyStmtClass),
1052    AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {}
1053
1054  const Stmt *getFinallyBody () const { return AtFinallyStmt; }
1055  Stmt *getFinallyBody () { return AtFinallyStmt; }
1056
1057  virtual SourceRange getSourceRange() const {
1058    return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
1059  }
1060
1061  static bool classof(const Stmt *T) {
1062    return T->getStmtClass() == ObjCAtFinallyStmtClass;
1063  }
1064  static bool classof(const ObjCAtFinallyStmt *) { return true; }
1065
1066  virtual child_iterator child_begin();
1067  virtual child_iterator child_end();
1068
1069  virtual void EmitImpl(llvm::Serializer& S) const;
1070  static ObjCAtFinallyStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1071};
1072
1073/// ObjCAtTryStmt - This represent objective-c's over-all
1074/// @try ... @catch ... @finally statement.
1075class ObjCAtTryStmt : public Stmt {
1076private:
1077  enum { TRY, CATCH, FINALLY, END_EXPR };
1078  Stmt* SubStmts[END_EXPR];
1079
1080  SourceLocation AtTryLoc;
1081public:
1082  ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
1083                Stmt *atCatchStmt,
1084                Stmt *atFinallyStmt)
1085  : Stmt(ObjCAtTryStmtClass) {
1086      SubStmts[TRY] = atTryStmt;
1087      SubStmts[CATCH] = atCatchStmt;
1088      SubStmts[FINALLY] = atFinallyStmt;
1089      AtTryLoc = atTryLoc;
1090    }
1091
1092  const Stmt *getTryBody() const { return SubStmts[TRY]; }
1093  Stmt *getTryBody() { return SubStmts[TRY]; }
1094  const ObjCAtCatchStmt *getCatchStmts() const {
1095    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1096  }
1097  ObjCAtCatchStmt *getCatchStmts() {
1098    return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
1099  }
1100  const ObjCAtFinallyStmt *getFinallyStmt() const {
1101    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1102  }
1103  ObjCAtFinallyStmt *getFinallyStmt() {
1104    return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
1105  }
1106  virtual SourceRange getSourceRange() const {
1107    return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
1108  }
1109
1110  static bool classof(const Stmt *T) {
1111    return T->getStmtClass() == ObjCAtTryStmtClass;
1112  }
1113  static bool classof(const ObjCAtTryStmt *) { return true; }
1114
1115  virtual child_iterator child_begin();
1116  virtual child_iterator child_end();
1117
1118  virtual void EmitImpl(llvm::Serializer& S) const;
1119  static ObjCAtTryStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1120};
1121
1122/// ObjCAtSynchronizedStmt - This is for objective-c's @synchronized statement.
1123/// Example: @synchronized (sem) {
1124///             do-something;
1125///          }
1126///
1127class ObjCAtSynchronizedStmt : public Stmt {
1128private:
1129  enum { SYNC_EXPR, SYNC_BODY, END_EXPR };
1130  Stmt* SubStmts[END_EXPR];
1131  SourceLocation AtSynchronizedLoc;
1132
1133public:
1134  ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr,
1135                         Stmt *synchBody)
1136  : Stmt(ObjCAtSynchronizedStmtClass) {
1137      SubStmts[SYNC_EXPR] = synchExpr;
1138      SubStmts[SYNC_BODY] = synchBody;
1139      AtSynchronizedLoc = atSynchronizedLoc;
1140    }
1141
1142  const CompoundStmt *getSynchBody() const {
1143    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1144  }
1145  CompoundStmt *getSynchBody() {
1146    return reinterpret_cast<CompoundStmt*>(SubStmts[SYNC_BODY]);
1147  }
1148
1149  const Expr *getSynchExpr() const {
1150    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1151  }
1152  Expr *getSynchExpr() {
1153    return reinterpret_cast<Expr*>(SubStmts[SYNC_EXPR]);
1154  }
1155
1156  virtual SourceRange getSourceRange() const {
1157    return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
1158  }
1159
1160  static bool classof(const Stmt *T) {
1161    return T->getStmtClass() == ObjCAtSynchronizedStmtClass;
1162  }
1163  static bool classof(const ObjCAtSynchronizedStmt *) { return true; }
1164
1165  virtual child_iterator child_begin();
1166  virtual child_iterator child_end();
1167
1168  virtual void EmitImpl(llvm::Serializer& S) const;
1169  static ObjCAtSynchronizedStmt* CreateImpl(llvm::Deserializer& D,
1170                                            ASTContext& C);
1171};
1172
1173/// ObjCAtThrowStmt - This represents objective-c's @throw statement.
1174class ObjCAtThrowStmt : public Stmt {
1175  Stmt *Throw;
1176  SourceLocation AtThrowLoc;
1177public:
1178  ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr)
1179  : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) {
1180    AtThrowLoc = atThrowLoc;
1181  }
1182
1183  const Expr *getThrowExpr() const { return reinterpret_cast<Expr*>(Throw); }
1184  Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); }
1185
1186  virtual SourceRange getSourceRange() const {
1187    if (Throw)
1188      return SourceRange(AtThrowLoc, Throw->getLocEnd());
1189    else
1190      return SourceRange(AtThrowLoc);
1191  }
1192
1193  static bool classof(const Stmt *T) {
1194    return T->getStmtClass() == ObjCAtThrowStmtClass;
1195  }
1196  static bool classof(const ObjCAtThrowStmt *) { return true; }
1197
1198  virtual child_iterator child_begin();
1199  virtual child_iterator child_end();
1200
1201  virtual void EmitImpl(llvm::Serializer& S) const;
1202  static ObjCAtThrowStmt* CreateImpl(llvm::Deserializer& D, ASTContext& C);
1203};
1204
1205}  // end namespace clang
1206
1207#endif
1208