1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

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

This commit is contained in:
John Camelon 2005-02-24 02:05:51 +00:00
parent c0d9fbb554
commit 14feb82cc2
8 changed files with 135 additions and 15 deletions

View file

@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
@ -2190,5 +2191,25 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstances( col, j, 3 );
assertInstances( col, x, 5 );
}
public void testBug84478() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "void foo() {\n" ); //$NON-NLS-1$
buffer.append( " struct A {\n" ); //$NON-NLS-1$
buffer.append( " int val;\n" ); //$NON-NLS-1$
buffer.append( " A(int i) : val(i) { }\n" ); //$NON-NLS-1$
buffer.append( " ~A() { }\n" ); //$NON-NLS-1$
buffer.append( " operator bool() { return val != 0; }\n" ); //$NON-NLS-1$
buffer.append( " };\n" ); //$NON-NLS-1$
buffer.append( " int i = 1;\n" ); //$NON-NLS-1$
buffer.append( " while (A a = i) {\n" ); //$NON-NLS-1$
buffer.append( " i = 0;\n" ); //$NON-NLS-1$
buffer.append( " }\n" ); //$NON-NLS-1$
buffer.append( "}\n" ); //$NON-NLS-1$
IASTFunctionDefinition foo = (IASTFunctionDefinition) parse( buffer.toString(), ParserLanguage.CPP ).getDeclarations()[0];
ICPPASTWhileStatement whileStatement = (ICPPASTWhileStatement) ((IASTCompoundStatement)foo.getBody()).getStatements()[2];
assertNull( whileStatement.getCondition() );
assertNotNull( whileStatement.getConditionDeclaration() );
}
}

View file

@ -43,7 +43,6 @@ public interface IASTForStatement extends IASTStatement {
* @return
*/
public IASTDeclaration getInitDeclaration();
public void setInit(IASTDeclaration declaration);
/**

View file

@ -17,7 +17,7 @@ package org.eclipse.cdt.core.dom.ast;
*/
public interface IASTWhileStatement extends IASTStatement {
public static final ASTNodeProperty CONDITION = new ASTNodeProperty("condition"); //$NON-NLS-1$
public static final ASTNodeProperty CONDITIONEXPRESSION = new ASTNodeProperty("condition"); //$NON-NLS-1$
public static final ASTNodeProperty BODY = new ASTNodeProperty("body"); //$NON-NLS-1$
/**
@ -26,7 +26,6 @@ public interface IASTWhileStatement extends IASTStatement {
* @return expression for the condition
*/
public IASTExpression getCondition();
public void setCondition(IASTExpression condition);
/**

View file

@ -0,0 +1,27 @@
/**********************************************************************
* 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.IASTWhileStatement;
/**
* @author jcamelon
*
*/
public interface ICPPASTWhileStatement extends IASTWhileStatement {
public static final ASTNodeProperty CONDITIONDECLARATION = new ASTNodeProperty("initDeclaration"); //$NON-NLS-1$
public IASTDeclaration getConditionDeclaration();
public void setConditionDeclaration(IASTDeclaration declaration);
}

View file

@ -1276,7 +1276,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTExpression condition() throws BacktrackException,
EndOfFileException {
IASTExpression cond = expression();
return cond;
}
@ -1776,8 +1775,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*/
protected IASTStatement parseWhileStatement() throws EndOfFileException,
BacktrackException {
int startOffset;
startOffset = consume(IToken.t_while).getOffset();
int startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN);
IASTExpression while_condition = condition();
consume(IToken.tRPAREN);
@ -1788,7 +1786,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
calculateEndOffset(while_body) - startOffset);
while_statement.setCondition(while_condition);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.CONDITION);
while_condition.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
while_statement.setBody(while_body);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.BODY);

View file

@ -10,17 +10,19 @@
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
/**
* @author jcamelon
*/
public class CPPASTWhileStatement extends CPPASTNode implements
IASTWhileStatement {
ICPPASTWhileStatement {
private IASTExpression condition;
private IASTStatement body;
private IASTDeclaration condition2;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IASTWhileStatement#getCondition()
@ -50,4 +52,18 @@ public class CPPASTWhileStatement extends CPPASTNode implements
this.body = body;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement#getInitDeclaration()
*/
public IASTDeclaration getConditionDeclaration() {
return condition2;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement#setInit(org.eclipse.cdt.core.dom.ast.IASTDeclaration)
*/
public void setConditionDeclaration(IASTDeclaration declaration) {
condition2 = declaration;
}
}

View file

@ -116,6 +116,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -1275,8 +1276,14 @@ public class CPPVisitor implements ICPPASTVisitor {
if( !visitExpression( ((IASTSwitchStatement) statement ).getController(), action ) ) return false;
if( !visitStatement( ((IASTSwitchStatement) statement ).getBody(), action ) ) return false;
} else if( statement instanceof IASTWhileStatement ){
if( !visitExpression( ((IASTWhileStatement) statement ).getCondition(), action ) ) return false;
if( !visitStatement( ((IASTWhileStatement) statement ).getBody(), action ) ) return false;
IASTWhileStatement whileStatement = (IASTWhileStatement) statement;
if( whileStatement.getCondition() != null && !visitExpression( (whileStatement ).getCondition(), action ) ) return false;
if( !visitStatement( (whileStatement ).getBody(), action ) ) return false;
if( whileStatement instanceof ICPPASTWhileStatement )
{
ICPPASTWhileStatement cppWhile = ((ICPPASTWhileStatement)whileStatement);
if ( cppWhile.getConditionDeclaration() != null && !visitDeclaration( cppWhile.getConditionDeclaration(), action ) ) return false;
}
} else if( statement instanceof IASTForStatement ){
IASTForStatement s = (IASTForStatement) statement;
if( s.getInitDeclaration() != null )

View file

@ -114,6 +114,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTBinaryExpression;
@ -4310,8 +4311,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if( LT(1) != IToken.tSEMI )
e = expression();
consume(IToken.tSEMI);
// TODO is this a problem? Should we wrap this in an expression
// statement?
return e;
} catch (BacktrackException bt) {
backup(mark);
@ -4323,7 +4322,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return null;
}
}
}
/**
@ -4848,4 +4846,59 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
.resolveOtherAmbiguitiesAsDeclaration(ds, expressionStatement);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#parseWhileStatement()
*/
protected IASTStatement parseWhileStatement() throws EndOfFileException,
BacktrackException {
int startOffset = consume(IToken.t_while).getOffset();
consume(IToken.tLPAREN);
IASTNode while_condition = whileCondition();
consume(IToken.tRPAREN);
IASTStatement while_body = statement();
ICPPASTWhileStatement while_statement = (ICPPASTWhileStatement) createWhileStatement();
((ASTNode) while_statement).setOffsetAndLength(startOffset,
calculateEndOffset(while_body) - startOffset);
if( while_condition instanceof IASTExpression )
{
while_statement.setCondition((IASTExpression)while_condition);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(IASTWhileStatement.CONDITIONEXPRESSION);
}
else if ( while_condition instanceof IASTDeclaration )
{
while_statement.setConditionDeclaration((IASTDeclaration) while_condition);
while_condition.setParent(while_statement);
while_condition.setPropertyInParent(ICPPASTWhileStatement.CONDITIONDECLARATION);
}
while_statement.setBody(while_body);
while_body.setParent(while_statement);
while_body.setPropertyInParent(IASTWhileStatement.BODY);
return while_statement;
}
/**
* @return
*/
protected IASTNode whileCondition() throws BacktrackException, EndOfFileException {
IToken mark = mark();
try {
IASTExpression e = expression();
if( LT(1) != IToken.tRPAREN )
throwBacktrack(LA(1));
return e;
} catch (BacktrackException bt) {
backup(mark);
try {
return simpleDeclaration( SimpleDeclarationStrategy.TRY_VARIABLE, true );
} catch (BacktrackException b) {
failParse();
throwBacktrack(b);
return null;
}
}
}
}