1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fixed Bug 95411 incorrect parse of for statement

This commit is contained in:
John Camelon 2005-05-27 19:09:16 +00:00
parent b453ede83c
commit 6597aae483
11 changed files with 98 additions and 218 deletions

View file

@ -132,6 +132,27 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame(A, A_2);
}
public void testBug95411() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "class A {\n" );
buffer.append( " public:" );
buffer.append( "int x;" );
buffer.append( "A * next;" );
buffer.append( "};" );
buffer.append( "A * start;" );
buffer.append( "void test() {" );
buffer.append( "for(A *y = start; y->x != 0; y = y->next) {" );
buffer.append( "42;" );
buffer.append( "}" );
buffer.append( "for(int x = 0 ; x < 10; x++ ) {" );
buffer.append( "}" );
buffer.append( "}" );
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector nameCol = new CPPNameCollector();
tu.accept( nameCol );
assertNoProblemBindings( nameCol );
}
public void testClassForwardDecl() throws Exception {
StringBuffer buffer = new StringBuffer("class A; class A {};"); //$NON-NLS-1$

View file

@ -1024,9 +1024,9 @@ public class AST2Tests extends AST2BaseTest {
// for(
IASTForStatement for_stmt = (IASTForStatement) compound.getStatements()[0];
// int i = 0;
assertNull(for_stmt.getInitExpression());
IASTSimpleDeclaration initDecl = (IASTSimpleDeclaration) for_stmt
.getInitDeclaration();
IASTSimpleDeclaration initDecl = (IASTSimpleDeclaration) ((IASTDeclarationStatement) for_stmt
.getInitializerStatement()).getDeclaration();
IASTDeclarator dtor = initDecl.getDeclarators()[0];
IASTName name_i = dtor.getName();
// i < 5;

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement;
@ -457,7 +458,7 @@ public class DOMLocationTests extends AST2BaseTest {
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTForStatement for_stmt = (IASTForStatement) ((IASTCompoundStatement)((IASTFunctionDefinition)tu.getDeclarations()[0]).getBody()).getStatements()[1];
assertNull( for_stmt.getInitDeclaration() );
assertTrue( for_stmt.getInitializerStatement() instanceof IASTNullStatement );
}
}

View file

@ -17,23 +17,7 @@ package org.eclipse.cdt.core.dom.ast;
* @author Doug Schaefer
*/
public interface IASTForStatement extends IASTStatement {
/**
* <code>INITEXPRESSION</code> represents the relationship between a
* <code>IASTForStatement</code> and its <code>IASTExpression</code>
* initializer.
*/
public static final ASTNodeProperty INITEXPRESSION = new ASTNodeProperty(
"IASTForStatement.INITEXPRESSION - IASTExpression initializer for IASTForStatement"); //$NON-NLS-1$
/**
* <code>INITDECLARATION</code> represents the relationship between a
* <code>IASTForStatement</code> and its <code>IASTDeclaration</code>
* initializer.
*/
public static final ASTNodeProperty INITDECLARATION = new ASTNodeProperty(
"IASTForStatement.INITDECLARATION - IASTDeclaration initializer for IASTForStatement"); //$NON-NLS-1$
/**
* <code>CONDITION</code> represents the relationship between a
* <code>IASTForStatement</code> and its <code>IASTExpression</code>
@ -57,38 +41,24 @@ public interface IASTForStatement extends IASTStatement {
*/
public static final ASTNodeProperty BODY = new ASTNodeProperty("IASTForStatement.BODY - IASTStatement body of IASTForStatement"); //$NON-NLS-1$
/**
* Get the initial expression for the loop. Returns null if there is none.
* You can not have both an initial expression and an initial declaration.
*
* @return <code>IASTExpression</code>
*/
public IASTExpression getInitExpression();
/**
* Set the initial expression for the loop.
*
* @param expression
* <code>IASTExpression</code>
*/
public void setInit(IASTExpression expression);
/**
* Get the initial declaration for the loop. Returns null if there is none.
* You can not have both an initial declaration and an initial declaration.
*
* @return <code>IASTDeclaration</code>
*/
public IASTDeclaration getInitDeclaration();
/**
* Set the intiial declaration for the loop.
*
* @param declaration
* <code>IASTDeclaration</code>
*/
public void setInit(IASTDeclaration declaration);
/**
* <code>INITDECLARATION</code> represents the relationship between a
* <code>IASTForStatement</code> and its <code>IASTDeclaration</code>
* initializer.
*/
public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(
"IASTForStatement.INITIALIZER - initializer for IASTForStatement"); //$NON-NLS-1$
/**
* @return
*/
public IASTStatement getInitializerStatement();
/**
* @param statement
*/
public void setInitializerStatement( IASTStatement statement );
/**
* Get the condition expression for the loop.
*

View file

@ -1450,8 +1450,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract IASTDeclaration declaration() throws BacktrackException,
EndOfFileException;
protected abstract IASTNode forInitStatement() throws BacktrackException,
EndOfFileException;
/**
* @return
@ -1826,7 +1825,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
int startOffset;
startOffset = consume(IToken.t_for).getOffset();
consume(IToken.tLPAREN);
IASTNode init = forInitStatement();
IASTStatement init = forInitStatement();
IASTExpression for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
@ -1869,17 +1868,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
calculateEndOffset(for_body) - startOffset);
}
if (init instanceof IASTDeclaration) {
for_statement.setInit((IASTDeclaration) init);
((IASTDeclaration) init).setParent(for_statement);
((IASTDeclaration) init)
.setPropertyInParent(IASTForStatement.INITDECLARATION);
} else if (init instanceof IASTExpression) {
for_statement.setInit((IASTExpression) init);
((IASTExpression) init).setParent(for_statement);
((IASTExpression) init)
.setPropertyInParent(IASTForStatement.INITEXPRESSION);
}
for_statement.setInitializerStatement(init);
init.setParent(for_statement);
init.setPropertyInParent(IASTForStatement.INITIALIZER);
if (for_condition != null) {
for_statement.setCondition(for_condition);
for_condition.setParent(for_statement);
@ -2186,5 +2178,17 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throwBacktrack(LA(1));
return null;
}
protected abstract IASTDeclaration simpleDeclaration() throws BacktrackException,
EndOfFileException;
/**
* @throws BacktrackException
*/
protected IASTStatement forInitStatement() throws BacktrackException, EndOfFileException {
if( LT(1) == IToken.tSEMI )
return parseNullStatement();
return parseDeclarationOrExpressionStatement();
}
}

View file

@ -10,7 +10,6 @@
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -24,39 +23,10 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
public class CASTForStatement extends CASTNode implements IASTForStatement, IASTAmbiguityParent {
private IScope scope = null;
private IASTExpression initialExpression;
private IASTDeclaration initDeclaration;
private IASTExpression condition;
private IASTExpression iterationExpression;
private IASTStatement body;
private IASTStatement body, init;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getInitExpression()
*/
public IASTExpression getInitExpression() {
return initialExpression;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setInit(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/
public void setInit(IASTExpression expression) {
this.initialExpression = expression;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getInitDeclaration()
*/
public IASTDeclaration getInitDeclaration() {
return initDeclaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setInit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public void setInit(IASTDeclaration declaration) {
this.initDeclaration = declaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
@ -118,8 +88,7 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
default : break;
}
}
if( initDeclaration != null ) if( !initDeclaration.accept( action ) ) return false;
if( initialExpression != null ) if( !initialExpression.accept( action ) ) return false;
if( init != null ) if( !init.accept( action ) ) return false;
if( condition != null ) if( !condition.accept( action ) ) return false;
if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false;
if( body != null ) if( !body.accept( action ) ) return false;
@ -133,11 +102,11 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
other.setParent( child.getParent() );
body = (IASTStatement) other;
}
if( child == initialExpression )
if( child == init )
{
other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() );
initialExpression = (IASTExpression) other;
init = (IASTStatement) other;
}
if( child == iterationExpression)
{
@ -154,4 +123,13 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
}
public IASTStatement getInitializerStatement() {
return init;
}
public void setInitializerStatement(IASTStatement statement) {
init = statement;
}
}

View file

@ -1398,8 +1398,8 @@ public class CVisitor {
return checkForBinding( scope, ((IASTDeclarationStatement)node).getDeclaration(), name, typesOnly, prefixMap );
} else if( node instanceof IASTForStatement ){
IASTForStatement forStatement = (IASTForStatement) node;
if( forStatement.getInitDeclaration() != null ){
return checkForBinding( scope, forStatement.getInitDeclaration(), name, typesOnly, prefixMap );
if( forStatement.getInitializerStatement() instanceof IASTDeclarationStatement ){
return checkForBinding( scope, ((IASTDeclarationStatement)forStatement.getInitializerStatement()).getDeclaration(), name, typesOnly, prefixMap );
}
}
return null;

View file

@ -53,7 +53,6 @@ import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -2266,44 +2265,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTParameterDeclaration();
}
/**
* @throws BacktrackException
*/
protected IASTNode forInitStatement() throws BacktrackException,
EndOfFileException {
IToken mark = mark();
try {
IASTExpression e = null;
if( LT(1) != IToken.tSEMI )
e = expression();
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
// TODO is this a problem? Should we wrap this in an expression
// statement?
return e;
} catch (BacktrackException bt) {
backup(mark);
try {
return simpleDeclaration();
} catch (BacktrackException b) {
IASTProblem p = failParse(b);
IASTProblemExpression pe = createProblemExpression();
((CASTNode) pe).setOffsetAndLength(((CASTNode) p));
pe.setProblem(p);
p.setParent(pe);
p.setPropertyInParent(IASTProblemHolder.PROBLEM);
return pe;
}
}
}
/*
* (non-Javadoc)
*

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -25,39 +24,9 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent {
private IScope scope = null;
private IASTExpression initialExpression;
private IASTDeclaration initDeclaration;
private IASTExpression condition;
private IASTExpression iterationExpression;
private IASTStatement body;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getInitExpression()
*/
public IASTExpression getInitExpression() {
return initialExpression;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setInit(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/
public void setInit(IASTExpression expression) {
this.initialExpression = expression;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getInitDeclaration()
*/
public IASTDeclaration getInitDeclaration() {
return initDeclaration;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setInit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public void setInit(IASTDeclaration declaration) {
this.initDeclaration = declaration;
}
private IASTStatement body, init;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
@ -119,8 +88,7 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
default : break;
}
}
if( initDeclaration != null ) if( !initDeclaration.accept( action ) ) return false;
if( initialExpression != null ) if( !initialExpression.accept( action ) ) return false;
if( init != null ) if( !init.accept( action ) ) return false;
if( condition != null ) if( !condition.accept( action ) ) return false;
if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false;
if( body != null ) if( !body.accept( action ) ) return false;
@ -146,18 +114,19 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
other.setParent( child.getParent() );
iterationExpression = (IASTExpression) other;
}
if( child == initialExpression )
if( child == init )
{
other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() );
initialExpression = (IASTExpression) other;
}
if( initDeclaration == child )
{
other.setParent( child.getParent() );
other.setPropertyInParent( child.getPropertyInParent() );
initDeclaration = (IASTDeclaration) other;
init = (IASTStatement) other;
}
}
public IASTStatement getInitializerStatement() {
return init;
}
public void setInitializerStatement(IASTStatement statement) {
init = statement;
}
}

