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;
+ }
}