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); 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 { public void testClassForwardDecl() throws Exception {
StringBuffer buffer = new StringBuffer("class A; class A {};"); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("class A; class A {};"); //$NON-NLS-1$

View file

@ -1024,9 +1024,9 @@ public class AST2Tests extends AST2BaseTest {
// for( // for(
IASTForStatement for_stmt = (IASTForStatement) compound.getStatements()[0]; IASTForStatement for_stmt = (IASTForStatement) compound.getStatements()[0];
// int i = 0; // int i = 0;
assertNull(for_stmt.getInitExpression());
IASTSimpleDeclaration initDecl = (IASTSimpleDeclaration) for_stmt IASTSimpleDeclaration initDecl = (IASTSimpleDeclaration) ((IASTDeclarationStatement) for_stmt
.getInitDeclaration(); .getInitializerStatement()).getDeclaration();
IASTDeclarator dtor = initDecl.getDeclarators()[0]; IASTDeclarator dtor = initDecl.getDeclarators()[0];
IASTName name_i = dtor.getName(); IASTName name_i = dtor.getName();
// i < 5; // 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.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; 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.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement;
@ -457,7 +458,7 @@ public class DOMLocationTests extends AST2BaseTest {
: null) { : null) {
IASTTranslationUnit tu = parse(code, p); IASTTranslationUnit tu = parse(code, p);
IASTForStatement for_stmt = (IASTForStatement) ((IASTCompoundStatement)((IASTFunctionDefinition)tu.getDeclarations()[0]).getBody()).getStatements()[1]; IASTForStatement for_stmt = (IASTForStatement) ((IASTCompoundStatement)((IASTFunctionDefinition)tu.getDeclarations()[0]).getBody()).getStatements()[1];
assertNull( for_stmt.getInitDeclaration() ); assertTrue( for_stmt.getInitializerStatement() instanceof IASTNullStatement );
} }
} }

View file