View file

@ -1373,7 +1373,11 @@ public class CPPSemantics {
else if( node instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)node).getDeclaration();
else if( node instanceof IASTForStatement && checkAux )
declaration = ((IASTForStatement)node).getInitDeclaration();
{
if( ((IASTForStatement)node).getInitializerStatement() instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)((IASTForStatement)node).getInitializerStatement()).getDeclaration();
}
else if( node instanceof IASTParameterDeclaration ){
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
IASTDeclarator dtor = parameterDeclaration.getDeclarator();

View file

@ -2447,7 +2447,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return simpleDeclarationStrategyUnion();
}
}
protected IASTDeclaration simpleDeclarationStrategyUnion()
throws EndOfFileException, BacktrackException {
IToken simpleDeclarationMark = mark();
@ -4537,38 +4537,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return compoundStatement();
}
/**
* @throws BacktrackException
*/
protected IASTNode forInitStatement() throws BacktrackException,
EndOfFileException {
IToken mark = mark();
try {
IASTExpression e = null;
if (LT(1) != IToken.tSEMI)
e = expression();
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
return e;
} catch (BacktrackException bt) {
backup(mark);
try {
return simpleDeclarationStrategyUnion();
} catch (BacktrackException b) {
failParse();
throwBacktrack(b);
return null;
}
}
}
/**
* This is the top-level entry point into the ANSI C++ grammar.
* translationUnit : (declaration)*
@ -5335,4 +5303,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
--functionBodyCount;
return s;
}
protected IASTDeclaration simpleDeclaration() throws BacktrackException, EndOfFileException {
return simpleDeclarationStrategyUnion();
}
}