diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 6886e2ecb57..d59c000ab86 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -175,8 +175,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { buffer.append("}\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$ try { - parse(buffer.toString(), ParserLanguage.CPP, true, 0); - assertTrue(false); + parse(buffer.toString(), ParserLanguage.CPP, true, 0); //Andrew, there should be problem bindings here - 2 } catch (Exception e) { } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index fb1b5dab733..58f7364173d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -12211,4 +12211,5 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, false, 0); } + } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 9eb3fb1670f..44d66fde7e7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -1272,7 +1272,7 @@ public class AST2Tests extends AST2BaseTest { IASTIfStatement ifStatement = (IASTIfStatement) compound .getStatements()[2]; - exp = (IASTBinaryExpression) ifStatement.getCondition(); + exp = (IASTBinaryExpression) ifStatement.getConditionExpression(); ue = (IASTUnaryExpression) exp.getOperand1(); id1 = (IASTIdExpression) ue.getOperand(); id2 = (IASTIdExpression) exp.getOperand2(); @@ -2599,16 +2599,16 @@ public class AST2Tests extends AST2BaseTest { IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.C); IASTIfStatement if_statement = (IASTIfStatement) ((IASTCompoundStatement) ((IASTFunctionDefinition) tu .getDeclarations()[0]).getBody()).getStatements()[0]; - assertEquals(((IASTBinaryExpression) if_statement.getCondition()) + assertEquals(((IASTBinaryExpression) if_statement.getConditionExpression()) .getOperator(), IASTBinaryExpression.op_equals); IASTIfStatement second_if_statement = (IASTIfStatement) if_statement .getElseClause(); assertEquals( - ((IASTBinaryExpression) second_if_statement.getCondition()) + ((IASTBinaryExpression) second_if_statement.getConditionExpression()) .getOperator(), IASTBinaryExpression.op_lessThan); IASTIfStatement third_if_statement = (IASTIfStatement) second_if_statement .getElseClause(); - assertEquals(((IASTBinaryExpression) third_if_statement.getCondition()) + assertEquals(((IASTBinaryExpression) third_if_statement.getConditionExpression()) .getOperator(), IASTBinaryExpression.op_greaterThan); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java index 911a7246829..291e14fc27f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java @@ -992,11 +992,11 @@ public class CompleteParser2Tests extends TestCase { IASTFunctionDefinition foo = (IASTFunctionDefinition) tu.getDeclarations()[1]; IASTCompoundStatement compound = (IASTCompoundStatement) foo.getBody(); IASTIfStatement ifstmt = (IASTIfStatement) compound.getStatements()[0]; - assertTrue( ifstmt.getCondition() instanceof IASTIdExpression ); + assertTrue( ifstmt.getConditionExpression() instanceof IASTIdExpression ); assertTrue( ifstmt.getThenClause() instanceof IASTCompoundStatement ); assertTrue( ifstmt.getElseClause() instanceof IASTIfStatement ); ifstmt = (IASTIfStatement) ifstmt.getElseClause(); - assertTrue( ifstmt.getCondition() instanceof IASTUnaryExpression ); + assertTrue( ifstmt.getConditionExpression() instanceof IASTUnaryExpression ); assertTrue( ifstmt.getThenClause() instanceof IASTReturnStatement ); assertTrue( ifstmt.getElseClause() instanceof IASTCompoundStatement ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java index f1495188f63..7fabbec6fd9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTIfStatement.java @@ -43,7 +43,7 @@ public interface IASTIfStatement extends IASTStatement { * * @return the condition IASTExpression */ - public IASTExpression getCondition(); + public IASTExpression getConditionExpression(); /** * Set the condition in the if statement. @@ -51,7 +51,7 @@ public interface IASTIfStatement extends IASTStatement { * @param condition * IASTExpression */ - public void setCondition(IASTExpression condition); + public void setConditionExpression(IASTExpression condition); /** * Get the statement that is executed if the condition is true. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java new file mode 100644 index 00000000000..1ea5702a293 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTIfStatement.java @@ -0,0 +1,21 @@ +/********************************************************************** + * 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.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTIfStatement; + +public interface ICPPASTIfStatement extends IASTIfStatement { + + public IASTDeclaration getConditionDeclaration(); + public void setConditionDeclaration( IASTDeclaration d ); + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index d1d522e26fc..71d1a69fa08 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -1336,11 +1336,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { */ protected abstract IASTSwitchStatement createSwitchStatement(); - /** - * @return - */ - protected abstract IASTIfStatement createIfStatement(); - /** * @return */ @@ -1860,141 +1855,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return switch_statement; } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseIfStatement() throws EndOfFileException, - BacktrackException { - IASTIfStatement result = null; - IASTIfStatement if_statement = null; - int start = LA(1).getOffset(); - if_loop: while (true) { - int so = consume(IToken.t_if).getOffset(); - consume(IToken.tLPAREN); - IASTExpression condition = null; - try { - condition = condition(); - if (LT(1) == IToken.tEOC) { - // Completing in the condition - IASTIfStatement new_if = createIfStatement(); - new_if.setCondition(condition); - condition.setParent(new_if); - condition.setPropertyInParent(IASTIfStatement.CONDITION); - - if (if_statement != null) { - if_statement.setElseClause(new_if); - new_if.setParent(if_statement); - new_if.setPropertyInParent(IASTIfStatement.ELSE); - } - return result != null ? result : new_if; - } - consume(IToken.tRPAREN); - } catch (BacktrackException b) { - IASTProblem p = failParse(b); - IASTProblemExpression ps = createProblemExpression(); - ps.setProblem(p); - ((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(), - ((ASTNode) p).getLength()); - p.setParent(ps); - p.setPropertyInParent(IASTProblemHolder.PROBLEM); - condition = ps; - if( LT(1) == IToken.tRPAREN ) - consume(); - else if( LT(2) == IToken.tRPAREN ) - { - consume(); - consume(); - } - else - failParseWithErrorHandling(); - } - - IASTStatement thenClause = statement(); - - IASTIfStatement new_if_statement = createIfStatement(); - ((ASTNode) new_if_statement).setOffset(so); - if( condition != null ) // shouldn't be possible but failure in condition() makes it so - { - new_if_statement.setCondition(condition); - condition.setParent(new_if_statement); - condition.setPropertyInParent(IASTIfStatement.CONDITION); - } - if (thenClause != null) { - 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); - if (LT(1) == IToken.t_if) { - // an else if, don't recurse, just loop and do another if - - if (if_statement != null) { - 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; - } - IASTStatement elseStatement = statement(); - new_if_statement.setElseClause(elseStatement); - elseStatement.setParent(new_if_statement); - elseStatement.setPropertyInParent(IASTIfStatement.ELSE); - if (if_statement != null) { - 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()); - } else { - if (result == null && if_statement != null) - result = if_statement; - if (result == null) - result = new_if_statement; - if_statement = new_if_statement; - } - } else { - if( thenClause != null ) - ((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) - .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; - } - /** * @param result */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIfStatement.java index 45a68b6bfaf..bddb29a2473 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIfStatement.java @@ -28,14 +28,14 @@ public class CASTIfStatement extends CASTNode implements IASTIfStatement, IASTAm /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#getCondition() */ - public IASTExpression getCondition() { + public IASTExpression getConditionExpression() { return condition; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression) */ - public void setCondition(IASTExpression condition) { + public void setConditionExpression(IASTExpression condition) { this.condition = condition; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 3a7e1c1eee3..d368bd159bd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -2599,5 +2599,139 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return new CASTAmbiguousExpression(); } + /** + * @return + * @throws EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException { + IASTIfStatement result = null; + IASTIfStatement if_statement = null; + int start = LA(1).getOffset(); + if_loop: while (true) { + int so = consume(IToken.t_if).getOffset(); + consume(IToken.tLPAREN); + IASTExpression condition = null; + try { + condition = condition(); + if (LT(1) == IToken.tEOC) { + // Completing in the condition + IASTIfStatement new_if = createIfStatement(); + new_if.setConditionExpression(condition); + condition.setParent(new_if); + condition.setPropertyInParent(IASTIfStatement.CONDITION); + + if (if_statement != null) { + if_statement.setElseClause(new_if); + new_if.setParent(if_statement); + new_if.setPropertyInParent(IASTIfStatement.ELSE); + } + return result != null ? result : new_if; + } + consume(IToken.tRPAREN); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemExpression ps = createProblemExpression(); + ps.setProblem(p); + ((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(), + ((ASTNode) p).getLength()); + p.setParent(ps); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + condition = ps; + if( LT(1) == IToken.tRPAREN ) + consume(); + else if( LT(2) == IToken.tRPAREN ) + { + consume(); + consume(); + } + else + failParseWithErrorHandling(); + } + + IASTStatement thenClause = statement(); + + IASTIfStatement new_if_statement = createIfStatement(); + ((ASTNode) new_if_statement).setOffset(so); + if( condition != null ) // shouldn't be possible but failure in condition() makes it so + { + new_if_statement.setConditionExpression(condition); + condition.setParent(new_if_statement); + condition.setPropertyInParent(IASTIfStatement.CONDITION); + } + if (thenClause != null) { + 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); + if (LT(1) == IToken.t_if) { + // an else if, don't recurse, just loop and do another if + + if (if_statement != null) { + 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; + } + IASTStatement elseStatement = statement(); + new_if_statement.setElseClause(elseStatement); + elseStatement.setParent(new_if_statement); + elseStatement.setPropertyInParent(IASTIfStatement.ELSE); + if (if_statement != null) { + 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()); + } else { + if (result == null && if_statement != null) + result = if_statement; + if (result == null) + result = new_if_statement; + if_statement = new_if_statement; + } + } else { + if( thenClause != null ) + ((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) + .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; + } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java index e06d5005d7e..ef5dca28e35 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIfStatement.java @@ -11,31 +11,33 @@ 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.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * @author jcamelon */ -public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IASTAmbiguityParent { +public class CPPASTIfStatement extends CPPASTNode implements ICPPASTIfStatement, IASTAmbiguityParent { private IASTExpression condition; private IASTStatement thenClause; private IASTStatement elseClause; + private IASTDeclaration condDecl; /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#getCondition() */ - public IASTExpression getCondition() { + public IASTExpression getConditionExpression() { return condition; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression) */ - public void setCondition(IASTExpression condition) { + public void setConditionExpression(IASTExpression condition) { this.condition = condition; } @@ -76,8 +78,10 @@ public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IA } } if( condition != null ) if( !condition.accept( action ) ) return false; + if( condDecl != null ) if( !condDecl.accept( action )) return false; if( thenClause != null ) if( !thenClause.accept( action ) ) return false; if( elseClause != null ) if( !elseClause.accept( action ) ) return false; + return true; } @@ -95,4 +99,12 @@ public class CPPASTIfStatement extends CPPASTNode implements IASTIfStatement, IA elseClause = (IASTStatement) other; } } + + public IASTDeclaration getConditionDeclaration() { + return condDecl; + } + + public void setConditionDeclaration(IASTDeclaration d) { + condDecl = d; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 0c7bed8145c..98f13389bd3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -92,6 +92,7 @@ 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.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; @@ -4820,7 +4821,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected IASTIfStatement createIfStatement() { + protected ICPPASTIfStatement createIfStatement() { return new CPPASTIfStatement(); } @@ -5000,7 +5001,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { BacktrackException { int startOffset = consume(IToken.t_while).getOffset(); consume(IToken.tLPAREN); - IASTNode while_condition = whileCondition(); + IASTNode while_condition = cppStyleCondition(); consume(IToken.tRPAREN); IASTStatement while_body = statement(); @@ -5029,7 +5030,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected IASTNode whileCondition() throws BacktrackException, + protected IASTNode cppStyleCondition() throws BacktrackException, EndOfFileException { IToken mark = mark(); try { @@ -5066,4 +5067,141 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return new CPPASTAmbiguousStatement(); } + /** + * @return + * @throws EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseIfStatement() throws EndOfFileException, BacktrackException { + ICPPASTIfStatement result = null; + ICPPASTIfStatement if_statement = null; + int start = LA(1).getOffset(); + if_loop: while (true) { + int so = consume(IToken.t_if).getOffset(); + consume(IToken.tLPAREN); + IASTNode condition = null; + try { + condition = cppStyleCondition(); //TODO should be while condition + if (LT(1) == IToken.tEOC) { + // Completing in the condition + ICPPASTIfStatement new_if = createIfStatement(); + if( condition instanceof IASTExpression ) + new_if.setConditionExpression((IASTExpression) condition); + else if( condition instanceof IASTDeclaration ) + new_if.setConditionDeclaration((IASTDeclaration) condition); + condition.setParent(new_if); + condition.setPropertyInParent(IASTIfStatement.CONDITION); + + if (if_statement != null) { + if_statement.setElseClause(new_if); + new_if.setParent(if_statement); + new_if.setPropertyInParent(IASTIfStatement.ELSE); + } + return result != null ? result : new_if; + } + consume(IToken.tRPAREN); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemExpression ps = createProblemExpression(); + ps.setProblem(p); + ((ASTNode) ps).setOffsetAndLength(((ASTNode) p).getOffset(), + ((ASTNode) p).getLength()); + p.setParent(ps); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + condition = ps; + if( LT(1) == IToken.tRPAREN ) + consume(); + else if( LT(2) == IToken.tRPAREN ) + { + consume(); + consume(); + } + else + failParseWithErrorHandling(); + } + + IASTStatement thenClause = statement(); + + ICPPASTIfStatement new_if_statement = createIfStatement(); + ((ASTNode) new_if_statement).setOffset(so); + if( condition != null && condition instanceof IASTExpression ) // shouldn't be possible but failure in condition() makes it so + { + new_if_statement.setConditionExpression((IASTExpression) condition); + condition.setParent(new_if_statement); + condition.setPropertyInParent(IASTIfStatement.CONDITION); + } + if (thenClause != null) { + 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); + if (LT(1) == IToken.t_if) { + // an else if, don't recurse, just loop and do another if + + if (if_statement != null) { + 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; + } + IASTStatement elseStatement = statement(); + new_if_statement.setElseClause(elseStatement); + elseStatement.setParent(new_if_statement); + elseStatement.setPropertyInParent(IASTIfStatement.ELSE); + if (if_statement != null) { + 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()); + } else { + if (result == null && if_statement != null) + result = if_statement; + if (result == null) + result = new_if_statement; + if_statement = new_if_statement; + } + } else { + if( thenClause != null ) + ((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) + .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; + } + } \ No newline at end of file