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:
parent
4feef1ec43
commit
f964f14e19
9 changed files with 225 additions and 95 deletions
|
@ -4770,4 +4770,11 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1031,7 +1031,7 @@ public class AST2Tests extends AST2BaseTest {
|
|||
IASTName name_i = dtor.getName();
|
||||
// i < 5;
|
||||
IASTBinaryExpression exp = (IASTBinaryExpression) for_stmt
|
||||
.getCondition();
|
||||
.getConditionExpression();
|
||||
IASTIdExpression id_i = (IASTIdExpression) exp.getOperand1();
|
||||
IASTName name_i2 = id_i.getName();
|
||||
IASTLiteralExpression lit_5 = (IASTLiteralExpression) exp.getOperand2();
|
||||
|
|
|
@ -64,7 +64,7 @@ public interface IASTForStatement extends IASTStatement {
|
|||
*
|
||||
* @return <code>IASTExpression</code>
|
||||
*/
|
||||
public IASTExpression getCondition();
|
||||
public IASTExpression getConditionExpression();
|
||||
|
||||
/**
|
||||
* Set the condition expression for the loop.
|
||||
|
@ -72,7 +72,7 @@ public interface IASTForStatement extends IASTStatement {
|
|||
* @param condition
|
||||
* <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
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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.IASTExpressionStatement;
|
||||
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.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||
|
@ -1415,12 +1414,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
* @return
|
||||
*/
|
||||
protected abstract IASTBreakStatement createBreakStatement();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
protected abstract IASTForStatement createForStatement();
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
|
@ -1817,81 +1811,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
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
|
||||
* @throws EndOfFileException
|
||||
|
|
|
@ -31,14 +31,14 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST
|
|||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
|
||||
*/
|
||||
public IASTExpression getCondition() {
|
||||
public IASTExpression getConditionExpression() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
|
|
|
@ -2841,5 +2841,79 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -11,34 +11,38 @@
|
|||
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;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent {
|
||||
public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent, ICPPASTForStatement {
|
||||
private IScope scope = null;
|
||||
|
||||
private IASTExpression condition;
|
||||
private IASTExpression iterationExpression;
|
||||
private IASTStatement body, init;
|
||||
|
||||
private IASTDeclaration cond_declaration;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition()
|
||||
*/
|
||||
public IASTExpression getCondition() {
|
||||
public IASTExpression getConditionExpression() {
|
||||
return condition;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @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;
|
||||
}
|
||||
|
||||
|
@ -108,6 +112,13 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
|
|||
other.setParent( child.getParent() );
|
||||
condition = (IASTExpression) other;
|
||||
}
|
||||
if( child == cond_declaration )
|
||||
{
|
||||
other.setPropertyInParent( child.getPropertyInParent() );
|
||||
other.setParent( child.getParent() );
|
||||
cond_declaration = (IASTDeclaration) other;
|
||||
}
|
||||
|
||||
if( child == iterationExpression )
|
||||
{
|
||||
other.setPropertyInParent( child.getPropertyInParent() );
|
||||
|
@ -129,4 +140,12 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
|
|||
public void setInitializerStatement(IASTStatement statement) {
|
||||
init = statement;
|
||||
}
|
||||
|
||||
public void setConditionDeclaration(IASTDeclaration d) {
|
||||
cond_declaration = d;
|
||||
}
|
||||
|
||||
public IASTDeclaration getConditionDeclaration() {
|
||||
return cond_declaration;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.ICPPASTExplicitTemplateInstantiation;
|
||||
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.ICPPASTFunctionTryBlockDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
|
@ -2869,6 +2870,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
switch (LT(1)) {
|
||||
case IToken.tSEMI:
|
||||
if( fromCatchHandler )
|
||||
break;
|
||||
semiOffset = consume(IToken.tSEMI).getEndOffset();
|
||||
consumedSemi = true;
|
||||
break;
|
||||
|
@ -4852,7 +4855,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
/**
|
||||
* @return
|
||||
*/
|
||||
protected IASTForStatement createForStatement() {
|
||||
protected ICPPASTForStatement createForStatement() {
|
||||
return new CPPASTForStatement();
|
||||
}
|
||||
|
||||
|
@ -5081,7 +5084,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
BacktrackException {
|
||||
int startOffset = consume(IToken.t_while).getOffset();
|
||||
consume(IToken.tLPAREN);
|
||||
IASTNode while_condition = cppStyleCondition();
|
||||
IASTNode while_condition = cppStyleCondition(true);
|
||||
consume(IToken.tRPAREN);
|
||||
IASTStatement while_body = statement();
|
||||
|
||||
|
@ -5108,13 +5111,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param expectSemi TODO
|
||||
* @return
|
||||
*/
|
||||
protected IASTNode cppStyleCondition() throws BacktrackException,
|
||||
protected IASTNode cppStyleCondition(boolean expectSemi) throws BacktrackException,
|
||||
EndOfFileException {
|
||||
IToken mark = mark();
|
||||
try {
|
||||
IASTExpression e = expression();
|
||||
if( ! expectSemi )
|
||||
return e;
|
||||
switch (LT(1)) {
|
||||
case IToken.tRPAREN:
|
||||
case IToken.tEOC:
|
||||
|
@ -5169,7 +5175,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
consume(IToken.tLPAREN);
|
||||
IASTNode condition = null;
|
||||
try {
|
||||
condition = cppStyleCondition();
|
||||
condition = cppStyleCondition(true);
|
||||
// condition
|
||||
if (LT(1) == IToken.tEOC) {
|
||||
// Completing in the condition
|
||||
|
@ -5350,7 +5356,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
int startOffset;
|
||||
startOffset = consume(IToken.t_switch).getOffset();
|
||||
consume(IToken.tLPAREN);
|
||||
IASTNode switch_condition = cppStyleCondition();
|
||||
IASTNode switch_condition = cppStyleCondition(true);
|
||||
consume(IToken.tRPAREN);
|
||||
IASTStatement switch_body = statement();
|
||||
|
||||
|
@ -5374,4 +5380,86 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
switch_body.setPropertyInParent(IASTSwitchStatement.BODY);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue