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

Fixed Bug 84478 [C++ Parser] does not support declarations inside while condition

This commit is contained in:
John Camelon 2005-06-22 15:56:14 +00:00
parent 4feef1ec43
commit f964f14e19
9 changed files with 225 additions and 95 deletions

View file

@ -4770,4 +4770,11 @@ public class AST2CPPTests extends AST2BaseTest {
assertNoProblemBindings( col ); assertNoProblemBindings( col );
} }
public void testBug84478_4() throws Exception {
IASTTranslationUnit tu = parse( "void foo() { for( int i = 0; int j = 0; ++i) {} }", ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
assertNoProblemBindings( col );
}
} }

View file

@ -1031,7 +1031,7 @@ public class AST2Tests extends AST2BaseTest {
IASTName name_i = dtor.getName(); IASTName name_i = dtor.getName();
// i < 5; // i < 5;
IASTBinaryExpression exp = (IASTBinaryExpression) for_stmt IASTBinaryExpression exp = (IASTBinaryExpression) for_stmt
.getCondition(); .getConditionExpression();
IASTIdExpression id_i = (IASTIdExpression) exp.getOperand1(); IASTIdExpression id_i = (IASTIdExpression) exp.getOperand1();
IASTName name_i2 = id_i.getName(); IASTName name_i2 = id_i.getName();
IASTLiteralExpression lit_5 = (IASTLiteralExpression) exp.getOperand2(); IASTLiteralExpression lit_5 = (IASTLiteralExpression) exp.getOperand2();

View file

@ -64,7 +64,7 @@ public interface IASTForStatement extends IASTStatement {
* *
* @return <code>IASTExpression</code> * @return <code>IASTExpression</code>
*/ */
public IASTExpression getCondition(); public IASTExpression getConditionExpression();
/** /**
* Set the condition expression for the loop. * Set the condition expression for the loop.
@ -72,7 +72,7 @@ public interface IASTForStatement extends IASTStatement {
* @param condition * @param condition
* <code>IASTExpression</code> * <code>IASTExpression</code>
*/ */
public void setCondition(IASTExpression condition); public void setConditionExpression(IASTExpression condition);
/** /**
* Get the expression that is evaluated after the completion of an iteration * Get the expression that is evaluated after the completion of an iteration

View file

@ -0,0 +1,23 @@
/**********************************************************************
* Copyright (c) 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
public interface ICPPASTForStatement extends IASTForStatement {
public static final ASTNodeProperty CONDITION_DECLARATION = new ASTNodeProperty( "org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement"); //$NON-NLS-1$
public void setConditionDeclaration( IASTDeclaration d );
public IASTDeclaration getConditionDeclaration();
}

View file

@ -30,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; 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.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
@ -1416,11 +1415,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*/ */
protected abstract IASTBreakStatement createBreakStatement(); protected abstract IASTBreakStatement createBreakStatement();
/**
* @return
*/
protected abstract IASTForStatement createForStatement();
/** /**
* @return * @return
*/ */
@ -1817,81 +1811,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return return_statement; return return_statement;
} }
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseForStatement() throws EndOfFileException,
BacktrackException {
int startOffset;
startOffset = consume(IToken.t_for).getOffset();
consume(IToken.tLPAREN);
IASTStatement init = forInitStatement();
IASTExpression for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
break;
default:
for_condition = condition();
}
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTExpression iterationExpression = null;
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
break;
default:
iterationExpression = expression();
}
switch (LT(1)) {
case IToken.tRPAREN:
consume(IToken.tRPAREN);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTForStatement for_statement = createForStatement();
IASTStatement for_body = null;
if (LT(1) != IToken.tEOC) {
for_body = statement();
((ASTNode) for_statement).setOffsetAndLength(startOffset,
calculateEndOffset(for_body) - startOffset);
}
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);
for_condition.setPropertyInParent(IASTForStatement.CONDITION);
}
if (iterationExpression != null) {
for_statement.setIterationExpression(iterationExpression);
iterationExpression.setParent(for_statement);
iterationExpression.setPropertyInParent(IASTForStatement.ITERATION);
}
if (for_body != null) {
for_statement.setBody(for_body);
for_body.setParent(for_statement);
for_body.setPropertyInParent(IASTForStatement.BODY);
}
return for_statement;
}
/** /**
* @return * @return
* @throws EndOfFileException * @throws EndOfFileException

View file

@ -31,14 +31,14 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
*/ */
public IASTExpression getCondition() { public IASTExpression getConditionExpression() {
return condition; return condition;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/ */
public void setCondition(IASTExpression condition) { public void setConditionExpression(IASTExpression condition) {
this.condition = condition; this.condition = condition;
} }

View file

@ -2841,5 +2841,79 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return switch_statement; return switch_statement;
} }
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_for).getOffset();
consume(IToken.tLPAREN);
IASTStatement init = forInitStatement();
IASTExpression for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
break;
default:
for_condition = condition();
}
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTExpression iterationExpression = null;
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
break;
default:
iterationExpression = expression();
}
switch (LT(1)) {
case IToken.tRPAREN:
consume(IToken.tRPAREN);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTForStatement for_statement = createForStatement();
IASTStatement for_body = null;
if (LT(1) != IToken.tEOC) {
for_body = statement();
((ASTNode) for_statement).setOffsetAndLength(startOffset,
calculateEndOffset(for_body) - startOffset);
}
for_statement.setInitializerStatement(init);
init.setParent(for_statement);
init.setPropertyInParent(IASTForStatement.INITIALIZER);
if (for_condition != null) {
for_statement.setConditionExpression(for_condition);
for_condition.setParent(for_statement);
for_condition.setPropertyInParent(IASTForStatement.CONDITION);
}
if (iterationExpression != null) {
for_statement.setIterationExpression(iterationExpression);
iterationExpression.setParent(for_statement);
iterationExpression.setPropertyInParent(IASTForStatement.ITERATION);
}
if (for_body != null) {
for_statement.setBody(for_body);
for_body.setParent(for_statement);
for_body.setPropertyInParent(IASTForStatement.BODY);
}
return for_statement;
}
} }

