mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +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("void foo() "); //$NON-NLS-1$
|
||||||
writer.write("{ "); //$NON-NLS-1$
|
writer.write("{ "); //$NON-NLS-1$
|
||||||
writer.write(" if (0) { } "); //$NON-NLS-1$
|
writer.write(" if (0) { } "); //$NON-NLS-1$
|
||||||
writer.write(" /* 11,000 else if's. */ "); //$NON-NLS-1$
|
writer.write(" /* 5,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(" THOU THOU THOU THOU THOU "); //$NON-NLS-1$
|
||||||
writer.write("} "); //$NON-NLS-1$
|
writer.write("} "); //$NON-NLS-1$
|
||||||
|
|
||||||
parse( writer.toString() );
|
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.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
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.IASTInitializerExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
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) {
|
private void assertSoleLocation(IASTNode n, int offset, int length) {
|
||||||
IASTNodeLocation [] locations = n.getNodeLocations();
|
IASTNodeLocation [] locations = n.getNodeLocations();
|
||||||
assertEquals( locations.length, 1 );
|
assertEquals( 1, locations.length );
|
||||||
IASTNodeLocation nodeLocation = locations[0];
|
IASTNodeLocation nodeLocation = locations[0];
|
||||||
assertEquals( nodeLocation.getNodeOffset(), offset );
|
assertEquals( offset, nodeLocation.getNodeOffset() );
|
||||||
assertEquals( nodeLocation.getNodeLength(), length );
|
assertEquals( length, nodeLocation.getNodeLength() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBug83664() throws Exception {
|
public void testBug83664() throws Exception {
|
||||||
|
@ -233,8 +234,29 @@ public class DOMLocationTests extends AST2BaseTest {
|
||||||
IASTConditionalExpression conditional = (IASTConditionalExpression) unaryExpression.getOperand();
|
IASTConditionalExpression conditional = (IASTConditionalExpression) unaryExpression.getOperand();
|
||||||
assertSoleLocation( conditional,code.indexOf( "1?0:1"), "1?0:1".length() ); //$NON-NLS-1$ //$NON-NLS-2$
|
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
|
* This is the single entry point for setting parsePassed to false
|
||||||
* making note what token offset we failed upon.
|
|
||||||
*
|
|
||||||
* @throws EndOfFileException
|
|
||||||
*/
|
*/
|
||||||
protected void failParse() {
|
protected void failParse() {
|
||||||
parsePassed = false;
|
parsePassed = false;
|
||||||
|
@ -1730,6 +1727,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
*/
|
*/
|
||||||
protected IASTStatement parseIfStatement() throws EndOfFileException,
|
protected IASTStatement parseIfStatement() throws EndOfFileException,
|
||||||
BacktrackException {
|
BacktrackException {
|
||||||
|
IASTIfStatement result = null;
|
||||||
IASTIfStatement if_statement = null;
|
IASTIfStatement if_statement = null;
|
||||||
int start = LA(1).getOffset();
|
int start = LA(1).getOffset();
|
||||||
if_loop: while (true) {
|
if_loop: while (true) {
|
||||||
|
@ -1767,6 +1765,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
new_if_statement.setThenClause(thenClause);
|
new_if_statement.setThenClause(thenClause);
|
||||||
thenClause.setParent(new_if_statement);
|
thenClause.setParent(new_if_statement);
|
||||||
thenClause.setPropertyInParent(IASTIfStatement.THEN);
|
thenClause.setPropertyInParent(IASTIfStatement.THEN);
|
||||||
|
((ASTNode)new_if_statement).setLength( calculateEndOffset( thenClause ) - ((ASTNode)new_if_statement).getOffset() );
|
||||||
}
|
}
|
||||||
if (LT(1) == IToken.t_else) {
|
if (LT(1) == IToken.t_else) {
|
||||||
consume(IToken.t_else);
|
consume(IToken.t_else);
|
||||||
|
@ -1777,7 +1776,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
if_statement.setElseClause(new_if_statement);
|
if_statement.setElseClause(new_if_statement);
|
||||||
new_if_statement.setParent(if_statement);
|
new_if_statement.setParent(if_statement);
|
||||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
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;
|
if_statement = new_if_statement;
|
||||||
continue if_loop;
|
continue if_loop;
|
||||||
}
|
}
|
||||||
|
@ -1789,22 +1794,65 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
if_statement.setElseClause(new_if_statement);
|
if_statement.setElseClause(new_if_statement);
|
||||||
new_if_statement.setParent(if_statement);
|
new_if_statement.setParent(if_statement);
|
||||||
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
new_if_statement.setPropertyInParent(IASTIfStatement.ELSE);
|
||||||
((ASTNode) new_if_statement)
|
((ASTNode)if_statement).setLength( calculateEndOffset( new_if_statement ) - ((ASTNode)if_statement).getOffset() ) ;
|
||||||
.setLength(calculateEndOffset(new_if_statement) - start);
|
|
||||||
} else {
|
} else {
|
||||||
((ASTNode) new_if_statement)
|
if( result == null && if_statement != null )
|
||||||
.setLength(calculateEndOffset(new_if_statement) - start);
|
result = if_statement;
|
||||||
|
if( result == null )
|
||||||
|
result = new_if_statement;
|
||||||
if_statement = new_if_statement;
|
if_statement = new_if_statement;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
((ASTNode) new_if_statement)
|
||||||
|
.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)
|
((ASTNode) new_if_statement)
|
||||||
.setLength(calculateEndOffset(new_if_statement) - start);
|
.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;
|
if_statement = new_if_statement;
|
||||||
}
|
}
|
||||||
break if_loop;
|
break if_loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
return if_statement;
|
reconcileLengths( result );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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,6 +1322,7 @@ public class CVisitor {
|
||||||
} else if( statement instanceof IASTIfStatement ){
|
} else if( statement instanceof IASTIfStatement ){
|
||||||
if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false;
|
if( !visitExpression( ((IASTIfStatement) statement ).getCondition(), action ) ) return false;
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false;
|
if( !visitStatement( ((IASTIfStatement) statement ).getThenClause(), action ) ) return false;
|
||||||
|
if( ((IASTIfStatement) statement ).getElseClause() != null )
|
||||||
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
|
if( !visitStatement( ((IASTIfStatement) statement ).getElseClause(), action ) ) return false;
|
||||||
} else if( statement instanceof IASTLabelStatement ){
|
} else if( statement instanceof IASTLabelStatement ){
|
||||||
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
if( !visitName( ((IASTLabelStatement)statement).getName(), action ) ) return false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue