StmtCXX.h revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
10a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org//===--- StmtCXX.h - Classes for representing C++ statements ----*- C++ -*-===//
2a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
3a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//                     The LLVM Compiler Infrastructure
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This file is distributed under the University of Illinois Open Source
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// License. See LICENSE.TXT for details.
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
8a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
9a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
10a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// This file defines the C++ statement AST node classes.
11a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//
12a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org//===----------------------------------------------------------------------===//
13a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
14a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef LLVM_CLANG_AST_STMTCXX_H
15a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define LLVM_CLANG_AST_STMTCXX_H
16a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
17a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/AST/DeclarationName.h"
18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/AST/Expr.h"
19a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/AST/NestedNameSpecifier.h"
20a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "clang/AST/Stmt.h"
21a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "llvm/Support/Compiler.h"
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace clang {
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass VarDecl;
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
27a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// CXXCatchStmt - This represents a C++ catch block.
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///
29a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CXXCatchStmt : public Stmt {
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation CatchLoc;
31a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// The exception-declaration of the type.
327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  VarDecl *ExceptionDecl;
331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  /// The handler block.
34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Stmt *HandlerBlock;
35fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgpublic:
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXCatchStmt(SourceLocation catchLoc, VarDecl *exDecl, Stmt *handlerBlock)
38ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  : Stmt(CXXCatchStmtClass), CatchLoc(catchLoc), ExceptionDecl(exDecl),
39ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    HandlerBlock(handlerBlock) {}
40a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
41a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXCatchStmt(EmptyShell Empty)
42a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
43a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
44a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
45a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocEnd() const LLVM_READONLY {
46a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return HandlerBlock->getLocEnd();
47a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
48a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
49a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getCatchLoc() const { return CatchLoc; }
50a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VarDecl *getExceptionDecl() const { return ExceptionDecl; }
51a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  QualType getCaughtType() const;
52a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Stmt *getHandlerBlock() const { return HandlerBlock; }
53a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
54a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static bool classof(const Stmt *T) {
55dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    return T->getStmtClass() == CXXCatchStmtClass;
56a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
57a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
58a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  child_range children() { return child_range(&HandlerBlock, &HandlerBlock+1); }
59a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
60a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class ASTStmtReader;
61a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
6231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
63a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// CXXTryStmt - A C++ try block, including all handlers.
64a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///
65a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CXXTryStmt : public Stmt {
66a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation TryLoc;
67a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned NumHandlers;
68a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
69a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock, ArrayRef<Stmt*> handlers);
70a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
71a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXTryStmt(EmptyShell Empty, unsigned numHandlers)
72a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    : Stmt(CXXTryStmtClass), NumHandlers(numHandlers) { }
73a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Stmt const * const *getStmts() const {
75a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reinterpret_cast<Stmt const * const*>(this + 1);
764f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
77a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Stmt **getStmts() {
78a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reinterpret_cast<Stmt **>(this + 1);
79a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
80a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
81a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgpublic:
82a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static CXXTryStmt *Create(const ASTContext &C, SourceLocation tryLoc,
83a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            Stmt *tryBlock, ArrayRef<Stmt*> handlers);
84a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
85a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static CXXTryStmt *Create(const ASTContext &C, EmptyShell Empty,
86a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                            unsigned numHandlers);
87a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
88a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
89a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
90a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
91a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getTryLoc() const { return TryLoc; }
92a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getEndLoc() const {
93c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    return getStmts()[NumHandlers]->getLocEnd();
944f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  }
954f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
964f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  CompoundStmt *getTryBlock() {
974f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org    return cast<CompoundStmt>(getStmts()[0]);
980a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  }
994f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  const CompoundStmt *getTryBlock() const {
100a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return cast<CompoundStmt>(getStmts()[0]);
10183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
102a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
103a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  unsigned getNumHandlers() const { return NumHandlers; }
104a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXCatchStmt *getHandler(unsigned i) {
1057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    return cast<CXXCatchStmt>(getStmts()[i + 1]);
106a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1074acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org  const CXXCatchStmt *getHandler(unsigned i) const {
108c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    return cast<CXXCatchStmt>(getStmts()[i + 1]);
109a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
11049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
111a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static bool classof(const Stmt *T) {
112a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return T->getStmtClass() == CXXTryStmtClass;
113a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1144f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1154f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  child_range children() {
1163847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    return child_range(getStmts(), getStmts() + getNumHandlers() + 1);
117a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
118d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org
119160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  friend class ASTStmtReader;
1204f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org};
1214f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
1224f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org/// CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for
1234f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org/// statement, represented as 'for (range-declarator : range-expression)'.
1244f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org///
1259e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org/// This is stored in a partially-desugared form to allow full semantic
126a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// analysis of the constituent components. The original syntactic components
127c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org/// can be extracted using getLoopVariable and getRangeInit.
128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass CXXForRangeStmt : public Stmt {
1294d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END };
130378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // SubExprs[RANGE] is an expression or declstmt.
131c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // SubExprs[COND] and SubExprs[INC] are expressions.
132c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Stmt *SubExprs[END];
133717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  SourceLocation ForLoc;
134a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation ColonLoc;
135a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation RParenLoc;
1367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgpublic:
137a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd,
1387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                  Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body,
139a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                  SourceLocation FL, SourceLocation CL, SourceLocation RPL);
140a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { }
141a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
142a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
143a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  VarDecl *getLoopVariable();
14483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Expr *getRangeInit();
145a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1465f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  const VarDecl *getLoopVariable() const;
147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const Expr *getRangeInit() const;
148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
150a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); }
151a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeclStmt *getBeginEndStmt() {
152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
153a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
154e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org  Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); }
155a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); }
15683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); }
15774f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org  Stmt *getBody() { return SubExprs[BODY]; }
15874f333bce721daf6b1f9d7d3d3faa623f77658d7vegorov@chromium.org
159717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  const DeclStmt *getRangeStmt() const {
160a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return cast<DeclStmt>(SubExprs[RANGE]);
161a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
162d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  const DeclStmt *getBeginEndStmt() const {
163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return cast_or_null<DeclStmt>(SubExprs[BEGINEND]);
164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
165160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org  const Expr *getCond() const {
1660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org    return cast_or_null<Expr>(SubExprs[COND]);
167b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  }
1680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  const Expr *getInc() const {
169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return cast_or_null<Expr>(SubExprs[INC]);
170d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  }
171a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const DeclStmt *getLoopVarStmt() const {
172ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return cast<DeclStmt>(SubExprs[LOOPVAR]);
173d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  }
174a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const Stmt *getBody() const { return SubExprs[BODY]; }
1754f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
176a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); }
177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; }
178d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; }
179a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); }
180a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); }
181a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; }
182a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setBody(Stmt *S) { SubExprs[BODY] = S; }
183a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
185a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getForLoc() const { return ForLoc; }
1862c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  void setForLoc(SourceLocation Loc) { ForLoc = Loc; }
1877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  SourceLocation getColonLoc() const { return ColonLoc; }
188a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
189a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getRParenLoc() const { return RParenLoc; }
190a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
19183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; }
193a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocEnd() const LLVM_READONLY {
194dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    return SubExprs[BODY]->getLocEnd();
195a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
196a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static bool classof(const Stmt *T) {
198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return T->getStmtClass() == CXXForRangeStmtClass;
199dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  }
200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Iterators
202dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  child_range children() {
203a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return child_range(&SubExprs[0], &SubExprs[END]);
204dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  }
205dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org};
206dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org
207dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org/// \brief Representation of a Microsoft __if_exists or __if_not_exists
208dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org/// statement with a dependent name.
209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///
210a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// The __if_exists statement can be used to include a sequence of statements
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// in the program only when a particular dependent name does not exist. For
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// example:
2138f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org///
2148f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// \code
2158f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// template<typename T>
2168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// void call_foo(T &t) {
2178f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org///   __if_exists (T::foo) {
218a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///     t.foo(); // okay: only called when T::foo exists.
219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///   }
2208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// }
2218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// \endcode
2228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org///
2238f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org/// Similarly, the __if_not_exists statement can be used to include the
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// statements when a particular name does not exist.
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org///
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// Note that this statement only captures __if_exists and __if_not_exists
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// statements whose name is dependent. All non-dependent cases are handled
228a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// directly in the parser, so that they don't introduce a new scope. Clang
229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org/// introduces scopes in the dependent case to keep names inside the compound
230ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org/// statement from leaking out into the surround statements, which would
231ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org/// compromise the template instantiation model. This behavior differs from
232ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org/// Visual C++ (which never introduces a scope), but is a fairly reasonable
233ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org/// approximation of the VC++ behavior.
234ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.orgclass MSDependentExistsStmt : public Stmt {
235a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation KeywordLoc;
236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsIfExists;
237a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  NestedNameSpecifierLoc QualifierLoc;
238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeclarationNameInfo NameInfo;
239a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Stmt *SubStmt;
2408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
241ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  friend class ASTReader;
242ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  friend class ASTStmtReader;
243ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org
2448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgpublic:
2458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  MSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists,
246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org                        NestedNameSpecifierLoc QualifierLoc,
2478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                        DeclarationNameInfo NameInfo,
2488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                        CompoundStmt *SubStmt)
2495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  : Stmt(MSDependentExistsStmtClass),
250a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    KeywordLoc(KeywordLoc), IsIfExists(IsIfExists),
251a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    QualifierLoc(QualifierLoc), NameInfo(NameInfo),
252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SubStmt(reinterpret_cast<Stmt *>(SubStmt)) { }
253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Retrieve the location of the __if_exists or __if_not_exists
2558f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  /// keyword.
2568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  SourceLocation getKeywordLoc() const { return KeywordLoc; }
257a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2588f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  /// \brief Determine whether this is an __if_exists statement.
2598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  bool isIfExists() const { return IsIfExists; }
2608f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
261a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Determine whether this is an __if_exists statement.
262a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool isIfNotExists() const { return !IsIfExists; }
263a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
264a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Retrieve the nested-name-specifier that qualifies this name, if
265a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// any.
266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Retrieve the name of the entity we're testing for, along with
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// location information
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DeclarationNameInfo getNameInfo() const { return NameInfo; }
271a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
272a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// \brief Retrieve the compound statement that will be included in the
273a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  /// program only if the existence of the symbol matches the initial keyword.
274a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  CompoundStmt *getSubStmt() const {
275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return reinterpret_cast<CompoundStmt *>(SubStmt);
276a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
277a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
278a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; }
279a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  SourceLocation getLocEnd() const LLVM_READONLY { return SubStmt->getLocEnd();}
280496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
281a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  child_range children() {
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return child_range(&SubStmt, &SubStmt+1);
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static bool classof(const Stmt *T) {
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return T->getStmtClass() == MSDependentExistsStmtClass;
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
290496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org}  // end namespace clang
291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org#endif
293a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org