Stmt.h revision 63c00d7f35fa060c0a446c9df3a4402d9c7757fe
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===--- Stmt.h - Classes for representing statements -----------*- C++ -*-===//
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//                     The LLVM Compiler Infrastructure
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This file is distributed under the University of Illinois Open Source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// License. See LICENSE.TXT for details.
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===//
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//  This file defines the Stmt interface and subclasses.
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===//
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#ifndef LLVM_CLANG_AST_STMT_H
15026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#define LLVM_CLANG_AST_STMT_H
16026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org
17026d1ce6fc5608190aa5fd48f51278c60515c093pbos@webrtc.org#include "llvm/Support/Casting.h"
18acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org#include "llvm/Support/raw_ostream.h"
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/Basic/SourceLocation.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/PrettyPrinter.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/StmtIterator.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/DeclGroup.h"
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "llvm/ADT/SmallVector.h"
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "clang/AST/ASTContext.h"
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string>
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgusing llvm::dyn_cast_or_null;
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace llvm {
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class FoldingSetNodeID;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace clang {
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class ASTContext;
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class Expr;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class Decl;
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class ParmVarDecl;
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class QualType;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class IdentifierInfo;
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class SourceManager;
403bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  class StringLiteral;
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class SwitchStmt;
423bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //===----------------------------------------------------------------------===//
443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // ExprIterator - Iterators for iterating over Stmt* arrays that contain
453bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  //  only Expr*.  This is needed because AST nodes use Stmt* arrays to store
463bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  //  references to children (to be compatible with StmtIterator).
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  //===----------------------------------------------------------------------===//
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class Stmt;
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class Expr;
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class ExprIterator {
533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    Stmt** I;
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  public:
553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    ExprIterator(Stmt** i) : I(i) {}
563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    ExprIterator() : I(0) {}
573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    ExprIterator& operator++() { ++I; return *this; }
583bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    ExprIterator operator-(size_t i) { return I-i; }
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ExprIterator operator+(size_t i) { return I+i; }
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Expr* operator[](size_t idx);
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // FIXME: Verify that this will correctly return a signed distance.
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    signed operator-(const ExprIterator& R) const { return I - R.I; }
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Expr* operator*() const;
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Expr* operator->() const;
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator==(const ExprIterator& R) const { return I == R.I; }
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator!=(const ExprIterator& R) const { return I != R.I; }
673bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    bool operator>(const ExprIterator& R) const { return I > R.I; }
683bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    bool operator>=(const ExprIterator& R) const { return I >= R.I; }
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class ConstExprIterator {
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const Stmt * const *I;
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  public:
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ConstExprIterator(const Stmt * const *i) : I(i) {}
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ConstExprIterator() : I(0) {}
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ConstExprIterator& operator++() { ++I; return *this; }
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ConstExprIterator operator+(size_t i) const { return I+i; }
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ConstExprIterator operator-(size_t i) const { return I-i; }
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const Expr * operator[](size_t idx) const;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    signed operator-(const ConstExprIterator& R) const { return I - R.I; }
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const Expr * operator*() const;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const Expr * operator->() const;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator==(const ConstExprIterator& R) const { return I == R.I; }
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator!=(const ConstExprIterator& R) const { return I != R.I; }
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator>(const ConstExprIterator& R) const { return I > R.I; }
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool operator>=(const ConstExprIterator& R) const { return I >= R.I; }
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===//
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// AST classes for statements.
913bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org//===----------------------------------------------------------------------===//
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// Stmt - This represents one statement.
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org///
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Stmt {
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  enum StmtClass {
983bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    NoStmtClass = 0,
993bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define STMT(CLASS, PARENT) CLASS##Class,
1003bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define STMT_RANGE(BASE, FIRST, LAST) \
1013bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class,
102ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org#define LAST_STMT_RANGE(BASE, FIRST, LAST) \
1033bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        first##BASE##Constant=FIRST##Class, last##BASE##Constant=LAST##Class
1043bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#define ABSTRACT_STMT(STMT)
1053bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#include "clang/AST/StmtNodes.inc"
1063bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  };
1073bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
1083bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // Make vanilla 'new' and 'delete' illegal for Stmts.
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprotected:
1103bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  void* operator new(size_t bytes) throw() {
1113bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    assert(0 && "Stmts cannot be allocated with regular 'new'.");
1123bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    return 0;
1133bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  }
1143bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  void operator delete(void* data) throw() {
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(0 && "Stmts cannot be released with regular 'delete'.");
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
118acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org  class StmtBitfields {
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class Stmt;
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /// \brief The statement class.
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned sClass : 8;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  enum { NumStmtBits = 8 };
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class CompoundStmtBitfields {
1273bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    friend class CompoundStmt;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned : NumStmtBits;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned NumStmts : 32 - NumStmtBits;
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class LabelStmtBitfields {
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class LabelStmt;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned : NumStmtBits;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned Used : 1;
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned HasUnusedAttr : 1;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class ExprBitfields {
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class Expr;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class DeclRefExpr; // computeDependence
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class InitListExpr; // ctor
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class DesignatedInitExpr; // ctor
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class BlockDeclRefExpr; // ctor
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class ASTStmtReader; // deserialization
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CXXNewExpr; // ctor
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class DependentScopeDeclRefExpr; // ctor
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CXXConstructExpr; // ctor
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CallExpr; // ctor
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class OffsetOfExpr; // ctor
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class ObjCMessageExpr; // ctor
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class ShuffleVectorExpr; // ctor
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class ParenListExpr; // ctor
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CXXUnresolvedConstructExpr; // ctor
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CXXDependentScopeMemberExpr; // ctor
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class OverloadExpr; // ctor
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned : NumStmtBits;
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned ValueKind : 2;
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned ObjectKind : 2;
1639787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org    unsigned TypeDependent : 1;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned ValueDependent : 1;
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned ContainsUnexpandedParameterPack : 1;
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  enum { NumExprBits = 15 };
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class CastExprBitfields {
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CastExpr;
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned : NumExprBits;
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned Kind : 6;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned BasePathSize : 32 - 6 - NumExprBits;
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  class CallExprBitfields {
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    friend class CallExpr;
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned : NumExprBits;
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18165952712c5e04c3a301a15ce7acfe8999a3686cafbarchard@google.com    unsigned NumPreArgs : 1;
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
1839787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  union {
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // FIXME: this is wasteful on 64-bit platforms.
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    void *Aligner;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    StmtBitfields StmtBits;
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CompoundStmtBitfields CompoundStmtBits;
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LabelStmtBitfields LabelStmtBits;
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ExprBitfields ExprBits;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CastExprBitfields CastExprBits;
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CallExprBitfields CallExprBits;
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  friend class ASTStmtReader;
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Only allow allocation of Stmts using the allocator in ASTContext
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // or by doing a placement new.
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void* operator new(size_t bytes, ASTContext& C,
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     unsigned alignment = 8) throw() {
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ::operator new(bytes, C, alignment);
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
205acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void* operator new(size_t bytes, ASTContext* C,
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     unsigned alignment = 8) throw() {
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return ::operator new(bytes, *C, alignment);
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void* operator new(size_t bytes, void* mem) throw() {
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return mem;
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2159787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org  void operator delete(void*, ASTContext&, unsigned) throw() { }
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void operator delete(void*, ASTContext*, unsigned) throw() { }
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void operator delete(void*, std::size_t) throw() { }
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void operator delete(void*, void*) throw() { }
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief A placeholder type used to construct an empty shell of a
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// type, that will be filled in later (e.g., by some
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// de-serialization).
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  struct EmptyShell { };
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgprotected:
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Construct an empty statement.
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit Stmt(StmtClass SC, EmptyShell) {
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    StmtBits.sClass = SC;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Stmt(StmtClass SC) {
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    StmtBits.sClass = SC;
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  StmtClass getStmtClass() const {
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return static_cast<StmtClass>(StmtBits.sClass);
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const char *getStmtClassName() const;
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// SourceLocation tokens are not useful in isolation - they are low level
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// value objects created/interpreted by SourceManager. We assume AST
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// clients will have a pointer to the respective SourceManager.
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceRange getSourceRange() const;
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // global temp stats (until we have a per-module visitor)
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static void addStmtClass(const StmtClass s);
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool CollectingStats(bool Enable = false);
2559787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org  static void PrintStats();
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// dump - This does a local dump of the specified AST fragment.  It dumps the
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// specified node and a few nodes underneath it, but not the whole subtree.
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// This is useful in a debugger.
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dump() const;
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dump(SourceManager &SM) const;
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// dumpAll - This does a dump of the specified AST fragment and all subtrees.
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dumpAll() const;
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dumpAll(SourceManager &SM) const;
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// back to its original source language syntax.
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void dumpPretty(ASTContext& Context) const;
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void printPretty(llvm::raw_ostream &OS, PrinterHelper *Helper,
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   const PrintingPolicy &Policy,
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   unsigned Indentation = 0) const {
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void printPretty(llvm::raw_ostream &OS, ASTContext &Context,
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   PrinterHelper *Helper,
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   const PrintingPolicy &Policy,
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                   unsigned Indentation = 0) const;
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void viewAST() const;
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Implement isa<T> support.
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool classof(const Stmt *) { return true; }
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// hasImplicitControlFlow - Some statements (e.g. short circuited operations)
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///  contain implicit control-flow in the order their subexpressions
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///  are evaluated.  This predicate returns true if this statement has
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///  such implicit control-flow.  Such statements are also specially handled
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///  within CFGs.
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool hasImplicitControlFlow() const;
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// Child Iterators: All subclasses must implement 'children'
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// to permit easy iteration over the substatements/subexpessions of an
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// AST node.  This permits easy iteration over all nodes in the AST.
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef StmtIterator       child_iterator;
299acb00f58442d54183500c472044768b6d757edb4henrike@webrtc.org  typedef ConstStmtIterator  const_child_iterator;
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef StmtRange          child_range;
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef ConstStmtRange     const_child_range;
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  child_range children();
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_child_range children() const {
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return const_cast<Stmt*>(this)->children();
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3099787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org  child_iterator child_begin() { return children().first; }
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  child_iterator child_end() { return children().second; }
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_child_iterator child_begin() const { return children().first; }
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_child_iterator child_end() const { return children().second; }
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Produce a unique representation of the given statement.
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief ID once the profiling operation is complete, will contain
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// the unique representation of the given statement.
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Context the AST context in which the statement resides
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Canonical whether the profile should be based on the canonical
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// representation of this statement (e.g., where non-type template
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// parameters are identified by index/level rather than their
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// declaration pointers) or the exact representation of the statement as
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// written in the source.
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               bool Canonical);
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// DeclStmt - Adaptor class for mixing declarations with statements and
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// expressions. For example, CompoundStmt mixes statements, expressions
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// and declarations (variables, types). Another example is ForStmt, where
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// the first statement can be an expression or a declaration.
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org///
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass DeclStmt : public Stmt {
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeclGroupRef DG;
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation StartLoc, EndLoc;
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeclStmt(DeclGroupRef dg, SourceLocation startLoc,
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org           SourceLocation endLoc) : Stmt(DeclStmtClass), DG(dg),
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                    StartLoc(startLoc), EndLoc(endLoc) {}
3449787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Build an empty declaration statement.
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit DeclStmt(EmptyShell Empty) : Stmt(DeclStmtClass, Empty) { }
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// isSingleDecl - This method returns true if this DeclStmt refers
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// to a single Decl.
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool isSingleDecl() const {
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return DG.isSingleDecl();
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const Decl *getSingleDecl() const { return DG.getSingleDecl(); }
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Decl *getSingleDecl() { return DG.getSingleDecl(); }
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const DeclGroupRef getDeclGroup() const { return DG; }
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeclGroupRef getDeclGroup() { return DG; }
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void setDeclGroup(DeclGroupRef DGR) { DG = DGR; }
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation getStartLoc() const { return StartLoc; }
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void setStartLoc(SourceLocation L) { StartLoc = L; }
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation getEndLoc() const { return EndLoc; }
3649787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org  void setEndLoc(SourceLocation L) { EndLoc = L; }
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceRange getSourceRange() const {
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return SourceRange(StartLoc, EndLoc);
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool classof(const Stmt *T) {
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return T->getStmtClass() == DeclStmtClass;
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool classof(const DeclStmt *) { return true; }
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Iterators over subexpressions.
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  child_range children() {
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return child_range(child_iterator(DG.begin(), DG.end()),
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                       child_iterator(DG.end(), DG.end()));
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef DeclGroupRef::iterator decl_iterator;
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef DeclGroupRef::const_iterator const_decl_iterator;
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  decl_iterator decl_begin() { return DG.begin(); }
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  decl_iterator decl_end() { return DG.end(); }
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_decl_iterator decl_begin() const { return DG.begin(); }
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_decl_iterator decl_end() const { return DG.end(); }
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// NullStmt - This is the null statement ";": C99 6.8.3p3.
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org///
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass NullStmt : public Stmt {
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation SemiLoc;
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Whether the null statement was preceded by an empty macro, e.g:
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// @code
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///   #define CALL(x)
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ///   CALL(0);
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// @endcode
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool LeadingEmptyMacro;
4019787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.orgpublic:
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  NullStmt(SourceLocation L, bool LeadingEmptyMacro = false)
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {}
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Build an empty null statement.
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit NullStmt(EmptyShell Empty) : Stmt(NullStmtClass, Empty) { }
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation getSemiLoc() const { return SemiLoc; }
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void setSemiLoc(SourceLocation L) { SemiLoc = L; }
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro; }
4129787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org
4139787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org  SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
4149787291a1ad012d16ad07de4c3b22a331718effamikhal@webrtc.org
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool classof(const Stmt *T) {
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return T->getStmtClass() == NullStmtClass;
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  static bool classof(const NullStmt *) { return true; }
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  child_range children() { return child_range(); }
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  friend class ASTStmtReader;
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  friend class ASTStmtWriter;
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// CompoundStmt - This represents a group of statements like { stmt stmt }.
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org///
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass CompoundStmt : public Stmt {
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Stmt** Body;
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation LBracLoc, RBracLoc;
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CompoundStmt(ASTContext& C, Stmt **StmtStart, unsigned NumStmts,
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               SourceLocation LB, SourceLocation RB)
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  : Stmt(CompoundStmtClass), LBracLoc(LB), RBracLoc(RB) {
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CompoundStmtBits.NumStmts = NumStmts;
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (NumStmts == 0) {
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      Body = 0;
4393bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org      return;
4403bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    }
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Body = new (C) Stmt*[NumStmts];
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memcpy(Body, StmtStart, NumStmts * sizeof(*Body));
4443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  }
445ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org
4463bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // \brief Build an empty compound statement.
4473bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  explicit CompoundStmt(EmptyShell Empty)
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : Stmt(CompoundStmtClass, Empty), Body(0) {
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CompoundStmtBits.NumStmts = 0;
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
4513bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
4523bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  void setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts);
4533bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
4543bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  bool body_empty() const { return CompoundStmtBits.NumStmts == 0; }
4553bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  unsigned size() const { return CompoundStmtBits.NumStmts; }
4563bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
4573bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  typedef Stmt** body_iterator;
4583bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  body_iterator body_begin() { return Body; }
4593bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  body_iterator body_end() { return Body + size(); }
4603bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; }
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void setLastStmt(Stmt *S) {
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    assert(!body_empty() && "setLastStmt");
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Body[size()-1] = S;
4653bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  }
4663bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef Stmt* const * const_body_iterator;
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_body_iterator body_begin() const { return Body; }
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const_body_iterator body_end() const { return Body + size(); }
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; }
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  reverse_body_iterator body_rbegin() {
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return reverse_body_iterator(body_end());
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  reverse_body_iterator body_rend() {
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return reverse_body_iterator(body_begin());
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef std::reverse_iterator<const_body_iterator>
481          const_reverse_body_iterator;
482
483  const_reverse_body_iterator body_rbegin() const {
484    return const_reverse_body_iterator(body_end());
485  }
486
487  const_reverse_body_iterator body_rend() const {
488    return const_reverse_body_iterator(body_begin());
489  }
490
491  SourceRange getSourceRange() const {
492    return SourceRange(LBracLoc, RBracLoc);
493  }
494
495  SourceLocation getLBracLoc() const { return LBracLoc; }
496  void setLBracLoc(SourceLocation L) { LBracLoc = L; }
497  SourceLocation getRBracLoc() const { return RBracLoc; }
498  void setRBracLoc(SourceLocation L) { RBracLoc = L; }
499
500  static bool classof(const Stmt *T) {
501    return T->getStmtClass() == CompoundStmtClass;
502  }
503  static bool classof(const CompoundStmt *) { return true; }
504
505  // Iterators
506  child_range children() {
507    return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
508  }
509};
510
511// SwitchCase is the base class for CaseStmt and DefaultStmt,
512class SwitchCase : public Stmt {
513protected:
514  // A pointer to the following CaseStmt or DefaultStmt class,
515  // used by SwitchStmt.
516  SwitchCase *NextSwitchCase;
517
518  SwitchCase(StmtClass SC) : Stmt(SC), NextSwitchCase(0) {}
519
520public:
521  const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
522
523  SwitchCase *getNextSwitchCase() { return NextSwitchCase; }
524
525  void setNextSwitchCase(SwitchCase *SC) { NextSwitchCase = SC; }
526
527  Stmt *getSubStmt();
528
529  SourceRange getSourceRange() const { return SourceRange(); }
530
531  static bool classof(const Stmt *T) {
532    return T->getStmtClass() == CaseStmtClass ||
533           T->getStmtClass() == DefaultStmtClass;
534  }
535  static bool classof(const SwitchCase *) { return true; }
536};
537
538class CaseStmt : public SwitchCase {
539  enum { SUBSTMT, LHS, RHS, END_EXPR };
540  Stmt* SubExprs[END_EXPR];  // The expression for the RHS is Non-null for
541                             // GNU "case 1 ... 4" extension
542  SourceLocation CaseLoc;
543  SourceLocation EllipsisLoc;
544  SourceLocation ColonLoc;
545public:
546  CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
547           SourceLocation ellipsisLoc, SourceLocation colonLoc)
548    : SwitchCase(CaseStmtClass) {
549    SubExprs[SUBSTMT] = 0;
550    SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
551    SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
552    CaseLoc = caseLoc;
553    EllipsisLoc = ellipsisLoc;
554    ColonLoc = colonLoc;
555  }
556
557  /// \brief Build an empty switch case statement.
558  explicit CaseStmt(EmptyShell Empty) : SwitchCase(CaseStmtClass) { }
559
560  SourceLocation getCaseLoc() const { return CaseLoc; }
561  void setCaseLoc(SourceLocation L) { CaseLoc = L; }
562  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
563  void setEllipsisLoc(SourceLocation L) { EllipsisLoc = L; }
564  SourceLocation getColonLoc() const { return ColonLoc; }
565  void setColonLoc(SourceLocation L) { ColonLoc = L; }
566
567  Expr *getLHS() { return reinterpret_cast<Expr*>(SubExprs[LHS]); }
568  Expr *getRHS() { return reinterpret_cast<Expr*>(SubExprs[RHS]); }
569  Stmt *getSubStmt() { return SubExprs[SUBSTMT]; }
570
571  const Expr *getLHS() const {
572    return reinterpret_cast<const Expr*>(SubExprs[LHS]);
573  }
574  const Expr *getRHS() const {
575    return reinterpret_cast<const Expr*>(SubExprs[RHS]);
576  }
577  const Stmt *getSubStmt() const { return SubExprs[SUBSTMT]; }
578
579  void setSubStmt(Stmt *S) { SubExprs[SUBSTMT] = S; }
580  void setLHS(Expr *Val) { SubExprs[LHS] = reinterpret_cast<Stmt*>(Val); }
581  void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
582
583
584  SourceRange getSourceRange() const {
585    // Handle deeply nested case statements with iteration instead of recursion.
586    const CaseStmt *CS = this;
587    while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
588      CS = CS2;
589
590    return SourceRange(CaseLoc, CS->getSubStmt()->getLocEnd());
591  }
592  static bool classof(const Stmt *T) {
593    return T->getStmtClass() == CaseStmtClass;
594  }
595  static bool classof(const CaseStmt *) { return true; }
596
597  // Iterators
598  child_range children() {
599    return child_range(&SubExprs[0], &SubExprs[END_EXPR]);
600  }
601};
602
603class DefaultStmt : public SwitchCase {
604  Stmt* SubStmt;
605  SourceLocation DefaultLoc;
606  SourceLocation ColonLoc;
607public:
608  DefaultStmt(SourceLocation DL, SourceLocation CL, Stmt *substmt) :
609    SwitchCase(DefaultStmtClass), SubStmt(substmt), DefaultLoc(DL),
610    ColonLoc(CL) {}
611
612  /// \brief Build an empty default statement.
613  explicit DefaultStmt(EmptyShell) : SwitchCase(DefaultStmtClass) { }
614
615  Stmt *getSubStmt() { return SubStmt; }
616  const Stmt *getSubStmt() const { return SubStmt; }
617  void setSubStmt(Stmt *S) { SubStmt = S; }
618
619  SourceLocation getDefaultLoc() const { return DefaultLoc; }
620  void setDefaultLoc(SourceLocation L) { DefaultLoc = L; }
621  SourceLocation getColonLoc() const { return ColonLoc; }
622  void setColonLoc(SourceLocation L) { ColonLoc = L; }
623
624  SourceRange getSourceRange() const {
625    return SourceRange(DefaultLoc, SubStmt->getLocEnd());
626  }
627  static bool classof(const Stmt *T) {
628    return T->getStmtClass() == DefaultStmtClass;
629  }
630  static bool classof(const DefaultStmt *) { return true; }
631
632  // Iterators
633  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
634};
635
636class LabelStmt : public Stmt {
637  IdentifierInfo *Label;
638  Stmt *SubStmt;
639  SourceLocation IdentLoc;
640public:
641  LabelStmt(SourceLocation IL, IdentifierInfo *label, Stmt *substmt,
642            bool hasUnusedAttr = false)
643    : Stmt(LabelStmtClass), Label(label), SubStmt(substmt), IdentLoc(IL) {
644    LabelStmtBits.Used = false;
645    LabelStmtBits.HasUnusedAttr = hasUnusedAttr;
646  }
647
648  // \brief Build an empty label statement.
649  explicit LabelStmt(EmptyShell Empty) : Stmt(LabelStmtClass, Empty) { }
650
651  SourceLocation getIdentLoc() const { return IdentLoc; }
652  IdentifierInfo *getID() const { return Label; }
653  void setID(IdentifierInfo *II) { Label = II; }
654  const char *getName() const;
655  Stmt *getSubStmt() { return SubStmt; }
656  const Stmt *getSubStmt() const { return SubStmt; }
657  void setIdentLoc(SourceLocation L) { IdentLoc = L; }
658  void setSubStmt(Stmt *SS) { SubStmt = SS; }
659
660  /// \brief Whether this label was used.
661  bool isUsed(bool CheckUnusedAttr = true) const {
662    return LabelStmtBits.Used ||
663           (CheckUnusedAttr && LabelStmtBits.HasUnusedAttr);
664  }
665  void setUsed(bool U = true) { LabelStmtBits.Used = U; }
666
667  bool HasUnusedAttribute() const { return LabelStmtBits.HasUnusedAttr; }
668  void setUnusedAttribute(bool U) { LabelStmtBits.HasUnusedAttr = U; }
669
670  SourceRange getSourceRange() const {
671    return SourceRange(IdentLoc, SubStmt->getLocEnd());
672  }
673  child_range children() { return child_range(&SubStmt, &SubStmt+1); }
674
675  static bool classof(const Stmt *T) {
676    return T->getStmtClass() == LabelStmtClass;
677  }
678  static bool classof(const LabelStmt *) { return true; }
679};
680
681
682/// IfStmt - This represents an if/then/else.
683///
684class IfStmt : public Stmt {
685  enum { VAR, COND, THEN, ELSE, END_EXPR };
686  Stmt* SubExprs[END_EXPR];
687
688  SourceLocation IfLoc;
689  SourceLocation ElseLoc;
690
691public:
692  IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
693         Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
694
695  /// \brief Build an empty if/then/else statement
696  explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
697
698  /// \brief Retrieve the variable declared in this "if" statement, if any.
699  ///
700  /// In the following example, "x" is the condition variable.
701  /// \code
702  /// if (int x = foo()) {
703  ///   printf("x is %d", x);
704  /// }
705  /// \endcode
706  VarDecl *getConditionVariable() const;
707  void setConditionVariable(ASTContext &C, VarDecl *V);
708
709  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
710  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
711  const Stmt *getThen() const { return SubExprs[THEN]; }
712  void setThen(Stmt *S) { SubExprs[THEN] = S; }
713  const Stmt *getElse() const { return SubExprs[ELSE]; }
714  void setElse(Stmt *S) { SubExprs[ELSE] = S; }
715
716  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
717  Stmt *getThen() { return SubExprs[THEN]; }
718  Stmt *getElse() { return SubExprs[ELSE]; }
719
720  SourceLocation getIfLoc() const { return IfLoc; }
721  void setIfLoc(SourceLocation L) { IfLoc = L; }
722  SourceLocation getElseLoc() const { return ElseLoc; }
723  void setElseLoc(SourceLocation L) { ElseLoc = L; }
724
725  SourceRange getSourceRange() const {
726    if (SubExprs[ELSE])
727      return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
728    else
729      return SourceRange(IfLoc, SubExprs[THEN]->getLocEnd());
730  }
731
732  // Iterators over subexpressions.  The iterators will include iterating
733  // over the initialization expression referenced by the condition variable.
734  child_range children() {
735    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
736  }
737
738  static bool classof(const Stmt *T) {
739    return T->getStmtClass() == IfStmtClass;
740  }
741  static bool classof(const IfStmt *) { return true; }
742};
743
744/// SwitchStmt - This represents a 'switch' stmt.
745///
746class SwitchStmt : public Stmt {
747  enum { VAR, COND, BODY, END_EXPR };
748  Stmt* SubExprs[END_EXPR];
749  // This points to a linked list of case and default statements.
750  SwitchCase *FirstCase;
751  SourceLocation SwitchLoc;
752
753  /// If the SwitchStmt is a switch on an enum value, this records whether
754  /// all the enum values were covered by CaseStmts.  This value is meant to
755  /// be a hint for possible clients.
756  unsigned AllEnumCasesCovered : 1;
757
758public:
759  SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond);
760
761  /// \brief Build a empty switch statement.
762  explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { }
763
764  /// \brief Retrieve the variable declared in this "switch" statement, if any.
765  ///
766  /// In the following example, "x" is the condition variable.
767  /// \code
768  /// switch (int x = foo()) {
769  ///   case 0: break;
770  ///   // ...
771  /// }
772  /// \endcode
773  VarDecl *getConditionVariable() const;
774  void setConditionVariable(ASTContext &C, VarDecl *V);
775
776  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
777  const Stmt *getBody() const { return SubExprs[BODY]; }
778  const SwitchCase *getSwitchCaseList() const { return FirstCase; }
779
780  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);}
781  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); }
782  Stmt *getBody() { return SubExprs[BODY]; }
783  void setBody(Stmt *S) { SubExprs[BODY] = S; }
784  SwitchCase *getSwitchCaseList() { return FirstCase; }
785
786  /// \brief Set the case list for this switch statement.
787  ///
788  /// The caller is responsible for incrementing the retain counts on
789  /// all of the SwitchCase statements in this list.
790  void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
791
792  SourceLocation getSwitchLoc() const { return SwitchLoc; }
793  void setSwitchLoc(SourceLocation L) { SwitchLoc = L; }
794
795  void setBody(Stmt *S, SourceLocation SL) {
796    SubExprs[BODY] = S;
797    SwitchLoc = SL;
798  }
799  void addSwitchCase(SwitchCase *SC) {
800    assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
801    SC->setNextSwitchCase(FirstCase);
802    FirstCase = SC;
803  }
804
805  /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a
806  /// switch over an enum value then all cases have been explicitly covered.
807  void setAllEnumCasesCovered() {
808    AllEnumCasesCovered = 1;
809  }
810
811  /// Returns true if the SwitchStmt is a switch of an enum value and all cases
812  /// have been explicitly covered.
813  bool isAllEnumCasesCovered() const {
814    return (bool) AllEnumCasesCovered;
815  }
816
817  SourceRange getSourceRange() const {
818    return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
819  }
820  // Iterators
821  child_range children() {
822    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
823  }
824
825  static bool classof(const Stmt *T) {
826    return T->getStmtClass() == SwitchStmtClass;
827  }
828  static bool classof(const SwitchStmt *) { return true; }
829};
830
831
832/// WhileStmt - This represents a 'while' stmt.
833///
834class WhileStmt : public Stmt {
835  enum { VAR, COND, BODY, END_EXPR };
836  Stmt* SubExprs[END_EXPR];
837  SourceLocation WhileLoc;
838public:
839  WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
840            SourceLocation WL);
841
842  /// \brief Build an empty while statement.
843  explicit WhileStmt(EmptyShell Empty) : Stmt(WhileStmtClass, Empty) { }
844
845  /// \brief Retrieve the variable declared in this "while" statement, if any.
846  ///
847  /// In the following example, "x" is the condition variable.
848  /// \code
849  /// while (int x = random()) {
850  ///   // ...
851  /// }
852  /// \endcode
853  VarDecl *getConditionVariable() const;
854  void setConditionVariable(ASTContext &C, VarDecl *V);
855
856  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
857  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
858  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
859  Stmt *getBody() { return SubExprs[BODY]; }
860  const Stmt *getBody() const { return SubExprs[BODY]; }
861  void setBody(Stmt *S) { SubExprs[BODY] = S; }
862
863  SourceLocation getWhileLoc() const { return WhileLoc; }
864  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
865
866  SourceRange getSourceRange() const {
867    return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
868  }
869  static bool classof(const Stmt *T) {
870    return T->getStmtClass() == WhileStmtClass;
871  }
872  static bool classof(const WhileStmt *) { return true; }
873
874  // Iterators
875  child_range children() {
876    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
877  }
878};
879
880/// DoStmt - This represents a 'do/while' stmt.
881///
882class DoStmt : public Stmt {
883  enum { BODY, COND, END_EXPR };
884  Stmt* SubExprs[END_EXPR];
885  SourceLocation DoLoc;
886  SourceLocation WhileLoc;
887  SourceLocation RParenLoc;  // Location of final ')' in do stmt condition.
888
889public:
890  DoStmt(Stmt *body, Expr *cond, SourceLocation DL, SourceLocation WL,
891         SourceLocation RP)
892    : Stmt(DoStmtClass), DoLoc(DL), WhileLoc(WL), RParenLoc(RP) {
893    SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
894    SubExprs[BODY] = body;
895  }
896
897  /// \brief Build an empty do-while statement.
898  explicit DoStmt(EmptyShell Empty) : Stmt(DoStmtClass, Empty) { }
899
900  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
901  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
902  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
903  Stmt *getBody() { return SubExprs[BODY]; }
904  const Stmt *getBody() const { return SubExprs[BODY]; }
905  void setBody(Stmt *S) { SubExprs[BODY] = S; }
906
907  SourceLocation getDoLoc() const { return DoLoc; }
908  void setDoLoc(SourceLocation L) { DoLoc = L; }
909  SourceLocation getWhileLoc() const { return WhileLoc; }
910  void setWhileLoc(SourceLocation L) { WhileLoc = L; }
911
912  SourceLocation getRParenLoc() const { return RParenLoc; }
913  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
914
915  SourceRange getSourceRange() const {
916    return SourceRange(DoLoc, RParenLoc);
917  }
918  static bool classof(const Stmt *T) {
919    return T->getStmtClass() == DoStmtClass;
920  }
921  static bool classof(const DoStmt *) { return true; }
922
923  // Iterators
924  child_range children() {
925    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
926  }
927};
928
929
930/// ForStmt - This represents a 'for (init;cond;inc)' stmt.  Note that any of
931/// the init/cond/inc parts of the ForStmt will be null if they were not
932/// specified in the source.
933///
934class ForStmt : public Stmt {
935  enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR };
936  Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt.
937  SourceLocation ForLoc;
938  SourceLocation LParenLoc, RParenLoc;
939
940public:
941  ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, Expr *Inc,
942          Stmt *Body, SourceLocation FL, SourceLocation LP, SourceLocation RP);
943
944  /// \brief Build an empty for statement.
945  explicit ForStmt(EmptyShell Empty) : Stmt(ForStmtClass, Empty) { }
946
947  Stmt *getInit() { return SubExprs[INIT]; }
948
949  /// \brief Retrieve the variable declared in this "for" statement, if any.
950  ///
951  /// In the following example, "y" is the condition variable.
952  /// \code
953  /// for (int x = random(); int y = mangle(x); ++x) {
954  ///   // ...
955  /// }
956  /// \endcode
957  VarDecl *getConditionVariable() const;
958  void setConditionVariable(ASTContext &C, VarDecl *V);
959
960  Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]); }
961  Expr *getInc()  { return reinterpret_cast<Expr*>(SubExprs[INC]); }
962  Stmt *getBody() { return SubExprs[BODY]; }
963
964  const Stmt *getInit() const { return SubExprs[INIT]; }
965  const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);}
966  const Expr *getInc()  const { return reinterpret_cast<Expr*>(SubExprs[INC]); }
967  const Stmt *getBody() const { return SubExprs[BODY]; }
968
969  void setInit(Stmt *S) { SubExprs[INIT] = S; }
970  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
971  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
972  void setBody(Stmt *S) { SubExprs[BODY] = S; }
973
974  SourceLocation getForLoc() const { return ForLoc; }
975  void setForLoc(SourceLocation L) { ForLoc = L; }
976  SourceLocation getLParenLoc() const { return LParenLoc; }
977  void setLParenLoc(SourceLocation L) { LParenLoc = L; }
978  SourceLocation getRParenLoc() const { return RParenLoc; }
979  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
980
981  SourceRange getSourceRange() const {
982    return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
983  }
984  static bool classof(const Stmt *T) {
985    return T->getStmtClass() == ForStmtClass;
986  }
987  static bool classof(const ForStmt *) { return true; }
988
989  // Iterators
990  child_range children() {
991    return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
992  }
993};
994
995/// GotoStmt - This represents a direct goto.
996///
997class GotoStmt : public Stmt {
998  LabelStmt *Label;
999  SourceLocation GotoLoc;
1000  SourceLocation LabelLoc;
1001public:
1002  GotoStmt(LabelStmt *label, SourceLocation GL, SourceLocation LL)
1003    : Stmt(GotoStmtClass), Label(label), GotoLoc(GL), LabelLoc(LL) {}
1004
1005  /// \brief Build an empty goto statement.
1006  explicit GotoStmt(EmptyShell Empty) : Stmt(GotoStmtClass, Empty) { }
1007
1008  LabelStmt *getLabel() const { return Label; }
1009  void setLabel(LabelStmt *S) { Label = S; }
1010
1011  SourceLocation getGotoLoc() const { return GotoLoc; }
1012  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
1013  SourceLocation getLabelLoc() const { return LabelLoc; }
1014  void setLabelLoc(SourceLocation L) { LabelLoc = L; }
1015
1016  SourceRange getSourceRange() const {
1017    return SourceRange(GotoLoc, LabelLoc);
1018  }
1019  static bool classof(const Stmt *T) {
1020    return T->getStmtClass() == GotoStmtClass;
1021  }
1022  static bool classof(const GotoStmt *) { return true; }
1023
1024  // Iterators
1025  child_range children() { return child_range(); }
1026};
1027
1028/// IndirectGotoStmt - This represents an indirect goto.
1029///
1030class IndirectGotoStmt : public Stmt {
1031  SourceLocation GotoLoc;
1032  SourceLocation StarLoc;
1033  Stmt *Target;
1034public:
1035  IndirectGotoStmt(SourceLocation gotoLoc, SourceLocation starLoc,
1036                   Expr *target)
1037    : Stmt(IndirectGotoStmtClass), GotoLoc(gotoLoc), StarLoc(starLoc),
1038      Target((Stmt*)target) {}
1039
1040  /// \brief Build an empty indirect goto statement.
1041  explicit IndirectGotoStmt(EmptyShell Empty)
1042    : Stmt(IndirectGotoStmtClass, Empty) { }
1043
1044  void setGotoLoc(SourceLocation L) { GotoLoc = L; }
1045  SourceLocation getGotoLoc() const { return GotoLoc; }
1046  void setStarLoc(SourceLocation L) { StarLoc = L; }
1047  SourceLocation getStarLoc() const { return StarLoc; }
1048
1049  Expr *getTarget() { return reinterpret_cast<Expr*>(Target); }
1050  const Expr *getTarget() const {return reinterpret_cast<const Expr*>(Target);}
1051  void setTarget(Expr *E) { Target = reinterpret_cast<Stmt*>(E); }
1052
1053  /// getConstantTarget - Returns the fixed target of this indirect
1054  /// goto, if one exists.
1055  LabelStmt *getConstantTarget();
1056  const LabelStmt *getConstantTarget() const {
1057    return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
1058  }
1059
1060  SourceRange getSourceRange() const {
1061    return SourceRange(GotoLoc, Target->getLocEnd());
1062  }
1063
1064  static bool classof(const Stmt *T) {
1065    return T->getStmtClass() == IndirectGotoStmtClass;
1066  }
1067  static bool classof(const IndirectGotoStmt *) { return true; }
1068
1069  // Iterators
1070  child_range children() { return child_range(&Target, &Target+1); }
1071};
1072
1073
1074/// ContinueStmt - This represents a continue.
1075///
1076class ContinueStmt : public Stmt {
1077  SourceLocation ContinueLoc;
1078public:
1079  ContinueStmt(SourceLocation CL) : Stmt(ContinueStmtClass), ContinueLoc(CL) {}
1080
1081  /// \brief Build an empty continue statement.
1082  explicit ContinueStmt(EmptyShell Empty) : Stmt(ContinueStmtClass, Empty) { }
1083
1084  SourceLocation getContinueLoc() const { return ContinueLoc; }
1085  void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
1086
1087  SourceRange getSourceRange() const {
1088    return SourceRange(ContinueLoc);
1089  }
1090
1091  static bool classof(const Stmt *T) {
1092    return T->getStmtClass() == ContinueStmtClass;
1093  }
1094  static bool classof(const ContinueStmt *) { return true; }
1095
1096  // Iterators
1097  child_range children() { return child_range(); }
1098};
1099
1100/// BreakStmt - This represents a break.
1101///
1102class BreakStmt : public Stmt {
1103  SourceLocation BreakLoc;
1104public:
1105  BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {}
1106
1107  /// \brief Build an empty break statement.
1108  explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { }
1109
1110  SourceLocation getBreakLoc() const { return BreakLoc; }
1111  void setBreakLoc(SourceLocation L) { BreakLoc = L; }
1112
1113  SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
1114
1115  static bool classof(const Stmt *T) {
1116    return T->getStmtClass() == BreakStmtClass;
1117  }
1118  static bool classof(const BreakStmt *) { return true; }
1119
1120  // Iterators
1121  child_range children() { return child_range(); }
1122};
1123
1124
1125/// ReturnStmt - This represents a return, optionally of an expression:
1126///   return;
1127///   return 4;
1128///
1129/// Note that GCC allows return with no argument in a function declared to
1130/// return a value, and it allows returning a value in functions declared to
1131/// return void.  We explicitly model this in the AST, which means you can't
1132/// depend on the return type of the function and the presence of an argument.
1133///
1134class ReturnStmt : public Stmt {
1135  Stmt *RetExpr;
1136  SourceLocation RetLoc;
1137  const VarDecl *NRVOCandidate;
1138
1139public:
1140  ReturnStmt(SourceLocation RL)
1141    : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
1142
1143  ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
1144    : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
1145      NRVOCandidate(NRVOCandidate) {}
1146
1147  /// \brief Build an empty return expression.
1148  explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { }
1149
1150  const Expr *getRetValue() const;
1151  Expr *getRetValue();
1152  void setRetValue(Expr *E) { RetExpr = reinterpret_cast<Stmt*>(E); }
1153
1154  SourceLocation getReturnLoc() const { return RetLoc; }
1155  void setReturnLoc(SourceLocation L) { RetLoc = L; }
1156
1157  /// \brief Retrieve the variable that might be used for the named return
1158  /// value optimization.
1159  ///
1160  /// The optimization itself can only be performed if the variable is
1161  /// also marked as an NRVO object.
1162  const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
1163  void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
1164
1165  SourceRange getSourceRange() const;
1166
1167  static bool classof(const Stmt *T) {
1168    return T->getStmtClass() == ReturnStmtClass;
1169  }
1170  static bool classof(const ReturnStmt *) { return true; }
1171
1172  // Iterators
1173  child_range children() {
1174    if (RetExpr) return child_range(&RetExpr, &RetExpr+1);
1175    return child_range();
1176  }
1177};
1178
1179/// AsmStmt - This represents a GNU inline-assembly statement extension.
1180///
1181class AsmStmt : public Stmt {
1182  SourceLocation AsmLoc, RParenLoc;
1183  StringLiteral *AsmStr;
1184
1185  bool IsSimple;
1186  bool IsVolatile;
1187  bool MSAsm;
1188
1189  unsigned NumOutputs;
1190  unsigned NumInputs;
1191  unsigned NumClobbers;
1192
1193  // FIXME: If we wanted to, we could allocate all of these in one big array.
1194  IdentifierInfo **Names;
1195  StringLiteral **Constraints;
1196  Stmt **Exprs;
1197  StringLiteral **Clobbers;
1198
1199public:
1200  AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
1201          bool msasm, unsigned numoutputs, unsigned numinputs,
1202          IdentifierInfo **names, StringLiteral **constraints,
1203          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
1204          StringLiteral **clobbers, SourceLocation rparenloc);
1205
1206  /// \brief Build an empty inline-assembly statement.
1207  explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
1208    Names(0), Constraints(0), Exprs(0), Clobbers(0) { }
1209
1210  SourceLocation getAsmLoc() const { return AsmLoc; }
1211  void setAsmLoc(SourceLocation L) { AsmLoc = L; }
1212  SourceLocation getRParenLoc() const { return RParenLoc; }
1213  void setRParenLoc(SourceLocation L) { RParenLoc = L; }
1214
1215  bool isVolatile() const { return IsVolatile; }
1216  void setVolatile(bool V) { IsVolatile = V; }
1217  bool isSimple() const { return IsSimple; }
1218  void setSimple(bool V) { IsSimple = V; }
1219  bool isMSAsm() const { return MSAsm; }
1220  void setMSAsm(bool V) { MSAsm = V; }
1221
1222  //===--- Asm String Analysis ---===//
1223
1224  const StringLiteral *getAsmString() const { return AsmStr; }
1225  StringLiteral *getAsmString() { return AsmStr; }
1226  void setAsmString(StringLiteral *E) { AsmStr = E; }
1227
1228  /// AsmStringPiece - this is part of a decomposed asm string specification
1229  /// (for use with the AnalyzeAsmString function below).  An asm string is
1230  /// considered to be a concatenation of these parts.
1231  class AsmStringPiece {
1232  public:
1233    enum Kind {
1234      String,  // String in .ll asm string form, "$" -> "$$" and "%%" -> "%".
1235      Operand  // Operand reference, with optional modifier %c4.
1236    };
1237  private:
1238    Kind MyKind;
1239    std::string Str;
1240    unsigned OperandNo;
1241  public:
1242    AsmStringPiece(const std::string &S) : MyKind(String), Str(S) {}
1243    AsmStringPiece(unsigned OpNo, char Modifier)
1244      : MyKind(Operand), Str(), OperandNo(OpNo) {
1245      Str += Modifier;
1246    }
1247
1248    bool isString() const { return MyKind == String; }
1249    bool isOperand() const { return MyKind == Operand; }
1250
1251    const std::string &getString() const {
1252      assert(isString());
1253      return Str;
1254    }
1255
1256    unsigned getOperandNo() const {
1257      assert(isOperand());
1258      return OperandNo;
1259    }
1260
1261    /// getModifier - Get the modifier for this operand, if present.  This
1262    /// returns '\0' if there was no modifier.
1263    char getModifier() const {
1264      assert(isOperand());
1265      return Str[0];
1266    }
1267  };
1268
1269  /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
1270  /// it into pieces.  If the asm string is erroneous, emit errors and return
1271  /// true, otherwise return false.  This handles canonicalization and
1272  /// translation of strings from GCC syntax to LLVM IR syntax, and handles
1273  //// flattening of named references like %[foo] to Operand AsmStringPiece's.
1274  unsigned AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece> &Pieces,
1275                            ASTContext &C, unsigned &DiagOffs) const;
1276
1277
1278  //===--- Output operands ---===//
1279
1280  unsigned getNumOutputs() const { return NumOutputs; }
1281
1282  IdentifierInfo *getOutputIdentifier(unsigned i) const {
1283    return Names[i];
1284  }
1285
1286  llvm::StringRef getOutputName(unsigned i) const {
1287    if (IdentifierInfo *II = getOutputIdentifier(i))
1288      return II->getName();
1289
1290    return llvm::StringRef();
1291  }
1292
1293  /// getOutputConstraint - Return the constraint string for the specified
1294  /// output operand.  All output constraints are known to be non-empty (either
1295  /// '=' or '+').
1296  llvm::StringRef getOutputConstraint(unsigned i) const;
1297
1298  const StringLiteral *getOutputConstraintLiteral(unsigned i) const {
1299    return Constraints[i];
1300  }
1301  StringLiteral *getOutputConstraintLiteral(unsigned i) {
1302    return Constraints[i];
1303  }
1304
1305  Expr *getOutputExpr(unsigned i);
1306
1307  const Expr *getOutputExpr(unsigned i) const {
1308    return const_cast<AsmStmt*>(this)->getOutputExpr(i);
1309  }
1310
1311  /// isOutputPlusConstraint - Return true if the specified output constraint
1312  /// is a "+" constraint (which is both an input and an output) or false if it
1313  /// is an "=" constraint (just an output).
1314  bool isOutputPlusConstraint(unsigned i) const {
1315    return getOutputConstraint(i)[0] == '+';
1316  }
1317
1318  /// getNumPlusOperands - Return the number of output operands that have a "+"
1319  /// constraint.
1320  unsigned getNumPlusOperands() const;
1321
1322  //===--- Input operands ---===//
1323
1324  unsigned getNumInputs() const { return NumInputs; }
1325
1326  IdentifierInfo *getInputIdentifier(unsigned i) const {
1327    return Names[i + NumOutputs];
1328  }
1329
1330  llvm::StringRef getInputName(unsigned i) const {
1331    if (IdentifierInfo *II = getInputIdentifier(i))
1332      return II->getName();
1333
1334    return llvm::StringRef();
1335  }
1336
1337  /// getInputConstraint - Return the specified input constraint.  Unlike output
1338  /// constraints, these can be empty.
1339  llvm::StringRef getInputConstraint(unsigned i) const;
1340
1341  const StringLiteral *getInputConstraintLiteral(unsigned i) const {
1342    return Constraints[i + NumOutputs];
1343  }
1344  StringLiteral *getInputConstraintLiteral(unsigned i) {
1345    return Constraints[i + NumOutputs];
1346  }
1347
1348  Expr *getInputExpr(unsigned i);
1349
1350  const Expr *getInputExpr(unsigned i) const {
1351    return const_cast<AsmStmt*>(this)->getInputExpr(i);
1352  }
1353
1354  void setOutputsAndInputsAndClobbers(ASTContext &C,
1355                                      IdentifierInfo **Names,
1356                                      StringLiteral **Constraints,
1357                                      Stmt **Exprs,
1358                                      unsigned NumOutputs,
1359                                      unsigned NumInputs,
1360                                      StringLiteral **Clobbers,
1361                                      unsigned NumClobbers);
1362
1363  //===--- Other ---===//
1364
1365  /// getNamedOperand - Given a symbolic operand reference like %[foo],
1366  /// translate this into a numeric value needed to reference the same operand.
1367  /// This returns -1 if the operand name is invalid.
1368  int getNamedOperand(llvm::StringRef SymbolicName) const;
1369
1370  unsigned getNumClobbers() const { return NumClobbers; }
1371  StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
1372  const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
1373
1374  SourceRange getSourceRange() const {
1375    return SourceRange(AsmLoc, RParenLoc);
1376  }
1377
1378  static bool classof(const Stmt *T) {return T->getStmtClass() == AsmStmtClass;}
1379  static bool classof(const AsmStmt *) { return true; }
1380
1381  // Input expr iterators.
1382
1383  typedef ExprIterator inputs_iterator;
1384  typedef ConstExprIterator const_inputs_iterator;
1385
1386  inputs_iterator begin_inputs() {
1387    return &Exprs[0] + NumOutputs;
1388  }
1389
1390  inputs_iterator end_inputs() {
1391    return &Exprs[0] + NumOutputs + NumInputs;
1392  }
1393
1394  const_inputs_iterator begin_inputs() const {
1395    return &Exprs[0] + NumOutputs;
1396  }
1397
1398  const_inputs_iterator end_inputs() const {
1399    return &Exprs[0] + NumOutputs + NumInputs;
1400  }
1401
1402  // Output expr iterators.
1403
1404  typedef ExprIterator outputs_iterator;
1405  typedef ConstExprIterator const_outputs_iterator;
1406
1407  outputs_iterator begin_outputs() {
1408    return &Exprs[0];
1409  }
1410  outputs_iterator end_outputs() {
1411    return &Exprs[0] + NumOutputs;
1412  }
1413
1414  const_outputs_iterator begin_outputs() const {
1415    return &Exprs[0];
1416  }
1417  const_outputs_iterator end_outputs() const {
1418    return &Exprs[0] + NumOutputs;
1419  }
1420
1421  child_range children() {
1422    return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
1423  }
1424};
1425
1426}  // end namespace clang
1427
1428#endif
1429