@ -18,22 +18,6 @@ package org.eclipse.cdt.core.dom.ast;
*/ */
public interface IASTForStatement extends IASTStatement { 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>CONDITION</code> represents the relationship between a
* <code>IASTForStatement</code> and its <code>IASTExpression</code> * <code>IASTForStatement</code> and its <code>IASTExpression</code>
@ -58,36 +42,22 @@ public interface IASTForStatement extends IASTStatement {
public static final ASTNodeProperty BODY = new ASTNodeProperty("IASTForStatement.BODY - IASTStatement body of IASTForStatement"); //$NON-NLS-1$ 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. * <code>INITDECLARATION</code> represents the relationship between a
* You can not have both an initial expression and an initial declaration. * <code>IASTForStatement</code> and its <code>IASTDeclaration</code>
* * initializer.
* @return <code>IASTExpression</code>
*/ */
public IASTExpression getInitExpression(); public static final ASTNodeProperty INITIALIZER = new ASTNodeProperty(
"IASTForStatement.INITIALIZER - initializer for IASTForStatement"); //$NON-NLS-1$
/** /**
* Set the initial expression for the loop. * @return
*
* @param expression
* <code>IASTExpression</code>
*/ */
public void setInit(IASTExpression expression); public IASTStatement getInitializerStatement();
/** /**
* Get the initial declaration for the loop. Returns null if there is none. * @param statement
* You can not have both an initial declaration and an initial declaration.
*
* @return <code>IASTDeclaration</code>
*/ */
public IASTDeclaration getInitDeclaration(); public void setInitializerStatement( IASTStatement statement );
/**
* Set the intiial declaration for the loop.
*
* @param declaration
* <code>IASTDeclaration</code>
*/
public void setInit(IASTDeclaration declaration);
/** /**
* Get the condition expression for the loop. * 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, protected abstract IASTDeclaration declaration() throws BacktrackException,
EndOfFileException; EndOfFileException;
protected abstract IASTNode forInitStatement() throws BacktrackException,
EndOfFileException;
/** /**
* @return * @return
@ -1826,7 +1825,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
int startOffset; int startOffset;
startOffset = consume(IToken.t_for).getOffset(); startOffset = consume(IToken.t_for).getOffset();
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
IASTNode init = forInitStatement(); IASTStatement init = forInitStatement();
IASTExpression for_condition = null; IASTExpression for_condition = null;
switch (LT(1)) { switch (LT(1)) {
case IToken.tSEMI: case IToken.tSEMI:
@ -1869,17 +1868,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
calculateEndOffset(for_body) - startOffset); calculateEndOffset(for_body) - startOffset);
} }
if (init instanceof IASTDeclaration) { for_statement.setInitializerStatement(init);
for_statement.setInit((IASTDeclaration) init); init.setParent(for_statement);
((IASTDeclaration) init).setParent(for_statement); init.setPropertyInParent(IASTForStatement.INITIALIZER);
((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);
}
if (for_condition != null) { if (for_condition != null) {
for_statement.setCondition(for_condition); for_statement.setCondition(for_condition);
for_condition.setParent(for_statement); for_condition.setParent(for_statement);
@ -2187,4 +2179,16 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return null; 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; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; 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.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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 { public class CASTForStatement extends CASTNode implements IASTForStatement, IASTAmbiguityParent {
private IScope scope = null; private IScope scope = null;
private IASTExpression initialExpression;
private IASTDeclaration initDeclaration;
private IASTExpression condition; private IASTExpression condition;
private IASTExpression iterationExpression; 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
@ -118,8 +88,7 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
default : break; default : break;
} }
} }
if( initDeclaration != null ) if( !initDeclaration.accept( action ) ) return false; if( init != null ) if( !init.accept( action ) ) return false;
if( initialExpression != null ) if( !initialExpression.accept( action ) ) return false;
if( condition != null ) if( !condition.accept( action ) ) return false; if( condition != null ) if( !condition.accept( action ) ) return false;
if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false; if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false;
if( body != null ) if( !body.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() ); other.setParent( child.getParent() );
body = (IASTStatement) other; body = (IASTStatement) other;
} }
if( child == initialExpression ) if( child == init )
{ {
other.setPropertyInParent( child.getPropertyInParent() ); other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() ); other.setParent( child.getParent() );
initialExpression = (IASTExpression) other; init = (IASTStatement) other;
} }
if( child == iterationExpression) 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 ); return checkForBinding( scope, ((IASTDeclarationStatement)node).getDeclaration(), name, typesOnly, prefixMap );
} else if( node instanceof IASTForStatement ){ } else if( node instanceof IASTForStatement ){
IASTForStatement forStatement = (IASTForStatement) node; IASTForStatement forStatement = (IASTForStatement) node;
if( forStatement.getInitDeclaration() != null ){ if( forStatement.getInitializerStatement() instanceof IASTDeclarationStatement ){
return checkForBinding( scope, forStatement.getInitDeclaration(), name, typesOnly, prefixMap ); return checkForBinding( scope, ((IASTDeclarationStatement)forStatement.getInitializerStatement()).getDeclaration(), name, typesOnly, prefixMap );
} }
} }
return null; 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.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; 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.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@ -2266,44 +2265,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTParameterDeclaration(); 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) * (non-Javadoc)
* *

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; 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.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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 { public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent {
private IScope scope = null; private IScope scope = null;
private IASTExpression initialExpression;
private IASTDeclaration initDeclaration;
private IASTExpression condition; private IASTExpression condition;
private IASTExpression iterationExpression; 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) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
@ -119,8 +88,7 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
default : break; default : break;
} }
} }
if( initDeclaration != null ) if( !initDeclaration.accept( action ) ) return false; if( init != null ) if( !init.accept( action ) ) return false;
if( initialExpression != null ) if( !initialExpression.accept( action ) ) return false;
if( condition != null ) if( !condition.accept( action ) ) return false; if( condition != null ) if( !condition.accept( action ) ) return false;
if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false; if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false;
if( body != null ) if( !body.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() ); other.setParent( child.getParent() );
iterationExpression = (IASTExpression) other; iterationExpression = (IASTExpression) other;
} }
if( child == initialExpression ) if( child == init )
{ {
other.setPropertyInParent( child.getPropertyInParent() ); other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() ); other.setParent( child.getParent() );
initialExpression = (IASTExpression) other; init = (IASTStatement) other;
} }
if( initDeclaration == child )
{
other.setParent( child.getParent() );
other.setPropertyInParent( child.getPropertyInParent() );
initDeclaration = (IASTDeclaration) 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 ) else if( node instanceof IASTDeclarationStatement )
declaration = ((IASTDeclarationStatement)node).getDeclaration(); declaration = ((IASTDeclarationStatement)node).getDeclaration();
else if( node instanceof IASTForStatement && checkAux ) 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 ){ else if( node instanceof IASTParameterDeclaration ){
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node; IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
IASTDeclarator dtor = parameterDeclaration.getDeclarator(); IASTDeclarator dtor = parameterDeclaration.getDeclarator();

View file

@ -4537,38 +4537,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return compoundStatement(); 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. * This is the top-level entry point into the ANSI C++ grammar.
* translationUnit : (declaration)* * translationUnit : (declaration)*
@ -5335,4 +5303,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
--functionBodyCount; --functionBodyCount;
return s; return s;
} }
protected IASTDeclaration simpleDeclaration() throws BacktrackException, EndOfFileException {
return simpleDeclarationStrategyUnion();
}
} }