blob: a0ef5a64280b0fe96faf42b0d9551b0416f70928 [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 {
Douglas Gregor43d9d922009-08-08 01:41:12 +000046 return getStmtInfoTableEntry((StmtClass)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 Gregor43d9d922009-08-08 01:41:12 +0000107void SwitchStmt::DoDestroy(ASTContext &Ctx) {
108 // Destroy the SwitchCase statements in this switch. In the normal
109 // case, this loop will merely decrement the reference counts from
110 // the Retain() calls in addSwitchCase();
111 SwitchCase *SC = FirstCase;
112 while (SC) {
113 SwitchCase *Next = SC->getNextSwitchCase();
114 SC->Destroy(Ctx);
115 SC = Next;
116 }
117
118 Stmt::DoDestroy(Ctx);
119}
120
Douglas Gregor025452f2009-04-17 00:04:06 +0000121void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
122 if (this->Body)
123 C.Deallocate(Body);
124 this->NumStmts = NumStmts;
125
126 Body = new (C) Stmt*[NumStmts];
127 memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
128}
Reid Spencer5f016e22007-07-11 17:01:13 +0000129
Reid Spencer5f016e22007-07-11 17:01:13 +0000130const char *LabelStmt::getName() const {
131 return getID()->getName();
132}
133
Steve Naroff507f2d52007-08-31 23:49:30 +0000134// This is defined here to avoid polluting Stmt.h with importing Expr.h
Nico Weber608b17f2008-08-05 23:15:29 +0000135SourceRange ReturnStmt::getSourceRange() const {
Steve Naroff507f2d52007-08-31 23:49:30 +0000136 if (RetExpr)
137 return SourceRange(RetLoc, RetExpr->getLocEnd());
138 else
139 return SourceRange(RetLoc);
140}
141
Ted Kremenekd48ade62007-10-01 16:34:52 +0000142bool Stmt::hasImplicitControlFlow() const {
143 switch (sClass) {
144 default:
145 return false;
Nico Weber608b17f2008-08-05 23:15:29 +0000146
Ted Kremenekd48ade62007-10-01 16:34:52 +0000147 case CallExprClass:
148 case ConditionalOperatorClass:
149 case ChooseExprClass:
150 case StmtExprClass:
151 case DeclStmtClass:
Nico Weber608b17f2008-08-05 23:15:29 +0000152 return true;
153
Ted Kremenekd48ade62007-10-01 16:34:52 +0000154 case Stmt::BinaryOperatorClass: {
155 const BinaryOperator* B = cast<BinaryOperator>(this);
156 if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
157 return true;
158 else
159 return false;
160 }
161 }
162}
163
Chris Lattnerb3277932009-03-10 04:59:06 +0000164Expr *AsmStmt::getOutputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000165 return cast<Expr>(Exprs[i]);
166}
Chris Lattnerb3277932009-03-10 04:59:06 +0000167
168/// getOutputConstraint - Return the constraint string for the specified
169/// output operand. All output constraints are known to be non-empty (either
170/// '=' or '+').
171std::string AsmStmt::getOutputConstraint(unsigned i) const {
172 return std::string(Constraints[i]->getStrData(),
173 Constraints[i]->getByteLength());
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000174}
Chris Lattnerb3277932009-03-10 04:59:06 +0000175
Chris Lattner85759272009-03-11 00:23:13 +0000176/// getNumPlusOperands - Return the number of output operands that have a "+"
177/// constraint.
178unsigned AsmStmt::getNumPlusOperands() const {
179 unsigned Res = 0;
180 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
181 if (isOutputPlusConstraint(i))
182 ++Res;
183 return Res;
184}
185
186
Chris Lattnerb3277932009-03-10 04:59:06 +0000187
188Expr *AsmStmt::getInputExpr(unsigned i) {
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000189 return cast<Expr>(Exprs[i + NumOutputs]);
190}
Chris Lattnerb3277932009-03-10 04:59:06 +0000191
192/// getInputConstraint - Return the specified input constraint. Unlike output
193/// constraints, these can be empty.
194std::string AsmStmt::getInputConstraint(unsigned i) const {
195 return std::string(Constraints[i + NumOutputs]->getStrData(),
196 Constraints[i + NumOutputs]->getByteLength());
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000197}
198
Chris Lattner10ca96a2009-03-10 06:33:24 +0000199
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000200void AsmStmt::setOutputsAndInputs(unsigned NumOutputs,
201 unsigned NumInputs,
202 const std::string *Names,
203 StringLiteral **Constraints,
204 Stmt **Exprs) {
205 this->NumOutputs = NumOutputs;
206 this->NumInputs = NumInputs;
207 this->Names.clear();
208 this->Names.insert(this->Names.end(), Names, Names + NumOutputs + NumInputs);
209 this->Constraints.clear();
210 this->Constraints.insert(this->Constraints.end(),
211 Constraints, Constraints + NumOutputs + NumInputs);
212 this->Exprs.clear();
213 this->Exprs.insert(this->Exprs.end(), Exprs, Exprs + NumOutputs + NumInputs);
214}
215
Chris Lattner10ca96a2009-03-10 06:33:24 +0000216/// getNamedOperand - Given a symbolic operand reference like %[foo],
217/// translate this into a numeric value needed to reference the same operand.
218/// This returns -1 if the operand name is invalid.
219int AsmStmt::getNamedOperand(const std::string &SymbolicName) const {
220 unsigned NumPlusOperands = 0;
221
222 // Check if this is an output operand.
223 for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
224 if (getOutputName(i) == SymbolicName)
225 return i;
Chris Lattner10ca96a2009-03-10 06:33:24 +0000226 }
227
228 for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
229 if (getInputName(i) == SymbolicName)
230 return getNumOutputs() + NumPlusOperands + i;
231
232 // Not found.
233 return -1;
234}
235
Douglas Gregorcd7d5a92009-04-17 20:57:14 +0000236void AsmStmt::setClobbers(StringLiteral **Clobbers, unsigned NumClobbers) {
237 this->Clobbers.clear();
238 this->Clobbers.insert(this->Clobbers.end(), Clobbers, Clobbers + NumClobbers);
239}
Chris Lattner10ca96a2009-03-10 06:33:24 +0000240
Chris Lattner458cd9c2009-03-10 23:21:44 +0000241/// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
242/// it into pieces. If the asm string is erroneous, emit errors and return
243/// true, otherwise return false.
Chris Lattnerfb5058e2009-03-10 23:41:04 +0000244unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
245 ASTContext &C, unsigned &DiagOffs) const {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000246 const char *StrStart = getAsmString()->getStrData();
247 const char *StrEnd = StrStart + getAsmString()->getByteLength();
Chris Lattner3182db12009-03-10 23:51:40 +0000248 const char *CurPtr = StrStart;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000249
250 // "Simple" inline asms have no constraints or operands, just convert the asm
251 // string to escape $'s.
252 if (isSimple()) {
253 std::string Result;
Chris Lattner3182db12009-03-10 23:51:40 +0000254 for (; CurPtr != StrEnd; ++CurPtr) {
255 switch (*CurPtr) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000256 case '$':
257 Result += "$$";
258 break;
259 default:
Chris Lattner3182db12009-03-10 23:51:40 +0000260 Result += *CurPtr;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000261 break;
262 }
263 }
264 Pieces.push_back(AsmStringPiece(Result));
Chris Lattner3182db12009-03-10 23:51:40 +0000265 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000266 }
267
268 // CurStringPiece - The current string that we are building up as we scan the
269 // asm string.
270 std::string CurStringPiece;
271
272 while (1) {
273 // Done with the string?
Chris Lattner3182db12009-03-10 23:51:40 +0000274 if (CurPtr == StrEnd) {
Chris Lattner458cd9c2009-03-10 23:21:44 +0000275 if (!CurStringPiece.empty())
276 Pieces.push_back(AsmStringPiece(CurStringPiece));
Chris Lattner3182db12009-03-10 23:51:40 +0000277 return 0;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000278 }
279
Chris Lattner3182db12009-03-10 23:51:40 +0000280 char CurChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000281 if (CurChar == '$') {
282 CurStringPiece += "$$";
283 continue;
284 } else if (CurChar != '%') {
285 CurStringPiece += CurChar;
286 continue;
287 }
288
289 // Escaped "%" character in asm string.
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000290 if (CurPtr == StrEnd) {
291 // % at end of string is invalid (no escape).
292 DiagOffs = CurPtr-StrStart-1;
293 return diag::err_asm_invalid_escape;
294 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000295
Chris Lattner3182db12009-03-10 23:51:40 +0000296 char EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000297 if (EscapedChar == '%') { // %% -> %
298 // Escaped percentage sign.
299 CurStringPiece += '%';
300 continue;
301 }
302
303 if (EscapedChar == '=') { // %= -> Generate an unique ID.
304 CurStringPiece += "${:uid}";
305 continue;
306 }
307
308 // Otherwise, we have an operand. If we have accumulated a string so far,
309 // add it to the Pieces list.
310 if (!CurStringPiece.empty()) {
311 Pieces.push_back(AsmStringPiece(CurStringPiece));
312 CurStringPiece.clear();
313 }
314
315 // Handle %x4 and %x[foo] by capturing x as the modifier character.
316 char Modifier = '\0';
317 if (isalpha(EscapedChar)) {
318 Modifier = EscapedChar;
Chris Lattner3182db12009-03-10 23:51:40 +0000319 EscapedChar = *CurPtr++;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000320 }
321
322 if (isdigit(EscapedChar)) {
323 // %n - Assembler operand n
Chris Lattnercafc2222009-03-11 22:52:17 +0000324 unsigned N = 0;
325
326 --CurPtr;
327 while (CurPtr != StrEnd && isdigit(*CurPtr))
Chris Lattner32a47ed2009-03-11 23:09:16 +0000328 N = N*10 + ((*CurPtr++)-'0');
Chris Lattner85759272009-03-11 00:23:13 +0000329
330 unsigned NumOperands =
331 getNumOutputs() + getNumPlusOperands() + getNumInputs();
332 if (N >= NumOperands) {
333 DiagOffs = CurPtr-StrStart-1;
334 return diag::err_asm_invalid_operand_number;
335 }
336
Chris Lattner458cd9c2009-03-10 23:21:44 +0000337 Pieces.push_back(AsmStringPiece(N, Modifier));
338 continue;
339 }
340
341 // Handle %[foo], a symbolic operand reference.
342 if (EscapedChar == '[') {
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000343 DiagOffs = CurPtr-StrStart-1;
344
345 // Find the ']'.
Chris Lattner3182db12009-03-10 23:51:40 +0000346 const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000347 if (NameEnd == 0)
348 return diag::err_asm_unterminated_symbolic_operand_name;
349 if (NameEnd == CurPtr)
350 return diag::err_asm_empty_symbolic_operand_name;
351
Chris Lattner3182db12009-03-10 23:51:40 +0000352 std::string SymbolicName(CurPtr, NameEnd);
Chris Lattner458cd9c2009-03-10 23:21:44 +0000353
354 int N = getNamedOperand(SymbolicName);
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000355 if (N == -1) {
356 // Verify that an operand with that name exists.
357 DiagOffs = CurPtr-StrStart;
358 return diag::err_asm_unknown_symbolic_operand_name;
359 }
Chris Lattner458cd9c2009-03-10 23:21:44 +0000360 Pieces.push_back(AsmStringPiece(N, Modifier));
Chris Lattnereab8cfb2009-03-11 00:06:36 +0000361
362 CurPtr = NameEnd+1;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000363 continue;
364 }
365
Chris Lattner2ff0f422009-03-10 23:57:07 +0000366 DiagOffs = CurPtr-StrStart-1;
Chris Lattner3182db12009-03-10 23:51:40 +0000367 return diag::err_asm_invalid_escape;
Chris Lattner458cd9c2009-03-10 23:21:44 +0000368 }
369}
370
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000371//===----------------------------------------------------------------------===//
372// Constructors
373//===----------------------------------------------------------------------===//
374
Anders Carlssondfab34a2008-02-05 23:03:50 +0000375AsmStmt::AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000376 unsigned numoutputs, unsigned numinputs,
377 std::string *names, StringLiteral **constraints,
378 Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
379 StringLiteral **clobbers, SourceLocation rparenloc)
Anders Carlssonb235fc22007-11-22 01:36:19 +0000380 : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
Anders Carlssondfab34a2008-02-05 23:03:50 +0000381 , IsSimple(issimple), IsVolatile(isvolatile)
382 , NumOutputs(numoutputs), NumInputs(numinputs) {
Anders Carlssonb235fc22007-11-22 01:36:19 +0000383 for (unsigned i = 0, e = numinputs + numoutputs; i != e; i++) {
384 Names.push_back(names[i]);
385 Exprs.push_back(exprs[i]);
Nico Weber608b17f2008-08-05 23:15:29 +0000386 Constraints.push_back(constraints[i]);
Anders Carlssonb235fc22007-11-22 01:36:19 +0000387 }
Nico Weber608b17f2008-08-05 23:15:29 +0000388
Anders Carlssonb235fc22007-11-22 01:36:19 +0000389 for (unsigned i = 0; i != numclobbers; i++)
390 Clobbers.push_back(clobbers[i]);
391}
392
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000393ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
394 Stmt *Body, SourceLocation FCL,
Nico Weber608b17f2008-08-05 23:15:29 +0000395 SourceLocation RPL)
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000396: Stmt(ObjCForCollectionStmtClass) {
397 SubExprs[ELEM] = Elem;
398 SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
399 SubExprs[BODY] = Body;
400 ForLoc = FCL;
401 RParenLoc = RPL;
402}
403
404
Nico Weber608b17f2008-08-05 23:15:29 +0000405ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
406 SourceLocation rparenloc,
Steve Naroff7ba138a2009-03-03 19:52:17 +0000407 ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000408 Stmt *atCatchList)
409: Stmt(ObjCAtCatchStmtClass) {
Steve Naroff7ba138a2009-03-03 19:52:17 +0000410 ExceptionDecl = catchVarDecl;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000411 SubExprs[BODY] = atCatchStmt;
Eli Friedman0613c372008-05-25 04:34:57 +0000412 SubExprs[NEXT_CATCH] = NULL;
Daniel Dunbar93b2bdb2009-03-01 04:28:32 +0000413 // FIXME: O(N^2) in number of catch blocks.
Eli Friedman0613c372008-05-25 04:34:57 +0000414 if (atCatchList) {
Ted Kremenekff981022008-02-01 21:28:59 +0000415 ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
416
Nico Weber608b17f2008-08-05 23:15:29 +0000417 while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
Ted Kremenekff981022008-02-01 21:28:59 +0000418 AtCatchList = NextCatch;
Nico Weber608b17f2008-08-05 23:15:29 +0000419
Ted Kremenekff981022008-02-01 21:28:59 +0000420 AtCatchList->SubExprs[NEXT_CATCH] = this;
Chris Lattnerdb6ed172008-01-30 05:01:46 +0000421 }
422 AtCatchLoc = atCatchLoc;
423 RParenLoc = rparenloc;
424}
425
426
Ted Kremenek82977772007-08-24 21:09:09 +0000427//===----------------------------------------------------------------------===//
428// Child Iterators for iterating over subexpressions/substatements
429//===----------------------------------------------------------------------===//
430
431// DeclStmt
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000432Stmt::child_iterator DeclStmt::child_begin() {
433 return StmtIterator(DG.begin(), DG.end());
Ted Kremenek14f8b4f2008-08-05 20:46:55 +0000434}
435
Ted Kremenek8ffb1592008-10-07 23:09:49 +0000436Stmt::child_iterator DeclStmt::child_end() {
437 return StmtIterator(DG.end(), DG.end());
Ted Kremenek65aa3b92008-10-06 20:54:44 +0000438}
439
Ted Kremenek82977772007-08-24 21:09:09 +0000440// NullStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000441Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
442Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000443
444// CompoundStmt
445Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
Ted Kremenek8189cde2009-02-07 01:47:29 +0000446Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
Ted Kremenek82977772007-08-24 21:09:09 +0000447
Ted Kremenekd97bb6c2007-08-30 16:50:46 +0000448// CaseStmt
449Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
450Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
451
452// DefaultStmt
453Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
454Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000455
456// LabelStmt
457Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
Chris Lattnerb3938792007-08-30 00:53:54 +0000458Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000459
460// IfStmt
461Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
462Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
463
464// SwitchStmt
465Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
466Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
467
468// WhileStmt
469Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
470Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
471
472// DoStmt
473Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
474Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
475
476// ForStmt
477Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
478Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
479
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000480// ObjCForCollectionStmt
Nico Weber608b17f2008-08-05 23:15:29 +0000481Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
482 return &SubExprs[0];
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000483}
Nico Weber608b17f2008-08-05 23:15:29 +0000484Stmt::child_iterator ObjCForCollectionStmt::child_end() {
485 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian0196cab2008-01-02 22:54:34 +0000486}
487
Ted Kremenek82977772007-08-24 21:09:09 +0000488// GotoStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000489Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
490Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000491
492// IndirectGotoStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000493Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
494const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
Ted Kremenek82977772007-08-24 21:09:09 +0000495
Ted Kremenek1060aff2008-06-17 03:11:08 +0000496Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
497Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
Ted Kremenek82977772007-08-24 21:09:09 +0000498
499// ContinueStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000500Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
501Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000502
503// BreakStmt
Ted Kremenek9ac59282007-10-18 23:28:49 +0000504Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
505Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
Ted Kremenek82977772007-08-24 21:09:09 +0000506
507// ReturnStmt
Ted Kremenek1060aff2008-06-17 03:11:08 +0000508const Expr* ReturnStmt::getRetValue() const {
509 return cast_or_null<Expr>(RetExpr);
510}
511Expr* ReturnStmt::getRetValue() {
512 return cast_or_null<Expr>(RetExpr);
Ted Kremenek82977772007-08-24 21:09:09 +0000513}
514
Ted Kremenek1060aff2008-06-17 03:11:08 +0000515Stmt::child_iterator ReturnStmt::child_begin() {
516 return &RetExpr;
517}
518Stmt::child_iterator ReturnStmt::child_end() {
519 return RetExpr ? &RetExpr+1 : &RetExpr;
Ted Kremenek2298f912007-08-27 20:58:16 +0000520}
Ted Kremenek82977772007-08-24 21:09:09 +0000521
Chris Lattnerfe795952007-10-29 04:04:16 +0000522// AsmStmt
Ted Kremenekce2fc3a2008-10-27 18:40:21 +0000523Stmt::child_iterator AsmStmt::child_begin() {
524 return Exprs.empty() ? 0 : &Exprs[0];
525}
526Stmt::child_iterator AsmStmt::child_end() {
527 return Exprs.empty() ? 0 : &Exprs[0] + Exprs.size();
528}
Chris Lattnerfe795952007-10-29 04:04:16 +0000529
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000530// ObjCAtCatchStmt
531Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000532Stmt::child_iterator ObjCAtCatchStmt::child_end() {
533 return &SubExprs[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000534}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000535
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000536// ObjCAtFinallyStmt
537Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
538Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000539
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000540// ObjCAtTryStmt
541Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
Nico Weber608b17f2008-08-05 23:15:29 +0000542Stmt::child_iterator ObjCAtTryStmt::child_end() {
543 return &SubStmts[0]+END_EXPR;
Fariborz Jahanian3b1191d2007-11-01 23:59:59 +0000544}
Fariborz Jahanianb210bd02007-11-01 21:12:44 +0000545
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000546// ObjCAtThrowStmt
547Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000548 return &Throw;
549}
550
Ted Kremeneka526c5c2008-01-07 19:49:32 +0000551Stmt::child_iterator ObjCAtThrowStmt::child_end() {
Fariborz Jahanian39f8f152007-11-07 02:00:49 +0000552 return &Throw+1;
553}
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000554
555// ObjCAtSynchronizedStmt
556Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000557 return &SubStmts[0];
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000558}
559
560Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
Fariborz Jahaniana0f55792008-01-29 22:59:37 +0000561 return &SubStmts[0]+END_EXPR;
Fariborz Jahanianfa3ee8e2008-01-29 19:14:59 +0000562}
563
Sebastian Redl4b07b292008-12-22 19:15:10 +0000564// CXXCatchStmt
565Stmt::child_iterator CXXCatchStmt::child_begin() {
566 return &HandlerBlock;
567}
568
569Stmt::child_iterator CXXCatchStmt::child_end() {
570 return &HandlerBlock + 1;
571}
572
573QualType CXXCatchStmt::getCaughtType() {
574 if (ExceptionDecl)
Douglas Gregord308e622009-05-18 20:51:54 +0000575 return ExceptionDecl->getType();
Sebastian Redl4b07b292008-12-22 19:15:10 +0000576 return QualType();
577}
578
Douglas Gregor42602bb2009-08-07 06:08:38 +0000579void CXXCatchStmt::DoDestroy(ASTContext& C) {
Sebastian Redl8351da02008-12-22 21:35:02 +0000580 if (ExceptionDecl)
581 ExceptionDecl->Destroy(C);
Douglas Gregor42602bb2009-08-07 06:08:38 +0000582 Stmt::DoDestroy(C);
Sebastian Redl4b07b292008-12-22 19:15:10 +0000583}
Sebastian Redl8351da02008-12-22 21:35:02 +0000584
585// CXXTryStmt
586Stmt::child_iterator CXXTryStmt::child_begin() { return &Stmts[0]; }
587Stmt::child_iterator CXXTryStmt::child_end() { return &Stmts[0]+Stmts.size(); }
588
589CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
590 Stmt **handlers, unsigned numHandlers)
591 : Stmt(CXXTryStmtClass), TryLoc(tryLoc) {
592 Stmts.push_back(tryBlock);
593 Stmts.insert(Stmts.end(), handlers, handlers + numHandlers);
594}