blob: 668f7ef57fb6fb6f190df3004aa8825c06ddcc46 [file] [log] [blame]
Chris Lattnerf42cce72006-10-25 04:09:21 +00001//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattnerf42cce72006-10-25 04:09:21 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Stmt class and statement subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/Stmt.h"
Chris Lattner29375652006-12-04 18:06:35 +000015#include "clang/AST/ExprCXX.h"
Steve Naroff021ca182008-05-29 21:12:08 +000016#include "clang/AST/ExprObjC.h"
Chris Lattnerf0b64d72009-04-26 01:32:48 +000017#include "clang/AST/StmtCXX.h"
18#include "clang/AST/StmtObjC.h"
Sebastian Redl54c04d42008-12-22 19:15:10 +000019#include "clang/AST/Type.h"
Ted Kremenekfe7a9602009-02-06 01:42:09 +000020#include "clang/AST/ASTContext.h"
Chris Lattnera41b8472009-03-10 23:51:40 +000021#include "clang/AST/ASTDiagnostic.h"
Chris Lattnerf42cce72006-10-25 04:09:21 +000022using namespace clang;
23
Steve Narofff84d11f2007-05-23 21:48:04 +000024static struct StmtClassNameTable {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000025 const char *Name;
26 unsigned Counter;
27 unsigned Size;
Chris Lattnerd8c9fc52007-08-25 01:55:00 +000028} StmtClassInfo[Stmt::lastExprConstant+1];
Chris Lattner4d15a0d2007-08-25 01:42:24 +000029
30static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
31 static bool Initialized = false;
32 if (Initialized)
33 return StmtClassInfo[E];
34
35 // Intialize the table on the first use.
36 Initialized = true;
Douglas Gregorbe35ce92008-11-14 12:46:07 +000037#define STMT(CLASS, PARENT) \
38 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
39 StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
Steve Narofff1e53692007-03-23 22:27:02 +000040#include "clang/AST/StmtNodes.def"
Nico Weberde565e32008-08-05 23:15:29 +000041
Chris Lattner4d15a0d2007-08-25 01:42:24 +000042 return StmtClassInfo[E];
43}
44
Steve Narofff1e53692007-03-23 22:27:02 +000045const char *Stmt::getStmtClassName() const {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000046 return getStmtInfoTableEntry(sClass).Name;
Steve Narofff1e53692007-03-23 22:27:02 +000047}
Steve Narofff84d11f2007-05-23 21:48:04 +000048
Chris Lattner34a22092009-03-04 04:23:07 +000049void Stmt::DestroyChildren(ASTContext &C) {
50 for (child_iterator I = child_begin(), E = child_end(); I !=E; )
Douglas Gregor2b5d4302009-01-16 06:50:08 +000051 if (Stmt* Child = *I++) Child->Destroy(C);
Ted Kremenekce20e8f2008-05-20 00:43:19 +000052}
53
Douglas Gregore26a2852009-08-07 06:08:38 +000054void Stmt::DoDestroy(ASTContext &C) {
Ted Kremenekce20e8f2008-05-20 00:43:19 +000055 DestroyChildren(C);
Ted Kremenekfe7a9602009-02-06 01:42:09 +000056 this->~Stmt();
57 C.Deallocate((void *)this);
Ted Kremenekee579422008-05-19 22:02:12 +000058}
59
Steve Narofff84d11f2007-05-23 21:48:04 +000060void Stmt::PrintStats() {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000061 // Ensure the table is primed.
62 getStmtInfoTableEntry(Stmt::NullStmtClass);
Nico Weberde565e32008-08-05 23:15:29 +000063
Steve Narofff84d11f2007-05-23 21:48:04 +000064 unsigned sum = 0;
65 fprintf(stderr, "*** Stmt/Expr Stats:\n");
Chris Lattnerd8c9fc52007-08-25 01:55:00 +000066 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000067 if (StmtClassInfo[i].Name == 0) continue;
68 sum += StmtClassInfo[i].Counter;
Steve Narofff84d11f2007-05-23 21:48:04 +000069 }
70 fprintf(stderr, " %d stmts/exprs total.\n", sum);
71 sum = 0;
Chris Lattnerd8c9fc52007-08-25 01:55:00 +000072 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000073 if (StmtClassInfo[i].Name == 0) continue;
Douglas Gregora30d0462009-05-26 14:40:08 +000074 if (StmtClassInfo[i].Counter == 0) continue;
Nico Weberde565e32008-08-05 23:15:29 +000075 fprintf(stderr, " %d %s, %d each (%d bytes)\n",
Chris Lattner4d15a0d2007-08-25 01:42:24 +000076 StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
77 StmtClassInfo[i].Size,
78 StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
79 sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
Steve Narofff84d11f2007-05-23 21:48:04 +000080 }
81 fprintf(stderr, "Total bytes = %d\n", sum);
82}
83
84void Stmt::addStmtClass(StmtClass s) {
Chris Lattner4d15a0d2007-08-25 01:42:24 +000085 ++getStmtInfoTableEntry(s).Counter;
Steve Narofff84d11f2007-05-23 21:48:04 +000086}
87
88static bool StatSwitch = false;
89
90bool Stmt::CollectingStats(bool enable) {
91 if (enable) StatSwitch = true;
Chris Lattner4d15a0d2007-08-25 01:42:24 +000092 return StatSwitch;
Steve Narofff84d11f2007-05-23 21:48:04 +000093}
94
Anders Carlsson03b0dd592009-05-15 00:21:21 +000095NullStmt* NullStmt::Clone(ASTContext &C) const {
96 return new (C) NullStmt(SemiLoc);
97}
98
Douglas Gregorca602242009-05-15 22:32:39 +000099ContinueStmt* ContinueStmt::Clone(ASTContext &C) const {
100 return new (C) ContinueStmt(ContinueLoc);
101}
102
103BreakStmt* BreakStmt::Clone(ASTContext &C) const {
104 return new (C) BreakStmt(BreakLoc);
105}
106
Douglas Gregora9af1d12009-04-17 00:04:06 +0000107void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
108 if (this->Body)
109 C.Deallocate(Body);
110 this->NumStmts = NumStmts;
111
112 Body = new (C) Stmt*[NumStmts];
113 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
114}
Steve Narofff84d11f2007-05-23 21:48:04 +0000115
Chris Lattnereefa10e2007-05-28 06:56:27 +0000116const char *LabelStmt::getName() const {
117 return getID()->getName();
118}
119
Steve Naroffdc9f36e2007-08-31 23:49:30 +0000120// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weberde565e32008-08-05 23:15:29 +0000121SourceRange ReturnStmt::getSourceRange() const {
Steve Naroffdc9f36e2007-08-31 23:49:30 +0000122 if (RetExpr)
123 return SourceRange(RetLoc, RetExpr->getLocEnd());
124 else
125 return SourceRange(RetLoc);
126}
127
Ted Kremenek7f74e132007-10-01 16:34:52 +0000128bool Stmt::hasImplicitControlFlow() const {
129 switch (sClass) {
130 default:
131 return false;
Nico Weberde565e32008-08-05 23:15:29 +0000132
Ted Kremenek7f74e132007-10-01 16:34:52 +0000133 case CallExprClass:
134 case ConditionalOperatorClass:
135 case ChooseExprClass:
136 case StmtExprClass:
137 case DeclStmtClass:
Nico Weberde565e32008-08-05 23:15:29 +0000138 return true;
139
Ted Kremenek7f74e132007-10-01 16:34:52 +0000140 case Stmt::BinaryOperatorClass: {
141 const BinaryOperator* B = cast<BinaryOperator>(this);
142 if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
143 return true;
144 else
145 return false;
146 }
147 }
148}
149
Chris Lattner72bbf172009-03-10 04:59:06 +0000150Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenek5778acf2008-10-27 18:40:21 +0000151 return cast<Expr>(Exprs[i]);
152}
Chris Lattner72bbf172009-03-10 04:59:06 +0000153
154/// getOutputConstraint - Return the constraint string for the specified
155/// output operand. All output constraints are known to be non-empty (either
156/// '=' or '+').
157std::string AsmStmt::getOutputConstraint(unsigned i) const {
158 return std::string(Constraints[i]->getStrData(),
159 Constraints[i]->getByteLength());
Ted Kremenek5778acf2008-10-27 18:40:21 +0000160}
Chris Lattner72bbf172009-03-10 04:59:06 +0000161
Chris Lattner14311922009-03-11 00:23:13 +0000162/// getNumPlusOperands - Return the number of output operands that have a "+"
163/// constraint.
164unsigned AsmStmt::getNumPlusOperands() const {
165 unsigned Res = 0;
166 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
167 if (isOutputPlusConstraint(i))
168 ++Res;
169 return Res;
170}
171
172
Chris Lattner72bbf172009-03-10 04:59:06 +0000173
174Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenek5778acf2008-10-27 18:40:21 +0000175 return cast<Expr>(Exprs[i + NumOutputs]);
176}
Chris Lattner72bbf172009-03-10 04:59:06 +0000177
178/// getInputConstraint - Return the specified input constraint. Unlike output
179/// constraints, these can be empty.
180std::string AsmStmt::getInputConstraint(unsigned i) const {
181 return std::string(Constraints[i + NumOutputs]->getStrData(),
182 Constraints[i + NumOutputs]->getByteLength());
Ted Kremenek5778acf2008-10-27 18:40:21 +0000183}
184
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000185
Douglas Gregorf994f062009-04-17 20:57:14 +0000186void AsmStmt::setOutputsAndInputs(unsigned NumOutputs,
187 unsigned NumInputs,
188 const std::string *Names,
189 StringLiteral **Constraints,
190 Stmt **Exprs) {
191 this->NumOutputs = NumOutputs;
192 this->NumInputs = NumInputs;
193 this->Names.clear();
194 this->Names.insert(this->Names.end(), Names, Names + NumOutputs + NumInputs);
195 this->Constraints.clear();
196 this->Constraints.insert(this->Constraints.end(),
197 Constraints, Constraints + NumOutputs + NumInputs);
198 this->Exprs.clear();
199 this->Exprs.insert(this->Exprs.end(), Exprs, Exprs + NumOutputs + NumInputs);
200}
201
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000202/// getNamedOperand - Given a symbolic operand reference like %[foo],
203/// translate this into a numeric value needed to reference the same operand.
204/// This returns -1 if the operand name is invalid.
205int AsmStmt::getNamedOperand(const std::string &SymbolicName) const {
206 unsigned NumPlusOperands = 0;
207
208 // Check if this is an output operand.
209 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
210 if (getOutputName(i) == SymbolicName)
211 return i;
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000212 }
213
214 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
215 if (getInputName(i) == SymbolicName)
216 return getNumOutputs() + NumPlusOperands + i;
217
218 // Not found.
219 return -1;
220}
221
Douglas Gregorf994f062009-04-17 20:57:14 +0000222void AsmStmt::setClobbers(StringLiteral **Clobbers, unsigned NumClobbers) {
223 this->Clobbers.clear();
224 this->Clobbers.insert(this->Clobbers.end(), Clobbers, Clobbers + NumClobbers);
225}
Chris Lattnerd7d5fdf2009-03-10 06:33:24 +0000226
Chris Lattner35b58362009-03-10 23:21:44 +0000227/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
228/// it into pieces. If the asm string is erroneous, emit errors and return
229/// true, otherwise return false.
Chris Lattnerd8c7ba22009-03-10 23:41:04 +0000230unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
231 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner35b58362009-03-10 23:21:44 +0000232 const char *StrStart = getAsmString()->getStrData();
233 const char *StrEnd = StrStart + getAsmString()->getByteLength();
Chris Lattnera41b8472009-03-10 23:51:40 +0000234 const char *CurPtr = StrStart;
Chris Lattner35b58362009-03-10 23:21:44 +0000235
236 // "Simple" inline asms have no constraints or operands, just convert the asm
237 // string to escape $'s.
238 if (isSimple()) {
239 std::string Result;
Chris Lattnera41b8472009-03-10 23:51:40 +0000240 for (; CurPtr != StrEnd; ++CurPtr) {
241 switch (*CurPtr) {
Chris Lattner35b58362009-03-10 23:21:44 +0000242 case '$':
243 Result += "$$";
244 break;
245 default:
Chris Lattnera41b8472009-03-10 23:51:40 +0000246 Result += *CurPtr;
Chris Lattner35b58362009-03-10 23:21:44 +0000247 break;
248 }
249 }
250 Pieces.push_back(AsmStringPiece(Result));
Chris Lattnera41b8472009-03-10 23:51:40 +0000251 return 0;
Chris Lattner35b58362009-03-10 23:21:44 +0000252 }
253
254 // CurStringPiece - The current string that we are building up as we scan the
255 // asm string.
256 std::string CurStringPiece;
257
258 while (1) {
259 // Done with the string?
Chris Lattnera41b8472009-03-10 23:51:40 +0000260 if (CurPtr == StrEnd) {
Chris Lattner35b58362009-03-10 23:21:44 +0000261 if (!CurStringPiece.empty())
262 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattnera41b8472009-03-10 23:51:40 +0000263 return 0;
Chris Lattner35b58362009-03-10 23:21:44 +0000264 }
265
Chris Lattnera41b8472009-03-10 23:51:40 +0000266 char CurChar = *CurPtr++;
Chris Lattner35b58362009-03-10 23:21:44 +0000267 if (CurChar == '$') {
268 CurStringPiece += "$$";
269 continue;
270 } else if (CurChar != '%') {
271 CurStringPiece += CurChar;
272 continue;
273 }
274
275 // Escaped "%" character in asm string.
Chris Lattner3fa25c62009-03-11 00:06:36 +0000276 if (CurPtr == StrEnd) {
277 // % at end of string is invalid (no escape).
278 DiagOffs = CurPtr-StrStart-1;
279 return diag::err_asm_invalid_escape;
280 }
Chris Lattner35b58362009-03-10 23:21:44 +0000281
Chris Lattnera41b8472009-03-10 23:51:40 +0000282 char EscapedChar = *CurPtr++;
Chris Lattner35b58362009-03-10 23:21:44 +0000283 if (EscapedChar == '%') { // %% -> %
284 // Escaped percentage sign.
285 CurStringPiece += '%';
286 continue;
287 }
288
289 if (EscapedChar == '=') { // %= -> Generate an unique ID.
290 CurStringPiece += "${:uid}";
291 continue;
292 }
293
294 // Otherwise, we have an operand. If we have accumulated a string so far,
295 // add it to the Pieces list.
296 if (!CurStringPiece.empty()) {
297 Pieces.push_back(AsmStringPiece(CurStringPiece));
298 CurStringPiece.clear();
299 }
300
301 // Handle %x4 and %x[foo] by capturing x as the modifier character.
302 char Modifier = '\0';
303 if (isalpha(EscapedChar)) {
304 Modifier = EscapedChar;
Chris Lattnera41b8472009-03-10 23:51:40 +0000305 EscapedChar = *CurPtr++;
Chris Lattner35b58362009-03-10 23:21:44 +0000306 }
307
308 if (isdigit(EscapedChar)) {
309 // %n - Assembler operand n
Chris Lattner99d892b2009-03-11 22:52:17 +0000310 unsigned N = 0;
311
312 --CurPtr;
313 while (CurPtr != StrEnd && isdigit(*CurPtr))
Chris Lattner84f3afa2009-03-11 23:09:16 +0000314 N = N*10 + ((*CurPtr++)-'0');
Chris Lattner14311922009-03-11 00:23:13 +0000315
316 unsigned NumOperands =
317 getNumOutputs() + getNumPlusOperands() + getNumInputs();
318 if (N >= NumOperands) {
319 DiagOffs = CurPtr-StrStart-1;
320 return diag::err_asm_invalid_operand_number;
321 }
322
Chris Lattner35b58362009-03-10 23:21:44 +0000323 Pieces.push_back(AsmStringPiece(N, Modifier));
324 continue;
325 }
326
327 // Handle %[foo], a symbolic operand reference.
328 if (EscapedChar == '[') {
Chris Lattner3fa25c62009-03-11 00:06:36 +0000329 DiagOffs = CurPtr-StrStart-1;
330
331 // Find the ']'.
Chris Lattnera41b8472009-03-10 23:51:40 +0000332 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Chris Lattner3fa25c62009-03-11 00:06:36 +0000333 if (NameEnd == 0)
334 return diag::err_asm_unterminated_symbolic_operand_name;
335 if (NameEnd == CurPtr)
336 return diag::err_asm_empty_symbolic_operand_name;
337
Chris Lattnera41b8472009-03-10 23:51:40 +0000338 std::string SymbolicName(CurPtr, NameEnd);
Chris Lattner35b58362009-03-10 23:21:44 +0000339
340 int N = getNamedOperand(SymbolicName);
Chris Lattner3fa25c62009-03-11 00:06:36 +0000341 if (N == -1) {
342 // Verify that an operand with that name exists.
343 DiagOffs = CurPtr-StrStart;
344 return diag::err_asm_unknown_symbolic_operand_name;
345 }
Chris Lattner35b58362009-03-10 23:21:44 +0000346 Pieces.push_back(AsmStringPiece(N, Modifier));
Chris Lattner3fa25c62009-03-11 00:06:36 +0000347
348 CurPtr = NameEnd+1;
Chris Lattner35b58362009-03-10 23:21:44 +0000349 continue;
350 }
351
Chris Lattner0cdaa2e2009-03-10 23:57:07 +0000352 DiagOffs = CurPtr-StrStart-1;
Chris Lattnera41b8472009-03-10 23:51:40 +0000353 return diag::err_asm_invalid_escape;
Chris Lattner35b58362009-03-10 23:21:44 +0000354 }
355}
356
Chris Lattner86f5e132008-01-30 05:01:46 +0000357//===----------------------------------------------------------------------===//
358// Constructors
359//===----------------------------------------------------------------------===//
360
Anders Carlsson19fe1162008-02-05 23:03:50 +0000361AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
Chris Lattner86f5e132008-01-30 05:01:46 +0000362 unsigned numoutputs, unsigned numinputs,
363 std::string *names, StringLiteral **constraints,
364 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
365 StringLiteral **clobbers, SourceLocation rparenloc)
Anders Carlsson94ea8aa2007-11-22 01:36:19 +0000366 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Anders Carlsson19fe1162008-02-05 23:03:50 +0000367 , IsSimple(issimple), IsVolatile(isvolatile)
368 , NumOutputs(numoutputs), NumInputs(numinputs) {
Anders Carlsson94ea8aa2007-11-22 01:36:19 +0000369 for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
370 Names.push_back(names[i]);
371 Exprs.push_back(exprs[i]);
Nico Weberde565e32008-08-05 23:15:29 +0000372 Constraints.push_back(constraints[i]);
Anders Carlsson94ea8aa2007-11-22 01:36:19 +0000373 }
Nico Weberde565e32008-08-05 23:15:29 +0000374
Anders Carlsson94ea8aa2007-11-22 01:36:19 +0000375 for (unsigned i = 0; i != numclobbers; i++)
376 Clobbers.push_back(clobbers[i]);
377}
378
Chris Lattner86f5e132008-01-30 05:01:46 +0000379ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
380 Stmt *Body, SourceLocation FCL,
Nico Weberde565e32008-08-05 23:15:29 +0000381 SourceLocation RPL)
Chris Lattner86f5e132008-01-30 05:01:46 +0000382: Stmt(ObjCForCollectionStmtClass) {
383 SubExprs[ELEM] = Elem;
384 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
385 SubExprs[BODY] = Body;
386 ForLoc = FCL;
387 RParenLoc = RPL;
388}
389
390
Nico Weberde565e32008-08-05 23:15:29 +0000391ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
392 SourceLocation rparenloc,
Steve Naroff371b8fb2009-03-03 19:52:17 +0000393 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
Chris Lattner86f5e132008-01-30 05:01:46 +0000394 Stmt *atCatchList)
395: Stmt(ObjCAtCatchStmtClass) {
Steve Naroff371b8fb2009-03-03 19:52:17 +0000396 ExceptionDecl = catchVarDecl;
Chris Lattner86f5e132008-01-30 05:01:46 +0000397 SubExprs[BODY] = atCatchStmt;
Eli Friedman1f97e572008-05-25 04:34:57 +0000398 SubExprs[NEXT_CATCH] = NULL;
Daniel Dunbar947bca22009-03-01 04:28:32 +0000399 // FIXME: O(N^2) in number of catch blocks.
Eli Friedman1f97e572008-05-25 04:34:57 +0000400 if (atCatchList) {
Ted Kremeneka4965842008-02-01 21:28:59 +0000401 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
402
Nico Weberde565e32008-08-05 23:15:29 +0000403 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
Ted Kremeneka4965842008-02-01 21:28:59 +0000404 AtCatchList = NextCatch;
Nico Weberde565e32008-08-05 23:15:29 +0000405
Ted Kremeneka4965842008-02-01 21:28:59 +0000406 AtCatchList->SubExprs[NEXT_CATCH] = this;
Chris Lattner86f5e132008-01-30 05:01:46 +0000407 }
408 AtCatchLoc = atCatchLoc;
409 RParenLoc = rparenloc;
410}
411
412
Ted Kremenek066dd932007-08-24 21:09:09 +0000413//===----------------------------------------------------------------------===//
414// Child Iterators for iterating over subexpressions/substatements
415//===----------------------------------------------------------------------===//
416
417// DeclStmt
Ted Kremenek9bb286f2008-10-07 23:09:49 +0000418Stmt::child_iterator DeclStmt::child_begin() {
419 return StmtIterator(DG.begin(), DG.end());
Ted Kremenek4f8792b2008-08-05 20:46:55 +0000420}
421
Ted Kremenek9bb286f2008-10-07 23:09:49 +0000422Stmt::child_iterator DeclStmt::child_end() {
423 return StmtIterator(DG.end(), DG.end());
Ted Kremenekacf920d2008-10-06 20:54:44 +0000424}
425
Ted Kremenek066dd932007-08-24 21:09:09 +0000426// NullStmt
Ted Kremenek04746ce2007-10-18 23:28:49 +0000427Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
428Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
Ted Kremenek066dd932007-08-24 21:09:09 +0000429
430// CompoundStmt
431Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
Ted Kremenek5a201952009-02-07 01:47:29 +0000432Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
Ted Kremenek066dd932007-08-24 21:09:09 +0000433
Ted Kremenek14f0d1a2007-08-30 16:50:46 +0000434// CaseStmt
435Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
436Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
437
438// DefaultStmt
439Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
440Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
Ted Kremenek066dd932007-08-24 21:09:09 +0000441
442// LabelStmt
443Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
Chris Lattnercfb83dd2007-08-30 00:53:54 +0000444Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
Ted Kremenek066dd932007-08-24 21:09:09 +0000445
446// IfStmt
447Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
448Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
449
450// SwitchStmt
451Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
452Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
453
454// WhileStmt
455Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
456Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
457
458// DoStmt
459Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
460Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
461
462// ForStmt
463Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
464Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
465
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000466// ObjCForCollectionStmt
Nico Weberde565e32008-08-05 23:15:29 +0000467Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
468 return &SubExprs[0];
Fariborz Jahanian83615522008-01-02 22:54:34 +0000469}
Nico Weberde565e32008-08-05 23:15:29 +0000470Stmt::child_iterator ObjCForCollectionStmt::child_end() {
471 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian83615522008-01-02 22:54:34 +0000472}
473
Ted Kremenek066dd932007-08-24 21:09:09 +0000474// GotoStmt
Ted Kremenek04746ce2007-10-18 23:28:49 +0000475Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
476Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
Ted Kremenek066dd932007-08-24 21:09:09 +0000477
478// IndirectGotoStmt
Ted Kremenekc6501db2008-06-17 03:11:08 +0000479Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
480const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
Ted Kremenek066dd932007-08-24 21:09:09 +0000481
Ted Kremenekc6501db2008-06-17 03:11:08 +0000482Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
483Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
Ted Kremenek066dd932007-08-24 21:09:09 +0000484
485// ContinueStmt
Ted Kremenek04746ce2007-10-18 23:28:49 +0000486Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
487Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
Ted Kremenek066dd932007-08-24 21:09:09 +0000488
489// BreakStmt
Ted Kremenek04746ce2007-10-18 23:28:49 +0000490Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
491Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
Ted Kremenek066dd932007-08-24 21:09:09 +0000492
493// ReturnStmt
Ted Kremenekc6501db2008-06-17 03:11:08 +0000494const Expr* ReturnStmt::getRetValue() const {
495 return cast_or_null<Expr>(RetExpr);
496}
497Expr* ReturnStmt::getRetValue() {
498 return cast_or_null<Expr>(RetExpr);
Ted Kremenek066dd932007-08-24 21:09:09 +0000499}
500
Ted Kremenekc6501db2008-06-17 03:11:08 +0000501Stmt::child_iterator ReturnStmt::child_begin() {
502 return &RetExpr;
503}
504Stmt::child_iterator ReturnStmt::child_end() {
505 return RetExpr ? &RetExpr+1 : &RetExpr;
Ted Kremenek5b3ed282007-08-27 20:58:16 +0000506}
Ted Kremenek066dd932007-08-24 21:09:09 +0000507
Chris Lattner73c56c02007-10-29 04:04:16 +0000508// AsmStmt
Ted Kremenek5778acf2008-10-27 18:40:21 +0000509Stmt::child_iterator AsmStmt::child_begin() {
510 return Exprs.empty() ? 0 : &Exprs[0];
511}
512Stmt::child_iterator AsmStmt::child_end() {
513 return Exprs.empty() ? 0 : &Exprs[0] + Exprs.size();
514}
Chris Lattner73c56c02007-10-29 04:04:16 +0000515
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000516// ObjCAtCatchStmt
517Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
Nico Weberde565e32008-08-05 23:15:29 +0000518Stmt::child_iterator ObjCAtCatchStmt::child_end() {
519 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian9e63b982007-11-01 23:59:59 +0000520}
Fariborz Jahanian65590b22007-11-01 21:12:44 +0000521
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000522// ObjCAtFinallyStmt
523Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
524Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
Fariborz Jahanian65590b22007-11-01 21:12:44 +0000525
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000526// ObjCAtTryStmt
527Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
Nico Weberde565e32008-08-05 23:15:29 +0000528Stmt::child_iterator ObjCAtTryStmt::child_end() {
529 return &SubStmts[0]+END_EXPR;
Fariborz Jahanian9e63b982007-11-01 23:59:59 +0000530}
Fariborz Jahanian65590b22007-11-01 21:12:44 +0000531
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000532// ObjCAtThrowStmt
533Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
Fariborz Jahanianadfbbc32007-11-07 02:00:49 +0000534 return &Throw;
535}
536
Ted Kremenek1b0ea822008-01-07 19:49:32 +0000537Stmt::child_iterator ObjCAtThrowStmt::child_end() {
Fariborz Jahanianadfbbc32007-11-07 02:00:49 +0000538 return &Throw+1;
539}
Fariborz Jahanian48085b82008-01-29 19:14:59 +0000540
541// ObjCAtSynchronizedStmt
542Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
Fariborz Jahanian284011b2008-01-29 22:59:37 +0000543 return &SubStmts[0];
Fariborz Jahanian48085b82008-01-29 19:14:59 +0000544}
545
546Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
Fariborz Jahanian284011b2008-01-29 22:59:37 +0000547 return &SubStmts[0]+END_EXPR;
Fariborz Jahanian48085b82008-01-29 19:14:59 +0000548}
549
Sebastian Redl54c04d42008-12-22 19:15:10 +0000550// CXXCatchStmt
551Stmt::child_iterator CXXCatchStmt::child_begin() {
552 return &HandlerBlock;
553}
554
555Stmt::child_iterator CXXCatchStmt::child_end() {
556 return &HandlerBlock + 1;
557}
558
559QualType CXXCatchStmt::getCaughtType() {
560 if (ExceptionDecl)
Douglas Gregor5e16fbe2009-05-18 20:51:54 +0000561 return ExceptionDecl->getType();
Sebastian Redl54c04d42008-12-22 19:15:10 +0000562 return QualType();
563}
564
Douglas Gregore26a2852009-08-07 06:08:38 +0000565void CXXCatchStmt::DoDestroy(ASTContext& C) {
Sebastian Redl9b244a82008-12-22 21:35:02 +0000566 if (ExceptionDecl)
567 ExceptionDecl->Destroy(C);
Douglas Gregore26a2852009-08-07 06:08:38 +0000568 Stmt::DoDestroy(C);
Sebastian Redl54c04d42008-12-22 19:15:10 +0000569}
Sebastian Redl9b244a82008-12-22 21:35:02 +0000570
571// CXXTryStmt
572Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
573Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }
574
575CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
576 Stmt **handlers, unsigned numHandlers)
577 : Stmt(CXXTryStmtClass), TryLoc(tryLoc) {
578 Stmts.push_back(tryBlock);
579 Stmts.insert(Stmts.end(), handlers, handlers + numHandlers);
580}