1193326Sed//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file defines the Stmt interface and subclasses.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#ifndef LLVM_CLANG_AST_STMT_H
15193326Sed#define LLVM_CLANG_AST_STMT_H
16193326Sed
17249423Sdim#include "clang/AST/DeclGroup.h"
18249423Sdim#include "clang/AST/StmtIterator.h"
19251662Sdim#include "clang/Basic/CapturedStmt.h"
20249423Sdim#include "clang/Basic/IdentifierTable.h"
21226633Sdim#include "clang/Basic/LLVM.h"
22193326Sed#include "clang/Basic/SourceLocation.h"
23249423Sdim#include "llvm/ADT/ArrayRef.h"
24251662Sdim#include "llvm/ADT/PointerIntPair.h"
25234353Sdim#include "llvm/Support/Compiler.h"
26249423Sdim#include "llvm/Support/ErrorHandling.h"
27193326Sed#include <string>
28193326Sed
29198092Srdivackynamespace llvm {
30198092Srdivacky  class FoldingSetNodeID;
31198092Srdivacky}
32198092Srdivacky
33193326Sednamespace clang {
34193326Sed  class ASTContext;
35249423Sdim  class Attr;
36251662Sdim  class CapturedDecl;
37249423Sdim  class Decl;
38193326Sed  class Expr;
39249423Sdim  class IdentifierInfo;
40249423Sdim  class LabelDecl;
41193326Sed  class ParmVarDecl;
42249423Sdim  class PrinterHelper;
43249423Sdim  struct PrintingPolicy;
44193326Sed  class QualType;
45251662Sdim  class RecordDecl;
46193326Sed  class SourceManager;
47193326Sed  class StringLiteral;
48193326Sed  class SwitchStmt;
49249423Sdim  class Token;
50239462Sdim  class VarDecl;
51198092Srdivacky
52234353Sdim  //===--------------------------------------------------------------------===//
53193326Sed  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
54193326Sed  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
55193326Sed  //  references to children (to be compatible with StmtIterator).
56234353Sdim  //===--------------------------------------------------------------------===//
57198092Srdivacky
58193326Sed  class Stmt;
59193326Sed  class Expr;
60198092Srdivacky
61193326Sed  class ExprIterator {
62193326Sed    Stmt** I;
63193326Sed  public:
64193326Sed    ExprIterator(Stmt** i) : I(i) {}
65198092Srdivacky    ExprIterator() : I(0) {}
66193326Sed    ExprIterator& operator++() { ++I; return *this; }
67193326Sed    ExprIterator operator-(size_t i) { return I-i; }
68193326Sed    ExprIterator operator+(size_t i) { return I+i; }
69193326Sed    Expr* operator[](size_t idx);
70193326Sed    // FIXME: Verify that this will correctly return a signed distance.
71193326Sed    signed operator-(const ExprIterator& R) const { return I - R.I; }
72193326Sed    Expr* operator*() const;
73193326Sed    Expr* operator->() const;
74193326Sed    bool operator==(const ExprIterator& R) const { return I == R.I; }
75193326Sed    bool operator!=(const ExprIterator& R) const { return I != R.I; }
76193326Sed    bool operator>(const ExprIterator& R) const { return I > R.I; }
77193326Sed    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
78193326Sed  };
79198092Srdivacky
80193326Sed  class ConstExprIterator {
81207619Srdivacky    const Stmt * const *I;
82193326Sed  public:
83207619Srdivacky    ConstExprIterator(const Stmt * const *i) : I(i) {}
84198092Srdivacky    ConstExprIterator() : I(0) {}
85193326Sed    ConstExprIterator& operator++() { ++I; return *this; }
86207619Srdivacky    ConstExprIterator operator+(size_t i) const { return I+i; }
87207619Srdivacky    ConstExprIterator operator-(size_t i) const { return I-i; }
88193326Sed    const Expr * operator[](size_t idx) const;
89193326Sed    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
90193326Sed    const Expr * operator*() const;
91193326Sed    const Expr * operator->() const;
92193326Sed    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
93193326Sed    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
94193326Sed    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
95193326Sed    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
96198092Srdivacky  };
97198092Srdivacky
98193326Sed//===----------------------------------------------------------------------===//
99193326Sed// AST classes for statements.
100193326Sed//===----------------------------------------------------------------------===//
101198092Srdivacky
102193326Sed/// Stmt - This represents one statement.
103193326Sed///
104193326Sedclass Stmt {
105193326Sedpublic:
106193326Sed  enum StmtClass {
107193326Sed    NoStmtClass = 0,
108193326Sed#define STMT(CLASS, PARENT) CLASS##Class,
109208600Srdivacky#define STMT_RANGE(BASE, FIRST, LAST) \
110210299Sed        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
111208600Srdivacky#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
112210299Sed        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
113208600Srdivacky#define ABSTRACT_STMT(STMT)
114208600Srdivacky#include "clang/AST/StmtNodes.inc"
115218893Sdim  };
116193326Sed
117193326Sed  // Make vanilla 'new' and 'delete' illegal for Stmts.
118193326Sedprotected:
119193326Sed  void* operator new(size_t bytes) throw() {
120226633Sdim    llvm_unreachable("Stmts cannot be allocated with regular 'new'.");
121193326Sed  }
122193326Sed  void operator delete(void* data) throw() {
123226633Sdim    llvm_unreachable("Stmts cannot be released with regular 'delete'.");
124193326Sed  }
125198092Srdivacky
126218893Sdim  class StmtBitfields {
127218893Sdim    friend class Stmt;
128218893Sdim
129218893Sdim    /// \brief The statement class.
130218893Sdim    unsigned sClass : 8;
131218893Sdim  };
132218893Sdim  enum { NumStmtBits = 8 };
133218893Sdim
134218893Sdim  class CompoundStmtBitfields {
135218893Sdim    friend class CompoundStmt;
136218893Sdim    unsigned : NumStmtBits;
137218893Sdim
138218893Sdim    unsigned NumStmts : 32 - NumStmtBits;
139218893Sdim  };
140218893Sdim
141218893Sdim  class ExprBitfields {
142218893Sdim    friend class Expr;
143218893Sdim    friend class DeclRefExpr; // computeDependence
144218893Sdim    friend class InitListExpr; // ctor
145218893Sdim    friend class DesignatedInitExpr; // ctor
146218893Sdim    friend class BlockDeclRefExpr; // ctor
147218893Sdim    friend class ASTStmtReader; // deserialization
148218893Sdim    friend class CXXNewExpr; // ctor
149218893Sdim    friend class DependentScopeDeclRefExpr; // ctor
150218893Sdim    friend class CXXConstructExpr; // ctor
151218893Sdim    friend class CallExpr; // ctor
152218893Sdim    friend class OffsetOfExpr; // ctor
153218893Sdim    friend class ObjCMessageExpr; // ctor
154234353Sdim    friend class ObjCArrayLiteral; // ctor
155234353Sdim    friend class ObjCDictionaryLiteral; // ctor
156218893Sdim    friend class ShuffleVectorExpr; // ctor
157218893Sdim    friend class ParenListExpr; // ctor
158218893Sdim    friend class CXXUnresolvedConstructExpr; // ctor
159218893Sdim    friend class CXXDependentScopeMemberExpr; // ctor
160218893Sdim    friend class OverloadExpr; // ctor
161234353Sdim    friend class PseudoObjectExpr; // ctor
162226633Sdim    friend class AtomicExpr; // ctor
163218893Sdim    unsigned : NumStmtBits;
164218893Sdim
165218893Sdim    unsigned ValueKind : 2;
166218893Sdim    unsigned ObjectKind : 2;
167218893Sdim    unsigned TypeDependent : 1;
168218893Sdim    unsigned ValueDependent : 1;
169224145Sdim    unsigned InstantiationDependent : 1;
170218893Sdim    unsigned ContainsUnexpandedParameterPack : 1;
171218893Sdim  };
172224145Sdim  enum { NumExprBits = 16 };
173218893Sdim
174234353Sdim  class CharacterLiteralBitfields {
175234353Sdim    friend class CharacterLiteral;
176234353Sdim    unsigned : NumExprBits;
177234353Sdim
178234353Sdim    unsigned Kind : 2;
179234353Sdim  };
180234353Sdim
181249423Sdim  enum APFloatSemantics {
182249423Sdim    IEEEhalf,
183249423Sdim    IEEEsingle,
184249423Sdim    IEEEdouble,
185249423Sdim    x87DoubleExtended,
186249423Sdim    IEEEquad,
187249423Sdim    PPCDoubleDouble
188249423Sdim  };
189249423Sdim
190234353Sdim  class FloatingLiteralBitfields {
191234353Sdim    friend class FloatingLiteral;
192234353Sdim    unsigned : NumExprBits;
193234353Sdim
194249423Sdim    unsigned Semantics : 3; // Provides semantics for APFloat construction
195234353Sdim    unsigned IsExact : 1;
196234353Sdim  };
197234353Sdim
198234353Sdim  class UnaryExprOrTypeTraitExprBitfields {
199234353Sdim    friend class UnaryExprOrTypeTraitExpr;
200234353Sdim    unsigned : NumExprBits;
201234353Sdim
202234353Sdim    unsigned Kind : 2;
203234353Sdim    unsigned IsType : 1; // true if operand is a type, false if an expression.
204234353Sdim  };
205234353Sdim
206221345Sdim  class DeclRefExprBitfields {
207221345Sdim    friend class DeclRefExpr;
208221345Sdim    friend class ASTStmtReader; // deserialization
209221345Sdim    unsigned : NumExprBits;
210221345Sdim
211221345Sdim    unsigned HasQualifier : 1;
212234353Sdim    unsigned HasTemplateKWAndArgsInfo : 1;
213221345Sdim    unsigned HasFoundDecl : 1;
214226633Sdim    unsigned HadMultipleCandidates : 1;
215234353Sdim    unsigned RefersToEnclosingLocal : 1;
216221345Sdim  };
217221345Sdim
218218893Sdim  class CastExprBitfields {
219218893Sdim    friend class CastExpr;
220218893Sdim    unsigned : NumExprBits;
221218893Sdim
222218893Sdim    unsigned Kind : 6;
223218893Sdim    unsigned BasePathSize : 32 - 6 - NumExprBits;
224218893Sdim  };
225218893Sdim
226218893Sdim  class CallExprBitfields {
227218893Sdim    friend class CallExpr;
228218893Sdim    unsigned : NumExprBits;
229218893Sdim
230218893Sdim    unsigned NumPreArgs : 1;
231218893Sdim  };
232218893Sdim
233234353Sdim  class ExprWithCleanupsBitfields {
234234353Sdim    friend class ExprWithCleanups;
235234353Sdim    friend class ASTStmtReader; // deserialization
236234353Sdim
237234353Sdim    unsigned : NumExprBits;
238234353Sdim
239234353Sdim    unsigned NumObjects : 32 - NumExprBits;
240234353Sdim  };
241234353Sdim
242234353Sdim  class PseudoObjectExprBitfields {
243234353Sdim    friend class PseudoObjectExpr;
244234353Sdim    friend class ASTStmtReader; // deserialization
245234353Sdim
246234353Sdim    unsigned : NumExprBits;
247234353Sdim
248234353Sdim    // These don't need to be particularly wide, because they're
249234353Sdim    // strictly limited by the forms of expressions we permit.
250234353Sdim    unsigned NumSubExprs : 8;
251234353Sdim    unsigned ResultIndex : 32 - 8 - NumExprBits;
252234353Sdim  };
253234353Sdim
254224145Sdim  class ObjCIndirectCopyRestoreExprBitfields {
255224145Sdim    friend class ObjCIndirectCopyRestoreExpr;
256224145Sdim    unsigned : NumExprBits;
257224145Sdim
258224145Sdim    unsigned ShouldCopy : 1;
259224145Sdim  };
260224145Sdim
261234353Sdim  class InitListExprBitfields {
262234353Sdim    friend class InitListExpr;
263234353Sdim
264234353Sdim    unsigned : NumExprBits;
265234353Sdim
266234353Sdim    /// Whether this initializer list originally had a GNU array-range
267234353Sdim    /// designator in it. This is a temporary marker used by CodeGen.
268234353Sdim    unsigned HadArrayRangeDesignator : 1;
269234353Sdim  };
270234353Sdim
271234353Sdim  class TypeTraitExprBitfields {
272234353Sdim    friend class TypeTraitExpr;
273234353Sdim    friend class ASTStmtReader;
274234353Sdim    friend class ASTStmtWriter;
275234353Sdim
276234353Sdim    unsigned : NumExprBits;
277234353Sdim
278234353Sdim    /// \brief The kind of type trait, which is a value of a TypeTrait enumerator.
279234353Sdim    unsigned Kind : 8;
280234353Sdim
281234353Sdim    /// \brief If this expression is not value-dependent, this indicates whether
282234353Sdim    /// the trait evaluated true or false.
283234353Sdim    unsigned Value : 1;
284234353Sdim
285234353Sdim    /// \brief The number of arguments to this type trait.
286234353Sdim    unsigned NumArgs : 32 - 8 - 1 - NumExprBits;
287234353Sdim  };
288263508Sdim
289218893Sdim  union {
290218893Sdim    // FIXME: this is wasteful on 64-bit platforms.
291218893Sdim    void *Aligner;
292218893Sdim
293218893Sdim    StmtBitfields StmtBits;
294218893Sdim    CompoundStmtBitfields CompoundStmtBits;
295218893Sdim    ExprBitfields ExprBits;
296234353Sdim    CharacterLiteralBitfields CharacterLiteralBits;
297234353Sdim    FloatingLiteralBitfields FloatingLiteralBits;
298234353Sdim    UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits;
299221345Sdim    DeclRefExprBitfields DeclRefExprBits;
300218893Sdim    CastExprBitfields CastExprBits;
301218893Sdim    CallExprBitfields CallExprBits;
302234353Sdim    ExprWithCleanupsBitfields ExprWithCleanupsBits;
303234353Sdim    PseudoObjectExprBitfields PseudoObjectExprBits;
304224145Sdim    ObjCIndirectCopyRestoreExprBitfields ObjCIndirectCopyRestoreExprBits;
305234353Sdim    InitListExprBitfields InitListExprBits;
306234353Sdim    TypeTraitExprBitfields TypeTraitExprBits;
307218893Sdim  };
308218893Sdim
309218893Sdim  friend class ASTStmtReader;
310234353Sdim  friend class ASTStmtWriter;
311218893Sdim
312193326Sedpublic:
313193326Sed  // Only allow allocation of Stmts using the allocator in ASTContext
314198092Srdivacky  // or by doing a placement new.
315263508Sdim  void* operator new(size_t bytes, const ASTContext& C,
316263508Sdim                     unsigned alignment = 8);
317198092Srdivacky
318263508Sdim  void* operator new(size_t bytes, const ASTContext* C,
319263508Sdim                     unsigned alignment = 8) {
320263508Sdim    return operator new(bytes, *C, alignment);
321263508Sdim  }
322198092Srdivacky
323193326Sed  void* operator new(size_t bytes, void* mem) throw() {
324193326Sed    return mem;
325193326Sed  }
326193326Sed
327263508Sdim  void operator delete(void*, const ASTContext&, unsigned) throw() { }
328263508Sdim  void operator delete(void*, const ASTContext*, unsigned) throw() { }
329263508Sdim  void operator delete(void*, size_t) throw() { }
330193326Sed  void operator delete(void*, void*) throw() { }
331193326Sed
332193326Sedpublic:
333193326Sed  /// \brief A placeholder type used to construct an empty shell of a
334193326Sed  /// type, that will be filled in later (e.g., by some
335193326Sed  /// de-serialization).
336193326Sed  struct EmptyShell { };
337193326Sed
338234353Sdimprivate:
339234353Sdim  /// \brief Whether statistic collection is enabled.
340234353Sdim  static bool StatisticsEnabled;
341234353Sdim
342193326Sedprotected:
343193326Sed  /// \brief Construct an empty statement.
344218893Sdim  explicit Stmt(StmtClass SC, EmptyShell) {
345218893Sdim    StmtBits.sClass = SC;
346234353Sdim    if (StatisticsEnabled) Stmt::addStmtClass(SC);
347193326Sed  }
348193326Sed
349193326Sedpublic:
350218893Sdim  Stmt(StmtClass SC) {
351218893Sdim    StmtBits.sClass = SC;
352234353Sdim    if (StatisticsEnabled) Stmt::addStmtClass(SC);
353193326Sed  }
354193326Sed
355234353Sdim  StmtClass getStmtClass() const {
356218893Sdim    return static_cast<StmtClass>(StmtBits.sClass);
357198092Srdivacky  }
358193326Sed  const char *getStmtClassName() const;
359198092Srdivacky
360193326Sed  /// SourceLocation tokens are not useful in isolation - they are low level
361193326Sed  /// value objects created/interpreted by SourceManager. We assume AST
362193326Sed  /// clients will have a pointer to the respective SourceManager.
363234353Sdim  SourceRange getSourceRange() const LLVM_READONLY;
364234353Sdim  SourceLocation getLocStart() const LLVM_READONLY;
365234353Sdim  SourceLocation getLocEnd() const LLVM_READONLY;
366218893Sdim
367193326Sed  // global temp stats (until we have a per-module visitor)
368193326Sed  static void addStmtClass(const StmtClass s);
369234353Sdim  static void EnableStatistics();
370193326Sed  static void PrintStats();
371193326Sed
372249423Sdim  /// \brief Dumps the specified AST fragment and all subtrees to
373249423Sdim  /// \c llvm::errs().
374234353Sdim  LLVM_ATTRIBUTE_USED void dump() const;
375234353Sdim  LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
376226633Sdim  void dump(raw_ostream &OS, SourceManager &SM) const;
377193326Sed
378249423Sdim  /// dumpColor - same as dump(), but forces color highlighting.
379249423Sdim  LLVM_ATTRIBUTE_USED void dumpColor() const;
380193326Sed
381193326Sed  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
382193326Sed  /// back to its original source language syntax.
383263508Sdim  void dumpPretty(const ASTContext &Context) const;
384226633Sdim  void printPretty(raw_ostream &OS, PrinterHelper *Helper,
385195341Sed                   const PrintingPolicy &Policy,
386193326Sed                   unsigned Indentation = 0) const;
387198092Srdivacky
388193326Sed  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
389193326Sed  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
390193326Sed  void viewAST() const;
391198092Srdivacky
392224145Sdim  /// Skip past any implicit AST nodes which might surround this
393224145Sdim  /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
394224145Sdim  Stmt *IgnoreImplicit();
395224145Sdim
396226633Sdim  const Stmt *stripLabelLikeStatements() const;
397226633Sdim  Stmt *stripLabelLikeStatements() {
398226633Sdim    return const_cast<Stmt*>(
399226633Sdim      const_cast<const Stmt*>(this)->stripLabelLikeStatements());
400226633Sdim  }
401226633Sdim
402218893Sdim  /// Child Iterators: All subclasses must implement 'children'
403218893Sdim  /// to permit easy iteration over the substatements/subexpessions of an
404218893Sdim  /// AST node.  This permits easy iteration over all nodes in the AST.
405193326Sed  typedef StmtIterator       child_iterator;
406193326Sed  typedef ConstStmtIterator  const_child_iterator;
407198092Srdivacky
408218893Sdim  typedef StmtRange          child_range;
409218893Sdim  typedef ConstStmtRange     const_child_range;
410198092Srdivacky
411218893Sdim  child_range children();
412218893Sdim  const_child_range children() const {
413218893Sdim    return const_cast<Stmt*>(this)->children();
414193326Sed  }
415198092Srdivacky
416218893Sdim  child_iterator child_begin() { return children().first; }
417218893Sdim  child_iterator child_end() { return children().second; }
418198092Srdivacky
419218893Sdim  const_child_iterator child_begin() const { return children().first; }
420218893Sdim  const_child_iterator child_end() const { return children().second; }
421218893Sdim
422198092Srdivacky  /// \brief Produce a unique representation of the given statement.
423198092Srdivacky  ///
424243830Sdim  /// \param ID once the profiling operation is complete, will contain
425198092Srdivacky  /// the unique representation of the given statement.
426198092Srdivacky  ///
427243830Sdim  /// \param Context the AST context in which the statement resides
428198092Srdivacky  ///
429243830Sdim  /// \param Canonical whether the profile should be based on the canonical
430198092Srdivacky  /// representation of this statement (e.g., where non-type template
431198092Srdivacky  /// parameters are identified by index/level rather than their
432198092Srdivacky  /// declaration pointers) or the exact representation of the statement as
433198092Srdivacky  /// written in the source.
434218893Sdim  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
435224145Sdim               bool Canonical) const;
436193326Sed};
437193326Sed
438193326Sed/// DeclStmt - Adaptor class for mixing declarations with statements and
439193326Sed/// expressions. For example, CompoundStmt mixes statements, expressions
440198092Srdivacky/// and declarations (variables, types). Another example is ForStmt, where
441193326Sed/// the first statement can be an expression or a declaration.
442193326Sed///
443193326Sedclass DeclStmt : public Stmt {
444193326Sed  DeclGroupRef DG;
445193326Sed  SourceLocation StartLoc, EndLoc;
446198092Srdivacky
447193326Sedpublic:
448198092Srdivacky  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
449193326Sed           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
450193326Sed                                    StartLoc(startLoc), EndLoc(endLoc) {}
451198092Srdivacky
452193326Sed  /// \brief Build an empty declaration statement.
453193326Sed  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
454193326Sed
455193326Sed  /// isSingleDecl - This method returns true if this DeclStmt refers
456193326Sed  /// to a single Decl.
457193326Sed  bool isSingleDecl() const {
458193326Sed    return DG.isSingleDecl();
459193326Sed  }
460198092Srdivacky
461193326Sed  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
462198092Srdivacky  Decl *getSingleDecl() { return DG.getSingleDecl(); }
463198092Srdivacky
464193326Sed  const DeclGroupRef getDeclGroup() const { return DG; }
465193326Sed  DeclGroupRef getDeclGroup() { return DG; }
466193326Sed  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
467193326Sed
468193326Sed  SourceLocation getStartLoc() const { return StartLoc; }
469193326Sed  void setStartLoc(SourceLocation L) { StartLoc = L; }
470193326Sed  SourceLocation getEndLoc() const { return EndLoc; }
471193326Sed  void setEndLoc(SourceLocation L) { EndLoc = L; }
472193326Sed
473249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return StartLoc; }
474249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
475198092Srdivacky
476198092Srdivacky  static bool classof(const Stmt *T) {
477198092Srdivacky    return T->getStmtClass() == DeclStmtClass;
478193326Sed  }
479198092Srdivacky
480193326Sed  // Iterators over subexpressions.
481218893Sdim  child_range children() {
482218893Sdim    return child_range(child_iterator(DG.begin(), DG.end()),
483218893Sdim                       child_iterator(DG.end(), DG.end()));
484218893Sdim  }
485198092Srdivacky
486193326Sed  typedef DeclGroupRef::iterator decl_iterator;
487193326Sed  typedef DeclGroupRef::const_iterator const_decl_iterator;
488198092Srdivacky
489193326Sed  decl_iterator decl_begin() { return DG.begin(); }
490193326Sed  decl_iterator decl_end() { return DG.end(); }
491193326Sed  const_decl_iterator decl_begin() const { return DG.begin(); }
492193326Sed  const_decl_iterator decl_end() const { return DG.end(); }
493239462Sdim
494239462Sdim  typedef std::reverse_iterator<decl_iterator> reverse_decl_iterator;
495239462Sdim  reverse_decl_iterator decl_rbegin() {
496239462Sdim    return reverse_decl_iterator(decl_end());
497239462Sdim  }
498239462Sdim  reverse_decl_iterator decl_rend() {
499239462Sdim    return reverse_decl_iterator(decl_begin());
500239462Sdim  }
501193326Sed};
502193326Sed
503193326Sed/// NullStmt - This is the null statement ";": C99 6.8.3p3.
504193326Sed///
505193326Sedclass NullStmt : public Stmt {
506193326Sed  SourceLocation SemiLoc;
507218893Sdim
508226633Sdim  /// \brief True if the null statement was preceded by an empty macro, e.g:
509218893Sdim  /// @code
510218893Sdim  ///   #define CALL(x)
511218893Sdim  ///   CALL(0);
512218893Sdim  /// @endcode
513226633Sdim  bool HasLeadingEmptyMacro;
514193326Sedpublic:
515226633Sdim  NullStmt(SourceLocation L, bool hasLeadingEmptyMacro = false)
516226633Sdim    : Stmt(NullStmtClass), SemiLoc(L),
517226633Sdim      HasLeadingEmptyMacro(hasLeadingEmptyMacro) {}
518193326Sed
519193326Sed  /// \brief Build an empty null statement.
520226633Sdim  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty),
521226633Sdim      HasLeadingEmptyMacro(false) { }
522193326Sed
523193326Sed  SourceLocation getSemiLoc() const { return SemiLoc; }
524193326Sed  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
525193326Sed
526226633Sdim  bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
527198092Srdivacky
528249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return SemiLoc; }
529249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return SemiLoc; }
530218893Sdim
531198092Srdivacky  static bool classof(const Stmt *T) {
532198092Srdivacky    return T->getStmtClass() == NullStmtClass;
533193326Sed  }
534198092Srdivacky
535218893Sdim  child_range children() { return child_range(); }
536218893Sdim
537218893Sdim  friend class ASTStmtReader;
538218893Sdim  friend class ASTStmtWriter;
539193326Sed};
540193326Sed
541193326Sed/// CompoundStmt - This represents a group of statements like { stmt stmt }.
542193326Sed///
543193326Sedclass CompoundStmt : public Stmt {
544193326Sed  Stmt** Body;
545193326Sed  SourceLocation LBracLoc, RBracLoc;
546193326Sedpublic:
547263508Sdim  CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
548239462Sdim               SourceLocation LB, SourceLocation RB);
549218893Sdim
550263508Sdim  // \brief Build an empty compound statement with a location.
551239462Sdim  explicit CompoundStmt(SourceLocation Loc)
552239462Sdim    : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) {
553239462Sdim    CompoundStmtBits.NumStmts = 0;
554198092Srdivacky  }
555193326Sed
556193326Sed  // \brief Build an empty compound statement.
557193326Sed  explicit CompoundStmt(EmptyShell Empty)
558218893Sdim    : Stmt(CompoundStmtClass, Empty), Body(0) {
559218893Sdim    CompoundStmtBits.NumStmts = 0;
560218893Sdim  }
561193326Sed
562263508Sdim  void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts);
563198092Srdivacky
564218893Sdim  bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
565218893Sdim  unsigned size() const { return CompoundStmtBits.NumStmts; }
566193326Sed
567193326Sed  typedef Stmt** body_iterator;
568193326Sed  body_iterator body_begin() { return Body; }
569218893Sdim  body_iterator body_end() { return Body + size(); }
570218893Sdim  Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; }
571234353Sdim
572218893Sdim  void setLastStmt(Stmt *S) {
573218893Sdim    assert(!body_empty() && "setLastStmt");
574218893Sdim    Body[size()-1] = S;
575218893Sdim  }
576193326Sed
577193326Sed  typedef Stmt* const * const_body_iterator;
578193326Sed  const_body_iterator body_begin() const { return Body; }
579218893Sdim  const_body_iterator body_end() const { return Body + size(); }
580218893Sdim  const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; }
581193326Sed
582193326Sed  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
583193326Sed  reverse_body_iterator body_rbegin() {
584193326Sed    return reverse_body_iterator(body_end());
585193326Sed  }
586193326Sed  reverse_body_iterator body_rend() {
587193326Sed    return reverse_body_iterator(body_begin());
588193326Sed  }
589193326Sed
590193326Sed  typedef std::reverse_iterator<const_body_iterator>
591193326Sed          const_reverse_body_iterator;
592193326Sed
593193326Sed  const_reverse_body_iterator body_rbegin() const {
594193326Sed    return const_reverse_body_iterator(body_end());
595193326Sed  }
596198092Srdivacky
597193326Sed  const_reverse_body_iterator body_rend() const {
598193326Sed    return const_reverse_body_iterator(body_begin());
599193326Sed  }
600198092Srdivacky
601249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; }
602249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; }
603198092Srdivacky
604193326Sed  SourceLocation getLBracLoc() const { return LBracLoc; }
605193326Sed  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
606193326Sed  SourceLocation getRBracLoc() const { return RBracLoc; }
607193326Sed  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
608198092Srdivacky
609198092Srdivacky  static bool classof(const Stmt *T) {
610198092Srdivacky    return T->getStmtClass() == CompoundStmtClass;
611193326Sed  }
612198092Srdivacky
613193326Sed  // Iterators
614218893Sdim  child_range children() {
615218893Sdim    return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
616218893Sdim  }
617234353Sdim
618226633Sdim  const_child_range children() const {
619226633Sdim    return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
620226633Sdim  }
621193326Sed};
622193326Sed
623193326Sed// SwitchCase is the base class for CaseStmt and DefaultStmt,
624193326Sedclass SwitchCase : public Stmt {
625193326Sedprotected:
626193326Sed  // A pointer to the following CaseStmt or DefaultStmt class,
627193326Sed  // used by SwitchStmt.
628193326Sed  SwitchCase *NextSwitchCase;
629249423Sdim  SourceLocation KeywordLoc;
630249423Sdim  SourceLocation ColonLoc;
631193326Sed
632249423Sdim  SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
633249423Sdim    : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
634198092Srdivacky
635249423Sdim  SwitchCase(StmtClass SC, EmptyShell)
636249423Sdim    : Stmt(SC), NextSwitchCase(0) {}
637249423Sdim
638193326Sedpublic:
639193326Sed  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
640193326Sed
641193326Sed  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
642193326Sed
643193326Sed  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
644193326Sed
645249423Sdim  SourceLocation getKeywordLoc() const { return KeywordLoc; }
646249423Sdim  void setKeywordLoc(SourceLocation L) { KeywordLoc = L; }
647249423Sdim  SourceLocation getColonLoc() const { return ColonLoc; }
648249423Sdim  void setColonLoc(SourceLocation L) { ColonLoc = L; }
649249423Sdim
650218893Sdim  Stmt *getSubStmt();
651221345Sdim  const Stmt *getSubStmt() const {
652221345Sdim    return const_cast<SwitchCase*>(this)->getSubStmt();
653221345Sdim  }
654193326Sed
655249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
656249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY;
657198092Srdivacky
658198092Srdivacky  static bool classof(const Stmt *T) {
659198092Srdivacky    return T->getStmtClass() == CaseStmtClass ||
660218893Sdim           T->getStmtClass() == DefaultStmtClass;
661193326Sed  }
662193326Sed};
663193326Sed
664193326Sedclass CaseStmt : public SwitchCase {
665221345Sdim  enum { LHS, RHS, SUBSTMT, END_EXPR };
666198092Srdivacky  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
667193326Sed                             // GNU "case 1 ... 4" extension
668193326Sed  SourceLocation EllipsisLoc;
669193326Sedpublic:
670193326Sed  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
671198092Srdivacky           SourceLocation ellipsisLoc, SourceLocation colonLoc)
672249423Sdim    : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
673193326Sed    SubExprs[SUBSTMT] = 0;
674193326Sed    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
675193326Sed    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
676193326Sed    EllipsisLoc = ellipsisLoc;
677193326Sed  }
678193326Sed
679193326Sed  /// \brief Build an empty switch case statement.
680249423Sdim  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass, Empty) { }
681193326Sed
682249423Sdim  SourceLocation getCaseLoc() const { return KeywordLoc; }
683249423Sdim  void setCaseLoc(SourceLocation L) { KeywordLoc = L; }
684193326Sed  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
685193326Sed  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
686193326Sed  SourceLocation getColonLoc() const { return ColonLoc; }
687193326Sed  void setColonLoc(SourceLocation L) { ColonLoc = L; }
688193326Sed
689193326Sed  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
690193326Sed  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
691193326Sed  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
692193326Sed
693198092Srdivacky  const Expr *getLHS() const {
694198092Srdivacky    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
695193326Sed  }
696198092Srdivacky  const Expr *getRHS() const {
697198092Srdivacky    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
698193326Sed  }
699193326Sed  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
700193326Sed
701193326Sed  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
702193326Sed  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
703193326Sed  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
704198092Srdivacky
705249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
706249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
707193326Sed    // Handle deeply nested case statements with iteration instead of recursion.
708193326Sed    const CaseStmt *CS = this;
709193326Sed    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
710193326Sed      CS = CS2;
711198092Srdivacky
712249423Sdim    return CS->getSubStmt()->getLocEnd();
713193326Sed  }
714249423Sdim
715198092Srdivacky  static bool classof(const Stmt *T) {
716198092Srdivacky    return T->getStmtClass() == CaseStmtClass;
717193326Sed  }
718198092Srdivacky
719193326Sed  // Iterators
720218893Sdim  child_range children() {
721218893Sdim    return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
722218893Sdim  }
723193326Sed};
724193326Sed
725193326Sedclass DefaultStmt : public SwitchCase {
726193326Sed  Stmt* SubStmt;
727193326Sedpublic:
728198092Srdivacky  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
729249423Sdim    SwitchCase(DefaultStmtClass, DL, CL), SubStmt(substmt) {}
730193326Sed
731193326Sed  /// \brief Build an empty default statement.
732249423Sdim  explicit DefaultStmt(EmptyShell Empty)
733249423Sdim    : SwitchCase(DefaultStmtClass, Empty) { }
734193326Sed
735193326Sed  Stmt *getSubStmt() { return SubStmt; }
736193326Sed  const Stmt *getSubStmt() const { return SubStmt; }
737193326Sed  void setSubStmt(Stmt *S) { SubStmt = S; }
738193326Sed
739249423Sdim  SourceLocation getDefaultLoc() const { return KeywordLoc; }
740249423Sdim  void setDefaultLoc(SourceLocation L) { KeywordLoc = L; }
741193326Sed  SourceLocation getColonLoc() const { return ColonLoc; }
742193326Sed  void setColonLoc(SourceLocation L) { ColonLoc = L; }
743193326Sed
744249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
745249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
746249423Sdim
747198092Srdivacky  static bool classof(const Stmt *T) {
748198092Srdivacky    return T->getStmtClass() == DefaultStmtClass;
749193326Sed  }
750198092Srdivacky
751193326Sed  // Iterators
752218893Sdim  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
753193326Sed};
754193326Sed
755249423Sdiminline SourceLocation SwitchCase::getLocEnd() const {
756249423Sdim  if (const CaseStmt *CS = dyn_cast<CaseStmt>(this))
757249423Sdim    return CS->getLocEnd();
758249423Sdim  return cast<DefaultStmt>(this)->getLocEnd();
759249423Sdim}
760234353Sdim
761218893Sdim/// LabelStmt - Represents a label, which has a substatement.  For example:
762218893Sdim///    foo: return;
763218893Sdim///
764193326Sedclass LabelStmt : public Stmt {
765218893Sdim  LabelDecl *TheDecl;
766193326Sed  Stmt *SubStmt;
767193326Sed  SourceLocation IdentLoc;
768193326Sedpublic:
769218893Sdim  LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt)
770218893Sdim    : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) {
771218893Sdim  }
772193326Sed
773193326Sed  // \brief Build an empty label statement.
774193326Sed  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
775198092Srdivacky
776193326Sed  SourceLocation getIdentLoc() const { return IdentLoc; }
777218893Sdim  LabelDecl *getDecl() const { return TheDecl; }
778218893Sdim  void setDecl(LabelDecl *D) { TheDecl = D; }
779193326Sed  const char *getName() const;
780193326Sed  Stmt *getSubStmt() { return SubStmt; }
781193326Sed  const Stmt *getSubStmt() const { return SubStmt; }
782193326Sed  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
783193326Sed  void setSubStmt(Stmt *SS) { SubStmt = SS; }
784193326Sed
785249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return IdentLoc; }
786249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
787249423Sdim
788218893Sdim  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
789218893Sdim
790198092Srdivacky  static bool classof(const Stmt *T) {
791198092Srdivacky    return T->getStmtClass() == LabelStmtClass;
792198092Srdivacky  }
793193326Sed};
794193326Sed
795193326Sed
796234982Sdim/// \brief Represents an attribute applied to a statement.
797234982Sdim///
798234982Sdim/// Represents an attribute applied to a statement. For example:
799234982Sdim///   [[omp::for(...)]] for (...) { ... }
800234982Sdim///
801234982Sdimclass AttributedStmt : public Stmt {
802234982Sdim  Stmt *SubStmt;
803234982Sdim  SourceLocation AttrLoc;
804239462Sdim  unsigned NumAttrs;
805239462Sdim  const Attr *Attrs[1];
806234982Sdim
807234982Sdim  friend class ASTStmtReader;
808234982Sdim
809239462Sdim  AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
810239462Sdim    : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
811239462Sdim      NumAttrs(Attrs.size()) {
812239462Sdim    memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*));
813234982Sdim  }
814234982Sdim
815239462Sdim  explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
816239462Sdim    : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
817239462Sdim    memset(Attrs, 0, NumAttrs * sizeof(Attr*));
818234982Sdim  }
819234982Sdim
820239462Sdimpublic:
821263508Sdim  static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
822239462Sdim                                ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
823239462Sdim  // \brief Build an empty attributed statement.
824263508Sdim  static AttributedStmt *CreateEmpty(const ASTContext &C, unsigned NumAttrs);
825239462Sdim
826234982Sdim  SourceLocation getAttrLoc() const { return AttrLoc; }
827239462Sdim  ArrayRef<const Attr*> getAttrs() const {
828239462Sdim    return ArrayRef<const Attr*>(Attrs, NumAttrs);
829239462Sdim  }
830234982Sdim  Stmt *getSubStmt() { return SubStmt; }
831234982Sdim  const Stmt *getSubStmt() const { return SubStmt; }
832234982Sdim
833249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return AttrLoc; }
834249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
835249423Sdim
836234982Sdim  child_range children() { return child_range(&SubStmt, &SubStmt + 1); }
837234982Sdim
838234982Sdim  static bool classof(const Stmt *T) {
839234982Sdim    return T->getStmtClass() == AttributedStmtClass;
840234982Sdim  }
841234982Sdim};
842234982Sdim
843234982Sdim
844193326Sed/// IfStmt - This represents an if/then/else.
845193326Sed///
846193326Sedclass IfStmt : public Stmt {
847210299Sed  enum { VAR, COND, THEN, ELSE, END_EXPR };
848193326Sed  Stmt* SubExprs[END_EXPR];
849199990Srdivacky
850193326Sed  SourceLocation IfLoc;
851193326Sed  SourceLocation ElseLoc;
852234353Sdim
853193326Sedpublic:
854263508Sdim  IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
855210299Sed         Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
856234353Sdim
857193326Sed  /// \brief Build an empty if/then/else statement
858193326Sed  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
859193326Sed
860199990Srdivacky  /// \brief Retrieve the variable declared in this "if" statement, if any.
861199990Srdivacky  ///
862199990Srdivacky  /// In the following example, "x" is the condition variable.
863199990Srdivacky  /// \code
864199990Srdivacky  /// if (int x = foo()) {
865199990Srdivacky  ///   printf("x is %d", x);
866199990Srdivacky  /// }
867199990Srdivacky  /// \endcode
868210299Sed  VarDecl *getConditionVariable() const;
869263508Sdim  void setConditionVariable(const ASTContext &C, VarDecl *V);
870234353Sdim
871221345Sdim  /// If this IfStmt has a condition variable, return the faux DeclStmt
872221345Sdim  /// associated with the creation of that condition variable.
873221345Sdim  const DeclStmt *getConditionVariableDeclStmt() const {
874221345Sdim    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
875221345Sdim  }
876234353Sdim
877193326Sed  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
878193326Sed  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
879193326Sed  const Stmt *getThen() const { return SubExprs[THEN]; }
880198092Srdivacky  void setThen(Stmt *S) { SubExprs[THEN] = S; }
881193326Sed  const Stmt *getElse() const { return SubExprs[ELSE]; }
882193326Sed  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
883193326Sed
884193326Sed  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
885193326Sed  Stmt *getThen() { return SubExprs[THEN]; }
886193326Sed  Stmt *getElse() { return SubExprs[ELSE]; }
887193326Sed
888193326Sed  SourceLocation getIfLoc() const { return IfLoc; }
889193326Sed  void setIfLoc(SourceLocation L) { IfLoc = L; }
890193326Sed  SourceLocation getElseLoc() const { return ElseLoc; }
891193326Sed  void setElseLoc(SourceLocation L) { ElseLoc = L; }
892193326Sed
893249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; }
894249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
895193326Sed    if (SubExprs[ELSE])
896249423Sdim      return SubExprs[ELSE]->getLocEnd();
897193326Sed    else
898249423Sdim      return SubExprs[THEN]->getLocEnd();
899193326Sed  }
900198092Srdivacky
901218893Sdim  // Iterators over subexpressions.  The iterators will include iterating
902218893Sdim  // over the initialization expression referenced by the condition variable.
903218893Sdim  child_range children() {
904218893Sdim    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
905218893Sdim  }
906218893Sdim
907198092Srdivacky  static bool classof(const Stmt *T) {
908198092Srdivacky    return T->getStmtClass() == IfStmtClass;
909193326Sed  }
910193326Sed};
911193326Sed
912193326Sed/// SwitchStmt - This represents a 'switch' stmt.
913193326Sed///
914193326Sedclass SwitchStmt : public Stmt {
915210299Sed  enum { VAR, COND, BODY, END_EXPR };
916198092Srdivacky  Stmt* SubExprs[END_EXPR];
917193326Sed  // This points to a linked list of case and default statements.
918193326Sed  SwitchCase *FirstCase;
919193326Sed  SourceLocation SwitchLoc;
920198092Srdivacky
921218893Sdim  /// If the SwitchStmt is a switch on an enum value, this records whether
922218893Sdim  /// all the enum values were covered by CaseStmts.  This value is meant to
923218893Sdim  /// be a hint for possible clients.
924218893Sdim  unsigned AllEnumCasesCovered : 1;
925218893Sdim
926193326Sedpublic:
927263508Sdim  SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond);
928198092Srdivacky
929193326Sed  /// \brief Build a empty switch statement.
930193326Sed  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
931193326Sed
932199990Srdivacky  /// \brief Retrieve the variable declared in this "switch" statement, if any.
933199990Srdivacky  ///
934199990Srdivacky  /// In the following example, "x" is the condition variable.
935199990Srdivacky  /// \code
936199990Srdivacky  /// switch (int x = foo()) {
937199990Srdivacky  ///   case 0: break;
938199990Srdivacky  ///   // ...
939199990Srdivacky  /// }
940199990Srdivacky  /// \endcode
941210299Sed  VarDecl *getConditionVariable() const;
942263508Sdim  void setConditionVariable(const ASTContext &C, VarDecl *V);
943234353Sdim
944221345Sdim  /// If this SwitchStmt has a condition variable, return the faux DeclStmt
945221345Sdim  /// associated with the creation of that condition variable.
946221345Sdim  const DeclStmt *getConditionVariableDeclStmt() const {
947221345Sdim    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
948221345Sdim  }
949199990Srdivacky
950193326Sed  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
951193326Sed  const Stmt *getBody() const { return SubExprs[BODY]; }
952193326Sed  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
953193326Sed
954193326Sed  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
955193326Sed  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
956193326Sed  Stmt *getBody() { return SubExprs[BODY]; }
957193326Sed  void setBody(Stmt *S) { SubExprs[BODY] = S; }
958193326Sed  SwitchCase *getSwitchCaseList() { return FirstCase; }
959198092Srdivacky
960198092Srdivacky  /// \brief Set the case list for this switch statement.
961193326Sed  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
962193326Sed
963193326Sed  SourceLocation getSwitchLoc() const { return SwitchLoc; }
964193326Sed  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
965193326Sed
966198092Srdivacky  void setBody(Stmt *S, SourceLocation SL) {
967198092Srdivacky    SubExprs[BODY] = S;
968193326Sed    SwitchLoc = SL;
969198092Srdivacky  }
970193326Sed  void addSwitchCase(SwitchCase *SC) {
971234353Sdim    assert(!SC->getNextSwitchCase()
972234353Sdim           && "case/default already added to a switch");
973193326Sed    SC->setNextSwitchCase(FirstCase);
974193326Sed    FirstCase = SC;
975193326Sed  }
976218893Sdim
977218893Sdim  /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
978218893Sdim  /// switch over an enum value then all cases have been explicitly covered.
979218893Sdim  void setAllEnumCasesCovered() {
980218893Sdim    AllEnumCasesCovered = 1;
981218893Sdim  }
982218893Sdim
983218893Sdim  /// Returns true if the SwitchStmt is a switch of an enum value and all cases
984218893Sdim  /// have been explicitly covered.
985218893Sdim  bool isAllEnumCasesCovered() const {
986218893Sdim    return (bool) AllEnumCasesCovered;
987218893Sdim  }
988218893Sdim
989249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; }
990249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
991249423Sdim    return SubExprs[BODY]->getLocEnd();
992193326Sed  }
993249423Sdim
994218893Sdim  // Iterators
995218893Sdim  child_range children() {
996218893Sdim    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
997218893Sdim  }
998218893Sdim
999198092Srdivacky  static bool classof(const Stmt *T) {
1000198092Srdivacky    return T->getStmtClass() == SwitchStmtClass;
1001193326Sed  }
1002193326Sed};
1003193326Sed
1004193326Sed
1005193326Sed/// WhileStmt - This represents a 'while' stmt.
1006193326Sed///
1007193326Sedclass WhileStmt : public Stmt {
1008210299Sed  enum { VAR, COND, BODY, END_EXPR };
1009193326Sed  Stmt* SubExprs[END_EXPR];
1010193326Sed  SourceLocation WhileLoc;
1011193326Sedpublic:
1012263508Sdim  WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
1013210299Sed            SourceLocation WL);
1014198092Srdivacky
1015193326Sed  /// \brief Build an empty while statement.
1016193326Sed  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
1017193326Sed
1018199990Srdivacky  /// \brief Retrieve the variable declared in this "while" statement, if any.
1019199990Srdivacky  ///
1020199990Srdivacky  /// In the following example, "x" is the condition variable.
1021199990Srdivacky  /// \code
1022199990Srdivacky  /// while (int x = random()) {
1023199990Srdivacky  ///   // ...
1024199990Srdivacky  /// }
1025199990Srdivacky  /// \endcode
1026210299Sed  VarDecl *getConditionVariable() const;
1027263508Sdim  void setConditionVariable(const ASTContext &C, VarDecl *V);
1028199990Srdivacky
1029221345Sdim  /// If this WhileStmt has a condition variable, return the faux DeclStmt
1030221345Sdim  /// associated with the creation of that condition variable.
1031221345Sdim  const DeclStmt *getConditionVariableDeclStmt() const {
1032221345Sdim    return reinterpret_cast<DeclStmt*>(SubExprs[VAR]);
1033221345Sdim  }
1034221345Sdim
1035193326Sed  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
1036193326Sed  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
1037193326Sed  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
1038193326Sed  Stmt *getBody() { return SubExprs[BODY]; }
1039193326Sed  const Stmt *getBody() const { return SubExprs[BODY]; }
1040193326Sed  void setBody(Stmt *S) { SubExprs[BODY] = S; }
1041193326Sed
1042193326Sed  SourceLocation getWhileLoc() const { return WhileLoc; }
1043193326Sed  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
1044193326Sed
1045249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return WhileLoc; }
1046249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
1047249423Sdim    return SubExprs[BODY]->getLocEnd();
1048193326Sed  }
1049249423Sdim
1050198092Srdivacky  static bool classof(const Stmt *T) {
1051198092Srdivacky    return T->getStmtClass() == WhileStmtClass;
1052193326Sed  }
1053198092Srdivacky
1054193326Sed  // Iterators
1055218893Sdim  child_range children() {
1056218893Sdim    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1057218893Sdim  }
1058193326Sed};
1059193326Sed
1060193326Sed/// DoStmt - This represents a 'do/while' stmt.
1061193326Sed///
1062193326Sedclass DoStmt : public Stmt {
1063218893Sdim  enum { BODY, COND, END_EXPR };
1064193326Sed  Stmt* SubExprs[END_EXPR];
1065193326Sed  SourceLocation DoLoc;
1066193326Sed  SourceLocation WhileLoc;
1067194179Sed  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
1068193326Sed
1069193326Sedpublic:
1070194179Sed  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
1071194179Sed         SourceLocation RP)
1072194179Sed    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
1073193326Sed    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
1074193326Sed    SubExprs[BODY] = body;
1075198092Srdivacky  }
1076193326Sed
1077193326Sed  /// \brief Build an empty do-while statement.
1078193326Sed  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
1079198092Srdivacky
1080193326Sed  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
1081193326Sed  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
1082193326Sed  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
1083193326Sed  Stmt *getBody() { return SubExprs[BODY]; }
1084198092Srdivacky  const Stmt *getBody() const { return SubExprs[BODY]; }
1085193326Sed  void setBody(Stmt *S) { SubExprs[BODY] = S; }
1086193326Sed
1087193326Sed  SourceLocation getDoLoc() const { return DoLoc; }
1088193326Sed  void setDoLoc(SourceLocation L) { DoLoc = L; }
1089193326Sed  SourceLocation getWhileLoc() const { return WhileLoc; }
1090193326Sed  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
1091193326Sed
1092194179Sed  SourceLocation getRParenLoc() const { return RParenLoc; }
1093194179Sed  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1094194179Sed
1095249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return DoLoc; }
1096249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
1097249423Sdim
1098198092Srdivacky  static bool classof(const Stmt *T) {
1099198092Srdivacky    return T->getStmtClass() == DoStmtClass;
1100193326Sed  }
1101193326Sed
1102193326Sed  // Iterators
1103218893Sdim  child_range children() {
1104218893Sdim    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1105218893Sdim  }
1106193326Sed};
1107193326Sed
1108193326Sed
1109193326Sed/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
1110193326Sed/// the init/cond/inc parts of the ForStmt will be null if they were not
1111193326Sed/// specified in the source.
1112193326Sed///
1113193326Sedclass ForStmt : public Stmt {
1114210299Sed  enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
1115193326Sed  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
1116193326Sed  SourceLocation ForLoc;
1117193326Sed  SourceLocation LParenLoc, RParenLoc;
1118193326Sed
1119193326Sedpublic:
1120263508Sdim  ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
1121263508Sdim          Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
1122263508Sdim          SourceLocation RP);
1123198092Srdivacky
1124193326Sed  /// \brief Build an empty for statement.
1125193326Sed  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
1126193326Sed
1127193326Sed  Stmt *getInit() { return SubExprs[INIT]; }
1128234353Sdim
1129199990Srdivacky  /// \brief Retrieve the variable declared in this "for" statement, if any.
1130199990Srdivacky  ///
1131199990Srdivacky  /// In the following example, "y" is the condition variable.
1132199990Srdivacky  /// \code
1133199990Srdivacky  /// for (int x = random(); int y = mangle(x); ++x) {
1134199990Srdivacky  ///   // ...
1135199990Srdivacky  /// }
1136199990Srdivacky  /// \endcode
1137210299Sed  VarDecl *getConditionVariable() const;
1138263508Sdim  void setConditionVariable(const ASTContext &C, VarDecl *V);
1139234353Sdim
1140221345Sdim  /// If this ForStmt has a condition variable, return the faux DeclStmt
1141221345Sdim  /// associated with the creation of that condition variable.
1142221345Sdim  const DeclStmt *getConditionVariableDeclStmt() const {
1143221345Sdim    return reinterpret_cast<DeclStmt*>(SubExprs[CONDVAR]);
1144221345Sdim  }
1145221345Sdim
1146193326Sed  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
1147193326Sed  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
1148193326Sed  Stmt *getBody() { return SubExprs[BODY]; }
1149193326Sed
1150193326Sed  const Stmt *getInit() const { return SubExprs[INIT]; }
1151193326Sed  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
1152193326Sed  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
1153193326Sed  const Stmt *getBody() const { return SubExprs[BODY]; }
1154193326Sed
1155193326Sed  void setInit(Stmt *S) { SubExprs[INIT] = S; }
1156193326Sed  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
1157193326Sed  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
1158193326Sed  void setBody(Stmt *S) { SubExprs[BODY] = S; }
1159193326Sed
1160193326Sed  SourceLocation getForLoc() const { return ForLoc; }
1161193326Sed  void setForLoc(SourceLocation L) { ForLoc = L; }
1162193326Sed  SourceLocation getLParenLoc() const { return LParenLoc; }
1163193326Sed  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
1164193326Sed  SourceLocation getRParenLoc() const { return RParenLoc; }
1165193326Sed  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1166193326Sed
1167249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
1168249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
1169249423Sdim    return SubExprs[BODY]->getLocEnd();
1170193326Sed  }
1171249423Sdim
1172198092Srdivacky  static bool classof(const Stmt *T) {
1173198092Srdivacky    return T->getStmtClass() == ForStmtClass;
1174193326Sed  }
1175198092Srdivacky
1176193326Sed  // Iterators
1177218893Sdim  child_range children() {
1178218893Sdim    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
1179218893Sdim  }
1180193326Sed};
1181198092Srdivacky
1182193326Sed/// GotoStmt - This represents a direct goto.
1183193326Sed///
1184193326Sedclass GotoStmt : public Stmt {
1185218893Sdim  LabelDecl *Label;
1186193326Sed  SourceLocation GotoLoc;
1187193326Sed  SourceLocation LabelLoc;
1188193326Sedpublic:
1189218893Sdim  GotoStmt(LabelDecl *label, SourceLocation GL, SourceLocation LL)
1190193326Sed    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
1191198092Srdivacky
1192193326Sed  /// \brief Build an empty goto statement.
1193193326Sed  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
1194193326Sed
1195218893Sdim  LabelDecl *getLabel() const { return Label; }
1196218893Sdim  void setLabel(LabelDecl *D) { Label = D; }
1197193326Sed
1198193326Sed  SourceLocation getGotoLoc() const { return GotoLoc; }
1199193326Sed  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
1200193326Sed  SourceLocation getLabelLoc() const { return LabelLoc; }
1201193326Sed  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
1202193326Sed
1203249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
1204249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return LabelLoc; }
1205249423Sdim
1206198092Srdivacky  static bool classof(const Stmt *T) {
1207198092Srdivacky    return T->getStmtClass() == GotoStmtClass;
1208193326Sed  }
1209198092Srdivacky
1210193326Sed  // Iterators
1211218893Sdim  child_range children() { return child_range(); }
1212193326Sed};
1213193326Sed
1214193326Sed/// IndirectGotoStmt - This represents an indirect goto.
1215193326Sed///
1216193326Sedclass IndirectGotoStmt : public Stmt {
1217193326Sed  SourceLocation GotoLoc;
1218193326Sed  SourceLocation StarLoc;
1219193326Sed  Stmt *Target;
1220193326Sedpublic:
1221198092Srdivacky  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
1222193326Sed                   Expr *target)
1223193326Sed    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
1224193326Sed      Target((Stmt*)target) {}
1225193326Sed
1226193326Sed  /// \brief Build an empty indirect goto statement.
1227198092Srdivacky  explicit IndirectGotoStmt(EmptyShell Empty)
1228193326Sed    : Stmt(IndirectGotoStmtClass, Empty) { }
1229198092Srdivacky
1230193326Sed  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
1231193326Sed  SourceLocation getGotoLoc() const { return GotoLoc; }
1232193326Sed  void setStarLoc(SourceLocation L) { StarLoc = L; }
1233193326Sed  SourceLocation getStarLoc() const { return StarLoc; }
1234198092Srdivacky
1235218893Sdim  Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
1236218893Sdim  const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
1237193326Sed  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
1238193326Sed
1239218893Sdim  /// getConstantTarget - Returns the fixed target of this indirect
1240218893Sdim  /// goto, if one exists.
1241218893Sdim  LabelDecl *getConstantTarget();
1242218893Sdim  const LabelDecl *getConstantTarget() const {
1243218893Sdim    return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
1244218893Sdim  }
1245218893Sdim
1246249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return GotoLoc; }
1247249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return Target->getLocEnd(); }
1248198092Srdivacky
1249198092Srdivacky  static bool classof(const Stmt *T) {
1250198092Srdivacky    return T->getStmtClass() == IndirectGotoStmtClass;
1251193326Sed  }
1252198092Srdivacky
1253193326Sed  // Iterators
1254218893Sdim  child_range children() { return child_range(&Target, &Target+1); }
1255193326Sed};
1256193326Sed
1257193326Sed
1258193326Sed/// ContinueStmt - This represents a continue.
1259193326Sed///
1260193326Sedclass ContinueStmt : public Stmt {
1261193326Sed  SourceLocation ContinueLoc;
1262193326Sedpublic:
1263193326Sed  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
1264198092Srdivacky
1265193326Sed  /// \brief Build an empty continue statement.
1266193326Sed  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
1267193326Sed
1268193326Sed  SourceLocation getContinueLoc() const { return ContinueLoc; }
1269193326Sed  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
1270193326Sed
1271249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return ContinueLoc; }
1272249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return ContinueLoc; }
1273193326Sed
1274198092Srdivacky  static bool classof(const Stmt *T) {
1275198092Srdivacky    return T->getStmtClass() == ContinueStmtClass;
1276193326Sed  }
1277198092Srdivacky
1278193326Sed  // Iterators
1279218893Sdim  child_range children() { return child_range(); }
1280193326Sed};
1281193326Sed
1282193326Sed/// BreakStmt - This represents a break.
1283193326Sed///
1284193326Sedclass BreakStmt : public Stmt {
1285193326Sed  SourceLocation BreakLoc;
1286193326Sedpublic:
1287193326Sed  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
1288198092Srdivacky
1289193326Sed  /// \brief Build an empty break statement.
1290193326Sed  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
1291193326Sed
1292193326Sed  SourceLocation getBreakLoc() const { return BreakLoc; }
1293193326Sed  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
1294193326Sed
1295249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return BreakLoc; }
1296249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return BreakLoc; }
1297193326Sed
1298198092Srdivacky  static bool classof(const Stmt *T) {
1299198092Srdivacky    return T->getStmtClass() == BreakStmtClass;
1300193326Sed  }
1301198092Srdivacky
1302193326Sed  // Iterators
1303218893Sdim  child_range children() { return child_range(); }
1304193326Sed};
1305193326Sed
1306193326Sed
1307193326Sed/// ReturnStmt - This represents a return, optionally of an expression:
1308193326Sed///   return;
1309193326Sed///   return 4;
1310193326Sed///
1311193326Sed/// Note that GCC allows return with no argument in a function declared to
1312193326Sed/// return a value, and it allows returning a value in functions declared to
1313193326Sed/// return void.  We explicitly model this in the AST, which means you can't
1314193326Sed/// depend on the return type of the function and the presence of an argument.
1315193326Sed///
1316193326Sedclass ReturnStmt : public Stmt {
1317193326Sed  Stmt *RetExpr;
1318193326Sed  SourceLocation RetLoc;
1319208600Srdivacky  const VarDecl *NRVOCandidate;
1320234353Sdim
1321193326Sedpublic:
1322208600Srdivacky  ReturnStmt(SourceLocation RL)
1323208600Srdivacky    : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
1324193326Sed
1325208600Srdivacky  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1326208600Srdivacky    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
1327208600Srdivacky      NRVOCandidate(NRVOCandidate) {}
1328208600Srdivacky
1329193326Sed  /// \brief Build an empty return expression.
1330193326Sed  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
1331193326Sed
1332193326Sed  const Expr *getRetValue() const;
1333193326Sed  Expr *getRetValue();
1334193326Sed  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
1335193326Sed
1336193326Sed  SourceLocation getReturnLoc() const { return RetLoc; }
1337193326Sed  void setReturnLoc(SourceLocation L) { RetLoc = L; }
1338193326Sed
1339208600Srdivacky  /// \brief Retrieve the variable that might be used for the named return
1340208600Srdivacky  /// value optimization.
1341208600Srdivacky  ///
1342208600Srdivacky  /// The optimization itself can only be performed if the variable is
1343208600Srdivacky  /// also marked as an NRVO object.
1344208600Srdivacky  const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
1345208600Srdivacky  void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
1346198092Srdivacky
1347249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return RetLoc; }
1348249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
1349249423Sdim    return RetExpr ? RetExpr->getLocEnd() : RetLoc;
1350249423Sdim  }
1351234353Sdim
1352198092Srdivacky  static bool classof(const Stmt *T) {
1353198092Srdivacky    return T->getStmtClass() == ReturnStmtClass;
1354193326Sed  }
1355198092Srdivacky
1356193326Sed  // Iterators
1357218893Sdim  child_range children() {
1358218893Sdim    if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
1359218893Sdim    return child_range();
1360218893Sdim  }
1361193326Sed};
1362193326Sed
1363243830Sdim/// AsmStmt is the base class for GCCAsmStmt and MSAsmStmt.
1364193326Sed///
1365193326Sedclass AsmStmt : public Stmt {
1366243830Sdimprotected:
1367243830Sdim  SourceLocation AsmLoc;
1368243830Sdim  /// \brief True if the assembly statement does not have any input or output
1369243830Sdim  /// operands.
1370243830Sdim  bool IsSimple;
1371193326Sed
1372243830Sdim  /// \brief If true, treat this inline assembly as having side effects.
1373243830Sdim  /// This assembly statement should not be optimized, deleted or moved.
1374193326Sed  bool IsVolatile;
1375198092Srdivacky
1376193326Sed  unsigned NumOutputs;
1377193326Sed  unsigned NumInputs;
1378203955Srdivacky  unsigned NumClobbers;
1379198092Srdivacky
1380203955Srdivacky  Stmt **Exprs;
1381234353Sdim
1382243830Sdim  AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile,
1383243830Sdim          unsigned numoutputs, unsigned numinputs, unsigned numclobbers) :
1384243830Sdim    Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile),
1385243830Sdim    NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { }
1386243830Sdim
1387251662Sdim  friend class ASTStmtReader;
1388251662Sdim
1389193326Sedpublic:
1390193326Sed  /// \brief Build an empty inline-assembly statement.
1391243830Sdim  explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
1392251662Sdim    Stmt(SC, Empty), Exprs(0) { }
1393193326Sed
1394193326Sed  SourceLocation getAsmLoc() const { return AsmLoc; }
1395193326Sed  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1396193326Sed
1397193326Sed  bool isSimple() const { return IsSimple; }
1398202379Srdivacky  void setSimple(bool V) { IsSimple = V; }
1399193326Sed
1400243830Sdim  bool isVolatile() const { return IsVolatile; }
1401243830Sdim  void setVolatile(bool V) { IsVolatile = V; }
1402243830Sdim
1403249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
1404249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
1405243830Sdim
1406193326Sed  //===--- Asm String Analysis ---===//
1407193326Sed
1408243830Sdim  /// Assemble final IR asm string.
1409263508Sdim  std::string generateAsmString(const ASTContext &C) const;
1410243830Sdim
1411243830Sdim  //===--- Output operands ---===//
1412243830Sdim
1413243830Sdim  unsigned getNumOutputs() const { return NumOutputs; }
1414243830Sdim
1415243830Sdim  /// getOutputConstraint - Return the constraint string for the specified
1416243830Sdim  /// output operand.  All output constraints are known to be non-empty (either
1417243830Sdim  /// '=' or '+').
1418243830Sdim  StringRef getOutputConstraint(unsigned i) const;
1419243830Sdim
1420243830Sdim  /// isOutputPlusConstraint - Return true if the specified output constraint
1421243830Sdim  /// is a "+" constraint (which is both an input and an output) or false if it
1422243830Sdim  /// is an "=" constraint (just an output).
1423243830Sdim  bool isOutputPlusConstraint(unsigned i) const {
1424243830Sdim    return getOutputConstraint(i)[0] == '+';
1425243830Sdim  }
1426243830Sdim
1427243830Sdim  const Expr *getOutputExpr(unsigned i) const;
1428243830Sdim
1429243830Sdim  /// getNumPlusOperands - Return the number of output operands that have a "+"
1430243830Sdim  /// constraint.
1431243830Sdim  unsigned getNumPlusOperands() const;
1432243830Sdim
1433243830Sdim  //===--- Input operands ---===//
1434243830Sdim
1435243830Sdim  unsigned getNumInputs() const { return NumInputs; }
1436243830Sdim
1437243830Sdim  /// getInputConstraint - Return the specified input constraint.  Unlike output
1438243830Sdim  /// constraints, these can be empty.
1439243830Sdim  StringRef getInputConstraint(unsigned i) const;
1440243830Sdim
1441243830Sdim  const Expr *getInputExpr(unsigned i) const;
1442243830Sdim
1443243830Sdim  //===--- Other ---===//
1444243830Sdim
1445243830Sdim  unsigned getNumClobbers() const { return NumClobbers; }
1446243830Sdim  StringRef getClobber(unsigned i) const;
1447243830Sdim
1448243830Sdim  static bool classof(const Stmt *T) {
1449243830Sdim    return T->getStmtClass() == GCCAsmStmtClass ||
1450243830Sdim      T->getStmtClass() == MSAsmStmtClass;
1451243830Sdim  }
1452243830Sdim
1453243830Sdim  // Input expr iterators.
1454243830Sdim
1455243830Sdim  typedef ExprIterator inputs_iterator;
1456243830Sdim  typedef ConstExprIterator const_inputs_iterator;
1457243830Sdim
1458243830Sdim  inputs_iterator begin_inputs() {
1459243830Sdim    return &Exprs[0] + NumOutputs;
1460243830Sdim  }
1461243830Sdim
1462243830Sdim  inputs_iterator end_inputs() {
1463243830Sdim    return &Exprs[0] + NumOutputs + NumInputs;
1464243830Sdim  }
1465243830Sdim
1466243830Sdim  const_inputs_iterator begin_inputs() const {
1467243830Sdim    return &Exprs[0] + NumOutputs;
1468243830Sdim  }
1469243830Sdim
1470243830Sdim  const_inputs_iterator end_inputs() const {
1471243830Sdim    return &Exprs[0] + NumOutputs + NumInputs;
1472243830Sdim  }
1473243830Sdim
1474243830Sdim  // Output expr iterators.
1475243830Sdim
1476243830Sdim  typedef ExprIterator outputs_iterator;
1477243830Sdim  typedef ConstExprIterator const_outputs_iterator;
1478243830Sdim
1479243830Sdim  outputs_iterator begin_outputs() {
1480243830Sdim    return &Exprs[0];
1481243830Sdim  }
1482243830Sdim  outputs_iterator end_outputs() {
1483243830Sdim    return &Exprs[0] + NumOutputs;
1484243830Sdim  }
1485243830Sdim
1486243830Sdim  const_outputs_iterator begin_outputs() const {
1487243830Sdim    return &Exprs[0];
1488243830Sdim  }
1489243830Sdim  const_outputs_iterator end_outputs() const {
1490243830Sdim    return &Exprs[0] + NumOutputs;
1491243830Sdim  }
1492243830Sdim
1493243830Sdim  child_range children() {
1494243830Sdim    return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
1495243830Sdim  }
1496243830Sdim};
1497243830Sdim
1498243830Sdim/// This represents a GCC inline-assembly statement extension.
1499243830Sdim///
1500243830Sdimclass GCCAsmStmt : public AsmStmt {
1501243830Sdim  SourceLocation RParenLoc;
1502243830Sdim  StringLiteral *AsmStr;
1503243830Sdim
1504243830Sdim  // FIXME: If we wanted to, we could allocate all of these in one big array.
1505243830Sdim  StringLiteral **Constraints;
1506243830Sdim  StringLiteral **Clobbers;
1507251662Sdim  IdentifierInfo **Names;
1508243830Sdim
1509251662Sdim  friend class ASTStmtReader;
1510251662Sdim
1511243830Sdimpublic:
1512263508Sdim  GCCAsmStmt(const ASTContext &C, SourceLocation asmloc, bool issimple,
1513243830Sdim             bool isvolatile, unsigned numoutputs, unsigned numinputs,
1514243830Sdim             IdentifierInfo **names, StringLiteral **constraints, Expr **exprs,
1515243830Sdim             StringLiteral *asmstr, unsigned numclobbers,
1516243830Sdim             StringLiteral **clobbers, SourceLocation rparenloc);
1517243830Sdim
1518243830Sdim  /// \brief Build an empty inline-assembly statement.
1519243830Sdim  explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
1520251662Sdim    Constraints(0), Clobbers(0), Names(0) { }
1521243830Sdim
1522243830Sdim  SourceLocation getRParenLoc() const { return RParenLoc; }
1523243830Sdim  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1524243830Sdim
1525243830Sdim  //===--- Asm String Analysis ---===//
1526243830Sdim
1527193326Sed  const StringLiteral *getAsmString() const { return AsmStr; }
1528193326Sed  StringLiteral *getAsmString() { return AsmStr; }
1529193326Sed  void setAsmString(StringLiteral *E) { AsmStr = E; }
1530193326Sed
1531193326Sed  /// AsmStringPiece - this is part of a decomposed asm string specification
1532193326Sed  /// (for use with the AnalyzeAsmString function below).  An asm string is
1533193326Sed  /// considered to be a concatenation of these parts.
1534193326Sed  class AsmStringPiece {
1535193326Sed  public:
1536193326Sed    enum Kind {
1537193326Sed      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1538193326Sed      Operand  // Operand reference, with optional modifier %c4.
1539193326Sed    };
1540193326Sed  private:
1541193326Sed    Kind MyKind;
1542193326Sed    std::string Str;
1543193326Sed    unsigned OperandNo;
1544193326Sed  public:
1545193326Sed    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
1546193326Sed    AsmStringPiece(unsigned OpNo, char Modifier)
1547193326Sed      : MyKind(Operand), Str(), OperandNo(OpNo) {
1548193326Sed      Str += Modifier;
1549193326Sed    }
1550198092Srdivacky
1551193326Sed    bool isString() const { return MyKind == String; }
1552193326Sed    bool isOperand() const { return MyKind == Operand; }
1553198092Srdivacky
1554193326Sed    const std::string &getString() const {
1555193326Sed      assert(isString());
1556193326Sed      return Str;
1557193326Sed    }
1558193326Sed
1559193326Sed    unsigned getOperandNo() const {
1560193326Sed      assert(isOperand());
1561193326Sed      return OperandNo;
1562193326Sed    }
1563198092Srdivacky
1564193326Sed    /// getModifier - Get the modifier for this operand, if present.  This
1565193326Sed    /// returns '\0' if there was no modifier.
1566193326Sed    char getModifier() const {
1567193326Sed      assert(isOperand());
1568193326Sed      return Str[0];
1569193326Sed    }
1570193326Sed  };
1571198092Srdivacky
1572193326Sed  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1573193326Sed  /// it into pieces.  If the asm string is erroneous, emit errors and return
1574193326Sed  /// true, otherwise return false.  This handles canonicalization and
1575193326Sed  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1576198092Srdivacky  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1577226633Sdim  unsigned AnalyzeAsmString(SmallVectorImpl<AsmStringPiece> &Pieces,
1578263508Sdim                            const ASTContext &C, unsigned &DiagOffs) const;
1579198092Srdivacky
1580243830Sdim  /// Assemble final IR asm string.
1581263508Sdim  std::string generateAsmString(const ASTContext &C) const;
1582198092Srdivacky
1583193326Sed  //===--- Output operands ---===//
1584193326Sed
1585251662Sdim  IdentifierInfo *getOutputIdentifier(unsigned i) const {
1586251662Sdim    return Names[i];
1587251662Sdim  }
1588251662Sdim
1589251662Sdim  StringRef getOutputName(unsigned i) const {
1590251662Sdim    if (IdentifierInfo *II = getOutputIdentifier(i))
1591251662Sdim      return II->getName();
1592251662Sdim
1593251662Sdim    return StringRef();
1594251662Sdim  }
1595251662Sdim
1596226633Sdim  StringRef getOutputConstraint(unsigned i) const;
1597198092Srdivacky
1598193326Sed  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1599193326Sed    return Constraints[i];
1600193326Sed  }
1601193326Sed  StringLiteral *getOutputConstraintLiteral(unsigned i) {
1602193326Sed    return Constraints[i];
1603193326Sed  }
1604198092Srdivacky
1605193326Sed  Expr *getOutputExpr(unsigned i);
1606198092Srdivacky
1607193326Sed  const Expr *getOutputExpr(unsigned i) const {
1608243830Sdim    return const_cast<GCCAsmStmt*>(this)->getOutputExpr(i);
1609193326Sed  }
1610198092Srdivacky
1611193326Sed  //===--- Input operands ---===//
1612198092Srdivacky
1613251662Sdim  IdentifierInfo *getInputIdentifier(unsigned i) const {
1614251662Sdim    return Names[i + NumOutputs];
1615251662Sdim  }
1616251662Sdim
1617251662Sdim  StringRef getInputName(unsigned i) const {
1618251662Sdim    if (IdentifierInfo *II = getInputIdentifier(i))
1619251662Sdim      return II->getName();
1620251662Sdim
1621251662Sdim    return StringRef();
1622251662Sdim  }
1623251662Sdim
1624226633Sdim  StringRef getInputConstraint(unsigned i) const;
1625198092Srdivacky
1626193326Sed  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1627193326Sed    return Constraints[i + NumOutputs];
1628193326Sed  }
1629193326Sed  StringLiteral *getInputConstraintLiteral(unsigned i) {
1630193326Sed    return Constraints[i + NumOutputs];
1631193326Sed  }
1632198092Srdivacky
1633193326Sed  Expr *getInputExpr(unsigned i);
1634219077Sdim  void setInputExpr(unsigned i, Expr *E);
1635234353Sdim
1636193326Sed  const Expr *getInputExpr(unsigned i) const {
1637243830Sdim    return const_cast<GCCAsmStmt*>(this)->getInputExpr(i);
1638193326Sed  }
1639193326Sed
1640251662Sdimprivate:
1641263508Sdim  void setOutputsAndInputsAndClobbers(const ASTContext &C,
1642203955Srdivacky                                      IdentifierInfo **Names,
1643203955Srdivacky                                      StringLiteral **Constraints,
1644203955Srdivacky                                      Stmt **Exprs,
1645203955Srdivacky                                      unsigned NumOutputs,
1646234353Sdim                                      unsigned NumInputs,
1647203955Srdivacky                                      StringLiteral **Clobbers,
1648203955Srdivacky                                      unsigned NumClobbers);
1649251662Sdimpublic:
1650193326Sed
1651193326Sed  //===--- Other ---===//
1652198092Srdivacky
1653193326Sed  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1654193326Sed  /// translate this into a numeric value needed to reference the same operand.
1655193326Sed  /// This returns -1 if the operand name is invalid.
1656226633Sdim  int getNamedOperand(StringRef SymbolicName) const;
1657193326Sed
1658243830Sdim  StringRef getClobber(unsigned i) const;
1659243830Sdim  StringLiteral *getClobberStringLiteral(unsigned i) { return Clobbers[i]; }
1660243830Sdim  const StringLiteral *getClobberStringLiteral(unsigned i) const {
1661243830Sdim    return Clobbers[i];
1662243830Sdim  }
1663193326Sed
1664249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
1665249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; }
1666198092Srdivacky
1667243830Sdim  static bool classof(const Stmt *T) {
1668243830Sdim    return T->getStmtClass() == GCCAsmStmtClass;
1669193326Sed  }
1670193326Sed};
1671193326Sed
1672243830Sdim/// This represents a Microsoft inline-assembly statement extension.
1673239462Sdim///
1674243830Sdimclass MSAsmStmt : public AsmStmt {
1675249423Sdim  SourceLocation LBraceLoc, EndLoc;
1676251662Sdim  StringRef AsmStr;
1677239462Sdim
1678239462Sdim  unsigned NumAsmToks;
1679239462Sdim
1680239462Sdim  Token *AsmToks;
1681243830Sdim  StringRef *Constraints;
1682239462Sdim  StringRef *Clobbers;
1683239462Sdim
1684251662Sdim  friend class ASTStmtReader;
1685251662Sdim
1686239462Sdimpublic:
1687263508Sdim  MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
1688263508Sdim            SourceLocation lbraceloc, bool issimple, bool isvolatile,
1689263508Sdim            ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs,
1690251662Sdim            ArrayRef<StringRef> constraints,
1691243830Sdim            ArrayRef<Expr*> exprs, StringRef asmstr,
1692243830Sdim            ArrayRef<StringRef> clobbers, SourceLocation endloc);
1693239462Sdim
1694243830Sdim  /// \brief Build an empty MS-style inline-assembly statement.
1695243830Sdim  explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
1696243830Sdim    NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { }
1697243830Sdim
1698239462Sdim  SourceLocation getLBraceLoc() const { return LBraceLoc; }
1699239462Sdim  void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
1700239462Sdim  SourceLocation getEndLoc() const { return EndLoc; }
1701239462Sdim  void setEndLoc(SourceLocation L) { EndLoc = L; }
1702239462Sdim
1703239462Sdim  bool hasBraces() const { return LBraceLoc.isValid(); }
1704239462Sdim
1705239462Sdim  unsigned getNumAsmToks() { return NumAsmToks; }
1706239462Sdim  Token *getAsmToks() { return AsmToks; }
1707239462Sdim
1708239462Sdim  //===--- Asm String Analysis ---===//
1709251662Sdim  StringRef getAsmString() const { return AsmStr; }
1710239462Sdim
1711243830Sdim  /// Assemble final IR asm string.
1712263508Sdim  std::string generateAsmString(const ASTContext &C) const;
1713243830Sdim
1714243830Sdim  //===--- Output operands ---===//
1715243830Sdim
1716243830Sdim  StringRef getOutputConstraint(unsigned i) const {
1717251662Sdim    assert(i < NumOutputs);
1718243830Sdim    return Constraints[i];
1719243830Sdim  }
1720243830Sdim
1721243830Sdim  Expr *getOutputExpr(unsigned i);
1722243830Sdim
1723243830Sdim  const Expr *getOutputExpr(unsigned i) const {
1724243830Sdim    return const_cast<MSAsmStmt*>(this)->getOutputExpr(i);
1725243830Sdim  }
1726243830Sdim
1727243830Sdim  //===--- Input operands ---===//
1728243830Sdim
1729243830Sdim  StringRef getInputConstraint(unsigned i) const {
1730251662Sdim    assert(i < NumInputs);
1731243830Sdim    return Constraints[i + NumOutputs];
1732243830Sdim  }
1733243830Sdim
1734243830Sdim  Expr *getInputExpr(unsigned i);
1735243830Sdim  void setInputExpr(unsigned i, Expr *E);
1736243830Sdim
1737243830Sdim  const Expr *getInputExpr(unsigned i) const {
1738243830Sdim    return const_cast<MSAsmStmt*>(this)->getInputExpr(i);
1739243830Sdim  }
1740243830Sdim
1741239462Sdim  //===--- Other ---===//
1742239462Sdim
1743251662Sdim  ArrayRef<StringRef> getAllConstraints() const {
1744251662Sdim    return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs);
1745251662Sdim  }
1746251662Sdim  ArrayRef<StringRef> getClobbers() const {
1747251662Sdim    return ArrayRef<StringRef>(Clobbers, NumClobbers);
1748251662Sdim  }
1749251662Sdim  ArrayRef<Expr*> getAllExprs() const {
1750251662Sdim    return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs),
1751251662Sdim                           NumInputs + NumOutputs);
1752251662Sdim  }
1753239462Sdim
1754251662Sdim  StringRef getClobber(unsigned i) const { return getClobbers()[i]; }
1755251662Sdim
1756251662Sdimprivate:
1757263508Sdim  void initialize(const ASTContext &C, StringRef AsmString,
1758263508Sdim                  ArrayRef<Token> AsmToks, ArrayRef<StringRef> Constraints,
1759263508Sdim                  ArrayRef<Expr*> Exprs, ArrayRef<StringRef> Clobbers);
1760251662Sdimpublic:
1761251662Sdim
1762249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; }
1763249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
1764249423Sdim
1765239462Sdim  static bool classof(const Stmt *T) {
1766239462Sdim    return T->getStmtClass() == MSAsmStmtClass;
1767239462Sdim  }
1768239462Sdim
1769239462Sdim  child_range children() {
1770239462Sdim    return child_range(&Exprs[0], &Exprs[0]);
1771239462Sdim  }
1772239462Sdim};
1773239462Sdim
1774221345Sdimclass SEHExceptStmt : public Stmt {
1775221345Sdim  SourceLocation  Loc;
1776221345Sdim  Stmt           *Children[2];
1777221345Sdim
1778221345Sdim  enum { FILTER_EXPR, BLOCK };
1779221345Sdim
1780221345Sdim  SEHExceptStmt(SourceLocation Loc,
1781221345Sdim                Expr *FilterExpr,
1782221345Sdim                Stmt *Block);
1783221345Sdim
1784224145Sdim  friend class ASTReader;
1785224145Sdim  friend class ASTStmtReader;
1786224145Sdim  explicit SEHExceptStmt(EmptyShell E) : Stmt(SEHExceptStmtClass, E) { }
1787224145Sdim
1788221345Sdimpublic:
1789263508Sdim  static SEHExceptStmt* Create(const ASTContext &C,
1790221345Sdim                               SourceLocation ExceptLoc,
1791221345Sdim                               Expr *FilterExpr,
1792221345Sdim                               Stmt *Block);
1793221345Sdim
1794249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return getExceptLoc(); }
1795249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1796249423Sdim
1797221345Sdim  SourceLocation getExceptLoc() const { return Loc; }
1798221345Sdim  SourceLocation getEndLoc() const { return getBlock()->getLocEnd(); }
1799221345Sdim
1800234353Sdim  Expr *getFilterExpr() const {
1801234353Sdim    return reinterpret_cast<Expr*>(Children[FILTER_EXPR]);
1802234353Sdim  }
1803221345Sdim
1804234353Sdim  CompoundStmt *getBlock() const {
1805249423Sdim    return cast<CompoundStmt>(Children[BLOCK]);
1806234353Sdim  }
1807234353Sdim
1808221345Sdim  child_range children() {
1809221345Sdim    return child_range(Children,Children+2);
1810221345Sdim  }
1811221345Sdim
1812221345Sdim  static bool classof(const Stmt *T) {
1813221345Sdim    return T->getStmtClass() == SEHExceptStmtClass;
1814221345Sdim  }
1815221345Sdim
1816221345Sdim};
1817221345Sdim
1818221345Sdimclass SEHFinallyStmt : public Stmt {
1819221345Sdim  SourceLocation  Loc;
1820221345Sdim  Stmt           *Block;
1821221345Sdim
1822221345Sdim  SEHFinallyStmt(SourceLocation Loc,
1823221345Sdim                 Stmt *Block);
1824221345Sdim
1825224145Sdim  friend class ASTReader;
1826224145Sdim  friend class ASTStmtReader;
1827224145Sdim  explicit SEHFinallyStmt(EmptyShell E) : Stmt(SEHFinallyStmtClass, E) { }
1828224145Sdim
1829221345Sdimpublic:
1830263508Sdim  static SEHFinallyStmt* Create(const ASTContext &C,
1831221345Sdim                                SourceLocation FinallyLoc,
1832221345Sdim                                Stmt *Block);
1833221345Sdim
1834249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return getFinallyLoc(); }
1835249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1836221345Sdim
1837221345Sdim  SourceLocation getFinallyLoc() const { return Loc; }
1838221345Sdim  SourceLocation getEndLoc() const { return Block->getLocEnd(); }
1839221345Sdim
1840249423Sdim  CompoundStmt *getBlock() const { return cast<CompoundStmt>(Block); }
1841221345Sdim
1842221345Sdim  child_range children() {
1843221345Sdim    return child_range(&Block,&Block+1);
1844221345Sdim  }
1845221345Sdim
1846221345Sdim  static bool classof(const Stmt *T) {
1847221345Sdim    return T->getStmtClass() == SEHFinallyStmtClass;
1848221345Sdim  }
1849221345Sdim
1850221345Sdim};
1851221345Sdim
1852221345Sdimclass SEHTryStmt : public Stmt {
1853221345Sdim  bool            IsCXXTry;
1854221345Sdim  SourceLocation  TryLoc;
1855221345Sdim  Stmt           *Children[2];
1856221345Sdim
1857221345Sdim  enum { TRY = 0, HANDLER = 1 };
1858221345Sdim
1859221345Sdim  SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
1860221345Sdim             SourceLocation TryLoc,
1861221345Sdim             Stmt *TryBlock,
1862221345Sdim             Stmt *Handler);
1863221345Sdim
1864224145Sdim  friend class ASTReader;
1865224145Sdim  friend class ASTStmtReader;
1866224145Sdim  explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
1867224145Sdim
1868221345Sdimpublic:
1869263508Sdim  static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
1870263508Sdim                            SourceLocation TryLoc, Stmt *TryBlock,
1871221345Sdim                            Stmt *Handler);
1872221345Sdim
1873249423Sdim  SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
1874249423Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
1875221345Sdim
1876221345Sdim  SourceLocation getTryLoc() const { return TryLoc; }
1877221345Sdim  SourceLocation getEndLoc() const { return Children[HANDLER]->getLocEnd(); }
1878221345Sdim
1879221345Sdim  bool getIsCXXTry() const { return IsCXXTry; }
1880234353Sdim
1881234353Sdim  CompoundStmt* getTryBlock() const {
1882249423Sdim    return cast<CompoundStmt>(Children[TRY]);
1883234353Sdim  }
1884234353Sdim
1885221345Sdim  Stmt *getHandler() const { return Children[HANDLER]; }
1886221345Sdim
1887221345Sdim  /// Returns 0 if not defined
1888221345Sdim  SEHExceptStmt  *getExceptHandler() const;
1889221345Sdim  SEHFinallyStmt *getFinallyHandler() const;
1890221345Sdim
1891221345Sdim  child_range children() {
1892221345Sdim    return child_range(Children,Children+2);
1893221345Sdim  }
1894221345Sdim
1895221345Sdim  static bool classof(const Stmt *T) {
1896221345Sdim    return T->getStmtClass() == SEHTryStmtClass;
1897221345Sdim  }
1898221345Sdim};
1899221345Sdim
1900251662Sdim/// \brief This captures a statement into a function. For example, the following
1901251662Sdim/// pragma annotated compound statement can be represented as a CapturedStmt,
1902251662Sdim/// and this compound statement is the body of an anonymous outlined function.
1903251662Sdim/// @code
1904251662Sdim/// #pragma omp parallel
1905251662Sdim/// {
1906251662Sdim///   compute();
1907251662Sdim/// }
1908251662Sdim/// @endcode
1909251662Sdimclass CapturedStmt : public Stmt {
1910251662Sdimpublic:
1911251662Sdim  /// \brief The different capture forms: by 'this' or by reference, etc.
1912251662Sdim  enum VariableCaptureKind {
1913251662Sdim    VCK_This,
1914251662Sdim    VCK_ByRef
1915251662Sdim  };
1916251662Sdim
1917251662Sdim  /// \brief Describes the capture of either a variable or 'this'.
1918251662Sdim  class Capture {
1919251662Sdim    llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind;
1920251662Sdim    SourceLocation Loc;
1921251662Sdim
1922251662Sdim  public:
1923251662Sdim    /// \brief Create a new capture.
1924251662Sdim    ///
1925251662Sdim    /// \param Loc The source location associated with this capture.
1926251662Sdim    ///
1927251662Sdim    /// \param Kind The kind of capture (this, ByRef, ...).
1928251662Sdim    ///
1929251662Sdim    /// \param Var The variable being captured, or null if capturing this.
1930251662Sdim    ///
1931251662Sdim    Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0)
1932251662Sdim      : VarAndKind(Var, Kind), Loc(Loc) {
1933251662Sdim      switch (Kind) {
1934251662Sdim      case VCK_This:
1935251662Sdim        assert(Var == 0 && "'this' capture cannot have a variable!");
1936251662Sdim        break;
1937251662Sdim      case VCK_ByRef:
1938251662Sdim        assert(Var && "capturing by reference must have a variable!");
1939251662Sdim        break;
1940251662Sdim      }
1941251662Sdim    }
1942251662Sdim
1943251662Sdim    /// \brief Determine the kind of capture.
1944251662Sdim    VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); }
1945251662Sdim
1946251662Sdim    /// \brief Retrieve the source location at which the variable or 'this' was
1947251662Sdim    /// first used.
1948251662Sdim    SourceLocation getLocation() const { return Loc; }
1949251662Sdim
1950251662Sdim    /// \brief Determine whether this capture handles the C++ 'this' pointer.
1951251662Sdim    bool capturesThis() const { return getCaptureKind() == VCK_This; }
1952251662Sdim
1953251662Sdim    /// \brief Determine whether this capture handles a variable.
1954251662Sdim    bool capturesVariable() const { return getCaptureKind() != VCK_This; }
1955251662Sdim
1956251662Sdim    /// \brief Retrieve the declaration of the variable being captured.
1957251662Sdim    ///
1958251662Sdim    /// This operation is only valid if this capture does not capture 'this'.
1959251662Sdim    VarDecl *getCapturedVar() const {
1960251662Sdim      assert(!capturesThis() && "No variable available for 'this' capture");
1961251662Sdim      return VarAndKind.getPointer();
1962251662Sdim    }
1963251662Sdim    friend class ASTStmtReader;
1964251662Sdim  };
1965251662Sdim
1966251662Sdimprivate:
1967251662Sdim  /// \brief The number of variable captured, including 'this'.
1968251662Sdim  unsigned NumCaptures;
1969251662Sdim
1970251662Sdim  /// \brief The pointer part is the implicit the outlined function and the
1971251662Sdim  /// int part is the captured region kind, 'CR_Default' etc.
1972251662Sdim  llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
1973251662Sdim
1974251662Sdim  /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
1975251662Sdim  RecordDecl *TheRecordDecl;
1976251662Sdim
1977251662Sdim  /// \brief Construct a captured statement.
1978251662Sdim  CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
1979251662Sdim               ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
1980251662Sdim
1981251662Sdim  /// \brief Construct an empty captured statement.
1982251662Sdim  CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
1983251662Sdim
1984251662Sdim  Stmt **getStoredStmts() const {
1985251662Sdim    return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1);
1986251662Sdim  }
1987251662Sdim
1988251662Sdim  Capture *getStoredCaptures() const;
1989251662Sdim
1990251662Sdim  void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; }
1991251662Sdim
1992251662Sdimpublic:
1993263508Sdim  static CapturedStmt *Create(const ASTContext &Context, Stmt *S,
1994251662Sdim                              CapturedRegionKind Kind,
1995251662Sdim                              ArrayRef<Capture> Captures,
1996251662Sdim                              ArrayRef<Expr *> CaptureInits,
1997251662Sdim                              CapturedDecl *CD, RecordDecl *RD);
1998251662Sdim
1999263508Sdim  static CapturedStmt *CreateDeserialized(const ASTContext &Context,
2000251662Sdim                                          unsigned NumCaptures);
2001251662Sdim
2002251662Sdim  /// \brief Retrieve the statement being captured.
2003251662Sdim  Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; }
2004251662Sdim  const Stmt *getCapturedStmt() const {
2005251662Sdim    return const_cast<CapturedStmt *>(this)->getCapturedStmt();
2006251662Sdim  }
2007251662Sdim
2008251662Sdim  /// \brief Retrieve the outlined function declaration.
2009251662Sdim  CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); }
2010251662Sdim  const CapturedDecl *getCapturedDecl() const {
2011251662Sdim    return const_cast<CapturedStmt *>(this)->getCapturedDecl();
2012251662Sdim  }
2013251662Sdim
2014251662Sdim  /// \brief Set the outlined function declaration.
2015251662Sdim  void setCapturedDecl(CapturedDecl *D) {
2016251662Sdim    assert(D && "null CapturedDecl");
2017251662Sdim    CapDeclAndKind.setPointer(D);
2018251662Sdim  }
2019251662Sdim
2020251662Sdim  /// \brief Retrieve the captured region kind.
2021251662Sdim  CapturedRegionKind getCapturedRegionKind() const {
2022251662Sdim    return CapDeclAndKind.getInt();
2023251662Sdim  }
2024251662Sdim
2025251662Sdim  /// \brief Set the captured region kind.
2026251662Sdim  void setCapturedRegionKind(CapturedRegionKind Kind) {
2027251662Sdim    CapDeclAndKind.setInt(Kind);
2028251662Sdim  }
2029251662Sdim
2030251662Sdim  /// \brief Retrieve the record declaration for captured variables.
2031251662Sdim  const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
2032251662Sdim
2033251662Sdim  /// \brief Set the record declaration for captured variables.
2034251662Sdim  void setCapturedRecordDecl(RecordDecl *D) {
2035251662Sdim    assert(D && "null RecordDecl");
2036251662Sdim    TheRecordDecl = D;
2037251662Sdim  }
2038251662Sdim
2039251662Sdim  /// \brief True if this variable has been captured.
2040251662Sdim  bool capturesVariable(const VarDecl *Var) const;
2041251662Sdim
2042251662Sdim  /// \brief An iterator that walks over the captures.
2043251662Sdim  typedef Capture *capture_iterator;
2044251662Sdim  typedef const Capture *const_capture_iterator;
2045251662Sdim
2046251662Sdim  /// \brief Retrieve an iterator pointing to the first capture.
2047251662Sdim  capture_iterator capture_begin() { return getStoredCaptures(); }
2048251662Sdim  const_capture_iterator capture_begin() const { return getStoredCaptures(); }
2049251662Sdim
2050251662Sdim  /// \brief Retrieve an iterator pointing past the end of the sequence of
2051251662Sdim  /// captures.
2052251662Sdim  capture_iterator capture_end() const {
2053251662Sdim    return getStoredCaptures() + NumCaptures;
2054251662Sdim  }
2055251662Sdim
2056251662Sdim  /// \brief Retrieve the number of captures, including 'this'.
2057251662Sdim  unsigned capture_size() const { return NumCaptures; }
2058251662Sdim
2059251662Sdim  /// \brief Iterator that walks over the capture initialization arguments.
2060251662Sdim  typedef Expr **capture_init_iterator;
2061251662Sdim
2062251662Sdim  /// \brief Retrieve the first initialization argument.
2063251662Sdim  capture_init_iterator capture_init_begin() const {
2064251662Sdim    return reinterpret_cast<Expr **>(getStoredStmts());
2065251662Sdim  }
2066251662Sdim
2067251662Sdim  /// \brief Retrieve the iterator pointing one past the last initialization
2068251662Sdim  /// argument.
2069251662Sdim  capture_init_iterator capture_init_end() const {
2070251662Sdim    return capture_init_begin() + NumCaptures;
2071251662Sdim  }
2072251662Sdim
2073251662Sdim  SourceLocation getLocStart() const LLVM_READONLY {
2074251662Sdim    return getCapturedStmt()->getLocStart();
2075251662Sdim  }
2076251662Sdim  SourceLocation getLocEnd() const LLVM_READONLY {
2077251662Sdim    return getCapturedStmt()->getLocEnd();
2078251662Sdim  }
2079251662Sdim  SourceRange getSourceRange() const LLVM_READONLY {
2080251662Sdim    return getCapturedStmt()->getSourceRange();
2081251662Sdim  }
2082251662Sdim
2083251662Sdim  static bool classof(const Stmt *T) {
2084251662Sdim    return T->getStmtClass() == CapturedStmtClass;
2085251662Sdim  }
2086251662Sdim
2087251662Sdim  child_range children();
2088251662Sdim
2089251662Sdim  friend class ASTStmtReader;
2090251662Sdim};
2091251662Sdim
2092193326Sed}  // end namespace clang
2093193326Sed
2094193326Sed#endif
2095