blob: 28370342b1e05d0366f6f14b43af9a2bc56ea818 [file] [log] [blame]
Reid Spencer5f016e22007-07-11 17:01:13 +00001//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source 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/StmtVisitor.h"
17#include "clang/Lex/IdentifierTable.h"
18using namespace clang;
19
Reid Spencer5f016e22007-07-11 17:01:13 +000020static struct StmtClassNameTable {
21 int enumValue;
22 const char *className;
23 unsigned counter;
24 unsigned size;
25} sNames[] = {
26#define STMT(N, CLASS, PARENT) { N, #CLASS, 0, sizeof(CLASS) },
27#include "clang/AST/StmtNodes.def"
28 { 0, 0, 0, 0 }
29};
30
31const char *Stmt::getStmtClassName() const {
32 for (int i = 0; sNames[i].className; i++) {
33 if (sClass == sNames[i].enumValue)
34 return sNames[i].className;
35 }
36 return 0; // should never happen....
37}
38
39void Stmt::PrintStats() {
40 unsigned sum = 0;
41 fprintf(stderr, "*** Stmt/Expr Stats:\n");
42 for (int i = 0; sNames[i].className; i++) {
43 sum += sNames[i].counter;
44 }
45 fprintf(stderr, " %d stmts/exprs total.\n", sum);
46 sum = 0;
47 for (int i = 0; sNames[i].className; i++) {
48 fprintf(stderr, " %d %s, %d each (%d bytes)\n",
49 sNames[i].counter, sNames[i].className, sNames[i].size, sNames[i].counter*sNames[i].size);
50 sum += sNames[i].counter*sNames[i].size;
51 }
52 fprintf(stderr, "Total bytes = %d\n", sum);
53}
54
55void Stmt::addStmtClass(StmtClass s) {
56 for (int i = 0; sNames[i].className; i++) {
57 if (s == sNames[i].enumValue)
58 sNames[i].counter++;
59 }
60}
61
62static bool StatSwitch = false;
63
64bool Stmt::CollectingStats(bool enable) {
65 if (enable) StatSwitch = true;
66 return StatSwitch;
67}
68
69
70
71const char *LabelStmt::getName() const {
72 return getID()->getName();
73}
74
Ted Kremenek82977772007-08-24 21:09:09 +000075//===----------------------------------------------------------------------===//
76// Child Iterators for iterating over subexpressions/substatements
77//===----------------------------------------------------------------------===//
78
79// DeclStmt
80Stmt::child_iterator DeclStmt::child_begin() { return NULL; }
81Stmt::child_iterator DeclStmt::child_end() { return NULL; }
82
83// NullStmt
84Stmt::child_iterator NullStmt::child_begin() { return NULL; }
85Stmt::child_iterator NullStmt::child_end() { return NULL; }
86
87// CompoundStmt
88Stmt::child_iterator CompoundStmt::child_begin() { return &Body[0]; }
89Stmt::child_iterator CompoundStmt::child_end() { return &Body[0]+Body.size(); }
90
91// SwitchCase
92Stmt::child_iterator SwitchCase::child_begin() { return &SubStmt; }
93Stmt::child_iterator SwitchCase::child_end() { return child_begin()+1; }
94
95// LabelStmt
96Stmt::child_iterator LabelStmt::child_begin() { return &SubStmt; }
97Stmt::child_iterator LabelStmt::child_end() { return child_begin()+1; }
98
99// IfStmt
100Stmt::child_iterator IfStmt::child_begin() { return &SubExprs[0]; }
101Stmt::child_iterator IfStmt::child_end() { return &SubExprs[0]+END_EXPR; }
102
103// SwitchStmt
104Stmt::child_iterator SwitchStmt::child_begin() { return &SubExprs[0]; }
105Stmt::child_iterator SwitchStmt::child_end() { return &SubExprs[0]+END_EXPR; }
106
107// WhileStmt
108Stmt::child_iterator WhileStmt::child_begin() { return &SubExprs[0]; }
109Stmt::child_iterator WhileStmt::child_end() { return &SubExprs[0]+END_EXPR; }
110
111// DoStmt
112Stmt::child_iterator DoStmt::child_begin() { return &SubExprs[0]; }
113Stmt::child_iterator DoStmt::child_end() { return &SubExprs[0]+END_EXPR; }
114
115// ForStmt
116Stmt::child_iterator ForStmt::child_begin() { return &SubExprs[0]; }
117Stmt::child_iterator ForStmt::child_end() { return &SubExprs[0]+END_EXPR; }
118
119// GotoStmt
120Stmt::child_iterator GotoStmt::child_begin() { return NULL; }
121Stmt::child_iterator GotoStmt::child_end() { return NULL; }
122
123// IndirectGotoStmt
124Stmt::child_iterator IndirectGotoStmt::child_begin() {
125 return reinterpret_cast<Stmt**>(&Target);
126}
127
128Stmt::child_iterator IndirectGotoStmt::child_end() { return child_begin()+1; }
129
130// ContinueStmt
131Stmt::child_iterator ContinueStmt::child_begin() { return NULL; }
132Stmt::child_iterator ContinueStmt::child_end() { return NULL; }
133
134// BreakStmt
135Stmt::child_iterator BreakStmt::child_begin() { return NULL; }
136Stmt::child_iterator BreakStmt::child_end() { return NULL; }
137
138// ReturnStmt
139Stmt::child_iterator ReturnStmt::child_begin() {
140 return reinterpret_cast<Stmt**>(&RetExpr);
141}
142
143Stmt::child_iterator ReturnStmt::child_end() { return child_begin()+1; }
144