1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-13 12:05:21 +02:00

Cosmetics and refactoring related to commits of bug 84144

Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
Thomas Corbat 2014-07-10 08:53:29 +02:00
parent bf0ac98464
commit 4f239a093a
11 changed files with 121 additions and 186 deletions

View file

@ -10,7 +10,6 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Nathan Ridge * Nathan Ridge
* Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2; package org.eclipse.cdt.core.parser.tests.ast2;
@ -1011,19 +1010,6 @@ public class AST2CPPSpecTest extends AST2SpecTestBase {
parse(getAboveComment(), ParserLanguage.CPP, true, 1); parse(getAboveComment(), ParserLanguage.CPP, true, 1);
} }
// void f()
// {
// // ...
// void* labelPtr;
// labelPtr = &&foo;
// goto *labelPtr;
// foo:
// return;
// }
public void test6_bug84144() throws Exception {
parse(getAboveComment(), ParserLanguage.CPP, true, 0);
}
// int foo(int i) // int foo(int i)
// { // {
// static int s = foo(2*i); // recursive call - undefined // static int s = foo(2*i); // recursive call - undefined

View file

@ -7,7 +7,6 @@
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2; package org.eclipse.cdt.core.parser.tests.ast2;
@ -1728,19 +1727,6 @@ public class AST2CSpecTest extends AST2SpecTestBase {
buffer.append("}\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$
parseCandCPP(buffer.toString(), false, 0); parseCandCPP(buffer.toString(), false, 0);
} }
// void f()
// {
// // ...
// void* labelPtr;
// labelPtr = &&foo;
// goto *labelPtr;
// foo:
// return;
// }
public void test6_bug84144() throws Exception {
parseCandCPP(getAboveComment(), true, 0);
}
/** /**
[--Start Example(C 6.8.6.4-4): [--Start Example(C 6.8.6.4-4):

View file

@ -11,6 +11,7 @@
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Thomas Corbat (IFS) * Thomas Corbat (IFS)
* Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2; package org.eclipse.cdt.core.parser.tests.ast2;
@ -150,9 +151,14 @@ public class AST2Tests extends AST2TestBase {
} }
private void parseAndCheckBindings() throws Exception { private void parseAndCheckBindings() throws Exception {
parseAndCheckBindings(false);
}
private void parseAndCheckBindings(boolean useGnuExtensions) throws Exception {
String code= getAboveComment(); String code= getAboveComment();
parseAndCheckBindings(code, C); parseAndCheckBindings(code, C, useGnuExtensions);
parseAndCheckBindings(code, CPP); parseAndCheckBindings(code, CPP, useGnuExtensions);
} }
protected IASTTranslationUnit parseAndCheckBindings(String code) throws Exception { protected IASTTranslationUnit parseAndCheckBindings(String code) throws Exception {
@ -7548,4 +7554,17 @@ public class AST2Tests extends AST2TestBase {
public void testU8TokenAfterIfdef_429361() throws Exception { public void testU8TokenAfterIfdef_429361() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// void f()
// {
// // ...
// void* labelPtr;
// labelPtr = &&foo;
// goto *labelPtr;
// foo:
// return;
// }
public void testExpressionLabelReference_84144() throws Exception {
parseAndCheckBindings(true);
}
} }

View file

@ -125,8 +125,7 @@ public interface IASTUnaryExpression extends IASTExpression {
public static final int op_noexcept = 17; public static final int op_noexcept = 17;
/** /**
* For GCC parsers, only. {@code op_labelReference} is used for &&label type * For GCC parsers, only. {@code op_labelReference} is used for &&label type expressions.
* expressions.
* @since 5.8 * @since 5.8
*/ */
public static final int op_labelReference = 18; public static final int op_labelReference = 18;

View file