View file

@ -11,34 +11,38 @@
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;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** /**
* @author jcamelon * @author jcamelon
*/ */
public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent { public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent, ICPPASTForStatement {
private IScope scope = null; private IScope scope = null;
private IASTExpression condition; private IASTExpression condition;
private IASTExpression iterationExpression; private IASTExpression iterationExpression;
private IASTStatement body, init; private IASTStatement body, init;
private IASTDeclaration cond_declaration;
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
*/ */
public IASTExpression getCondition() { public IASTExpression getConditionExpression() {
return condition; return condition;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression)
*/ */
public void setCondition(IASTExpression condition) { public void setConditionExpression(IASTExpression condition) {
this.condition = condition; this.condition = condition;
} }
@ -108,6 +112,13 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
other.setParent( child.getParent() ); other.setParent( child.getParent() );
condition = (IASTExpression) other; condition = (IASTExpression) other;
} }
if( child == cond_declaration )
{
other.setPropertyInParent( child.getPropertyInParent() );
other.setParent( child.getParent() );
cond_declaration = (IASTDeclaration) other;
}
if( child == iterationExpression ) if( child == iterationExpression )
{ {
other.setPropertyInParent( child.getPropertyInParent() ); other.setPropertyInParent( child.getPropertyInParent() );
@ -129,4 +140,12 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
public void setInitializerStatement(IASTStatement statement) { public void setInitializerStatement(IASTStatement statement) {
init = statement; init = statement;
} }
public void setConditionDeclaration(IASTDeclaration d) {
cond_declaration = d;
}
public IASTDeclaration getConditionDeclaration() {
return cond_declaration;
}
} }

View file

@ -92,6 +92,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
@ -2869,6 +2870,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
switch (LT(1)) { switch (LT(1)) {
case IToken.tSEMI: case IToken.tSEMI:
if( fromCatchHandler )
break;
semiOffset = consume(IToken.tSEMI).getEndOffset(); semiOffset = consume(IToken.tSEMI).getEndOffset();
consumedSemi = true; consumedSemi = true;
break; break;
@ -4852,7 +4855,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
/** /**
* @return * @return
*/ */
protected IASTForStatement createForStatement() { protected ICPPASTForStatement createForStatement() {
return new CPPASTForStatement(); return new CPPASTForStatement();
} }
@ -5081,7 +5084,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
BacktrackException { BacktrackException {
int startOffset = consume(IToken.t_while).getOffset(); int startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
IASTNode while_condition = cppStyleCondition(); IASTNode while_condition = cppStyleCondition(true);
consume(IToken.tRPAREN); consume(IToken.tRPAREN);
IASTStatement while_body = statement(); IASTStatement while_body = statement();
@ -5108,13 +5111,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
/** /**
* @param expectSemi TODO
* @return * @return
*/ */
protected IASTNode cppStyleCondition() throws BacktrackException, protected IASTNode cppStyleCondition(boolean expectSemi) throws BacktrackException,
EndOfFileException { EndOfFileException {
IToken mark = mark(); IToken mark = mark();
try { try {
IASTExpression e = expression(); IASTExpression e = expression();
if( ! expectSemi )
return e;
switch (LT(1)) { switch (LT(1)) {
case IToken.tRPAREN: case IToken.tRPAREN:
case IToken.tEOC: case IToken.tEOC:
@ -5169,7 +5175,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
IASTNode condition = null; IASTNode condition = null;
try { try {
condition = cppStyleCondition(); condition = cppStyleCondition(true);
// condition // condition
if (LT(1) == IToken.tEOC) { if (LT(1) == IToken.tEOC) {
// Completing in the condition // Completing in the condition
@ -5350,7 +5356,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startOffset; int startOffset;
startOffset = consume(IToken.t_switch).getOffset(); startOffset = consume(IToken.t_switch).getOffset();
consume(IToken.tLPAREN); consume(IToken.tLPAREN);
IASTNode switch_condition = cppStyleCondition(); IASTNode switch_condition = cppStyleCondition(true);
consume(IToken.tRPAREN); consume(IToken.tRPAREN);
IASTStatement switch_body = statement(); IASTStatement switch_body = statement();
@ -5374,4 +5380,86 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
switch_body.setPropertyInParent(IASTSwitchStatement.BODY); switch_body.setPropertyInParent(IASTSwitchStatement.BODY);
return switch_statement; return switch_statement;
} }
/**
* @return
* @throws EndOfFileException
* @throws BacktrackException
*/
protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException {
int startOffset;
startOffset = consume(IToken.t_for).getOffset();
consume(IToken.tLPAREN);
IASTStatement init = forInitStatement();
IASTNode for_condition = null;
switch (LT(1)) {
case IToken.tSEMI:
case IToken.tEOC:
break;
default:
for_condition = cppStyleCondition(false);
}
switch (LT(1)) {
case IToken.tSEMI:
consume(IToken.tSEMI);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
IASTExpression iterationExpression = null;
switch (LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
break;
default:
iterationExpression = expression();
}
switch (LT(1)) {
case IToken.tRPAREN:
consume(IToken.tRPAREN);
break;
case IToken.tEOC:
break;
default:
throw backtrack;
}
ICPPASTForStatement for_statement = createForStatement();
IASTStatement for_body = null;
if (LT(1) != IToken.tEOC) {
for_body = statement();
((ASTNode) for_statement).setOffsetAndLength(startOffset,
calculateEndOffset(for_body) - startOffset);
}
for_statement.setInitializerStatement(init);
init.setParent(for_statement);
init.setPropertyInParent(IASTForStatement.INITIALIZER);
if (for_condition != null) {
for_condition.setParent(for_statement);
if( for_condition instanceof IASTExpression )
{
for_statement.setConditionExpression((IASTExpression) for_condition);
for_condition.setPropertyInParent(IASTForStatement.CONDITION);
}
else if( for_condition instanceof IASTDeclaration )
{
for_statement.setConditionDeclaration((IASTDeclaration) for_condition);
for_condition.setPropertyInParent(ICPPASTForStatement.CONDITION_DECLARATION);
}
}
if (iterationExpression != null) {
for_statement.setIterationExpression(iterationExpression);
iterationExpression.setParent(for_statement);
iterationExpression.setPropertyInParent(IASTForStatement.ITERATION);
}
if (for_body != null) {
for_statement.setBody(for_body);
for_body.setParent(for_statement);
for_body.setPropertyInParent(IASTForStatement.BODY);
}
return for_statement;
}
} }