001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2004, 2006 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.lang;
020:
021: import java.util.Iterator;
022:
023: import xtc.tree.LineMarker;
024: import xtc.tree.Node;
025: import xtc.tree.GNode;
026: import xtc.tree.Pragma;
027: import xtc.tree.Printer;
028: import xtc.tree.Visitor;
029:
030: /**
031: * A visitor to collect statistics on a C program.
032: *
033: * @author Robert Grimm
034: * @version $Revision: 1.9 $
035: */
036: public class CCounter extends Visitor {
037:
038: /** The counter for top-level declarations. */
039: public int countTopLevelDeclaration;
040:
041: /** The counter for top-level function definitions. */
042: public int countTopLevelFunction;
043:
044: /** The counter for nested declarations. */
045: public int countNestedDeclaration;
046:
047: /** The counter for nested function definitions. */
048: public int countNestedFunction;
049:
050: /** The counter for local label declarations. */
051: public int countLocalLabelDecl;
052:
053: /** The counter for named labels. */
054: public int countNamedLabel;
055:
056: /** The counter for case labels. */
057: public int countCaseLabel;
058:
059: /** The counter for default labels. */
060: public int countDefaultLabel;
061:
062: /** The counter for compound statements. */
063: public int countCompoundStmt;
064:
065: /** The counter for if statements. */
066: public int countIfStmt;
067:
068: /** The counter for if-else statements. */
069: public int countIfElseStmt;
070:
071: /** The counter for while statements. */
072: public int countWhileStmt;
073:
074: /** The counter for do-while statements. */
075: public int countDoStmt;
076:
077: /** The counter for for statements. */
078: public int countForStmt;
079:
080: /** The coutner for switch statements. */
081: public int countSwitchStmt;
082:
083: /** The counter for break statements. */
084: public int countBreakStmt;
085:
086: /** The counter for continue statements. */
087: public int countContinueStmt;
088:
089: /** The counter for return statements. */
090: public int countReturnStmt;
091:
092: /** The counter for goto statements. */
093: public int countGotoStmt;
094:
095: /** The counter for expression statements. */
096: public int countExpressionStmt;
097:
098: /** The counter for assembly statements. */
099: public int countAssemblyStmt;
100:
101: /** The counter for empty statements. */
102: public int countEmptyStmt;
103:
104: /** The counter for line markers. */
105: public int countLineMarker;
106:
107: /** The counter for pragmas. */
108: public int countPragma;
109:
110: /** The flag for top-level constructs. */
111: protected boolean isTopLevel;
112:
113: /** Create a new C counter. */
114: public CCounter() {
115: clearCounters();
116: }
117:
118: /** Clear all counters. */
119: public void clearCounters() {
120: countTopLevelDeclaration = 0;
121: countTopLevelFunction = 0;
122: countNestedDeclaration = 0;
123: countNestedFunction = 0;
124: countLocalLabelDecl = 0;
125: countNamedLabel = 0;
126: countCaseLabel = 0;
127: countDefaultLabel = 0;
128: countCompoundStmt = 0;
129: countIfStmt = 0;
130: countIfElseStmt = 0;
131: countWhileStmt = 0;
132: countDoStmt = 0;
133: countForStmt = 0;
134: countSwitchStmt = 0;
135: countBreakStmt = 0;
136: countContinueStmt = 0;
137: countReturnStmt = 0;
138: countGotoStmt = 0;
139: countExpressionStmt = 0;
140: countAssemblyStmt = 0;
141: countEmptyStmt = 0;
142: countLineMarker = 0;
143: countPragma = 0;
144: }
145:
146: /**
147: * Print all counters.
148: *
149: * @param printer The printer.
150: */
151: public void print(Printer printer) {
152: printer.pln().sep().pln();
153:
154: printer.indent().p("// Top-level declarations : ").pln(
155: countTopLevelDeclaration);
156: printer.indent().p("// Top-level function definitions : ").pln(
157: countTopLevelFunction);
158: printer.indent().p("// Nested declarations : ").pln(
159: countNestedDeclaration);
160: printer.indent().p("// Nested function definitions : ").pln(
161: countNestedFunction);
162: printer.indent().p("// Local label declarations : ").pln(
163: countLocalLabelDecl);
164: printer.indent().p("// Named labels : ").pln(
165: countNamedLabel);
166: printer.indent().p("// Case labels : ").pln(
167: countCaseLabel);
168: printer.indent().p("// Default labels : ").pln(
169: countDefaultLabel);
170: printer.indent().p("// Compound statements : ").pln(
171: countCompoundStmt);
172: printer.indent().p("// If statements : ").pln(
173: countIfStmt);
174: printer.indent().p("// If-else statements : ").pln(
175: countIfElseStmt);
176: printer.indent().p("// While statements : ").pln(
177: countWhileStmt);
178: printer.indent().p("// Do statements : ").pln(
179: countDoStmt);
180: printer.indent().p("// For statements : ").pln(
181: countForStmt);
182: printer.indent().p("// Switch statements : ").pln(
183: countSwitchStmt);
184: printer.indent().p("// Break statements : ").pln(
185: countBreakStmt);
186: printer.indent().p("// Continue statements : ").pln(
187: countContinueStmt);
188: printer.indent().p("// Return statements : ").pln(
189: countReturnStmt);
190: printer.indent().p("// Goto statements : ").pln(
191: countGotoStmt);
192: printer.indent().p("// Expression statements : ").pln(
193: countExpressionStmt);
194: printer.indent().p("// Assembly statements : ").pln(
195: countAssemblyStmt);
196: printer.indent().p("// Empty statements : ").pln(
197: countEmptyStmt);
198: printer.indent().p("// Line markers : ").pln(
199: countLineMarker);
200: printer.indent().p("// Pragmas : ").pln(
201: countPragma);
202:
203: printer.pln().sep().pln();
204: }
205:
206: /** Visit the specified translation unit node. */
207: public void visitTranslationUnit(GNode n) {
208: Iterator iter = n.iterator();
209: while (iter.hasNext()) {
210: isTopLevel = true;
211: dispatch((Node) iter.next());
212: }
213: }
214:
215: /** Visit the specified function definition node. */
216: public void visitFunctionDefinition(GNode n) {
217: if (isTopLevel) {
218: countTopLevelFunction++;
219: } else {
220: countNestedFunction++;
221: }
222: isTopLevel = false;
223:
224: dispatch(n.getNode(3));
225: dispatch(n.getNode(4));
226: }
227:
228: /** Visit the specified declaration list node. */
229: public void visitDeclarationList(GNode n) {
230: Iterator iter = n.iterator();
231: while (iter.hasNext()) {
232: dispatch((Node) iter.next());
233: }
234: }
235:
236: /** Visit the specified declaration node. */
237: public void visitDeclaration(GNode n) {
238: if (isTopLevel) {
239: countTopLevelDeclaration++;
240: } else {
241: countNestedDeclaration++;
242: }
243: isTopLevel = false;
244: }
245:
246: /** Visit the specified labeled statement node. */
247: public void visitLabeledStatement(GNode n) {
248: dispatch(n.getNode(0));
249: dispatch(n.getNode(1));
250: }
251:
252: /** Visit the specified named label node. */
253: public void visitNamedLabel(GNode n) {
254: countNamedLabel++;
255: }
256:
257: /** Visit the specified case label node. */
258: public void visitCaseLabel(GNode n) {
259: countCaseLabel++;
260: }
261:
262: /** Visit the specified default label node. */
263: public void visitDefaultLabel(GNode n) {
264: countDefaultLabel++;
265: }
266:
267: /** Visit the specified compound statement node. */
268: public void visitCompoundStatement(GNode n) {
269: countCompoundStmt++;
270:
271: Iterator iter = n.iterator();
272: while (iter.hasNext()) {
273: dispatch((Node) iter.next());
274: }
275: }
276:
277: /** Visit the specified local label declaration node. */
278: public void visitLocalLabelDeclaration(GNode n) {
279: countLocalLabelDecl += n.size();
280: }
281:
282: /** Visit the specified if else statement node. */
283: public void visitIfElseStatement(GNode n) {
284: countIfElseStmt++;
285:
286: dispatch(n.getNode(1));
287: dispatch(n.getNode(2));
288: }
289:
290: /** Visit the specified if statement node. */
291: public void visitIfStatement(GNode n) {
292: countIfStmt++;
293:
294: dispatch(n.getNode(1));
295: }
296:
297: /** Visit the specified while statement node. */
298: public void visitWhileStatement(GNode n) {
299: countWhileStmt++;
300:
301: dispatch(n.getNode(1));
302: }
303:
304: /** Visit the specified do statement node. */
305: public void visitDoStatement(GNode n) {
306: countDoStmt++;
307:
308: dispatch(n.getNode(0));
309: }
310:
311: /** Visit the specified for statement node. */
312: public void visitForStatement(GNode n) {
313: countForStmt++;
314:
315: dispatch(n.getNode(0));
316: dispatch(n.getNode(3));
317: }
318:
319: /** Visit the specified switch statement node. */
320: public void visitSwitchStatement(GNode n) {
321: countSwitchStmt++;
322:
323: dispatch(n.getNode(1));
324: }
325:
326: /** Visit the specified break statement node. */
327: public void visitBreakStatement(GNode n) {
328: countBreakStmt++;
329: }
330:
331: /** Visit the specified continue statement node. */
332: public void visitContinueStatement(GNode n) {
333: countContinueStmt++;
334: }
335:
336: /** Visit the specified return statement node. */
337: public void visitReturnStatement(GNode n) {
338: countReturnStmt++;
339: }
340:
341: /** Visit the specified goto statement node. */
342: public void visitGotoStatement(GNode n) {
343: countGotoStmt++;
344: }
345:
346: /** Visit the specified expression statement node. */
347: public void visitExpressionStatement(GNode n) {
348: countExpressionStmt++;
349: }
350:
351: /** Visit the specified assembly statement node. */
352: public void visitAssemblyStatement(GNode n) {
353: countAssemblyStmt++;
354: }
355:
356: /** Visit the specified empty statement node. */
357: public void visitEmptyStatement(GNode n) {
358: countEmptyStmt++;
359: }
360:
361: /** Visit the specified comma expression node. */
362: public void visitCommaExpression(GNode n) {
363: /* Nothing to do, yet. */
364: }
365:
366: /** Visit the specified assignment expression node. */
367: public void visitAssignmentExpression(GNode n) {
368: /* Nothing to do, yet. */
369: }
370:
371: /** Visit the specified conditional expression node. */
372: public void visitConditionalExpression(GNode n) {
373: /* Nothing to do, yet. */
374: }
375:
376: /** Visit the specified logical or expression node. */
377: public void visitLogicalOrExpression(GNode n) {
378: /* Nothing to do, yet. */
379: }
380:
381: /** Visit the specified logical and expression node. */
382: public void visitLogicalAndExpression(GNode n) {
383: /* Nothing to do, yet. */
384: }
385:
386: /** Visit the specified bitwise or expression node. */
387: public void visitBitwiseOrExpression(GNode n) {
388: /* Nothing to do, yet. */
389: }
390:
391: /** Visit the specified bitwise xor expression node. */
392: public void visitBitwiseXorExpression(GNode n) {
393: /* Nothing to do, yet. */
394: }
395:
396: /** Visit the specified bitwise and expression node. */
397: public void visitBitwiseAndExpression(GNode n) {
398: /* Nothing to do, yet. */
399: }
400:
401: /** Visit the specified equality expression node. */
402: public void visitEqualityExpression(GNode n) {
403: /* Nothing to do, yet. */
404: }
405:
406: /** Visit the specified relational expression node. */
407: public void visitRelationalExpression(GNode n) {
408: /* Nothing to do, yet. */
409: }
410:
411: /** Visit the specified shift expression node. */
412: public void visitShiftExpression(GNode n) {
413: /* Nothing to do, yet. */
414: }
415:
416: /** Visit the specified additive expression node. */
417: public void visitAdditiveExpression(GNode n) {
418: /* Nothing to do, yet. */
419: }
420:
421: /** Visit the specified multiplicative expression node. */
422: public void visitMultiplicativeExpression(GNode n) {
423: /* Nothing to do, yet. */
424: }
425:
426: /** Visit the specified cast expression node. */
427: public void visitCastExpression(GNode n) {
428: /* Nothing to do, yet. */
429: }
430:
431: /** Visit the specified sizeof expression node. */
432: public void visitSizeofExpression(GNode n) {
433: /* Nothing to do, yet. */
434: }
435:
436: /** Visit the specified unary minus expression node. */
437: public void visitUnaryMinusExpression(GNode n) {
438: /* Nothing to do, yet. */
439: }
440:
441: /** Visit the specified unary plus expression node. */
442: public void visitUnaryPlusExpression(GNode n) {
443: /* Nothing to do, yet. */
444: }
445:
446: /** Visit the specified logical negation expression node. */
447: public void visitLogicalNegationExpression(GNode n) {
448: /* Nothing to do, yet. */
449: }
450:
451: /** Visit the specified bitwise negation expression node. */
452: public void visitBitwiseNegationExpression(GNode n) {
453: /* Nothing to do, yet. */
454: }
455:
456: /** Visit the specified address expression node. */
457: public void visitAddressExpression(GNode n) {
458: /* Nothing to do, yet. */
459: }
460:
461: /** Visit the specified indirection expression node. */
462: public void visitIndirectionExpression(GNode n) {
463: /* Nothing to do, yet. */
464: }
465:
466: /** Visit the specified preincrement expression node. */
467: public void visitPreincrementExpression(GNode n) {
468: /* Nothing to do, yet. */
469: }
470:
471: /** Visit the specified predecrement expression node. */
472: public void visitPredecrementExpression(GNode n) {
473: /* Nothing to do, yet. */
474: }
475:
476: /** Visit the specified subscript expression node. */
477: public void visitSubscriptExpression(GNode n) {
478: /* Nothing to do, yet. */
479: }
480:
481: /** Visit the specified direct component selection node. */
482: public void visitDirectComponentSelection(GNode n) {
483: /* Nothing to do, yet. */
484: }
485:
486: /** Visit the specified indirect component selection node. */
487: public void visitIndirectComponentSelection(GNode n) {
488: /* Nothing to do, yet. */
489: }
490:
491: /** Visit the specified function call node. */
492: public void visitFunctionCall(GNode n) {
493: /* Nothing to do, yet. */
494: }
495:
496: /** Visit the specified postincrement expression node. */
497: public void visitPostincrementExpression(GNode n) {
498: /* Nothing to do, yet. */
499: }
500:
501: /** Visit the specified postdecrement expression node. */
502: public void visitPostdecrementExpresson(GNode n) {
503: /* Nothing to do, yet. */
504: }
505:
506: /** Visit the specified compound literal node. */
507: public void visitCompoundLiteral(GNode n) {
508: /* Nothing to do, yet. */
509: }
510:
511: /** Visit the specified primary identifier node. */
512: public void visitPrimaryIdentifier(GNode n) {
513: /* Nothing to do, yet. */
514: }
515:
516: /** Visit the specified floating constant node. */
517: public void visitFloatingConstant(GNode n) {
518: /* Nothing to do, yet. */
519: }
520:
521: /** Visit the specified integer constant node. */
522: public void visitIntegerConstant(GNode n) {
523: /* Nothing to do, yet. */
524: }
525:
526: /** Visit the specified character constant node. */
527: public void visitCharacterConstant(GNode n) {
528: /* Nothing to do, yet. */
529: }
530:
531: /** Visit the specified string constant node. */
532: public void visitStringConstant(GNode n) {
533: /* Nothing to do, yet. */
534: }
535:
536: /** Visit the specified line marker. */
537: public void visit(LineMarker mark) {
538: countLineMarker++;
539:
540: dispatch(mark.getNode());
541: }
542:
543: /** Visit the specified pragma. */
544: public void visit(Pragma p) {
545: countPragma++;
546:
547: dispatch(p.getNode());
548: }
549:
550: }
|