diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 77d7133f333..173d0267d66 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -4770,4 +4770,11 @@ public class AST2CPPTests extends AST2BaseTest { assertNoProblemBindings( col ); } + public void testBug84478_4() throws Exception { + IASTTranslationUnit tu = parse( "void foo() { for( int i = 0; int j = 0; ++i) {} }", ParserLanguage.CPP ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + assertNoProblemBindings( col ); + } + } 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 d179dbcf52a..3ceeb31543e 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 @@ -1031,7 +1031,7 @@ public class AST2Tests extends AST2BaseTest { IASTName name_i = dtor.getName(); // i < 5; IASTBinaryExpression exp = (IASTBinaryExpression) for_stmt - .getCondition(); + .getConditionExpression(); IASTIdExpression id_i = (IASTIdExpression) exp.getOperand1(); IASTName name_i2 = id_i.getName(); IASTLiteralExpression lit_5 = (IASTLiteralExpression) exp.getOperand2(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTForStatement.java index ce4198da318..57edcdc44f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTForStatement.java @@ -64,7 +64,7 @@ public interface IASTForStatement extends IASTStatement { * * @return IASTExpression */ - public IASTExpression getCondition(); + public IASTExpression getConditionExpression(); /** * Set the condition expression for the loop. @@ -72,7 +72,7 @@ public interface IASTForStatement extends IASTStatement { * @param condition * IASTExpression */ - public void setCondition(IASTExpression condition); + public void setConditionExpression(IASTExpression condition); /** * Get the expression that is evaluated after the completion of an iteration diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java new file mode 100644 index 00000000000..ed593449234 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTForStatement.java @@ -0,0 +1,23 @@ +/********************************************************************** + * 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.IASTForStatement; + +public interface ICPPASTForStatement extends IASTForStatement { + + public static final ASTNodeProperty CONDITION_DECLARATION = new ASTNodeProperty( "org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement"); //$NON-NLS-1$ + public void setConditionDeclaration( IASTDeclaration d ); + public IASTDeclaration getConditionDeclaration(); + +} 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 adb647cc2d2..e8708c042c3 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 @@ -30,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; -import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; @@ -1415,12 +1414,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { * @return */ protected abstract IASTBreakStatement createBreakStatement(); - - /** - * @return - */ - protected abstract IASTForStatement createForStatement(); - + /** * @return */ @@ -1817,81 +1811,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return return_statement; } - /** - * @return - * @throws EndOfFileException - * @throws BacktrackException - */ - protected IASTStatement parseForStatement() throws EndOfFileException, - BacktrackException { - int startOffset; - startOffset = consume(IToken.t_for).getOffset(); - consume(IToken.tLPAREN); - IASTStatement init = forInitStatement(); - IASTExpression for_condition = null; - switch (LT(1)) { - case IToken.tSEMI: - case IToken.tEOC: - break; - default: - for_condition = condition(); - } - switch (LT(1)) { - case IToken.tSEMI: - consume(IToken.tSEMI); - break; - case IToken.tEOC: - break; - default: - throw backtrack; - } - IASTExpression iterationExpression = null; - switch (LT(1)) { - case IToken.tRPAREN: - case IToken.tEOC: - break; - default: - iterationExpression = expression(); - } - switch (LT(1)) { - case IToken.tRPAREN: - consume(IToken.tRPAREN); - break; - case IToken.tEOC: - break; - default: - throw backtrack; - } - IASTForStatement for_statement = createForStatement(); - IASTStatement for_body = null; - if (LT(1) != IToken.tEOC) { - for_body = statement(); - ((ASTNode) for_statement).setOffsetAndLength(startOffset, - calculateEndOffset(for_body) - startOffset); - } - - for_statement.setInitializerStatement(init); - init.setParent(for_statement); - init.setPropertyInParent(IASTForStatement.INITIALIZER); - - if (for_condition != null) { - for_statement.setCondition(for_condition); - for_condition.setParent(for_statement); - for_condition.setPropertyInParent(IASTForStatement.CONDITION); - } - if (iterationExpression != null) { - for_statement.setIterationExpression(iterationExpression); - iterationExpression.setParent(for_statement); - iterationExpression.setPropertyInParent(IASTForStatement.ITERATION); - } - if (for_body != null) { - for_statement.setBody(for_body); - for_body.setParent(for_statement); - for_body.setPropertyInParent(IASTForStatement.BODY); - } - return for_statement; - } - /** * @return * @throws EndOfFileException diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTForStatement.java index 16dffd04196..2b39f0eb380 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTForStatement.java @@ -31,14 +31,14 @@ public class CASTForStatement extends CASTNode implements IASTForStatement, IAST /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() */ - public IASTExpression getCondition() { + public IASTExpression getConditionExpression() { return condition; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#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 aa42287f398..7509c72d12e 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 @@ -2841,5 +2841,79 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return switch_statement; } + /** + * @return + * @throws EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException { + int startOffset; + startOffset = consume(IToken.t_for).getOffset(); + consume(IToken.tLPAREN); + IASTStatement init = forInitStatement(); + IASTExpression for_condition = null; + switch (LT(1)) { + case IToken.tSEMI: + case IToken.tEOC: + break; + default: + for_condition = condition(); + } + switch (LT(1)) { + case IToken.tSEMI: + consume(IToken.tSEMI); + break; + case IToken.tEOC: + break; + default: + throw backtrack; + } + IASTExpression iterationExpression = null; + switch (LT(1)) { + case IToken.tRPAREN: + case IToken.tEOC: + break; + default: + iterationExpression = expression(); + } + switch (LT(1)) { + case IToken.tRPAREN: + consume(IToken.tRPAREN); + break; + case IToken.tEOC: + break; + default: + throw backtrack; + } + IASTForStatement for_statement = createForStatement(); + IASTStatement for_body = null; + if (LT(1) != IToken.tEOC) { + for_body = statement(); + ((ASTNode) for_statement).setOffsetAndLength(startOffset, + calculateEndOffset(for_body) - startOffset); + } + + for_statement.setInitializerStatement(init); + init.setParent(for_statement); + init.setPropertyInParent(IASTForStatement.INITIALIZER); + + if (for_condition != null) { + for_statement.setConditionExpression(for_condition); + for_condition.setParent(for_statement); + for_condition.setPropertyInParent(IASTForStatement.CONDITION); + } + if (iterationExpression != null) { + for_statement.setIterationExpression(iterationExpression); + iterationExpression.setParent(for_statement); + iterationExpression.setPropertyInParent(IASTForStatement.ITERATION); + } + if (for_body != null) { + for_statement.setBody(for_body); + for_body.setParent(for_statement); + for_body.setPropertyInParent(IASTForStatement.BODY); + } + return for_statement; + } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java index acedb48a640..1f907844ded 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTForStatement.java @@ -11,34 +11,38 @@ 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.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * @author jcamelon */ -public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent { +public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, IASTAmbiguityParent, ICPPASTForStatement { private IScope scope = null; private IASTExpression condition; private IASTExpression iterationExpression; private IASTStatement body, init; + private IASTDeclaration cond_declaration; + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#getCondition() */ - public IASTExpression getCondition() { + public IASTExpression getConditionExpression() { return condition; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTForStatement#setCondition(org.eclipse.cdt.core.dom.ast.IASTExpression) */ - public void setCondition(IASTExpression condition) { + public void setConditionExpression(IASTExpression condition) { this.condition = condition; } @@ -108,6 +112,13 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, other.setParent( child.getParent() ); condition = (IASTExpression) other; } + if( child == cond_declaration ) + { + other.setPropertyInParent( child.getPropertyInParent() ); + other.setParent( child.getParent() ); + cond_declaration = (IASTDeclaration) other; + } + if( child == iterationExpression ) { other.setPropertyInParent( child.getPropertyInParent() ); @@ -129,4 +140,12 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement, public void setInitializerStatement(IASTStatement statement) { init = statement; } + + public void setConditionDeclaration(IASTDeclaration d) { + cond_declaration = d; + } + + public IASTDeclaration getConditionDeclaration() { + return cond_declaration; + } } 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 fb0a1ce6e7b..e6631f06e55 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.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.ICPPASTForStatement; 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; @@ -2869,6 +2870,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch (LT(1)) { case IToken.tSEMI: + if( fromCatchHandler ) + break; semiOffset = consume(IToken.tSEMI).getEndOffset(); consumedSemi = true; break; @@ -4852,7 +4855,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected IASTForStatement createForStatement() { + protected ICPPASTForStatement createForStatement() { return new CPPASTForStatement(); } @@ -5081,7 +5084,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { BacktrackException { int startOffset = consume(IToken.t_while).getOffset(); consume(IToken.tLPAREN); - IASTNode while_condition = cppStyleCondition(); + IASTNode while_condition = cppStyleCondition(true); consume(IToken.tRPAREN); IASTStatement while_body = statement(); @@ -5108,13 +5111,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } /** + * @param expectSemi TODO * @return */ - protected IASTNode cppStyleCondition() throws BacktrackException, + protected IASTNode cppStyleCondition(boolean expectSemi) throws BacktrackException, EndOfFileException { IToken mark = mark(); try { IASTExpression e = expression(); + if( ! expectSemi ) + return e; switch (LT(1)) { case IToken.tRPAREN: case IToken.tEOC: @@ -5169,7 +5175,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consume(IToken.tLPAREN); IASTNode condition = null; try { - condition = cppStyleCondition(); + condition = cppStyleCondition(true); // condition if (LT(1) == IToken.tEOC) { // Completing in the condition @@ -5350,7 +5356,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { int startOffset; startOffset = consume(IToken.t_switch).getOffset(); consume(IToken.tLPAREN); - IASTNode switch_condition = cppStyleCondition(); + IASTNode switch_condition = cppStyleCondition(true); consume(IToken.tRPAREN); IASTStatement switch_body = statement(); @@ -5374,4 +5380,86 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch_body.setPropertyInParent(IASTSwitchStatement.BODY); return switch_statement; } + + /** + * @return + * @throws EndOfFileException + * @throws BacktrackException + */ + protected IASTStatement parseForStatement() throws EndOfFileException, BacktrackException { + int startOffset; + startOffset = consume(IToken.t_for).getOffset(); + consume(IToken.tLPAREN); + IASTStatement init = forInitStatement(); + IASTNode for_condition = null; + switch (LT(1)) { + case IToken.tSEMI: + case IToken.tEOC: + break; + default: + for_condition = cppStyleCondition(false); + } + switch (LT(1)) { + case IToken.tSEMI: + consume(IToken.tSEMI); + break; + case IToken.tEOC: + break; + default: + throw backtrack; + } + IASTExpression iterationExpression = null; + switch (LT(1)) { + case IToken.tRPAREN: + case IToken.tEOC: + break; + default: + iterationExpression = expression(); + } + switch (LT(1)) { + case IToken.tRPAREN: + consume(IToken.tRPAREN); + break; + case IToken.tEOC: + break; + default: + throw backtrack; + } + ICPPASTForStatement for_statement = createForStatement(); + IASTStatement for_body = null; + if (LT(1) != IToken.tEOC) { + for_body = statement(); + ((ASTNode) for_statement).setOffsetAndLength(startOffset, + calculateEndOffset(for_body) - startOffset); + } + + for_statement.setInitializerStatement(init); + init.setParent(for_statement); + init.setPropertyInParent(IASTForStatement.INITIALIZER); + + if (for_condition != null) { + for_condition.setParent(for_statement); + if( for_condition instanceof IASTExpression ) + { + for_statement.setConditionExpression((IASTExpression) for_condition); + for_condition.setPropertyInParent(IASTForStatement.CONDITION); + } + else if( for_condition instanceof IASTDeclaration ) + { + for_statement.setConditionDeclaration((IASTDeclaration) for_condition); + for_condition.setPropertyInParent(ICPPASTForStatement.CONDITION_DECLARATION); + } + } + if (iterationExpression != null) { + for_statement.setIterationExpression(iterationExpression); + iterationExpression.setParent(for_statement); + iterationExpression.setPropertyInParent(IASTForStatement.ITERATION); + } + if (for_body != null) { + for_statement.setBody(for_body); + for_body.setParent(for_statement); + for_body.setPropertyInParent(IASTForStatement.BODY); + } + return for_statement; + } }