@ -120,11 +120,10 @@ public interface INodeFactory {
public IGCCASTAttributeSpecifier newGCCAttributeSpecifier(); public IGCCASTAttributeSpecifier newGCCAttributeSpecifier();
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement); public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement);
public IASTGotoStatement newGotoStatement(IASTName name); public IASTGotoStatement newGotoStatement(IASTName name);
/** /**
* Note: Adding as separate function to avoid changing API.
* @since 5.8 * @since 5.8
*/ */
public IASTStatement newGotoStatement(IASTExpression expression); public IASTStatement newGotoStatement(IASTExpression expression);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2013 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2014 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -16,9 +16,12 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
@ -124,7 +127,27 @@ public class ASTQueries {
} }
return result; return result;
} }
/**
* Searches for the function enclosing the given node. May return <code>null</code>.
*/
public static IBinding findEnclosingFunction(IASTNode node) {
while (node != null && !(node instanceof IASTFunctionDefinition)) {
node= node.getParent();
}
if (node == null)
return null;
IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator());
if (dtor != null) {
IASTName name= dtor.getName();
if (name != null) {
return name.resolveBinding();
}
}
return null;
}
/** /**
* Extracts the active declarations from an array of declarations. * Extracts the active declarations from an array of declarations.
*/ */
@ -183,4 +206,16 @@ public class ASTQueries {
} while (descendant != null); } while (descendant != null);
return false; return false;
} }
protected static boolean isLabelReference(IASTNode node) {
boolean labelReference = false;
IASTNode parent = node.getParent();
if (parent instanceof IASTUnaryExpression) {
int operator = ((IASTUnaryExpression) parent).getOperator();
labelReference = operator == IASTUnaryExpression.op_labelReference;
}
return labelReference;
}
} }

View file

@ -1990,21 +1990,21 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException { protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
int startOffset = consume().getOffset(); // t_goto int startOffset = consume(IToken.t_goto).getOffset();
IASTStatement goto_statement = null; IASTStatement gotoStatement = null;
if (LT(1) == IToken.tSTAR) if (LT(1) == IToken.tSTAR)
{ {
IASTExpression goto_label_name_expression = expression(); IASTExpression gotoLabelNameExpression = expression();
goto_statement = nodeFactory.newGotoStatement(goto_label_name_expression); gotoStatement = nodeFactory.newGotoStatement(gotoLabelNameExpression);
} else { } else {
IASTName goto_label_name = identifier(); IASTName gotoLabelName = identifier();
goto_statement = nodeFactory.newGotoStatement(goto_label_name); gotoStatement = nodeFactory.newGotoStatement(gotoLabelName);
} }
int lastOffset = consume(IToken.tSEMI).getEndOffset(); int lastOffset = consume(IToken.tSEMI).getEndOffset();
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset); ((ASTNode) gotoStatement).setOffsetAndLength(startOffset, lastOffset - startOffset);
return goto_statement; return gotoStatement;
} }
protected IASTStatement parseBreakStatement() throws EndOfFileException, BacktrackException { protected IASTStatement parseBreakStatement() throws EndOfFileException, BacktrackException {

View file

@ -72,7 +72,6 @@ public class BacktrackException extends Exception {
length = l; length = l;
} }
/** /**
* @return Returns the length. * @return Returns the length.
*/ */
@ -85,15 +84,15 @@ public class BacktrackException extends Exception {
public int getOffset() { public int getOffset() {
return offset; return offset;
} }
@Override @Override
public Throwable fillInStackTrace() { public Throwable fillInStackTrace() {
// Do nothing, performance optimization // Do nothing, performance optimization
return this; return this;
} }
@Override @Override
public StackTraceElement[] getStackTrace() { public StackTraceElement[] getStackTrace() {
return EMPTY_STACK; return EMPTY_STACK;
} }
} }

View file

