diff options
author | Markus Schorn | 2009-02-03 12:14:36 +0000 |
---|---|---|
committer | Markus Schorn | 2009-02-03 12:14:36 +0000 |
commit | 155e36d7b3994372a61583002d809bd29b60c3a3 (patch) | |
tree | 4135a8b3c30a8295ee6020d04df883a34236bd12 /core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp | |
parent | c97571595e06e2ec4b32fa04518d6305e8b1b92a (diff) | |
download | org.eclipse.cdt-155e36d7b3994372a61583002d809bd29b60c3a3.tar.gz org.eclipse.cdt-155e36d7b3994372a61583002d809bd29b60c3a3.tar.xz org.eclipse.cdt-155e36d7b3994372a61583002d809bd29b60c3a3.zip |
Ambiguity handling for c++ conditions, bug 263158.
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp')
8 files changed, 219 insertions, 120 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java index a66240f9c5e..641c8fe53b8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java @@ -76,7 +76,9 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { } } else if (node instanceof IASTDeclarationStatement) { repopulateScope(((IASTDeclarationStatement) node).getDeclaration()); - } + } else if (node instanceof IASTDeclaration) { + repopulateScope((IASTDeclaration) node); + } return PROCESS_SKIP; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCondition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCondition.java new file mode 100644 index 00000000000..49fd7bf2e5b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCondition.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; + +/** + * Handles ambiguity between expression and declaration in a condition. + */ +public class CPPASTAmbiguousCondition extends ASTAmbiguousNode implements IASTAmbiguousCondition { + private IASTExpression fExpression; + private IASTDeclaration fDeclaration; + + public CPPASTAmbiguousCondition(IASTExpression expression, IASTSimpleDeclaration declaration) { + fExpression= expression; + fDeclaration= declaration; + + expression.setParent(this); + expression.setPropertyInParent(SUBCONDITION); + declaration.setParent(this); + declaration.setPropertyInParent(SUBCONDITION); + } + + @Override + public IASTNode[] getNodes() { + return new IASTNode[] {fExpression, fDeclaration}; + } + + @Override + protected void beforeResolution() { + // populate containing scope, so that it will not be affected by the alternative branches. + IScope scope= CPPVisitor.getContainingScope(this); + if (scope instanceof ICPPASTInternalScope) { + ((ICPPASTInternalScope) scope).populateCache(); + } + } + + public IASTExpression copy() { + throw new UnsupportedOperationException(); + } + + public IType getExpressionType() { + return null; + } +} 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 1cb23218e91..4808608262f 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 @@ -1,13 +1,14 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Emanuel Graf IFS - Bugfix for #198269 + * John Camelon (IBM) - Initial API and implementation + * Emanuel Graf IFS - Bug 198269 + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -22,16 +23,17 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * For statement in c++ */ public class CPPASTForStatement extends ASTNode implements ICPPASTForStatement, IASTAmbiguityParent { private IScope scope = null; + private IASTStatement init; private IASTExpression condition; + private IASTDeclaration condDeclaration; private IASTExpression iterationExpression; - private IASTStatement body, init; + private IASTStatement body; - private IASTDeclaration condDeclaration; public CPPASTForStatement() { @@ -74,6 +76,7 @@ public class CPPASTForStatement extends ASTNode implements ICPPASTForStatement, if (condition != null) { condition.setParent(this); condition.setPropertyInParent(CONDITION); + condDeclaration= null; } } @@ -134,39 +137,27 @@ public class CPPASTForStatement extends ASTNode implements ICPPASTForStatement, return true; } - public void replace(IASTNode child, IASTNode other) { - if( body == child ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - body = (IASTStatement) other; - } - if( child == condition ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - condition = (IASTExpression) other; - } - if( child == condDeclaration ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - condDeclaration = (IASTDeclaration) other; - } - - if( child == iterationExpression ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - iterationExpression = (IASTExpression) other; - } - if( child == init ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - init = (IASTStatement) other; - } - } + public void replace(IASTNode child, IASTNode other) { + if (body == child) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + body = (IASTStatement) other; + } else if (child == condition || child == condDeclaration) { + if (other instanceof IASTExpression) { + setConditionExpression((IASTExpression) other); + } else if (other instanceof IASTDeclaration) { + setConditionDeclaration((IASTDeclaration) other); + } + } else if (child == iterationExpression) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + iterationExpression = (IASTExpression) other; + } else if (child == init) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + init = (IASTStatement) other; + } + } public IASTStatement getInitializerStatement() { return init; @@ -187,6 +178,7 @@ public class CPPASTForStatement extends ASTNode implements ICPPASTForStatement, if (d != null) { d.setParent(this); d.setPropertyInParent(CONDITION_DECLARATION); + condition= null; } } 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 49c773f9d8a..63f49f3b2a9 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 @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * John Camelon (IBM) - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -21,7 +21,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * If statement in c++ */ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IASTAmbiguityParent { @@ -68,6 +68,7 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA if (condition != null) { condition.setParent(this); condition.setPropertyInParent(CONDITION); + condDecl= null; } } @@ -122,7 +123,7 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA return true; } - public void replace(IASTNode child, IASTNode other) { + public void replace(IASTNode child, IASTNode other) { if (thenClause == child) { other.setParent(child.getParent()); other.setPropertyInParent(child.getPropertyInParent()); @@ -131,14 +132,12 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA other.setParent(child.getParent()); other.setPropertyInParent(child.getPropertyInParent()); elseClause = (IASTStatement) other; - } else if (condDecl == child) { - other.setParent(child.getParent()); - other.setPropertyInParent(child.getPropertyInParent()); - condDecl = (IASTDeclaration) other; - } else if (condition == child) { - other.setParent(child.getParent()); - other.setPropertyInParent(child.getPropertyInParent()); - condition = (IASTExpression) other; + } else if (condition == child || condDecl == child) { + if (other instanceof IASTExpression) { + setConditionExpression((IASTExpression) other); + } else if (other instanceof IASTDeclaration) { + setConditionDeclaration((IASTDeclaration) other); + } } } @@ -152,6 +151,7 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA if (d != null) { d.setParent(this); d.setPropertyInParent(CONDITION); + condition= null; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java index 4911b83d354..3bbc43e61d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -21,15 +22,15 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * Switch statement in c++. */ public class CPPASTSwitchStatement extends ASTNode implements ICPPASTSwitchStatement, IASTAmbiguityParent { private IScope scope; - private IASTExpression controller; + private IASTExpression controllerExpression; + private IASTDeclaration controllerDeclaration; private IASTStatement body; - private IASTDeclaration decl; public CPPASTSwitchStatement() { @@ -47,23 +48,24 @@ public class CPPASTSwitchStatement extends ASTNode implements public CPPASTSwitchStatement copy() { CPPASTSwitchStatement copy = new CPPASTSwitchStatement(); - copy.setControllerDeclaration(decl == null ? null : decl.copy()); - copy.setControllerExpression(controller == null ? null : controller.copy()); + copy.setControllerDeclaration(controllerDeclaration == null ? null : controllerDeclaration.copy()); + copy.setControllerExpression(controllerExpression == null ? null : controllerExpression.copy()); copy.setBody(body == null ? null : body.copy()); copy.setOffsetAndLength(this); return copy; } public IASTExpression getControllerExpression() { - return controller; + return controllerExpression; } public void setControllerExpression(IASTExpression controller) { assertNotFrozen(); - this.controller = controller; + this.controllerExpression = controller; if (controller != null) { controller.setParent(this); controller.setPropertyInParent(CONTROLLER_EXP); + controllerDeclaration= null; } } @@ -89,8 +91,8 @@ public class CPPASTSwitchStatement extends ASTNode implements default : break; } } - if( controller != null ) if( !controller.accept( action ) ) return false; - if( decl != null ) if( !decl.accept( action ) ) return false; + if( controllerExpression != null ) if( !controllerExpression.accept( action ) ) return false; + if( controllerDeclaration != null ) if( !controllerDeclaration.accept( action ) ) return false; if( body != null ) if( !body.accept( action ) ) return false; if( action.shouldVisitStatements ){ @@ -104,37 +106,30 @@ public class CPPASTSwitchStatement extends ASTNode implements } public void replace(IASTNode child, IASTNode other) { - if( body == child ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - body = (IASTStatement) other; - } - if( child == controller ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - controller = (IASTExpression) other; - } - if( child == decl ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - decl = (IASTDeclaration) other; - } - - } + if (body == child) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + body = (IASTStatement) other; + } else if (controllerDeclaration == child || controllerExpression == child) { + if (other instanceof IASTExpression) { + setControllerExpression((IASTExpression) other); + } else if (other instanceof IASTDeclaration) { + setControllerDeclaration((IASTDeclaration) other); + } + } + } public IASTDeclaration getControllerDeclaration() { - return decl; + return controllerDeclaration; } public void setControllerDeclaration(IASTDeclaration d) { assertNotFrozen(); - decl = d; + controllerDeclaration = d; if (d != null) { d.setParent(this); d.setPropertyInParent(CONTROLLER_DECLARATION); + controllerExpression= null; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTWhileStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTWhileStatement.java index 9ea1db40ef1..2a0030127f1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTWhileStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTWhileStatement.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2008 IBM Corporation and others. + * Copyright (c) 2004, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * John Camelon (IBM) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -21,7 +22,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** - * @author jcamelon + * While statement in c++. */ public class CPPASTWhileStatement extends ASTNode implements ICPPASTWhileStatement, IASTAmbiguityParent { @@ -63,6 +64,7 @@ public class CPPASTWhileStatement extends ASTNode implements if (condition != null) { condition.setParent(this); condition.setPropertyInParent(CONDITIONEXPRESSION); + condition2= null; } } @@ -89,6 +91,7 @@ public class CPPASTWhileStatement extends ASTNode implements if (declaration != null) { declaration.setParent(this); declaration.setPropertyInParent(CONDITIONDECLARATION); + condition= null; } } @@ -115,26 +118,20 @@ public class CPPASTWhileStatement extends ASTNode implements return true; } - public void replace(IASTNode child, IASTNode other) { - if( body == child ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - body = (IASTStatement) other; - } - if( child == condition ) - { - other.setPropertyInParent( child.getPropertyInParent() ); - other.setParent( child.getParent() ); - condition = (IASTExpression) other; - } - if( condition2 == child ) - { - other.setParent( child.getParent() ); - other.setPropertyInParent( child.getPropertyInParent() ); - condition2 = (IASTDeclaration) other; - } - } + public void replace(IASTNode child, IASTNode other) { + if (body == child) { + other.setPropertyInParent(child.getPropertyInParent()); + other.setParent(child.getParent()); + body = (IASTStatement) other; + } + if (child == condition || child == condition2) { + if (other instanceof IASTExpression) { + setCondition((IASTExpression) other); + } else if (other instanceof IASTDeclaration) { + setConditionDeclaration((IASTDeclaration) other); + } + } + } public IScope getScope() { if( scope == null ) 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 5844c2f10f0..9e3fb102f94 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 @@ -3669,25 +3669,56 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } protected IASTNode cppStyleCondition(int expectToken) throws BacktrackException, EndOfFileException { + IASTExpression e= null; + IASTSimpleDeclaration decl= null; + IToken end= null; + IToken mark = mark(); try { - IASTExpression e = expression(); - final int lt1= LT(1); - if (lt1 == expectToken || lt1 == IToken.tEOC) { - return e; - } - } catch (BacktrackException bt) { + decl= simpleSingleDeclaration(DeclarationOptions.CONDITION); + end= LA(1); + final int la= end.getType(); + if (la != expectToken && la != IToken.tEOC) { + end= null; + decl= null; + } + } catch (BacktrackException b) { } + backup(mark); try { - return simpleSingleDeclaration(DeclarationOptions.CONDITION); - } catch (BacktrackException b) { - if (expectToken == IToken.tRPAREN) { - backup(mark); - return skipProblemConditionInParenthesis(mark.getOffset()); + e= expression(); + + final IToken end2= LA(1); + final int la= end2.getType(); + if (la != expectToken && la != IToken.tEOC) { + throwBacktrack(end2); + } + if (end == null) + return e; + + + final int endOffset = end.getOffset(); + final int endOffset2 = end2.getOffset(); + if (endOffset == endOffset2) { + CPPASTAmbiguousCondition ambig= new CPPASTAmbiguousCondition(e, decl); + setRange(ambig, e); + return ambig; + } + + if (endOffset < endOffset2) + return e; + } catch (BacktrackException bt) { + if (end == null) { + if (expectToken == IToken.tRPAREN) { + backup(mark); + return skipProblemConditionInParenthesis(mark.getOffset()); + } + throw bt; } - throw b; } + backup(end); + return decl; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/IASTAmbiguousCondition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/IASTAmbiguousCondition.java new file mode 100644 index 00000000000..2240ad51aff --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/IASTAmbiguousCondition.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2009 Wind River Systems, Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTExpression; + +/** + * Marks ambiguous condition nodes. + */ +public interface IASTAmbiguousCondition extends IASTExpression { + public static final ASTNodeProperty SUBCONDITION = new ASTNodeProperty( "IASTAmbiguousCondition.SUBCONDITION"); //$NON-NLS-1$ + +} |