From eb89746de5cb133ea553ff35c6e17d92e3181cb4 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Fri, 20 May 2005 12:10:35 +0000 Subject: [PATCH] Fixed broken JUnits. --- .../parser/tests/ast2/AST2CPPSpecTest.java | 2 + .../tests/ast2/CompleteParser2Tests.java | 15 +- .../cdt/core/dom/ast/ASTSignatureUtil.java | 24 +- .../parser/AbstractGNUSourceCodeParser.java | 32 ++- .../core/dom/parser/c/GNUCSourceParser.java | 8 - .../core/dom/parser/cpp/CPPASTAmbiguity.java | 15 +- .../dom/parser/cpp/GNUCPPSourceParser.java | 223 +++++++++++++----- 7 files changed, 239 insertions(+), 80 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 3c937c4eb2f..6008dbfe1fc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -12524,10 +12524,12 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { */ public void test8_5s2() throws ParserException { // 90641 StringBuffer buffer = new StringBuffer(); + buffer.append( "int z() { "); buffer.append("int f(int);\n"); //$NON-NLS-1$ buffer.append("int a = 2;\n"); //$NON-NLS-1$ buffer.append("int b = f(a);\n"); //$NON-NLS-1$ buffer.append("int c(b);\n"); //$NON-NLS-1$ + buffer.append( "}"); parse(buffer.toString(), ParserLanguage.CPP, true, 0); } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java index 6dc26ac684b..df2897a4e34 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java @@ -19,6 +19,7 @@ import junit.framework.TestCase; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; +import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; @@ -834,9 +835,11 @@ public class CompleteParser2Tests extends TestCase { public void testBug41520() throws Exception { - IASTTranslationUnit tu = parse( "const int x = 666; const int y( x );"); //$NON-NLS-1$ - - IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[1]; + IASTTranslationUnit tu = parse( "int f() { const int x = 666; const int y( x ); }"); //$NON-NLS-1$ + IASTCompoundStatement s = (IASTCompoundStatement) ((IASTFunctionDefinition)tu.getDeclarations()[0]).getBody(); + IASTDeclarationStatement ds = (IASTDeclarationStatement) s.getStatements()[1]; + + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) ds.getDeclaration(); IASTDeclarator dtor = decl.getDeclarators()[0]; assertFalse( dtor instanceof IASTFunctionDeclarator ); assertNotNull( dtor.getInitializer() ); @@ -844,9 +847,9 @@ public class CompleteParser2Tests extends TestCase { CPPNameCollector col = new CPPNameCollector(); tu.accept( col ); - assertEquals( col.size(), 3 ); - IVariable x = (IVariable) col.getName(0).resolveBinding(); - IVariable y = (IVariable) col.getName(1).resolveBinding(); + assertEquals( col.size(), 4 ); + IVariable x = (IVariable) col.getName(1).resolveBinding(); + IVariable y = (IVariable) col.getName(2).resolveBinding(); assertNotNull(y); assertInstances( col, x, 2 ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java index 7aa143fe3cc..f5e150c783e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java @@ -77,6 +77,26 @@ public class ASTSignatureUtil { return getSignature((IASTDeclSpecifier)node); if (node instanceof IASTTypeId) return getSignature((IASTTypeId)node); + if( node instanceof IASTSimpleDeclaration ) + { + IASTSimpleDeclaration decl = (IASTSimpleDeclaration) node; + StringBuffer buffer = new StringBuffer( getSignature( decl.getDeclSpecifier())); + + IASTDeclarator [] declarators = decl.getDeclarators(); + for( int i = 0; i < declarators.length; ++i ) + { + buffer.append( SPACE ); + buffer.append( getSignature( declarators[i] )); + if( declarators[i].getInitializer() != null && declarators[i].getInitializer() instanceof ICPPASTConstructorInitializer ) + buffer.append( getInitializerString( declarators[i].getInitializer() )); + } + buffer.append( ";"); //$NON-NLS-1$ + return buffer.toString(); + } + if( node instanceof IASTExpression ) + { + return getExpressionString( (IASTExpression) node ); + } return EMPTY_STRING; } @@ -256,7 +276,9 @@ public class ASTSignatureUtil { result.append(Keywords.cpASSIGN); result.append(getInitializerString(((ICASTDesignatedInitializer)init).getOperandInitializer())); } else if (init instanceof ICPPASTConstructorInitializer) { - + result.append( "("); //$NON-NLS-1$ + result.append( getExpressionString( ((ICPPASTConstructorInitializer)init).getExpression() )); + result.append( ")"); //$NON-NLS-1$ } return result.toString(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index bdd18f77271..19847fb3245 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -398,7 +398,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { throw backtrack; } - protected IToken simpleDeclarationMark; private static final IASTNode[] EMPTY_NODE_ARRAY = new IASTNode[0]; @@ -494,11 +493,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { errorHandling(); } - /** - */ - protected void throwAwayMarksForInitializerClause() { - simpleDeclarationMark = null; - } /** * @return TODO @@ -1590,6 +1584,32 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return expressionStatement; } + if (ds.getDeclaration() instanceof IASTAmbiguousDeclaration ) + { + IASTAmbiguousDeclaration amb = (IASTAmbiguousDeclaration) ds.getDeclaration(); + IASTDeclaration [] ambDs = amb.getDeclarations(); + int ambCount = 0; + for( int i = 0; i < ambDs.length; ++i ) + { + if (ambDs[i] instanceof IASTSimpleDeclaration + && ((IASTSimpleDeclaration) ambDs[i]) + .getDeclSpecifier() instanceof IASTSimpleDeclSpecifier + && ((IASTSimpleDeclSpecifier) ((IASTSimpleDeclaration) ambDs[i]).getDeclSpecifier()).getType() == IASTSimpleDeclSpecifier.t_unspecified) { + ++ambCount; + } + } + if ( ambCount == ambDs.length ) + { + backup(mark); + while (true) { + if (consume() == lastTokenOfExpression) + break; + } + + return expressionStatement; + } + } + if (ds.getDeclaration() instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) ds.getDeclaration()) .getDeclSpecifier() instanceof IASTNamedTypeSpecifier) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 4c75e3cd0dd..d9a387655cc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -139,18 +139,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { supportGCCStyleDesignators = config.supportGCCStyleDesignators(); } - /** - * @param d - */ - protected void throwAwayMarksForInitializerClause() { - simpleDeclarationMark = null; - } - protected IASTInitializer optionalCInitializer() throws EndOfFileException, BacktrackException { if (LT(1) == IToken.tASSIGN) { consume(IToken.tASSIGN); - throwAwayMarksForInitializerClause(); return cInitializerClause(Collections.EMPTY_LIST); } return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguity.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguity.java index 9926acccfa4..a4cdd532bc4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguity.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguity.java @@ -25,9 +25,10 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; public abstract class CPPASTAmbiguity extends CPPASTNode { +// private static final boolean debugging = false; + protected static class CPPASTNameCollector extends CPPASTVisitor { private IASTName[] names = new IASTName[2]; - { shouldVisitNames = true; } @@ -46,6 +47,8 @@ public abstract class CPPASTAmbiguity extends CPPASTNode { public boolean accept(ASTVisitor visitor) { IASTNode[] nodez = getNodes(); +// if( debugging ) +// printNode(); int[] issues = new int[nodez.length]; Arrays.fill(issues, 0); for (int i = 0; i < nodez.length; ++i) { @@ -84,4 +87,14 @@ public abstract class CPPASTAmbiguity extends CPPASTNode { return true; } +// protected void printNode() { +// System.out.println( "Ambiguity " + getClass().getName() + ": "); +// IASTNode [] nodes = getNodes(); +// for( int i = 0; i < nodes.length; ++i ) +// { +// System.out.print( "\t" + i + " : " ); +// System.out.println( ASTSignatureUtil.getNodeSignature(nodes[i]) ); +// } +// } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 8eff6cc302c..eb0dafa7c36 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -143,6 +143,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.parser.SimpleDeclarationStrategy; @@ -171,6 +172,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private ScopeStack templateIdScopes = new ScopeStack(); + private int templateCount = 0; + protected CPPASTTranslationUnit translationUnit; private static class ScopeStack { @@ -943,8 +946,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { declSpecifier = declSpecifierSeq(true, true); if (LT(1) != IToken.tEOC) - declarator = declarator( - SimpleDeclarationStrategy.TRY_FUNCTION, + declarator = declarator(SimpleDeclarationStrategy.TRY_FUNCTION, forNewExpression); } catch (BacktrackException bt) { backup(mark); @@ -2123,6 +2125,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IToken firstToken = null; boolean exported = false; boolean encounteredExtraMod = false; + ++templateCount; if (LT(1) == IToken.t_export) { exported = true; firstToken = consume(IToken.t_export); @@ -2166,14 +2169,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { templateInstantiation = temp; } else templateInstantiation = createTemplateInstantiation(); - IASTDeclaration d = declaration(); - ((ASTNode) templateInstantiation).setOffsetAndLength(firstToken - .getOffset(), calculateEndOffset(d) - - firstToken.getOffset()); - templateInstantiation.setDeclaration(d); - d.setParent(templateInstantiation); - d - .setPropertyInParent(ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION); + try { + IASTDeclaration d = declaration(); + ((ASTNode) templateInstantiation).setOffsetAndLength(firstToken + .getOffset(), calculateEndOffset(d) + - firstToken.getOffset()); + templateInstantiation.setDeclaration(d); + d.setParent(templateInstantiation); + d + .setPropertyInParent(ICPPASTExplicitTemplateInstantiation.OWNED_DECLARATION); + } finally { + --templateCount; + } return templateInstantiation; } consume(IToken.tLT); @@ -2182,34 +2189,46 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consume(IToken.tGT); ICPPASTTemplateSpecialization templateSpecialization = createTemplateSpecialization(); - IASTDeclaration d = declaration(); - ((ASTNode) templateSpecialization).setOffsetAndLength(firstToken - .getOffset(), calculateEndOffset(d) - - firstToken.getOffset()); - templateSpecialization.setDeclaration(d); - d.setParent(templateSpecialization); - d - .setPropertyInParent(ICPPASTTemplateSpecialization.OWNED_DECLARATION); + try { + IASTDeclaration d = declaration(); + ((ASTNode) templateSpecialization).setOffsetAndLength( + firstToken.getOffset(), calculateEndOffset(d) + - firstToken.getOffset()); + templateSpecialization.setDeclaration(d); + d.setParent(templateSpecialization); + d + .setPropertyInParent(ICPPASTTemplateSpecialization.OWNED_DECLARATION); + } finally { + --templateCount; + } + return templateSpecialization; } try { List parms = templateParameterList(); consume(IToken.tGT); - IASTDeclaration d = declaration(); ICPPASTTemplateDeclaration templateDecl = createTemplateDeclaration(); - ((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(), - calculateEndOffset(d) - firstToken.getOffset()); - templateDecl.setExported(exported); - templateDecl.setDeclaration(d); - d.setParent(templateDecl); - d.setPropertyInParent(ICPPASTTemplateDeclaration.OWNED_DECLARATION); - for (int i = 0; i < parms.size(); ++i) { - ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms - .get(i); - templateDecl.addTemplateParamter(parm); - parm.setParent(templateDecl); - parm.setPropertyInParent(ICPPASTTemplateDeclaration.PARAMETER); + try + { + IASTDeclaration d = declaration(); + ((ASTNode) templateDecl).setOffsetAndLength(firstToken.getOffset(), + calculateEndOffset(d) - firstToken.getOffset()); + templateDecl.setExported(exported); + templateDecl.setDeclaration(d); + d.setParent(templateDecl); + d.setPropertyInParent(ICPPASTTemplateDeclaration.OWNED_DECLARATION); + for (int i = 0; i < parms.size(); ++i) { + ICPPASTTemplateParameter parm = (ICPPASTTemplateParameter) parms + .get(i); + templateDecl.addTemplateParamter(parm); + parm.setParent(templateDecl); + parm.setPropertyInParent(ICPPASTTemplateDeclaration.PARAMETER); + } + } + finally + { + --templateCount; } return templateDecl; @@ -2426,24 +2445,101 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { protected IASTDeclaration simpleDeclarationStrategyUnion() throws EndOfFileException, BacktrackException { - simpleDeclarationMark = mark(); + IToken simpleDeclarationMark = mark(); + IASTDeclaration d1 = null, d2 = null; + IToken after = null; try { - IASTDeclaration d = simpleDeclaration( - SimpleDeclarationStrategy.TRY_FUNCTION, false); - throwAwayMarksForInitializerClause(); - return d; + d1 = simpleDeclaration(SimpleDeclarationStrategy.TRY_FUNCTION, + false); + try { + after = LA(1); + } catch (EndOfFileException eof) { + after = null; + } } catch (BacktrackException bt) { - if (simpleDeclarationMark == null) - throwBacktrack(bt); - // did not work - backup(simpleDeclarationMark); - - IASTDeclaration d = simpleDeclaration( - SimpleDeclarationStrategy.TRY_VARIABLE, false); - throwAwayMarksForInitializerClause(); - return d; - + d1 = null; } + if (d1 != null) { + if( templateCount != 0 ) + return d1; + if( functionBodyCount == 0 ) + return d1; + if (d1 instanceof IASTFunctionDefinition) + return d1; + if (d1 instanceof IASTSimpleDeclaration) { + IASTSimpleDeclaration sd = (IASTSimpleDeclaration) d1; + if( sd.getDeclSpecifier() instanceof ICPPASTDeclSpecifier && + ((ICPPASTDeclSpecifier)sd.getDeclSpecifier()).isFriend() ) + return d1; + if (sd.getDeclarators().length != 1) + return d1; + if (sd.getDeclSpecifier() instanceof IASTSimpleDeclSpecifier) { + IASTSimpleDeclSpecifier simpleSpec = (IASTSimpleDeclSpecifier) sd.getDeclSpecifier(); + if( simpleSpec.getType() == IASTSimpleDeclSpecifier.t_void && sd.getDeclarators()[0].getPointerOperators().length == 0 ) + return d1; + } + + if (sd.getDeclarators()[0] instanceof IASTStandardFunctionDeclarator) { + IASTStandardFunctionDeclarator fd = (IASTStandardFunctionDeclarator) sd + .getDeclarators()[0]; + if (sd.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) + return d1; + IASTParameterDeclaration[] parms = fd.getParameters(); + for (int i = 0; i < parms.length; ++i) { + if (!(parms[i].getDeclSpecifier() instanceof IASTNamedTypeSpecifier)) + return d1; + if (((ASTNode) parms[i].getDeclarator().getName()) + .getLength() > 0) + return d1; + IASTDeclarator d = parms[i].getDeclarator(); + while (d.getNestedDeclarator() != null) + d = d.getNestedDeclarator(); + if (((ASTNode) d.getName()).getLength() > 0) + return d1; + } + } else + return d1; + } + } + + // did not work + backup(simpleDeclarationMark); + + try { + d2 = simpleDeclaration(SimpleDeclarationStrategy.TRY_VARIABLE, + false); + if (after != null && after != LA(1)) { + backup(after); + return d1; + } + } catch (BacktrackException be) { + d2 = null; + if (d1 == null) + throwBacktrack(be); + } + + if (d2 == null && d1 != null) { + backup(after); + return d1; + } + + if (d1 == null && d2 != null) + return d2; + + IASTAmbiguousDeclaration result = createAmbiguousDeclaration(); + ((CPPASTNode) result).setOffsetAndLength((ASTNode) d1); + result.addDeclaration(d1); + d1.setParent(result); + d1.setPropertyInParent(IASTAmbiguousDeclaration.SUBDECLARATION); + result.addDeclaration(d2); + d2.setParent(result); + d2.setPropertyInParent(IASTAmbiguousDeclaration.SUBDECLARATION); + return result; + + } + + protected IASTAmbiguousDeclaration createAmbiguousDeclaration() { + return new CPPASTAmbiguousDeclaration(); } /** @@ -3475,7 +3571,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (LT(1) == IToken.tASSIGN) { consume(IToken.tASSIGN); - throwAwayMarksForInitializerClause(); try { return initializerClause(); } catch (EndOfFileException eof) { @@ -3492,8 +3587,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return null; } // initializer in constructor - int o = consume(IToken.tLPAREN).getOffset(); // EAT IT! + IToken t = consume(IToken.tLPAREN); // EAT IT! + int o = t.getOffset(); IASTExpression astExpression = expression(); + if( astExpression == null ) + throwBacktrack( t ); int l = consume(IToken.tRPAREN).getEndOffset(); ICPPASTConstructorInitializer result = createConstructorInitializer(); ((ASTNode) result).setOffsetAndLength(o, l - o); @@ -4972,6 +5070,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private static final EmptyVisitor EMPTY_VISITOR = new EmptyVisitor(); + private int functionBodyCount; + protected ASTVisitor createVisitor() { return EMPTY_VISITOR; } @@ -4996,7 +5096,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTNode condition = null; try { condition = cppStyleCondition(); // TODO should be while - // condition + // condition if (LT(1) == IToken.tEOC) { // Completing in the condition ICPPASTIfStatement new_if = createIfStatement(); @@ -5040,15 +5140,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { ICPPASTIfStatement new_if_statement = createIfStatement(); ((ASTNode) new_if_statement).setOffset(so); if (condition != null && condition instanceof IASTExpression) // shouldn't - // be - // possible - // but - // failure - // in - // condition() - // makes - // it - // so + // be + // possible + // but + // failure + // in + // condition() + // makes + // it + // so { new_if_statement .setConditionExpression((IASTExpression) condition); @@ -5138,4 +5238,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return super.checkTokenVsDeclarator(la, d); } } + + protected IASTStatement functionBody() throws EndOfFileException, BacktrackException { + ++functionBodyCount; + IASTStatement s = super.functionBody(); + --functionBodyCount; + return s; + } }