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:
parent
2091bd2767
commit
a1776b3151
5 changed files with 2482 additions and 2093 deletions
File diff suppressed because it is too large
Load diff
|
@ -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() );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 ){
|
||||
|
|
Loading…
Add table
Reference in a new issue