 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
82.0% |
91 / 111 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
86.5% |
96 / 111 |
| |
|
Line Coverage: |
90.4% |
310 / 343 |
| |
 |
|
 |
1 : //===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
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"
16 : #include "clang/AST/ExprObjC.h"
17 : #include "clang/AST/StmtCXX.h"
18 : #include "clang/AST/StmtObjC.h"
19 : #include "clang/AST/Type.h"
20 : #include "clang/AST/ASTContext.h"
21 : #include "clang/AST/ASTDiagnostic.h"
22 : #include <cstdio>
23 : using namespace clang;
24 :
25 : static struct StmtClassNameTable {
26 : const char *Name;
27 : unsigned Counter;
28 : unsigned Size;
29 : } StmtClassInfo[Stmt::lastExprConstant+1];
30 :
31 356: static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
32 : static bool Initialized = false;
350: branch 0 taken
6: branch 1 taken
33 356: if (Initialized)
34 350: return StmtClassInfo[E];
35 :
36 : // Intialize the table on the first use.
37 6: Initialized = true;
38 : #define ABSTRACT_EXPR(CLASS, PARENT)
39 : #define STMT(CLASS, PARENT) \
40 : StmtClassInfo[(unsigned)Stmt::CLASS##Class].Name = #CLASS; \
41 : StmtClassInfo[(unsigned)Stmt::CLASS##Class].Size = sizeof(CLASS);
42 : #include "clang/AST/StmtNodes.def"
43 :
44 6: return StmtClassInfo[E];
45 : }
46 :
47 354: const char *Stmt::getStmtClassName() const {
48 354: return getStmtInfoTableEntry((StmtClass)sClass).Name;
49 : }
50 :
51 2: void Stmt::PrintStats() {
52 : // Ensure the table is primed.
53 2: getStmtInfoTableEntry(Stmt::NullStmtClass);
54 :
55 2: unsigned sum = 0;
56 2: fprintf(stderr, "*** Stmt/Expr Stats:\n");
198: branch 0 taken
2: branch 1 taken
57 200: for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
196: branch 0 taken
2: branch 1 taken
58 198: if (StmtClassInfo[i].Name == 0) continue;
59 196: sum += StmtClassInfo[i].Counter;
60 : }
61 2: fprintf(stderr, " %d stmts/exprs total.\n", sum);
62 2: sum = 0;
198: branch 0 taken
2: branch 1 taken
63 200: for (int i = 0; i != Stmt::lastExprConstant+1; i++) {
196: branch 0 taken
2: branch 1 taken
64 198: if (StmtClassInfo[i].Name == 0) continue;
0: branch 0 not taken
196: branch 1 taken
65 196: if (StmtClassInfo[i].Counter == 0) continue;
66 : fprintf(stderr, " %d %s, %d each (%d bytes)\n",
67 : StmtClassInfo[i].Counter, StmtClassInfo[i].Name,
68 : StmtClassInfo[i].Size,
69 0: StmtClassInfo[i].Counter*StmtClassInfo[i].Size);
70 0: sum += StmtClassInfo[i].Counter*StmtClassInfo[i].Size;
71 : }
72 2: fprintf(stderr, "Total bytes = %d\n", sum);
73 2: }
74 :
75 0: void Stmt::addStmtClass(StmtClass s) {
76 0: ++getStmtInfoTableEntry(s).Counter;
77 0: }
78 :
79 : static bool StatSwitch = false;
80 :
81 177104: bool Stmt::CollectingStats(bool Enable) {
2: branch 0 taken
177102: branch 1 taken
82 177104: if (Enable) StatSwitch = true;
83 177104: return StatSwitch;
84 : }
85 :
86 43: void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
3: branch 0 taken
40: branch 1 taken
87 43: if (this->Body)
88 3: C.Deallocate(Body);
89 43: this->NumStmts = NumStmts;
90 :
91 43: Body = new (C) Stmt*[NumStmts];
92 43: memcpy(Body, Stmts, sizeof(Stmt *) * NumStmts);
93 43: }
94 :
95 45: const char *LabelStmt::getName() const {
96 45: return getID()->getNameStart();
97 : }
98 :
99 : // This is defined here to avoid polluting Stmt.h with importing Expr.h
100 4263: SourceRange ReturnStmt::getSourceRange() const {
3581: branch 0 taken
682: branch 1 taken
101 4263: if (RetExpr)
102 3581: return SourceRange(RetLoc, RetExpr->getLocEnd());
103 : else
104 682: return SourceRange(RetLoc);
105 : }
106 :
107 0: bool Stmt::hasImplicitControlFlow() const {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
108 0: switch (sClass) {
109 : default:
110 0: return false;
111 :
112 : case CallExprClass:
113 : case ConditionalOperatorClass:
114 : case ChooseExprClass:
115 : case StmtExprClass:
116 : case DeclStmtClass:
117 0: return true;
118 :
119 : case Stmt::BinaryOperatorClass: {
120 0: const BinaryOperator* B = cast<BinaryOperator>(this);
0: branch 1 not taken
0: branch 2 not taken
0: branch 4 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 7 not taken
121 0: if (B->isLogicalOp() || B->getOpcode() == BinaryOperator::Comma)
122 0: return true;
123 : else
124 0: return false;
125 : }
126 : }
127 : }
128 :
129 37: Expr *AsmStmt::getOutputExpr(unsigned i) {
130 37: return cast<Expr>(Exprs[i]);
131 : }
132 :
133 : /// getOutputConstraint - Return the constraint string for the specified
134 : /// output operand. All output constraints are known to be non-empty (either
135 : /// '=' or '+').
136 58: llvm::StringRef AsmStmt::getOutputConstraint(unsigned i) const {
137 58: return getOutputConstraintLiteral(i)->getString();
138 : }
139 :
140 : /// getNumPlusOperands - Return the number of output operands that have a "+"
141 : /// constraint.
142 17: unsigned AsmStmt::getNumPlusOperands() const {
143 17: unsigned Res = 0;
16: branch 1 taken
17: branch 2 taken
144 33: for (unsigned i = 0, e = getNumOutputs(); i != e; ++i)
6: branch 1 taken
10: branch 2 taken
145 16: if (isOutputPlusConstraint(i))
146 6: ++Res;
147 17: return Res;
148 : }
149 :
150 31: Expr *AsmStmt::getInputExpr(unsigned i) {
151 31: return cast<Expr>(Exprs[i + NumOutputs]);
152 : }
153 :
154 : /// getInputConstraint - Return the specified input constraint. Unlike output
155 : /// constraints, these can be empty.
156 46: llvm::StringRef AsmStmt::getInputConstraint(unsigned i) const {
157 46: return getInputConstraintLiteral(i)->getString();
158 : }
159 :
160 :
161 : void AsmStmt::setOutputsAndInputsAndClobbers(ASTContext &C,
162 : IdentifierInfo **Names,
163 : StringLiteral **Constraints,
164 : Stmt **Exprs,
165 : unsigned NumOutputs,
166 : unsigned NumInputs,
167 : StringLiteral **Clobbers,
168 5: unsigned NumClobbers) {
169 5: this->NumOutputs = NumOutputs;
170 5: this->NumInputs = NumInputs;
171 5: this->NumClobbers = NumClobbers;
172 :
173 5: unsigned NumExprs = NumOutputs + NumInputs;
174 :
175 5: C.Deallocate(this->Names);
176 5: this->Names = new (C) IdentifierInfo*[NumExprs];
177 5: std::copy(Names, Names + NumExprs, this->Names);
178 :
179 5: C.Deallocate(this->Exprs);
180 5: this->Exprs = new (C) Stmt*[NumExprs];
181 5: std::copy(Exprs, Exprs + NumExprs, this->Exprs);
182 :
183 5: C.Deallocate(this->Constraints);
184 5: this->Constraints = new (C) StringLiteral*[NumExprs];
185 5: std::copy(Constraints, Constraints + NumExprs, this->Constraints);
186 :
187 5: C.Deallocate(this->Clobbers);
188 5: this->Clobbers = new (C) StringLiteral*[NumClobbers];
189 5: std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
190 5: }
191 :
192 : /// getNamedOperand - Given a symbolic operand reference like %[foo],
193 : /// translate this into a numeric value needed to reference the same operand.
194 : /// This returns -1 if the operand name is invalid.
195 14: int AsmStmt::getNamedOperand(llvm::StringRef SymbolicName) const {
196 14: unsigned NumPlusOperands = 0;
197 :
198 : // Check if this is an output operand.
10: branch 1 taken
12: branch 2 taken
199 22: for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) {
2: branch 2 taken
8: branch 3 taken
200 10: if (getOutputName(i) == SymbolicName)
201 2: return i;
202 : }
203 :
18: branch 1 taken
1: branch 2 taken
204 19: for (unsigned i = 0, e = getNumInputs(); i != e; ++i)
11: branch 2 taken
7: branch 3 taken
205 18: if (getInputName(i) == SymbolicName)
206 11: return getNumOutputs() + NumPlusOperands + i;
207 :
208 : // Not found.
209 1: return -1;
210 : }
211 :
212 : /// AnalyzeAsmString - Analyze the asm string of the current asm, decomposing
213 : /// it into pieces. If the asm string is erroneous, emit errors and return
214 : /// true, otherwise return false.
215 : unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
216 124: ASTContext &C, unsigned &DiagOffs) const {
217 124: const char *StrStart = getAsmString()->getStrData();
218 124: const char *StrEnd = StrStart + getAsmString()->getByteLength();
219 124: const char *CurPtr = StrStart;
220 :
221 : // "Simple" inline asms have no constraints or operands, just convert the asm
222 : // string to escape $'s.
34: branch 1 taken
90: branch 2 taken
223 124: if (isSimple()) {
224 34: std::string Result;
168: branch 0 taken
34: branch 1 taken
225 202: for (; CurPtr != StrEnd; ++CurPtr) {
0: branch 0 not taken
168: branch 1 taken
226 168: switch (*CurPtr) {
227 : case '$':
228 0: Result += "$$";
229 0: break;
230 : default:
231 168: Result += *CurPtr;
232 : break;
233 : }
234 : }
235 34: Pieces.push_back(AsmStringPiece(Result));
236 34: return 0;
237 : }
238 :
239 : // CurStringPiece - The current string that we are building up as we scan the
240 : // asm string.
241 90: std::string CurStringPiece;
242 :
243 398: while (1) {
244 : // Done with the string?
84: branch 0 taken
404: branch 1 taken
245 488: if (CurPtr == StrEnd) {
50: branch 1 taken
34: branch 2 taken
246 84: if (!CurStringPiece.empty())
247 50: Pieces.push_back(AsmStringPiece(CurStringPiece));
248 84: return 0;
249 : }
250 :
251 404: char CurChar = *CurPtr++;
0: branch 0 not taken
404: branch 1 taken
252 404: if (CurChar == '$') {
253 0: CurStringPiece += "$$";
254 0: continue;
369: branch 0 taken
35: branch 1 taken
255 404: } else if (CurChar != '%') {
256 369: CurStringPiece += CurChar;
257 369: continue;
258 : }
259 :
260 : // Escaped "%" character in asm string.
1: branch 0 taken
34: branch 1 taken
261 35: if (CurPtr == StrEnd) {
262 : // % at end of string is invalid (no escape).
263 1: DiagOffs = CurPtr-StrStart-1;
264 1: return diag::err_asm_invalid_escape;
265 : }
266 :
267 34: char EscapedChar = *CurPtr++;
0: branch 0 not taken
34: branch 1 taken
268 34: if (EscapedChar == '%') { // %% -> %
269 : // Escaped percentage sign.
270 0: CurStringPiece += '%';
271 0: continue;
272 : }
273 :
0: branch 0 not taken
34: branch 1 taken
274 34: if (EscapedChar == '=') { // %= -> Generate an unique ID.
275 0: CurStringPiece += "${:uid}";
276 0: continue;
277 : }
278 :
279 : // Otherwise, we have an operand. If we have accumulated a string so far,
280 : // add it to the Pieces list.
25: branch 1 taken
9: branch 2 taken
281 34: if (!CurStringPiece.empty()) {
282 25: Pieces.push_back(AsmStringPiece(CurStringPiece));
283 25: CurStringPiece.clear();
284 : }
285 :
286 : // Handle %x4 and %x[foo] by capturing x as the modifier character.
287 34: char Modifier = '\0';
2: branch 1 taken
32: branch 2 taken
288 34: if (isalpha(EscapedChar)) {
289 2: Modifier = EscapedChar;
290 2: EscapedChar = *CurPtr++;
291 : }
292 :
17: branch 0 taken
17: branch 1 taken
293 34: if (isdigit(EscapedChar)) {
294 : // %n - Assembler operand n
295 17: unsigned N = 0;
296 :
297 17: --CurPtr;
22: branch 0 taken
12: branch 1 taken
17: branch 2 taken
5: branch 3 taken
298 51: while (CurPtr != StrEnd && isdigit(*CurPtr))
299 17: N = N*10 + ((*CurPtr++)-'0');
300 :
301 : unsigned NumOperands =
302 17: getNumOutputs() + getNumPlusOperands() + getNumInputs();
1: branch 0 taken
16: branch 1 taken
303 17: if (N >= NumOperands) {
304 1: DiagOffs = CurPtr-StrStart-1;
305 1: return diag::err_asm_invalid_operand_number;
306 : }
307 :
308 16: Pieces.push_back(AsmStringPiece(N, Modifier));
309 16: continue;
310 : }
311 :
312 : // Handle %[foo], a symbolic operand reference.
16: branch 0 taken
1: branch 1 taken
313 17: if (EscapedChar == '[') {
314 16: DiagOffs = CurPtr-StrStart-1;
315 :
316 : // Find the ']'.
317 16: const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
1: branch 0 taken
15: branch 1 taken
318 16: if (NameEnd == 0)
319 1: return diag::err_asm_unterminated_symbolic_operand_name;
1: branch 0 taken
14: branch 1 taken
320 15: if (NameEnd == CurPtr)
321 1: return diag::err_asm_empty_symbolic_operand_name;
322 :
323 14: llvm::StringRef SymbolicName(CurPtr, NameEnd - CurPtr);
324 :
325 14: int N = getNamedOperand(SymbolicName);
1: branch 0 taken
13: branch 1 taken
326 14: if (N == -1) {
327 : // Verify that an operand with that name exists.
328 1: DiagOffs = CurPtr-StrStart;
329 1: return diag::err_asm_unknown_symbolic_operand_name;
330 : }
331 13: Pieces.push_back(AsmStringPiece(N, Modifier));
332 :
333 13: CurPtr = NameEnd+1;
334 13: continue;
335 : }
336 :
337 1: DiagOffs = CurPtr-StrStart-1;
338 1: return diag::err_asm_invalid_escape;
339 90: }
340 : }
341 :
342 28: QualType CXXCatchStmt::getCaughtType() const {
28: branch 0 taken
0: branch 1 not taken
343 28: if (ExceptionDecl)
344 28: return ExceptionDecl->getType();
345 0: return QualType();
346 : }
347 :
348 : //===----------------------------------------------------------------------===//
349 : // Constructors
350 : //===----------------------------------------------------------------------===//
351 :
352 : AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
353 : bool isvolatile, bool msasm,
354 : unsigned numoutputs, unsigned numinputs,
355 : IdentifierInfo **names, StringLiteral **constraints,
356 : Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
357 89: StringLiteral **clobbers, SourceLocation rparenloc)
358 : : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
359 : , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
360 89: , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
361 :
362 89: unsigned NumExprs = NumOutputs +NumInputs;
363 :
364 89: Names = new (C) IdentifierInfo*[NumExprs];
365 89: std::copy(names, names + NumExprs, Names);
366 :
367 89: Exprs = new (C) Stmt*[NumExprs];
368 89: std::copy(exprs, exprs + NumExprs, Exprs);
369 :
370 89: Constraints = new (C) StringLiteral*[NumExprs];
371 89: std::copy(constraints, constraints + NumExprs, Constraints);
372 :
373 89: Clobbers = new (C) StringLiteral*[NumClobbers];
374 89: std::copy(clobbers, clobbers + NumClobbers, Clobbers);
375 89: }
376 :
377 : ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
378 : Stmt *Body, SourceLocation FCL,
379 51: SourceLocation RPL)
380 51: : Stmt(ObjCForCollectionStmtClass) {
381 51: SubExprs[ELEM] = Elem;
382 51: SubExprs[COLLECTION] = reinterpret_cast<Stmt*>(Collect);
383 51: SubExprs[BODY] = Body;
384 51: ForLoc = FCL;
385 51: RParenLoc = RPL;
386 51: }
387 :
388 :
389 : ObjCAtCatchStmt::ObjCAtCatchStmt(SourceLocation atCatchLoc,
390 : SourceLocation rparenloc,
391 : ParmVarDecl *catchVarDecl, Stmt *atCatchStmt,
392 57: Stmt *atCatchList)
393 57: : Stmt(ObjCAtCatchStmtClass) {
394 57: ExceptionDecl = catchVarDecl;
395 57: SubExprs[BODY] = atCatchStmt;
396 57: SubExprs[NEXT_CATCH] = NULL;
397 : // FIXME: O(N^2) in number of catch blocks.
57: branch 0 taken
57: branch 1 taken
20: branch 2 taken
37: branch 3 taken
398 57: if (atCatchList) {
399 20: ObjCAtCatchStmt *AtCatchList = static_cast<ObjCAtCatchStmt*>(atCatchList);
400 :
0: branch 1 not taken
0: branch 2 not taken
5: branch 4 taken
20: branch 5 taken
401 30: while (ObjCAtCatchStmt* NextCatch = AtCatchList->getNextCatchStmt())
402 5: AtCatchList = NextCatch;
403 :
404 20: AtCatchList->SubExprs[NEXT_CATCH] = this;
405 : }
406 57: AtCatchLoc = atCatchLoc;
407 57: RParenLoc = rparenloc;
408 57: }
409 :
410 : CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
411 : Stmt *tryBlock, Stmt **handlers,
412 25: unsigned numHandlers) {
413 25: std::size_t Size = sizeof(CXXTryStmt);
414 25: Size += ((numHandlers + 1) * sizeof(Stmt));
415 :
416 25: void *Mem = C.Allocate(Size, llvm::alignof<CXXTryStmt>());
25: branch 1 taken
0: branch 2 not taken
417 25: return new (Mem) CXXTryStmt(tryLoc, tryBlock, handlers, numHandlers);
418 : }
419 :
420 : CXXTryStmt::CXXTryStmt(SourceLocation tryLoc, Stmt *tryBlock,
421 25: Stmt **handlers, unsigned numHandlers)
422 25: : Stmt(CXXTryStmtClass), TryLoc(tryLoc), NumHandlers(numHandlers) {
423 25: Stmt **Stmts = reinterpret_cast<Stmt **>(this + 1);
424 25: Stmts[0] = tryBlock;
425 25: std::copy(handlers, handlers + NumHandlers, Stmts + 1);
426 25: }
427 :
428 : //===----------------------------------------------------------------------===//
429 : // AST Destruction.
430 : //===----------------------------------------------------------------------===//
431 :
432 3767: void Stmt::DestroyChildren(ASTContext &C) {
2172: branch 3 taken
3767: branch 4 taken
433 9706: for (child_iterator I = child_begin(), E = child_end(); I !=E; )
1503: branch 2 taken
669: branch 3 taken
434 2172: if (Stmt* Child = *I++) Child->Destroy(C);
435 3767: }
436 :
437 : static void BranchDestroy(ASTContext &C, Stmt *S, Stmt **SubExprs,
438 15: unsigned NumExprs) {
439 : // We do not use child_iterator here because that will include
440 : // the expressions referenced by the condition variable.
31: branch 0 taken
15: branch 1 taken
441 46: for (Stmt **I = SubExprs, **E = SubExprs + NumExprs; I != E; ++I)
27: branch 0 taken
4: branch 1 taken
442 31: if (Stmt *Child = *I) Child->Destroy(C);
443 :
444 15: S->~Stmt();
445 15: C.Deallocate((void *) S);
446 15: }
447 :
448 3446: void Stmt::DoDestroy(ASTContext &C) {
449 3446: DestroyChildren(C);
450 3446: this->~Stmt();
451 3446: C.Deallocate((void *)this);
452 3446: }
453 :
454 0: void CXXCatchStmt::DoDestroy(ASTContext& C) {
0: branch 0 not taken
0: branch 1 not taken
455 0: if (ExceptionDecl)
456 0: ExceptionDecl->Destroy(C);
457 0: Stmt::DoDestroy(C);
458 0: }
459 :
460 25: void DeclStmt::DoDestroy(ASTContext &C) {
461 : // Don't use StmtIterator to iterate over the Decls, as that can recurse
462 : // into VLA size expressions (which are owned by the VLA). Further, Decls
463 : // are owned by the DeclContext, and will be destroyed with them.
5: branch 1 taken
20: branch 2 taken
464 25: if (DG.isDeclGroup())
465 5: DG.getDeclGroup().Destroy(C);
466 25: }
467 :
468 1: void IfStmt::DoDestroy(ASTContext &C) {
469 1: BranchDestroy(C, this, SubExprs, END_EXPR);
470 1: }
471 :
472 0: void ForStmt::DoDestroy(ASTContext &C) {
473 0: BranchDestroy(C, this, SubExprs, END_EXPR);
474 0: }
475 :
476 14: void SwitchStmt::DoDestroy(ASTContext &C) {
477 : // Destroy the SwitchCase statements in this switch. In the normal
478 : // case, this loop will merely decrement the reference counts from
479 : // the Retain() calls in addSwitchCase();
480 14: SwitchCase *SC = FirstCase;
17: branch 0 taken
14: branch 1 taken
481 45: while (SC) {
482 17: SwitchCase *Next = SC->getNextSwitchCase();
483 17: SC->Destroy(C);
484 17: SC = Next;
485 : }
486 :
487 14: BranchDestroy(C, this, SubExprs, END_EXPR);
488 14: }
489 :
490 0: void WhileStmt::DoDestroy(ASTContext &C) {
491 0: BranchDestroy(C, this, SubExprs, END_EXPR);
492 0: }
493 :
494 7: void AsmStmt::DoDestroy(ASTContext &C) {
495 7: DestroyChildren(C);
496 :
497 7: C.Deallocate(Names);
498 7: C.Deallocate(Constraints);
499 7: C.Deallocate(Exprs);
500 7: C.Deallocate(Clobbers);
501 :
502 7: this->~AsmStmt();
503 7: C.Deallocate((void *)this);
504 7: }
505 :
506 : //===----------------------------------------------------------------------===//
507 : // Child Iterators for iterating over subexpressions/substatements
508 : //===----------------------------------------------------------------------===//
509 :
510 : // DeclStmt
511 3729: Stmt::child_iterator DeclStmt::child_begin() {
512 3729: return StmtIterator(DG.begin(), DG.end());
513 : }
514 :
515 3729: Stmt::child_iterator DeclStmt::child_end() {
516 3729: return StmtIterator(DG.end(), DG.end());
517 : }
518 :
519 : // NullStmt
520 79: Stmt::child_iterator NullStmt::child_begin() { return child_iterator(); }
521 79: Stmt::child_iterator NullStmt::child_end() { return child_iterator(); }
522 :
523 : // CompoundStmt
524 2559: Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
525 2559: Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+NumStmts; }
526 :
527 : // CaseStmt
528 129: Stmt::child_iterator CaseStmt::child_begin() { return &SubExprs[0]; }
529 129: Stmt::child_iterator CaseStmt::child_end() { return &SubExprs[END_EXPR]; }
530 :
531 : // DefaultStmt
532 15: Stmt::child_iterator DefaultStmt::child_begin() { return &SubStmt; }
533 15: Stmt::child_iterator DefaultStmt::child_end() { return &SubStmt+1; }
534 :
535 : // LabelStmt
536 54: Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
537 54: Stmt::child_iterator LabelStmt::child_end() { return &SubStmt+1; }
538 :
539 : // IfStmt
540 379: Stmt::child_iterator IfStmt::child_begin() {
541 379: return child_iterator(Var, &SubExprs[0]);
542 : }
543 379: Stmt::child_iterator IfStmt::child_end() {
544 379: return child_iterator(0, &SubExprs[0]+END_EXPR);
545 : }
546 :
547 : // SwitchStmt
548 26: Stmt::child_iterator SwitchStmt::child_begin() {
549 26: return child_iterator(Var, &SubExprs[0]);
550 : }
551 26: Stmt::child_iterator SwitchStmt::child_end() {
552 26: return child_iterator(0, &SubExprs[0]+END_EXPR);
553 : }
554 :
555 : // WhileStmt
556 38: Stmt::child_iterator WhileStmt::child_begin() {
557 38: return child_iterator(Var, &SubExprs[0]);
558 : }
559 38: Stmt::child_iterator WhileStmt::child_end() {
560 38: return child_iterator(0, &SubExprs[0]+END_EXPR);
561 : }
562 :
563 : // DoStmt
564 24: Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
565 24: Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
566 :
567 : // ForStmt
568 43: Stmt::child_iterator ForStmt::child_begin() {
569 43: return child_iterator(CondVar, &SubExprs[0]);
570 : }
571 43: Stmt::child_iterator ForStmt::child_end() {
572 43: return child_iterator(0, &SubExprs[0]+END_EXPR);
573 : }
574 :
575 : // ObjCForCollectionStmt
576 64: Stmt::child_iterator ObjCForCollectionStmt::child_begin() {
577 64: return &SubExprs[0];
578 : }
579 64: Stmt::child_iterator ObjCForCollectionStmt::child_end() {
580 64: return &SubExprs[0]+END_EXPR;
581 : }
582 :
583 : // GotoStmt
584 74: Stmt::child_iterator GotoStmt::child_begin() { return child_iterator(); }
585 74: Stmt::child_iterator GotoStmt::child_end() { return child_iterator(); }
586 :
587 : // IndirectGotoStmt
588 61: Expr* IndirectGotoStmt::getTarget() { return cast<Expr>(Target); }
589 12: const Expr* IndirectGotoStmt::getTarget() const { return cast<Expr>(Target); }
590 :
591 4: Stmt::child_iterator IndirectGotoStmt::child_begin() { return &Target; }
592 4: Stmt::child_iterator IndirectGotoStmt::child_end() { return &Target+1; }
593 :
594 : // ContinueStmt
595 12: Stmt::child_iterator ContinueStmt::child_begin() { return child_iterator(); }
596 12: Stmt::child_iterator ContinueStmt::child_end() { return child_iterator(); }
597 :
598 : // BreakStmt
599 147: Stmt::child_iterator BreakStmt::child_begin() { return child_iterator(); }
600 147: Stmt::child_iterator BreakStmt::child_end() { return child_iterator(); }
601 :
602 : // ReturnStmt
603 4579: const Expr* ReturnStmt::getRetValue() const {
604 4579: return cast_or_null<Expr>(RetExpr);
605 : }
606 2927: Expr* ReturnStmt::getRetValue() {
607 2927: return cast_or_null<Expr>(RetExpr);
608 : }
609 :
610 11564: Stmt::child_iterator ReturnStmt::child_begin() {
611 11564: return &RetExpr;
612 : }
613 11564: Stmt::child_iterator ReturnStmt::child_end() {
9978: branch 0 taken
1586: branch 1 taken
614 11564: return RetExpr ? &RetExpr+1 : &RetExpr;
615 : }
616 :
617 : // AsmStmt
618 18: Stmt::child_iterator AsmStmt::child_begin() {
13: branch 0 taken
5: branch 1 taken
619 18: return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0];
620 : }
621 18: Stmt::child_iterator AsmStmt::child_end() {
13: branch 0 taken
5: branch 1 taken
622 18: return NumOutputs + NumInputs == 0 ? 0 : &Exprs[0] + NumOutputs + NumInputs;
623 : }
624 :
625 : // ObjCAtCatchStmt
626 15: Stmt::child_iterator ObjCAtCatchStmt::child_begin() { return &SubExprs[0]; }
627 15: Stmt::child_iterator ObjCAtCatchStmt::child_end() {
628 15: return &SubExprs[0]+END_EXPR;
629 : }
630 :
631 : // ObjCAtFinallyStmt
632 30: Stmt::child_iterator ObjCAtFinallyStmt::child_begin() { return &AtFinallyStmt; }
633 30: Stmt::child_iterator ObjCAtFinallyStmt::child_end() { return &AtFinallyStmt+1; }
634 :
635 : // ObjCAtTryStmt
636 18: Stmt::child_iterator ObjCAtTryStmt::child_begin() { return &SubStmts[0]; }
637 18: Stmt::child_iterator ObjCAtTryStmt::child_end() {
638 18: return &SubStmts[0]+END_EXPR;
639 : }
640 :
641 : // ObjCAtThrowStmt
642 30: Stmt::child_iterator ObjCAtThrowStmt::child_begin() {
643 30: return &Throw;
644 : }
645 :
646 30: Stmt::child_iterator ObjCAtThrowStmt::child_end() {
647 30: return &Throw+1;
648 : }
649 :
650 : // ObjCAtSynchronizedStmt
651 11: Stmt::child_iterator ObjCAtSynchronizedStmt::child_begin() {
652 11: return &SubStmts[0];
653 : }
654 :
655 11: Stmt::child_iterator ObjCAtSynchronizedStmt::child_end() {
656 11: return &SubStmts[0]+END_EXPR;
657 : }
658 :
659 : // CXXCatchStmt
660 18: Stmt::child_iterator CXXCatchStmt::child_begin() {
661 18: return &HandlerBlock;
662 : }
663 :
664 18: Stmt::child_iterator CXXCatchStmt::child_end() {
665 18: return &HandlerBlock + 1;
666 : }
667 :
668 : // CXXTryStmt
669 10: Stmt::child_iterator CXXTryStmt::child_begin() {
670 10: return reinterpret_cast<Stmt **>(this + 1);
671 : }
672 :
673 10: Stmt::child_iterator CXXTryStmt::child_end() {
674 10: return reinterpret_cast<Stmt **>(this + 1) + NumHandlers + 1;
675 : }
Generated: 2010-02-10 01:31 by zcov