blob: 6b583ee577a44439261bd4d13bb21f617fdb1509 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner0bc735f2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer5f016e22007-07-11 17:01:13 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Stmt class and statement subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Stmt.h"
15#include "clang/AST/ExprCXX.h"
Steve Narofff494b572008-05-29 21:12:08 +000016#include "clang/AST/ExprObjC.h"
Sebastian Redl4b07b292008-12-22 19:15:10 +000017#include "clang/AST/Type.h"
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000018#include "clang/AST/ASTContext.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000019using namespace clang;
20
Reid Spencer5f016e22007-07-11 17:01:13 +000021static struct StmtClassNameTable {
Chris Lattner63381352007-08-25 01:42:24 +000022 const char *Name;
23 unsigned Counter;
24 unsigned Size;
Chris Lattner1f683e92007-08-25 01:55:00 +000025} StmtClassInfo[Stmt::lastExprConstant+1];
Chris Lattner63381352007-08-25 01:42:24 +000026
27static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
28 static bool Initialized = false;
29 if (Initialized)
30 return StmtClassInfo[E];
31
32 // Intialize the table on the first use.
33 Initialized = true;
Douglas Gregorf2cad862008-11-14 12:46:07 +000034#define STMT(CLASS, PARENT) \
35 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
36 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
Reid Spencer5f016e22007-07-11 17:01:13 +000037#include "clang/AST/StmtNodes.def"
Nico Weber608b17f2008-08-05 23:15:29 +000038
Chris Lattner63381352007-08-25 01:42:24 +000039 return StmtClassInfo[E];
40}
41
Reid Spencer5f016e22007-07-11 17:01:13 +000042const char *Stmt::getStmtClassName() const {
Chris Lattner63381352007-08-25 01:42:24 +000043 return getStmtInfoTableEntry(sClass).Name;
Reid Spencer5f016e22007-07-11 17:01:13 +000044}
45
Chris Lattner24e1e702009-03-04 04:23:07 +000046void Stmt::DestroyChildren(ASTContext &C) {
47 for (child_iterator I = child_begin(), E = child_end(); I !=E; )
Douglas Gregor860f6d42009-01-16 06:50:08 +000048 if (Stmt* Child = *I++) Child->Destroy(C);
Ted Kremenek27f8a282008-05-20 00:43:19 +000049}
50
Chris Lattner24e1e702009-03-04 04:23:07 +000051void Stmt::Destroy(ASTContext &C) {
Ted Kremenek27f8a282008-05-20 00:43:19 +000052 DestroyChildren(C);
Ted Kremenekf809e3b2008-05-20 04:10:52 +000053 // FIXME: Eventually all Stmts should be allocated with the allocator
54 // in ASTContext, just like with Decls.
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000055 this->~Stmt();
56 C.Deallocate((void *)this);
Ted Kremenek9c1863e2008-05-19 22:02:12 +000057}
58
Chris Lattner24e1e702009-03-04 04:23:07 +000059void DeclStmt::Destroy(ASTContext &C) {
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000060 this->~DeclStmt();
61 C.Deallocate((void *)this);
Ted Kremenek8e355f22008-05-21 15:53:55 +000062}
63
Reid Spencer5f016e22007-07-11 17:01:13 +000064void Stmt::PrintStats() {
Chris Lattner63381352007-08-25 01:42:24 +000065 // Ensure the table is primed.
66 getStmtInfoTableEntry(Stmt::NullStmtClass);
Nico Weber608b17f2008-08-05 23:15:29 +000067
Reid Spencer5f016e22007-07-11 17:01:13 +000068 unsigned sum = 0;
69 fprintf(stderr, "*** Stmt/Expr Stats:\n");
Chris Lattner1f683e92007-08-25 01:55:00 +000070 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000071 if (StmtClassInfo[i].Name == 0) continue;
72 sum += StmtClassInfo[i].Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000073 }
74 fprintf(stderr, " %d stmts/exprs total.\n", sum);
75 sum = 0;
Chris Lattner1f683e92007-08-25 01:55:00 +000076 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000077 if (StmtClassInfo[i].Name == 0) continue;
Nico Weber608b17f2008-08-05 23:15:29 +000078 fprintf(stderr, " %d %s, %d each (%d bytes)\n",
Chris Lattner63381352007-08-25 01:42:24 +000079 StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
80 StmtClassInfo[i].Size,
81 StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
82 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
Reid Spencer5f016e22007-07-11 17:01:13 +000083 }
84 fprintf(stderr, "Total bytes = %d\n", sum);
85}
86
87void Stmt::addStmtClass(StmtClass s) {
Chris Lattner63381352007-08-25 01:42:24 +000088 ++getStmtInfoTableEntry(s).Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000089}
90
91static bool StatSwitch = false;
92
93bool Stmt::CollectingStats(bool enable) {
94 if (enable) StatSwitch = true;
Chris Lattner63381352007-08-25 01:42:24 +000095 return StatSwitch;
Reid Spencer5f016e22007-07-11 17:01:13 +000096}
97
98
Reid Spencer5f016e22007-07-11 17:01:13 +000099const char *LabelStmt::getName() const {
100 return getID()->getName();
101}
102
Steve Naroff507f2d52007-08-31 23:49:30 +0000103// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weber608b17f2008-08-05 23:15:29 +0000104SourceRange ReturnStmt::getSourceRange() const {
Steve Naroff507f2d52007-08-31 23:49:30 +0000105 if (RetExpr)
106 return SourceRange(RetLoc, RetExpr->getLocEnd());
107 else
108 return SourceRange(RetLoc);
109}
110
Ted Kremenekd48ade62007-10-01 16:34:52 +0000111bool Stmt::hasImplicitControlFlow() const {
112 switch (sClass) {
113 default:
114 return false;
Nico Weber608b17f2008-08-05 23:15:29 +0000115
Ted Kremenekd48ade62007-10-01 16:34:52 +0000116 case CallExprClass:
117 case ConditionalOperatorClass:
118 case ChooseExprClass:
119 case StmtExprClass:
120 case DeclStmtClass:
Nico Weber608b17f2008-08-05 23:15:29 +0000121 return true;
122
Ted Kremenekd48ade62007-10-01 16:34:52 +0000123 case Stmt::BinaryOperatorClass: {
124 const BinaryOperator* B = cast<BinaryOperator>(this);
125 if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
126 return true;
127 else
128 return false;
129 }
130 }
131}
132
Chris Lattnerb3277932009-03-10 04:59:06 +0000133Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000134 return cast<Expr>(Exprs[i]);
135}
Chris Lattnerb3277932009-03-10 04:59:06 +0000136
137/// getOutputConstraint - Return the constraint string for the specified
138/// output operand. All output constraints are known to be non-empty (either
139/// '=' or '+').
140std::string AsmStmt::getOutputConstraint(unsigned i) const {
141 return std::string(Constraints[i]->getStrData(),
142 Constraints[i]->getByteLength());
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000143}
Chris Lattnerb3277932009-03-10 04:59:06 +0000144
145
146Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000147 return cast<Expr>(Exprs[i + NumOutputs]);
148}
Chris Lattnerb3277932009-03-10 04:59:06 +0000149
150/// getInputConstraint - Return the specified input constraint. Unlike output
151/// constraints, these can be empty.
152std::string AsmStmt::getInputConstraint(unsigned i) const {
153 return std::string(Constraints[i + NumOutputs]->getStrData(),
154 Constraints[i + NumOutputs]->getByteLength());
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000155}
156
Chris Lattner10ca96a2009-03-10 06:33:24 +0000157
158/// getNamedOperand - Given a symbolic operand reference like %[foo],
159/// translate this into a numeric value needed to reference the same operand.
160/// This returns -1 if the operand name is invalid.
161int AsmStmt::getNamedOperand(const std::string &SymbolicName) const {
162 unsigned NumPlusOperands = 0;
163
164 // Check if this is an output operand.
165 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
166 if (getOutputName(i) == SymbolicName)
167 return i;
168
169 // Keep track of the number of '+' operands.
170 if (isOutputPlusConstraint(i)) ++NumPlusOperands;
171 }
172
173 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
174 if (getInputName(i) == SymbolicName)
175 return getNumOutputs() + NumPlusOperands + i;
176
177 // Not found.
178 return -1;
179}
180
181
Chris Lattner458cd9c2009-03-10 23:21:44 +0000182/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
183/// it into pieces. If the asm string is erroneous, emit errors and return
184/// true, otherwise return false.
Chris Lattnerfb5058e2009-03-10 23:41:04 +0000185unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
186 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000187 const char *StrStart = getAsmString()->getStrData();
188 const char *StrEnd = StrStart + getAsmString()->getByteLength();
189
190 // "Simple" inline asms have no constraints or operands, just convert the asm
191 // string to escape $'s.
192 if (isSimple()) {
193 std::string Result;
194 for (; StrStart != StrEnd; ++StrStart) {
195 switch (*StrStart) {
196 case '$':
197 Result += "$$";
198 break;
199 default:
200 Result += *StrStart;
201 break;
202 }
203 }
204 Pieces.push_back(AsmStringPiece(Result));
205 return false;
206 }
207
208 // CurStringPiece - The current string that we are building up as we scan the
209 // asm string.
210 std::string CurStringPiece;
211
212 while (1) {
213 // Done with the string?
214 if (StrStart == StrEnd) {
215 if (!CurStringPiece.empty())
216 Pieces.push_back(AsmStringPiece(CurStringPiece));
217 return false;
218 }
219
220 char CurChar = *StrStart++;
221 if (CurChar == '$') {
222 CurStringPiece += "$$";
223 continue;
224 } else if (CurChar != '%') {
225 CurStringPiece += CurChar;
226 continue;
227 }
228
229 // Escaped "%" character in asm string.
230 // FIXME: This should be caught during Sema.
231 assert(StrStart != StrEnd && "Trailing '%' in asm string.");
232
233 char EscapedChar = *StrStart++;
234 if (EscapedChar == '%') { // %% -> %
235 // Escaped percentage sign.
236 CurStringPiece += '%';
237 continue;
238 }
239
240 if (EscapedChar == '=') { // %= -> Generate an unique ID.
241 CurStringPiece += "${:uid}";
242 continue;
243 }
244
245 // Otherwise, we have an operand. If we have accumulated a string so far,
246 // add it to the Pieces list.
247 if (!CurStringPiece.empty()) {
248 Pieces.push_back(AsmStringPiece(CurStringPiece));
249 CurStringPiece.clear();
250 }
251
252 // Handle %x4 and %x[foo] by capturing x as the modifier character.
253 char Modifier = '\0';
254 if (isalpha(EscapedChar)) {
255 Modifier = EscapedChar;
256 EscapedChar = *StrStart++;
257 }
258
259 if (isdigit(EscapedChar)) {
260 // %n - Assembler operand n
261 char *End;
262 unsigned long N = strtoul(StrStart-1, &End, 10);
263 assert(End != StrStart-1 && "We know that EscapedChar is a digit!");
264 StrStart = End;
265
266 // FIXME: This should be caught during Sema.
267 //unsigned NumOperands = S.getNumOutputs() + S.getNumInputs();
268 //assert(N < NumOperands && "Operand number out of range!");
269
270 Pieces.push_back(AsmStringPiece(N, Modifier));
271 continue;
272 }
273
274 // Handle %[foo], a symbolic operand reference.
275 if (EscapedChar == '[') {
276 const char *NameEnd = (const char*)memchr(StrStart, ']', StrEnd-StrStart);
277 // FIXME: Should be caught by sema.
278 // FIXME: Does sema catch multiple operands with the same name?
279 assert(NameEnd != 0 && "Could not parse symbolic name");
280 std::string SymbolicName(StrStart, NameEnd);
281 StrStart = NameEnd+1;
282
283 int N = getNamedOperand(SymbolicName);
284 assert(N != -1 && "FIXME: Catch in Sema.");
285 Pieces.push_back(AsmStringPiece(N, Modifier));
286 continue;
287 }
288
289 assert(0 && "FIXME: Reject");
290 return true;
291 }
292}
293
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000294//===----------------------------------------------------------------------===//
295// Constructors
296//===----------------------------------------------------------------------===//
297
Anders Carlssondfab34a2008-02-05 23:03:50 +0000298AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000299 unsigned numoutputs, unsigned numinputs,
300 std::string *names, StringLiteral **constraints,
301 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
302 StringLiteral **clobbers, SourceLocation rparenloc)
Anders Carlssonb235fc22007-11-22 01:36:19 +0000303 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Anders Carlssondfab34a2008-02-05 23:03:50 +0000304 , IsSimple(issimple), IsVolatile(isvolatile)
305 , NumOutputs(numoutputs), NumInputs(numinputs) {
Anders Carlssonb235fc22007-11-22 01:36:19 +0000306 for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
307 Names.push_back(names[i]);
308 Exprs.push_back(exprs[i]);
Nico Weber608b17f2008-08-05 23:15:29 +0000309 Constraints.push_back(constraints[i]);
Anders Carlssonb235fc22007-11-22 01:36:19 +0000310 }
Nico Weber608b17f2008-08-05 23:15:29 +0000311
Anders Carlssonb235fc22007-11-22 01:36:19 +0000312 for (unsigned i = 0; i != numclobbers; i++)
313 Clobbers.push_back(clobbers[i]);
314}
315
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000316ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
317 Stmt *Body, SourceLocation FCL,
Nico Weber608b17f2008-08-05 23:15:29 +0000318 SourceLocation RPL)
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000319: Stmt(ObjCForCollectionStmtClass) {
320 SubExprs[ELEM] = Elem;
321 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
322 SubExprs[BODY] = Body;
323 ForLoc = FCL;
324 RParenLoc = RPL;
325}
326
327
Nico Weber608b17f2008-08-05 23:15:29 +0000328ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
329 SourceLocation rparenloc,
Steve Naroff7ba138a2009-03-03 19:52:17 +0000330 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000331 Stmt *atCatchList)
332: Stmt(ObjCAtCatchStmtClass) {
Steve Naroff7ba138a2009-03-03 19:52:17 +0000333 ExceptionDecl = catchVarDecl;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000334 SubExprs[BODY] = atCatchStmt;
Eli Friedman0613c372008-05-25 04:34:57 +0000335 SubExprs[NEXT_CATCH] = NULL;
Daniel Dunbar93b2bdb2009-03-01 04:28:32 +0000336 // FIXME: O(N^2) in number of catch blocks.
Eli Friedman0613c372008-05-25 04:34:57 +0000337 if (atCatchList) {
Ted Kremenekff981022008-02-01 21:28:59 +0000338 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
339
Nico Weber608b17f2008-08-05 23:15:29 +0000340 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
Ted Kremenekff981022008-02-01 21:28:59 +0000341 AtCatchList = NextCatch;
Nico Weber608b17f2008-08-05 23:15:29 +0000342
Ted Kremenekff981022008-02-01 21:28:59 +0000343 AtCatchList->SubExprs[NEXT_CATCH] = this;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000344 }
345 AtCatchLoc = atCatchLoc;
346 RParenLoc = rparenloc;
347}
348
349
Ted Kremenek82977772007-08-24 21:09:09 +0000350//===----------------------------------------------------------------------===//
351// Child Iterators for iterating over subexpressions/substatements
352//===----------------------------------------------------------------------===//
353
354// DeclStmt
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000355Stmt::child_iterator DeclStmt::child_begin() {
356 return StmtIterator(DG.begin(), DG.end());
Ted Kremenek14f8b4f2008-08-05 20:46:55 +0000357}
358
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000359Stmt::child_iterator DeclStmt::child_end() {
360 return StmtIterator(DG.end(), DG.end());
Ted Kremenek65aa3b92008-10-06 20:54:44 +0000361}
362
Ted Kremenek82977772007-08-24 21:09:09 +0000363// NullStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000364Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
365Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000366
367// CompoundStmt
368Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
Ted Kremenek8189cde2009-02-07 01:47:29 +0000369Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
Ted Kremenek82977772007-08-24 21:09:09 +0000370
Ted Kremenekd97bb6c2007-08-30 16:50:46 +0000371// CaseStmt
372Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
373Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
374
375// DefaultStmt
376Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
377Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000378
379// LabelStmt
380Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
Chris Lattnerb3938792007-08-30 00:53:54 +0000381Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000382
383// IfStmt
384Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
385Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
386
387// SwitchStmt
388Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
389Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
390
391// WhileStmt
392Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
393Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
394
395// DoStmt
396Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
397Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
398
399// ForStmt
400Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
401Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
402
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000403// ObjCForCollectionStmt
Nico Weber608b17f2008-08-05 23:15:29 +0000404Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
405 return &SubExprs[0];
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000406}
Nico Weber608b17f2008-08-05 23:15:29 +0000407Stmt::child_iterator ObjCForCollectionStmt::child_end() {
408 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000409}
410
Ted Kremenek82977772007-08-24 21:09:09 +0000411// GotoStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000412Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
413Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000414
415// IndirectGotoStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000416Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
417const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
Ted Kremenek82977772007-08-24 21:09:09 +0000418
Ted Kremenek1060aff2008-06-17 03:11:08 +0000419Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
420Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000421
422// ContinueStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000423Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
424Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000425
426// BreakStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000427Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
428Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000429
430// ReturnStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000431const Expr* ReturnStmt::getRetValue() const {
432 return cast_or_null<Expr>(RetExpr);
433}
434Expr* ReturnStmt::getRetValue() {
435 return cast_or_null<Expr>(RetExpr);
Ted Kremenek82977772007-08-24 21:09:09 +0000436}
437
Ted Kremenek1060aff2008-06-17 03:11:08 +0000438Stmt::child_iterator ReturnStmt::child_begin() {
439 return &RetExpr;
440}
441Stmt::child_iterator ReturnStmt::child_end() {
442 return RetExpr ? &RetExpr+1 : &RetExpr;
Ted Kremenek2298f912007-08-27 20:58:16 +0000443}
Ted Kremenek82977772007-08-24 21:09:09 +0000444
Chris Lattnerfe795952007-10-29 04:04:16 +0000445// AsmStmt
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000446Stmt::child_iterator AsmStmt::child_begin() {
447 return Exprs.empty() ? 0 : &Exprs[0];
448}
449Stmt::child_iterator AsmStmt::child_end() {
450 return Exprs.empty() ? 0 : &Exprs[0] + Exprs.size();
451}
Chris Lattnerfe795952007-10-29 04:04:16 +0000452
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000453// ObjCAtCatchStmt
454Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000455Stmt::child_iterator ObjCAtCatchStmt::child_end() {
456 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000457}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000458
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000459// ObjCAtFinallyStmt
460Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
461Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000462
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000463// ObjCAtTryStmt
464Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000465Stmt::child_iterator ObjCAtTryStmt::child_end() {
466 return &SubStmts[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000467}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000468
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000469// ObjCAtThrowStmt
470Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000471 return &Throw;
472}
473
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000474Stmt::child_iterator ObjCAtThrowStmt::child_end() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000475 return &Throw+1;
476}
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000477
478// ObjCAtSynchronizedStmt
479Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000480 return &SubStmts[0];
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000481}
482
483Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000484 return &SubStmts[0]+END_EXPR;
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000485}
486
Sebastian Redl4b07b292008-12-22 19:15:10 +0000487// CXXCatchStmt
488Stmt::child_iterator CXXCatchStmt::child_begin() {
489 return &HandlerBlock;
490}
491
492Stmt::child_iterator CXXCatchStmt::child_end() {
493 return &HandlerBlock + 1;
494}
495
496QualType CXXCatchStmt::getCaughtType() {
497 if (ExceptionDecl)
498 return llvm::cast<VarDecl>(ExceptionDecl)->getType();
499 return QualType();
500}
501
502void CXXCatchStmt::Destroy(ASTContext& C) {
Sebastian Redl8351da02008-12-22 21:35:02 +0000503 if (ExceptionDecl)
504 ExceptionDecl->Destroy(C);
Sebastian Redl4b07b292008-12-22 19:15:10 +0000505 Stmt::Destroy(C);
506}
Sebastian Redl8351da02008-12-22 21:35:02 +0000507
508// CXXTryStmt
509Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
510Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }
511
512CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
513 Stmt **handlers, unsigned numHandlers)
514 : Stmt(CXXTryStmtClass), TryLoc(tryLoc) {
515 Stmts.push_back(tryBlock);
516 Stmts.insert(Stmts.end(), handlers, handlers + numHandlers);
517}