blob: 668f7ef57fb6fb6f190df3004aa8825c06ddcc46 [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"
Chris Lattner16f00492009-04-26 01:32:48 +000017#include "clang/AST/StmtCXX.h"
18#include "clang/AST/StmtObjC.h"
Sebastian Redl4b07b292008-12-22 19:15:10 +000019#include "clang/AST/Type.h"
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000020#include "clang/AST/ASTContext.h"
Chris Lattner3182db12009-03-10 23:51:40 +000021#include "clang/AST/ASTDiagnostic.h"
Reid Spencer5f016e22007-07-11 17:01:13 +000022using namespace clang;
23
Reid Spencer5f016e22007-07-11 17:01:13 +000024static struct StmtClassNameTable {
Chris Lattner63381352007-08-25 01:42:24 +000025 const char *Name;
26 unsigned Counter;
27 unsigned Size;
Chris Lattner1f683e92007-08-25 01:55:00 +000028} StmtClassInfo[Stmt::lastExprConstant+1];
Chris Lattner63381352007-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 Gregorf2cad862008-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);
Reid Spencer5f016e22007-07-11 17:01:13 +000040#include "clang/AST/StmtNodes.def"
Nico Weber608b17f2008-08-05 23:15:29 +000041
Chris Lattner63381352007-08-25 01:42:24 +000042 return StmtClassInfo[E];
43}
44
Reid Spencer5f016e22007-07-11 17:01:13 +000045const char *Stmt::getStmtClassName() const {
Chris Lattner63381352007-08-25 01:42:24 +000046 return getStmtInfoTableEntry(sClass).Name;
Reid Spencer5f016e22007-07-11 17:01:13 +000047}
48
Chris Lattner24e1e702009-03-04 04:23:07 +000049void Stmt::DestroyChildren(ASTContext &C) {
50 for (child_iterator I = child_begin(), E = child_end(); I !=E; )
Douglas Gregor860f6d42009-01-16 06:50:08 +000051 if (Stmt* Child = *I++) Child->Destroy(C);
Ted Kremenek27f8a282008-05-20 00:43:19 +000052}
53
Douglas Gregor42602bb2009-08-07 06:08:38 +000054void Stmt::DoDestroy(ASTContext &C) {
Ted Kremenek27f8a282008-05-20 00:43:19 +000055 DestroyChildren(C);
Ted Kremenek11e5a7f2009-02-06 01:42:09 +000056 this->~Stmt();
57 C.Deallocate((void *)this);
Ted Kremenek9c1863e2008-05-19 22:02:12 +000058}
59
Reid Spencer5f016e22007-07-11 17:01:13 +000060void Stmt::PrintStats() {
Chris Lattner63381352007-08-25 01:42:24 +000061 // Ensure the table is primed.
62 getStmtInfoTableEntry(Stmt::NullStmtClass);
Nico Weber608b17f2008-08-05 23:15:29 +000063
Reid Spencer5f016e22007-07-11 17:01:13 +000064 unsigned sum = 0;
65 fprintf(stderr, "*** Stmt/Expr Stats:\n");
Chris Lattner1f683e92007-08-25 01:55:00 +000066 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000067 if (StmtClassInfo[i].Name == 0) continue;
68 sum += StmtClassInfo[i].Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000069 }
70 fprintf(stderr, " %d stmts/exprs total.\n", sum);
71 sum = 0;
Chris Lattner1f683e92007-08-25 01:55:00 +000072 for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
Chris Lattner63381352007-08-25 01:42:24 +000073 if (StmtClassInfo[i].Name == 0) continue;
Douglas Gregordbe833d2009-05-26 14:40:08 +000074 if (StmtClassInfo[i].Counter == 0) continue;
Nico Weber608b17f2008-08-05 23:15:29 +000075 fprintf(stderr, " %d %s, %d each (%d bytes)\n",
Chris Lattner63381352007-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;
Reid Spencer5f016e22007-07-11 17:01:13 +000080 }
81 fprintf(stderr, "Total bytes = %d\n", sum);
82}
83
84void Stmt::addStmtClass(StmtClass s) {
Chris Lattner63381352007-08-25 01:42:24 +000085 ++getStmtInfoTableEntry(s).Counter;
Reid Spencer5f016e22007-07-11 17:01:13 +000086}
87
88static bool StatSwitch = false;
89
90bool Stmt::CollectingStats(bool enable) {
91 if (enable) StatSwitch = true;
Chris Lattner63381352007-08-25 01:42:24 +000092 return StatSwitch;
Reid Spencer5f016e22007-07-11 17:01:13 +000093}
94
Anders Carlssond19cd902009-05-15 00:21:21 +000095NullStmt* NullStmt::Clone(ASTContext &C) const {
96 return new (C) NullStmt(SemiLoc);
97}
98
Douglas Gregor861ce312009-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 Gregor025452f2009-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}
Reid Spencer5f016e22007-07-11 17:01:13 +0000115
Reid Spencer5f016e22007-07-11 17:01:13 +0000116const char *LabelStmt::getName() const {
117 return getID()->getName();
118}
119
Steve Naroff507f2d52007-08-31 23:49:30 +0000120// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weber608b17f2008-08-05 23:15:29 +0000121SourceRange ReturnStmt::getSourceRange() const {
Steve Naroff507f2d52007-08-31 23:49:30 +0000122 if (RetExpr)
123 return SourceRange(RetLoc, RetExpr->getLocEnd());
124 else
125 return SourceRange(RetLoc);
126}
127
Ted Kremenekd48ade62007-10-01 16:34:52 +0000128bool Stmt::hasImplicitControlFlow() const {
129 switch (sClass) {
130 default:
131 return false;
Nico Weber608b17f2008-08-05 23:15:29 +0000132
Ted Kremenekd48ade62007-10-01 16:34:52 +0000133 case CallExprClass:
134 case ConditionalOperatorClass:
135 case ChooseExprClass:
136 case StmtExprClass:
137 case DeclStmtClass:
Nico Weber608b17f2008-08-05 23:15:29 +0000138 return true;
139
Ted Kremenekd48ade62007-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 Lattnerb3277932009-03-10 04:59:06 +0000150Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000151 return cast<Expr>(Exprs[i]);
152}
Chris Lattnerb3277932009-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 Kremenekce2fc3a2008-10-27 18:40:21 +0000160}
Chris Lattnerb3277932009-03-10 04:59:06 +0000161
Chris Lattner85759272009-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 Lattnerb3277932009-03-10 04:59:06 +0000173
174Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000175 return cast<Expr>(Exprs[i + NumOutputs]);
176}
Chris Lattnerb3277932009-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 Kremenekce2fc3a2008-10-27 18:40:21 +0000183}
184
Chris Lattner10ca96a2009-03-10 06:33:24 +0000185
Douglas Gregorcd7d5a92009-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 Lattner10ca96a2009-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 Lattner10ca96a2009-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 Gregorcd7d5a92009-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 Lattner10ca96a2009-03-10 06:33:24 +0000226
Chris Lattner458cd9c2009-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 Lattnerfb5058e2009-03-10 23:41:04 +0000230unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
231 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000232 const char *StrStart = getAsmString()->getStrData();
233 const char *StrEnd = StrStart + getAsmString()->getByteLength();
Chris Lattner3182db12009-03-10 23:51:40 +0000234 const char *CurPtr = StrStart;
Chris Lattner458cd9c2009-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 Lattner3182db12009-03-10 23:51:40 +0000240 for (; CurPtr != StrEnd; ++CurPtr) {
241 switch (*CurPtr) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000242 case '$':
243 Result += "$$";
244 break;
245 default:
Chris Lattner3182db12009-03-10 23:51:40 +0000246 Result += *CurPtr;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000247 break;
248 }
249 }
250 Pieces.push_back(AsmStringPiece(Result));
Chris Lattner3182db12009-03-10 23:51:40 +0000251 return 0;
Chris Lattner458cd9c2009-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 Lattner3182db12009-03-10 23:51:40 +0000260 if (CurPtr == StrEnd) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000261 if (!CurStringPiece.empty())
262 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattner3182db12009-03-10 23:51:40 +0000263 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000264 }
265
Chris Lattner3182db12009-03-10 23:51:40 +0000266 char CurChar = *CurPtr++;
Chris Lattner458cd9c2009-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 Lattnereab8cfb2009-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 Lattner458cd9c2009-03-10 23:21:44 +0000281
Chris Lattner3182db12009-03-10 23:51:40 +0000282 char EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-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 Lattner3182db12009-03-10 23:51:40 +0000305 EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000306 }
307
308 if (isdigit(EscapedChar)) {
309 // %n - Assembler operand n
Chris Lattnercafc2222009-03-11 22:52:17 +0000310 unsigned N = 0;
311
312 --CurPtr;
313 while (CurPtr != StrEnd && isdigit(*CurPtr))
Chris Lattner32a47ed2009-03-11 23:09:16 +0000314 N = N*10 + ((*CurPtr++)-'0');
Chris Lattner85759272009-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 Lattner458cd9c2009-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 Lattnereab8cfb2009-03-11 00:06:36 +0000329 DiagOffs = CurPtr-StrStart-1;
330
331 // Find the ']'.
Chris Lattner3182db12009-03-10 23:51:40 +0000332 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Chris Lattnereab8cfb2009-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 Lattner3182db12009-03-10 23:51:40 +0000338 std::string SymbolicName(CurPtr, NameEnd);
Chris Lattner458cd9c2009-03-10 23:21:44 +0000339
340 int N = getNamedOperand(SymbolicName);
Chris Lattnereab8cfb2009-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 Lattner458cd9c2009-03-10 23:21:44 +0000346 Pieces.push_back(AsmStringPiece(N, Modifier));
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000347
348 CurPtr = NameEnd+1;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000349 continue;
350 }
351
Chris Lattner2ff0f422009-03-10 23:57:07 +0000352 DiagOffs = CurPtr-StrStart-1;
Chris Lattner3182db12009-03-10 23:51:40 +0000353 return diag::err_asm_invalid_escape;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000354 }
355}
356
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000357//===----------------------------------------------------------------------===//
358// Constructors
359//===----------------------------------------------------------------------===//
360
Anders Carlssondfab34a2008-02-05 23:03:50 +0000361AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
Chris Lattnerdb6ed172008-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 Carlssonb235fc22007-11-22 01:36:19 +0000366 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Anders Carlssondfab34a2008-02-05 23:03:50 +0000367 , IsSimple(issimple), IsVolatile(isvolatile)
368 , NumOutputs(numoutputs), NumInputs(numinputs) {
Anders Carlssonb235fc22007-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 Weber608b17f2008-08-05 23:15:29 +0000372 Constraints.push_back(constraints[i]);
Anders Carlssonb235fc22007-11-22 01:36:19 +0000373 }
Nico Weber608b17f2008-08-05 23:15:29 +0000374
Anders Carlssonb235fc22007-11-22 01:36:19 +0000375 for (unsigned i = 0; i != numclobbers; i++)
376 Clobbers.push_back(clobbers[i]);
377}
378
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000379ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
380 Stmt *Body, SourceLocation FCL,
Nico Weber608b17f2008-08-05 23:15:29 +0000381 SourceLocation RPL)
Chris Lattnerdb6ed172008-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 Weber608b17f2008-08-05 23:15:29 +0000391ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
392 SourceLocation rparenloc,
Steve Naroff7ba138a2009-03-03 19:52:17 +0000393 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000394 Stmt *atCatchList)
395: Stmt(ObjCAtCatchStmtClass) {
Steve Naroff7ba138a2009-03-03 19:52:17 +0000396 ExceptionDecl = catchVarDecl;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000397 SubExprs[BODY] = atCatchStmt;
Eli Friedman0613c372008-05-25 04:34:57 +0000398 SubExprs[NEXT_CATCH] = NULL;
Daniel Dunbar93b2bdb2009-03-01 04:28:32 +0000399 // FIXME: O(N^2) in number of catch blocks.
Eli Friedman0613c372008-05-25 04:34:57 +0000400 if (atCatchList) {
Ted Kremenekff981022008-02-01 21:28:59 +0000401 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
402
Nico Weber608b17f2008-08-05 23:15:29 +0000403 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
Ted Kremenekff981022008-02-01 21:28:59 +0000404 AtCatchList = NextCatch;
Nico Weber608b17f2008-08-05 23:15:29 +0000405
Ted Kremenekff981022008-02-01 21:28:59 +0000406 AtCatchList->SubExprs[NEXT_CATCH] = this;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000407 }
408 AtCatchLoc = atCatchLoc;
409 RParenLoc = rparenloc;
410}
411
412
Ted Kremenek82977772007-08-24 21:09:09 +0000413//===----------------------------------------------------------------------===//
414// Child Iterators for iterating over subexpressions/substatements
415//===----------------------------------------------------------------------===//
416
417// DeclStmt
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000418Stmt::child_iterator DeclStmt::child_begin() {
419 return StmtIterator(DG.begin(), DG.end());
Ted Kremenek14f8b4f2008-08-05 20:46:55 +0000420}
421
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000422Stmt::child_iterator DeclStmt::child_end() {
423 return StmtIterator(DG.end(), DG.end());
Ted Kremenek65aa3b92008-10-06 20:54:44 +0000424}
425
Ted Kremenek82977772007-08-24 21:09:09 +0000426// NullStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000427Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
428Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000429
430// CompoundStmt
431Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
Ted Kremenek8189cde2009-02-07 01:47:29 +0000432Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
Ted Kremenek82977772007-08-24 21:09:09 +0000433
Ted Kremenekd97bb6c2007-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 Kremenek82977772007-08-24 21:09:09 +0000441
442// LabelStmt
443Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
Chris Lattnerb3938792007-08-30 00:53:54 +0000444Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
Ted Kremenek82977772007-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 Kremeneka526c5c2008-01-07 19:49:32 +0000466// ObjCForCollectionStmt
Nico Weber608b17f2008-08-05 23:15:29 +0000467Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
468 return &SubExprs[0];
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000469}
Nico Weber608b17f2008-08-05 23:15:29 +0000470Stmt::child_iterator ObjCForCollectionStmt::child_end() {
471 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000472}
473
Ted Kremenek82977772007-08-24 21:09:09 +0000474// GotoStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000475Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
476Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000477
478// IndirectGotoStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000479Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
480const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
Ted Kremenek82977772007-08-24 21:09:09 +0000481
Ted Kremenek1060aff2008-06-17 03:11:08 +0000482Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
483Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000484
485// ContinueStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000486Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
487Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000488
489// BreakStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000490Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
491Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000492
493// ReturnStmt
Ted Kremenek1060aff2008-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 Kremenek82977772007-08-24 21:09:09 +0000499}
500
Ted Kremenek1060aff2008-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 Kremenek2298f912007-08-27 20:58:16 +0000506}
Ted Kremenek82977772007-08-24 21:09:09 +0000507
Chris Lattnerfe795952007-10-29 04:04:16 +0000508// AsmStmt
Ted Kremenekce2fc3a2008-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 Lattnerfe795952007-10-29 04:04:16 +0000515
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000516// ObjCAtCatchStmt
517Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000518Stmt::child_iterator ObjCAtCatchStmt::child_end() {
519 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000520}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000521
Ted Kremeneka526c5c2008-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 Jahanianb210bd02007-11-01 21:12:44 +0000525
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000526// ObjCAtTryStmt
527Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000528Stmt::child_iterator ObjCAtTryStmt::child_end() {
529 return &SubStmts[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000530}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000531
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000532// ObjCAtThrowStmt
533Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000534 return &Throw;
535}
536
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000537Stmt::child_iterator ObjCAtThrowStmt::child_end() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000538 return &Throw+1;
539}
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000540
541// ObjCAtSynchronizedStmt
542Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000543 return &SubStmts[0];
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000544}
545
546Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000547 return &SubStmts[0]+END_EXPR;
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000548}
549
Sebastian Redl4b07b292008-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 Gregord308e622009-05-18 20:51:54 +0000561 return ExceptionDecl->getType();
Sebastian Redl4b07b292008-12-22 19:15:10 +0000562 return QualType();
563}
564
Douglas Gregor42602bb2009-08-07 06:08:38 +0000565void CXXCatchStmt::DoDestroy(ASTContext& C) {
Sebastian Redl8351da02008-12-22 21:35:02 +0000566 if (ExceptionDecl)
567 ExceptionDecl->Destroy(C);
Douglas Gregor42602bb2009-08-07 06:08:38 +0000568 Stmt::DoDestroy(C);
Sebastian Redl4b07b292008-12-22 19:15:10 +0000569}
Sebastian Redl8351da02008-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}