@ -58,7 +58,6 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -106,7 +105,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLabel;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
@ -466,8 +464,7 @@ public class CVisitor extends ASTQueries {
boolean labelReference = isLabelReference(parent); boolean labelReference = isLabelReference(parent);
if (labelReference) { if (labelReference) {
IASTUnaryExpression expression = (IASTUnaryExpression) parent.getParent(); binding = createLabelReferenceBinding(name);
binding = createLabelReferenceBinding(name, expression);
} else if (parent instanceof CASTIdExpression) { } else if (parent instanceof CASTIdExpression) {
binding = resolveBinding(parent); binding = resolveBinding(parent);
} else if (parent instanceof ICASTTypedefNameSpecifier) { } else if (parent instanceof ICASTTypedefNameSpecifier) {
@ -608,55 +605,33 @@ public class CVisitor extends ASTQueries {
} }
return null; return null;
} }
private static boolean isLabelReference(IASTNode node) { private static IBinding createLabelReferenceBinding(IASTName name) {
boolean labelReference = false;
IASTNode parent = node.getParent();
if (parent instanceof IASTUnaryExpression) {
int operator = ((IASTUnaryExpression) parent).getOperator();
labelReference = operator == IASTUnaryExpression.op_labelReference;
}
return labelReference;
}
private static IBinding createLabelReferenceBinding(IASTName name, IASTUnaryExpression expression) {
IBinding binding = null;
// Find function scope for r-value expression // Find function scope for r-value expression
// void* labelPtr = &&foo; // void* labelPtr = &&foo;
// foo: ^^^ // foo: ^^^
// return // return
IScope scope = getContainingScope(name); IBinding binding = null;
IASTInternalScope s = (IASTInternalScope) scope; IBinding enclosingFunction = findEnclosingFunction(name);
IASTNode node = s.getPhysicalNode(); if (enclosingFunction instanceof IFunction) {
IFunction function = (IFunction) enclosingFunction;
while (node != null && !(node instanceof IASTFunctionDefinition)) { IScope functionScope = function.getFunctionScope();
node = node.getParent(); if (functionScope != null) {
} binding = functionScope.getBinding(name, false);
if (node != null) {
IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
CASTFunctionDeclarator declarator = (CASTFunctionDeclarator) definition.getDeclarator();
scope = declarator.getFunctionScope();
if (scope != null) {
binding = scope.getBinding(name, false);
if (!(binding instanceof ILabel)) { if (!(binding instanceof ILabel)) {
binding = new CPPLabel(name); binding = new CLabel(name);
ASTInternal.addName(scope, name); ASTInternal.addName(functionScope, name);
} }
} }
} }
if (binding == null) { if (binding == null) {
binding = new ProblemBinding(expression, IProblemBinding.SEMANTIC_BAD_SCOPE, IASTNode parentExpression = name.getParent();
expression.getRawSignature().toCharArray()); binding = new ProblemBinding(parentExpression, IProblemBinding.SEMANTIC_BAD_SCOPE,
} parentExpression.getRawSignature().toCharArray());
}
return binding;
return binding;
} }
/** /**
@ -1726,26 +1701,6 @@ public class CVisitor extends ASTQueries {
return true; return true;
} }
/**
* Searches for the function enclosing the given node. May return <code>null</code>.
*/
public static IBinding findEnclosingFunction(IASTNode node) {
while (node != null && !(node instanceof IASTFunctionDefinition)) {
node= node.getParent();
}
if (node == null)
return null;
IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator());
if (dtor != null) {
IASTName name= dtor.getName();
if (name != null) {
return name.resolveBinding();
}
}
return null;
}
/** /**
* Searches for the first function, struct or union enclosing the declaration the provided * Searches for the first function, struct or union enclosing the declaration the provided
* node belongs to and returns the binding for it. Returns <code>null</code>, if the declaration is not * node belongs to and returns the binding for it. Returns <code>null</code>, if the declaration is not

View file

@ -179,7 +179,6 @@ import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
@ -301,17 +300,16 @@ public class CPPVisitor extends ASTQueries {
id.resolveBinding(); id.resolveBinding();
return name.getBinding(); return name.getBinding();
} }
// GNU Goto label reference // GNU Goto label reference
// //
// void* labelPtr = &&foo; <-- label reference // void* labelPtr = &&foo; <-- label reference
// foo: // foo:
// //
boolean labelReference = isLabelReference(parent); boolean labelReference = isLabelReference(parent);
if (labelReference) { if (labelReference) {
IASTUnaryExpression expression = (IASTUnaryExpression) parent.getParent(); return createLabelReferenceBinding(name);
return createLabelReferenceBinding(name, expression);
} else if (parent instanceof IASTIdExpression) { } else if (parent instanceof IASTIdExpression) {
return resolveBinding(parent); return resolveBinding(parent);
} else if (parent instanceof ICPPASTFieldReference) { } else if (parent instanceof ICPPASTFieldReference) {
@ -389,53 +387,32 @@ public class CPPVisitor extends ASTQueries {
return scope == inScope; return scope == inScope;
} }
private static boolean isLabelReference(IASTNode node) { private static IBinding createLabelReferenceBinding(IASTName name) {
boolean labelReference = false;
IASTNode parent = node.getParent();
if (parent instanceof IASTUnaryExpression) {
int operator = ((IASTUnaryExpression) parent).getOperator();
labelReference = operator == IASTUnaryExpression.op_labelReference;
}
return labelReference;
}
private static IBinding createLabelReferenceBinding(IASTName name, IASTUnaryExpression expression) {
IBinding binding = null;
// Find function scope for r-value expression // Find function scope for r-value expression
// void* labelPtr = &&foo; // void* labelPtr = &&foo;
// foo: ^^^ // foo: ^^^
// return // return
IScope scope = getContainingScope(name); IBinding binding = null;
IASTInternalScope s = (IASTInternalScope) scope; IBinding enclosingFunction = findEnclosingFunction(name);
IASTNode node = s.getPhysicalNode(); if (enclosingFunction instanceof IFunction) {
IFunction function = (IFunction) enclosingFunction;
while (node != null && !(node instanceof IASTFunctionDefinition)) { IScope functionScope = function.getFunctionScope();
node = node.getParent(); if (functionScope != null) {
} binding = functionScope.getBinding(name, false);
if (node != null) {
IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
CPPASTFunctionDeclarator declarator = (CPPASTFunctionDeclarator) definition.getDeclarator();
scope = declarator.getFunctionScope();
if (scope != null) {
binding = scope.getBinding(name, false);
if (!(binding instanceof ILabel)) { if (!(binding instanceof ILabel)) {
binding = new CPPLabel(name); binding = new CPPLabel(name);
ASTInternal.addName(scope, name); ASTInternal.addName(functionScope, name);
} }
} }
} }
if (binding == null) { if (binding == null) {
binding = new CPPScope.CPPScopeProblem(expression, IProblemBinding.SEMANTIC_BAD_SCOPE, IASTNode parentExpression = name.getParent();
expression.getRawSignature().toCharArray()); binding = new CPPScope.CPPScopeProblem(parentExpression, IProblemBinding.SEMANTIC_BAD_SCOPE,
} parentExpression.getRawSignature().toCharArray());
}
return binding;
return binding;
} }
private static IBinding createBinding(IASTGotoStatement gotoStatement) { private static IBinding createBinding(IASTGotoStatement gotoStatement) {
@ -2532,26 +2509,6 @@ public class CPPVisitor extends ASTQueries {
return t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference(); return t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference();
} }
/**
* Searches for the function enclosing the given node. May return <code>null</code>.
*/
public static IBinding findEnclosingFunction(IASTNode node) {
while (node != null && !(node instanceof IASTFunctionDefinition)) {
node= node.getParent();
}
if (node == null)
return null;
IASTDeclarator dtor= findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator());
if (dtor != null) {
IASTName name= dtor.getName();
if (name != null) {
return name.resolveBinding();
}
}
return null;
}
/** /**
* Searches for the function or class enclosing the given node. May return <code>null</code>. * Searches for the function or class enclosing the given node. May return <code>null</code>.
*/ */

View file

@ -7,7 +7,6 @@
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action; package org.eclipse.cdt.core.dom.lrparser.action;
@ -45,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@ -598,7 +598,7 @@ public abstract class BuildASTParserAction extends AbstractParserAction {
*/ */
public void consumeStatementGoto() { public void consumeStatementGoto() {
IASTName name = createName(stream.getRuleTokens().get(1)); IASTName name = createName(stream.getRuleTokens().get(1));
IASTStatement gotoStat = nodeFactory.newGotoStatement(name); IASTGotoStatement gotoStat = nodeFactory.newGotoStatement(name);
setOffsetAndLength(gotoStat); setOffsetAndLength(gotoStat);
astStack.push(gotoStat); astStack.push(gotoStat);
} }