mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fix bug 84478: declarations inside conditions
This commit is contained in:
parent
6d31e93f68
commit
4f02892654
11 changed files with 132 additions and 20 deletions
|
@ -4764,12 +4764,12 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
}
|
||||
|
||||
public void testBug84478_3() throws Exception {
|
||||
IASTTranslationUnit tu = parse( "void foo() { switch( int x = 4 ) { case 4: break; default: break;} }", ParserLanguage.CPP ); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse( "void foo() { switch( int x = 4 ) { case 4: x++; break; default: break;} }", ParserLanguage.CPP ); //$NON-NLS-1$
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
assertNoProblemBindings( col );
|
||||
assertNoProblemBindings( col );
|
||||
assertSame( col.getName(1).resolveBinding(), col.getName(2).resolveBinding() );
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -4777,4 +4777,34 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertNoProblemBindings( col );
|
||||
}
|
||||
|
||||
public void testBug84478_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("void f(){ \n");
|
||||
buffer.append(" if( int x = 1 ) x++; \n");
|
||||
buffer.append(" else x--; \n");
|
||||
buffer.append(" while( int y = 2 ) \n");
|
||||
buffer.append(" y++; \n");
|
||||
buffer.append(" for( int a = 1; int b = 2; b++){ \n");
|
||||
buffer.append(" a++; b++; \n");
|
||||
buffer.append(" } \n");
|
||||
buffer.append("} \n");
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
assertNoProblemBindings( col );
|
||||
IVariable x = (IVariable) col.getName(1).resolveBinding();
|
||||
assertSame( x, col.getName(2).resolveBinding() );
|
||||
assertSame( x, col.getName(3).resolveBinding() );
|
||||
|
||||
IVariable y = (IVariable) col.getName(4).resolveBinding();
|
||||
assertSame( y, col.getName(5).resolveBinding() );
|
||||
|
||||
IVariable a = (IVariable) col.getName(6).resolveBinding();
|
||||
IVariable b = (IVariable) col.getName(7).resolveBinding();
|
||||
assertSame( b, col.getName(8).resolveBinding() );
|
||||
assertSame( a, col.getName(9).resolveBinding() );
|
||||
assertSame( b, col.getName(10).resolveBinding() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,17 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
|
||||
public interface ICPPASTIfStatement extends IASTIfStatement {
|
||||
|
||||
public IASTDeclaration getConditionDeclaration();
|
||||
public void setConditionDeclaration( IASTDeclaration d );
|
||||
|
||||
/**
|
||||
* Get the implicit <code>IScope</code> represented by this if statement
|
||||
*
|
||||
* @return <code>IScope</code>
|
||||
*/
|
||||
public IScope getScope();
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ 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.IASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
|
||||
public interface ICPPASTSwitchStatement extends IASTSwitchStatement {
|
||||
|
||||
|
@ -38,5 +39,11 @@ public interface ICPPASTSwitchStatement extends IASTSwitchStatement {
|
|||
*/
|
||||
public void setControllerDeclaration( IASTDeclaration d );
|
||||
|
||||
/**
|
||||
* Get the <code>IScope</code> represented by this switch.
|
||||
*
|
||||
* @return <code>IScope</code>
|
||||
*/
|
||||
public IScope getScope();
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ 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.IASTWhileStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
|
||||
/**
|
||||
* This inteface accommodates C++ allows for broader while loop syntax.
|
||||
|
@ -42,4 +43,10 @@ public interface ICPPASTWhileStatement extends IASTWhileStatement {
|
|||
*/
|
||||
public void setConditionDeclaration(IASTDeclaration declaration);
|
||||
|
||||
/**
|
||||
* Get the <code>IScope</code> represented by this while.
|
||||
*
|
||||
* @return <code>IScope</code>
|
||||
*/
|
||||
public IScope getScope();
|
||||
}
|
||||
|
|
|
@ -94,6 +94,7 @@ public class CPPASTForStatement extends CPPASTNode implements IASTForStatement,
|
|||
}
|
||||
if( init != null ) if( !init.accept( action ) ) return false;
|
||||
if( condition != null ) if( !condition.accept( action ) ) return false;
|
||||
if( cond_declaration != null ) if( !cond_declaration.accept( action ) ) return false;
|
||||
if( iterationExpression != null ) if( !iterationExpression.accept( action ) ) return false;
|
||||
if( body != null ) if( !body.accept( action ) ) return false;
|
||||
return true;
|
||||
|
|
|
@ -15,6 +15,7 @@ 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.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
|
||||
|
@ -26,6 +27,7 @@ public class CPPASTIfStatement extends CPPASTNode implements ICPPASTIfStatement,
|
|||
private IASTStatement thenClause;
|
||||
private IASTStatement elseClause;
|
||||
private IASTDeclaration condDecl;
|
||||
private IScope scope;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTIfStatement#getCondition()
|
||||
|
@ -113,4 +115,10 @@ public class CPPASTIfStatement extends CPPASTNode implements ICPPASTIfStatement,
|
|||
public void setConditionDeclaration(IASTDeclaration d) {
|
||||
condDecl = d;
|
||||
}
|
||||
|
||||
public IScope getScope() {
|
||||
if( scope == null )
|
||||
scope = new CPPBlockScope( this );
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ 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.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
|
||||
|
@ -24,6 +25,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
|||
public class CPPASTSwitchStatement extends CPPASTNode implements
|
||||
ICPPASTSwitchStatement, IASTAmbiguityParent {
|
||||
|
||||
private IScope scope;
|
||||
private IASTExpression controller;
|
||||
private IASTStatement body;
|
||||
private IASTDeclaration decl;
|
||||
|
@ -65,6 +67,7 @@ public class CPPASTSwitchStatement extends CPPASTNode implements
|
|||
}
|
||||
}
|
||||
if( controller != null ) if( !controller.accept( action ) ) return false;
|
||||
if( decl != null ) if( !decl.accept( action ) ) return false;
|
||||
if( body != null ) if( !body.accept( action ) ) return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -99,4 +102,10 @@ public class CPPASTSwitchStatement extends CPPASTNode implements
|
|||
decl = d;
|
||||
}
|
||||
|
||||
public IScope getScope() {
|
||||
if( scope == null )
|
||||
scope = new CPPBlockScope( this );
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ 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.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||
|
||||
|
@ -26,6 +27,7 @@ public class CPPASTWhileStatement extends CPPASTNode implements
|
|||
private IASTExpression condition;
|
||||
private IASTStatement body;
|
||||
private IASTDeclaration condition2;
|
||||
private IScope scope;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTWhileStatement#getCondition()
|
||||
|
@ -104,4 +106,10 @@ public class CPPASTWhileStatement extends CPPASTNode implements
|
|||
}
|
||||
}
|
||||
|
||||
public IScope getScope() {
|
||||
if( scope == null )
|
||||
scope = new CPPBlockScope( this );
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
|
@ -69,7 +68,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
|||
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.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||
|
@ -77,12 +78,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
|
@ -1416,13 +1419,29 @@ public class CPPSemantics {
|
|||
declaration = (IASTDeclaration) node;
|
||||
else if( node instanceof IASTDeclarationStatement )
|
||||
declaration = ((IASTDeclarationStatement)node).getDeclaration();
|
||||
else if( node instanceof IASTForStatement && checkAux )
|
||||
else if( node instanceof ICPPASTForStatement && checkAux )
|
||||
{
|
||||
if( ((IASTForStatement)node).getInitializerStatement() instanceof IASTDeclarationStatement )
|
||||
declaration = ((IASTDeclarationStatement)((IASTForStatement)node).getInitializerStatement()).getDeclaration();
|
||||
|
||||
}
|
||||
else if( node instanceof IASTParameterDeclaration ){
|
||||
ICPPASTForStatement forStatement = (ICPPASTForStatement) node;
|
||||
if( forStatement.getConditionDeclaration() == null ){
|
||||
if( forStatement.getInitializerStatement() instanceof IASTDeclarationStatement )
|
||||
declaration = ((IASTDeclarationStatement)forStatement.getInitializerStatement()).getDeclaration();
|
||||
} else {
|
||||
if( forStatement.getInitializerStatement() instanceof IASTDeclarationStatement ){
|
||||
Object o = collectResult( data, scope, forStatement.getInitializerStatement(), checkAux );
|
||||
if( o instanceof IASTName )
|
||||
resultName = (IASTName) o;
|
||||
else if( o instanceof IASTName[] )
|
||||
resultArray = (IASTName[]) o;
|
||||
}
|
||||
declaration = forStatement.getConditionDeclaration();
|
||||
}
|
||||
} else if( node instanceof ICPPASTSwitchStatement ){
|
||||
declaration = ((ICPPASTSwitchStatement)node).getControllerDeclaration();
|
||||
} else if( node instanceof ICPPASTIfStatement ) {
|
||||
declaration = ((ICPPASTIfStatement)node).getConditionDeclaration();
|
||||
} else if( node instanceof ICPPASTWhileStatement ){
|
||||
declaration = ((ICPPASTWhileStatement)node).getConditionDeclaration();
|
||||
} else if( node instanceof IASTParameterDeclaration ){
|
||||
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
|
||||
IASTDeclarator dtor = parameterDeclaration.getDeclarator();
|
||||
if (dtor != null) { // could be null when content assist in the declSpec
|
||||
|
|
|
@ -89,6 +89,7 @@ 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.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
|
||||
|
@ -100,6 +101,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
|
@ -109,6 +111,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
|
@ -491,13 +494,6 @@ public class CPPVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
if( prop == IASTDeclarationStatement.DECLARATION ){
|
||||
//implicit scope, see 6.4-1
|
||||
prop = parent.getParent().getPropertyInParent();
|
||||
if( prop != IASTCompoundStatement.NESTED_STATEMENT )
|
||||
scope = null;
|
||||
}
|
||||
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = ( scope != null ) ? scope.getBinding( name, false ) : null;
|
||||
|
@ -668,6 +664,12 @@ public class CPPVisitor {
|
|||
return ((IASTCompositeTypeSpecifier)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTNamespaceDefinition ) {
|
||||
return ((ICPPASTNamespaceDefinition)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTSwitchStatement ){
|
||||
return ((ICPPASTSwitchStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTIfStatement ){
|
||||
return ((ICPPASTIfStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTWhileStatement ){
|
||||
return ((ICPPASTWhileStatement)parent).getScope();
|
||||
}
|
||||
} else if( node instanceof IASTStatement ){
|
||||
return getContainingScope( (IASTStatement) node );
|
||||
|
@ -711,6 +713,12 @@ public class CPPVisitor {
|
|||
IASTNode parent = node.getParent();
|
||||
if( parent instanceof IASTForStatement ){
|
||||
return ((IASTForStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTIfStatement ){
|
||||
return ((ICPPASTIfStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTSwitchStatement ){
|
||||
return ((ICPPASTSwitchStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTWhileStatement ){
|
||||
return ((ICPPASTWhileStatement)parent).getScope();
|
||||
} else if( parent instanceof IASTCompoundStatement ){
|
||||
return ((IASTCompoundStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
||||
|
@ -822,6 +830,12 @@ public class CPPVisitor {
|
|||
scope = compound.getScope();
|
||||
} else if( parent instanceof IASTForStatement ){
|
||||
scope = ((IASTForStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTSwitchStatement ){
|
||||
scope = ((ICPPASTSwitchStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTIfStatement ){
|
||||
scope = ((ICPPASTIfStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTWhileStatement ){
|
||||
scope = ((ICPPASTWhileStatement)parent).getScope();
|
||||
} else if( parent instanceof IASTStatement ){
|
||||
scope = getContainingScope( (IASTStatement)parent );
|
||||
} else if( parent instanceof IASTFunctionDefinition ){
|
||||
|
|
|
@ -5219,7 +5219,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
ICPPASTIfStatement new_if_statement = createIfStatement();
|
||||
((ASTNode) new_if_statement).setOffset(so);
|
||||
if (condition != null && condition instanceof IASTExpression) // shouldn't
|
||||
if (condition != null && (condition instanceof IASTExpression || condition instanceof IASTDeclaration)) // shouldn't
|
||||
// be
|
||||
// possible
|
||||
// but
|
||||
|
@ -5230,8 +5230,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
// it
|
||||
// so
|
||||
{
|
||||
new_if_statement
|
||||
.setConditionExpression((IASTExpression) condition);
|
||||
if( condition instanceof IASTExpression )
|
||||
new_if_statement.setConditionExpression((IASTExpression) condition);
|
||||
else if( condition instanceof IASTDeclaration )
|
||||
new_if_statement.setConditionDeclaration((IASTDeclaration) condition);
|
||||
condition.setParent(new_if_statement);
|
||||
condition.setPropertyInParent(IASTIfStatement.CONDITION);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue