1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 02:06:01 +02:00

Fixed Bug 83737 - [Parser2] if else if else if parsed incorrectly

This commit is contained in:
John Camelon 2005-01-28 17:17:46 +00:00
parent 2091bd2767
commit a1776b3151
5 changed files with 2482 additions and 2093 deletions

View file

@ -1890,8 +1890,8 @@ public class CompleteParser2Tests extends TestCase {
writer.write("void foo() "); //$NON-NLS-1$
writer.write("{ "); //$NON-NLS-1$
writer.write(" if (0) { } "); //$NON-NLS-1$
writer.write(" /* 11,000 else if's. */ "); //$NON-NLS-1$
writer.write(" THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU "); //$NON-NLS-1$
writer.write(" /* 5,000 else if's. */ "); //$NON-NLS-1$
writer.write(" THOU THOU THOU THOU THOU "); //$NON-NLS-1$
writer.write("} "); //$NON-NLS-1$
parse( writer.toString() );

View file

@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
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;
@ -151,10 +152,10 @@ public class DOMLocationTests extends AST2BaseTest {
*/
private void assertSoleLocation(IASTNode n, int offset, int length) {
IASTNodeLocation [] locations = n.getNodeLocations();
assertEquals( locations.length, 1 );
assertEquals( 1, locations.length );
IASTNodeLocation nodeLocation = locations[0];
assertEquals( nodeLocation.getNodeOffset(), offset );
assertEquals( nodeLocation.getNodeLength(), length );
assertEquals( offset, nodeLocation.getNodeOffset() );
assertEquals( length, nodeLocation.getNodeLength() );
}
public void testBug83664() throws Exception {
@ -232,9 +233,30 @@ public class DOMLocationTests extends AST2BaseTest {
assertEquals( unaryExpression.getOperator(), IASTUnaryExpression.op_bracketedPrimary );
IASTConditionalExpression conditional = (IASTConditionalExpression) unaryExpression.getOperand();
assertSoleLocation( conditional,code.indexOf( "1?0:1"), "1?0:1".length() ); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void testBug83737() throws Exception {
String code = "void f() { if( a == 0 ) g( a ); else if( a < 0 ) g( a >> 1 ); else if( a > 0 ) g( *(&a + 2) ); }"; //$NON-NLS-1$
for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP
: null) {
IASTTranslationUnit tu = parse(code, p);
IASTFunctionDefinition definition = (IASTFunctionDefinition) tu.getDeclarations()[0];
IASTCompoundStatement statement = (IASTCompoundStatement) definition.getBody();
IASTIfStatement first_if = (IASTIfStatement) statement.getStatements()[0];
IASTIfStatement second_if = (IASTIfStatement) first_if.getElseClause();
IASTIfStatement third_if = (IASTIfStatement) second_if.getElseClause();
assertNull( third_if.getElseClause() );
int first_if_start = code.indexOf( "if( a == 0 )" ); //$NON-NLS-1$
int total_if_length = "if( a == 0 ) g( a ); else if( a < 0 ) g( a >> 1 ); else if( a > 0 ) g( *(&a + 2) );".length(); //$NON-NLS-1$
int total_if_end = first_if_start + total_if_length;
int second_if_start = code.indexOf( "if( a < 0 )"); //$NON-NLS-1$
int third_if_start = code.indexOf( "if( a > 0 )"); //$NON-NLS-1$
assertSoleLocation( first_if, first_if_start, total_if_length );
assertSoleLocation( second_if, second_if_start, total_if_end - second_if_start );
assertSoleLocation( third_if, third_if_start, total_if_end - third_if_start );
}
}
}

View file

@ -243,10 +243,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
/**
* This is the single entry point for setting parsePassed to false, and also
* making note what token offset we failed upon.
*
* @throws EndOfFileException
* This is the single entry point for setting parsePassed to false
*/
protected void failParse() {
parsePassed = false;
@ -1730,6 +1727,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*/
protected IASTStatement parseIfStatement() throws EndOfFileException,
BacktrackException {
IASTIfStatement result = null;
IASTIfStatement if_statement = null;
int start = LA(1).getOffset();
if_loop: while (true) {
@ -1767,6 +1765,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
new_if_statement.setThenClause(thenClause);
thenClause.setParent(new_if_statement);
thenClause.setPropertyInParent(IASTIfStatement.THEN);
((ASTNode)new_if_statement).setLength( calculateEndOffset( thenClause ) - ((ASTNode)new_if_statement).getOffset() );
}
if (LT(1) == IToken.t_else) {
consume(IToken.t_else);
@ -1777,7 +1776,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if_statement.setElseClause(new_if_statement);
new_if_statement.setParent(if_statement);
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
((ASTNode)if_statement).setLength( calculateEndOffset( new_if_statement ) - ((ASTNode)if_statement).getOffset() );
}
if( result == null && if_statement != null )
result = if_statement;
if( result == null )
result = new_if_statement;
if_statement = new_if_statement;
continue if_loop;
}
@ -1789,22 +1794,65 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
if_statement.setElseClause(new_if_statement);
new_if_statement.setParent(if_statement);
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
((ASTNode) new_if_statement)
.setLength(calculateEndOffset(new_if_statement) - start);
((ASTNode)if_statement).setLength( calculateEndOffset( new_if_statement ) - ((ASTNode)if_statement).getOffset() ) ;
} else {
((ASTNode) new_if_statement)
.setLength(calculateEndOffset(new_if_statement) - start);
if( result == null && if_statement != null )
result = if_statement;
if( result == null )
result = new_if_statement;
if_statement = new_if_statement;
}
} else {
((ASTNode) new_if_statement)
.setLength(calculateEndOffset(new_if_statement) - start);
.setLength(calculateEndOffset(thenClause) - start);
if (if_statement != null) {
if_statement.setElseClause(new_if_statement);
new_if_statement.setParent(if_statement);
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
((ASTNode) new_if_statement)
.setLength(calculateEndOffset(new_if_statement) - start);
}
if( result == null && if_statement != null )
result = if_statement;
if( result == null )
result = new_if_statement;
if_statement = new_if_statement;
}
break if_loop;
}
reconcileLengths( result );
return result;
}
return if_statement;
/**
* @param result
*/
protected void reconcileLengths(IASTIfStatement result) {
if( result == null ) return;
IASTIfStatement current = result;
while( current.getElseClause() instanceof IASTIfStatement )
current = (IASTIfStatement) current.getElseClause();
while( current != null )
{
ASTNode r = ((ASTNode)current);
if( current.getElseClause() != null )
{
ASTNode else_clause = ((ASTNode)current.getElseClause() );
r.setLength( else_clause.getOffset() + else_clause.getLength() - r.getOffset() );
}
else
{
ASTNode then_clause = (ASTNode) current.getThenClause();
r.setLength( then_clause.getOffset() + then_clause.getLength() - r.getOffset() );
}
if( current.getParent() != null && current.getParent() instanceof IASTIfStatement )
current = (IASTIfStatement) current.getParent();
else
current = null;
}
}
/**

View file

@ -1322,7 +1322,8 @@ public class CVisitor {
} else if( statement instanceof IASTIfStatement ){
if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false;
if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false;
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
if( ((IASTIfStatement) statement ).getElseClause() != null )
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
} else if( statement instanceof IASTLabelStatement ){
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
} else if( statement instanceof IASTReturnStatement ){