mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
fix bug 84228 for C++
This commit is contained in:
parent
1af4417856
commit
ae97aa9b2a
8 changed files with 133 additions and 66 deletions
|
@ -1054,5 +1054,33 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
s = (ICompositeType) col.getName(0).resolveBinding();
|
||||
assertNotNull( s );
|
||||
}
|
||||
|
||||
public void testBug84228() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "void f( int m, int c[m][m] ); \n" ); //$NON-NLS-1$
|
||||
buffer.append( "void f( int m, int c[m][m] ){ \n" ); //$NON-NLS-1$
|
||||
buffer.append( " int x; \n" ); //$NON-NLS-1$
|
||||
buffer.append( " { int x = x; } \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
assertEquals(col.size(), 13);
|
||||
|
||||
IParameter m = (IParameter) col.getName(3).resolveBinding();
|
||||
IVariable x3 = (IVariable) col.getName(12).resolveBinding();
|
||||
IVariable x2 = (IVariable) col.getName(11).resolveBinding();
|
||||
IVariable x1 = (IVariable) col.getName(10).resolveBinding();
|
||||
|
||||
assertSame( x2, x3 );
|
||||
assertNotSame( x1, x2 );
|
||||
|
||||
assertInstances( col, m, 6 );
|
||||
assertInstances( col, x1, 1 );
|
||||
assertInstances( col, x2, 2 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2788,7 +2788,7 @@ public class AST2Tests extends AST2BaseTest {
|
|||
|
||||
assertEquals(col.size(), 13);
|
||||
|
||||
IParameter m = (IParameter) col.getName(1).resolveBinding();
|
||||
IParameter m = (IParameter) col.getName(3).resolveBinding();
|
||||
IVariable x3 = (IVariable) col.getName(12).resolveBinding();
|
||||
IVariable x2 = (IVariable) col.getName(11).resolveBinding();
|
||||
IVariable x1 = (IVariable) col.getName(10).resolveBinding();
|
||||
|
|
|
@ -41,4 +41,5 @@ public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarato
|
|||
public ICPPASTConstructorChainInitializer[] getConstructorChain();
|
||||
public void addConstructorToChain( ICPPASTConstructorChainInitializer initializer );
|
||||
|
||||
public ICPPFunctionScope getFunctionScope();
|
||||
}
|
||||
|
|
|
@ -10,10 +10,14 @@
|
|||
**********************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -23,7 +27,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements
|
|||
|
||||
private IASTParameterDeclaration [] parameters = null;
|
||||
private static final int DEFAULT_PARAMETERS_LIST_SIZE = 2;
|
||||
|
||||
private ICPPFunctionScope scope = null;
|
||||
private int currentIndex = 0;
|
||||
private boolean varArgs;
|
||||
private boolean pureVirtual;
|
||||
|
@ -232,6 +236,14 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements
|
|||
constructorChain[ currentConstructorChainIndex++ ] = initializer;
|
||||
}
|
||||
|
||||
|
||||
public ICPPFunctionScope getFunctionScope(){
|
||||
if( scope != null )
|
||||
return scope;
|
||||
|
||||
ASTNodeProperty prop = getPropertyInParent();
|
||||
if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR )
|
||||
scope = new CPPFunctionScope( this );
|
||||
return scope;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -26,7 +26,6 @@ public class CPPASTFunctionDefinition extends CPPASTNode implements
|
|||
private IASTDeclSpecifier declSpecifier;
|
||||
private IASTFunctionDeclarator declarator;
|
||||
private IASTStatement bodyStatement;
|
||||
private ICPPFunctionScope scope;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getDeclSpecifier()
|
||||
|
@ -74,9 +73,7 @@ public class CPPASTFunctionDefinition extends CPPASTNode implements
|
|||
* @see org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition#getScope()
|
||||
*/
|
||||
public IScope getScope() {
|
||||
if( scope == null )
|
||||
scope = new CPPFunctionScope( this );
|
||||
return scope;
|
||||
return ((ICPPASTFunctionDeclarator)declarator).getFunctionScope();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,14 +16,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.ILabel;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +37,7 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
|||
/**
|
||||
* @param physicalNode
|
||||
*/
|
||||
public CPPFunctionScope(IASTFunctionDefinition physicalNode) {
|
||||
public CPPFunctionScope(IASTFunctionDeclarator physicalNode) {
|
||||
super(physicalNode);
|
||||
}
|
||||
|
||||
|
@ -71,12 +72,23 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
|
|||
}
|
||||
|
||||
public IScope getParent() throws DOMException {
|
||||
IASTFunctionDefinition fn = (IASTFunctionDefinition) getPhysicalNode();
|
||||
IFunction function = (IFunction) fn.getDeclarator().getName().resolveBinding();
|
||||
if( function instanceof ICPPMethod ){
|
||||
return function.getScope();
|
||||
}
|
||||
return super.getParent();
|
||||
//we can't just resolve the function and get its parent scope, since there are cases where that
|
||||
//could loop since resolving functions requires resolving their parameter types
|
||||
IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) getPhysicalNode();
|
||||
IASTName name = fdtor.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
if( ns.length > 1){
|
||||
IBinding binding = ns[ ns.length - 2 ].resolveBinding();
|
||||
if( binding instanceof ICPPClassType )
|
||||
return ((ICPPClassType)binding).getCompositeScope();
|
||||
else if( binding instanceof ICPPNamespace )
|
||||
return ((ICPPNamespace)binding).getNamespaceScope();
|
||||
return binding.getScope();
|
||||
}
|
||||
}
|
||||
|
||||
return CPPVisitor.getContainingScope( fdtor );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,6 +121,16 @@ public class CPPSemantics {
|
|||
astName = null;
|
||||
this.name = n;
|
||||
}
|
||||
public boolean includeBlockItem( IASTNode item ){
|
||||
if( astName == null ) return false;
|
||||
if( astName.getParent() instanceof IASTIdExpression ||
|
||||
item instanceof IASTNamespaceDefinition ||
|
||||
(item instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration)item).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean typesOnly(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode parent = astName.getParent();
|
||||
|
@ -649,8 +659,14 @@ public class CPPSemantics {
|
|||
List found = null;
|
||||
|
||||
if( parent instanceof IASTCompoundStatement ){
|
||||
IASTCompoundStatement compound = (IASTCompoundStatement) parent;
|
||||
nodes = compound.getStatements();
|
||||
if( parent.getParent() instanceof IASTFunctionDefinition ){
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ((IASTFunctionDefinition)parent.getParent()).getDeclarator();
|
||||
nodes = dtor.getParameters();
|
||||
}
|
||||
if( nodes == null || nodes.length == 0 ){
|
||||
IASTCompoundStatement compound = (IASTCompoundStatement) parent;
|
||||
nodes = compound.getStatements();
|
||||
}
|
||||
} else if ( parent instanceof IASTTranslationUnit ){
|
||||
IASTTranslationUnit translation = (IASTTranslationUnit) parent;
|
||||
nodes = translation.getDeclarations();
|
||||
|
@ -664,6 +680,9 @@ public class CPPSemantics {
|
|||
|
||||
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[0].getParent()).getDeclarations();
|
||||
namespaceIdx = -1;
|
||||
} else if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent;
|
||||
nodes = dtor.getParameters();
|
||||
}
|
||||
|
||||
if( scope instanceof ICPPClassScope ){
|
||||
|
@ -676,14 +695,8 @@ public class CPPSemantics {
|
|||
while( item != null ) {
|
||||
if( item == null || ( blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() ))
|
||||
break;
|
||||
if( item == blockItem ){
|
||||
if( !(item instanceof IASTNamespaceDefinition) &&
|
||||
!(item instanceof IASTSimpleDeclaration &&
|
||||
((IASTSimpleDeclaration)item).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( item == blockItem && !data.includeBlockItem( item ) )
|
||||
break;
|
||||
|
||||
if( item instanceof ICPPASTUsingDirective && !data.ignoreUsingDirectives ) {
|
||||
if( usingDirectives != null )
|
||||
|
@ -696,18 +709,32 @@ public class CPPSemantics {
|
|||
found.add( possible );
|
||||
}
|
||||
}
|
||||
if( item == blockItem )
|
||||
break;
|
||||
if( idx > -1 && ++idx < nodes.length ){
|
||||
item = nodes[idx];
|
||||
} else {
|
||||
item = null;
|
||||
|
||||
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
|
||||
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[0].getParent()).getDeclarations();
|
||||
if( nodes.length > 0 ){
|
||||
if( namespaceIdx > -1 ) {
|
||||
//check all definitions of this namespace
|
||||
while( namespaceIdx > -1 && namespaceDefs.length > ++namespaceIdx ){
|
||||
nodes = ((ICPPASTNamespaceDefinition)namespaceDefs[0].getParent()).getDeclarations();
|
||||
if( nodes.length > 0 ){
|
||||
idx = 0;
|
||||
item = nodes[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if( parent instanceof IASTCompoundStatement && nodes instanceof IASTParameterDeclaration [] ){
|
||||
//function body, we were looking at parameters, now check the body itself
|
||||
IASTCompoundStatement compound = (IASTCompoundStatement) parent;
|
||||
nodes = compound.getStatements();
|
||||
if( nodes.length > 0 ){
|
||||
idx = 0;
|
||||
item = nodes[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -760,7 +787,13 @@ public class CPPSemantics {
|
|||
declaration = ((IASTDeclarationStatement)node).getDeclaration();
|
||||
else if( node instanceof IASTForStatement )
|
||||
declaration = ((IASTForStatement)node).getInitDeclaration();
|
||||
|
||||
else if( node instanceof IASTParameterDeclaration && !data.typesOnly() ){
|
||||
IASTParameterDeclaration parameterDeclaration = (IASTParameterDeclaration) node;
|
||||
IASTName declName = parameterDeclaration.getDeclarator().getName();
|
||||
if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){
|
||||
return declName;
|
||||
}
|
||||
}
|
||||
if( declaration == null )
|
||||
return null;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
|||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||
|
@ -488,7 +489,7 @@ public class CPPVisitor {
|
|||
} else if( parent instanceof IASTCompoundStatement ){
|
||||
return ((IASTCompoundStatement)parent).getScope();
|
||||
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
||||
IASTNode node = getContainingBlockItem( parent );
|
||||
IASTNode node = getContainingBlockItem( parent.getParent() );
|
||||
if( node instanceof IASTFunctionDefinition ){
|
||||
IASTCompoundStatement body = (IASTCompoundStatement) ((IASTFunctionDefinition)node).getBody();
|
||||
return body.getScope();
|
||||
|
@ -555,44 +556,27 @@ public class CPPVisitor {
|
|||
} else if( parent instanceof IASTStatement ){
|
||||
scope = getContainingScope( (IASTStatement)parent );
|
||||
} else if( parent instanceof IASTFunctionDefinition ){
|
||||
IASTFunctionDeclarator fnDeclarator = ((IASTFunctionDefinition) parent ).getDeclarator();
|
||||
IASTFunctionDeclarator fnDeclarator = ((IASTFunctionDefinition) parent ).getDeclarator();
|
||||
IFunction function = (IFunction) fnDeclarator.getName().resolveBinding();
|
||||
|
||||
try {
|
||||
scope = function.getFunctionScope();
|
||||
} catch ( DOMException e ) {
|
||||
return e.getProblem();
|
||||
}
|
||||
scope = function.getScope();
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
|
||||
if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){
|
||||
//labels have function scope
|
||||
while( scope != null && !(scope instanceof ICPPFunctionScope) ){
|
||||
try {
|
||||
scope = scope.getParent();
|
||||
} catch ( DOMException e ) {
|
||||
return e.getProblem();
|
||||
}
|
||||
while( !(parent instanceof IASTFunctionDefinition) ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
IASTFunctionDefinition fdef = (IASTFunctionDefinition) parent;
|
||||
return ((ICPPASTFunctionDeclarator)fdef.getDeclarator()).getFunctionScope();
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
public static IScope getContainingScope( IASTDeclSpecifier typeSpec ){
|
||||
// if( typeSpec instanceof ICPPASTCompositeTypeSpecifier ){
|
||||
// ICPPASTCompositeTypeSpecifier compTypeSpec = (ICPPASTCompositeTypeSpecifier) typeSpec;
|
||||
// IASTName name = compTypeSpec.getName();
|
||||
// if( name instanceof ICPPASTQualifiedName ){
|
||||
// IASTName [] names = ((ICPPASTQualifiedName)name).getNames();
|
||||
// if( names.length > 1 ){
|
||||
// IBinding binding = names[ names.length - 2 ].resolveBinding();
|
||||
// if( binding instanceof ICPPClassType )
|
||||
// return ((ICPPClassType)binding).getCompositeScope();
|
||||
// else if( binding instanceof ICPPNamespace )
|
||||
// return ((ICPPNamespace)binding).getNamespaceScope();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
IASTNode parent = typeSpec.getParent();
|
||||
if( parent instanceof IASTSimpleDeclaration )
|
||||
return getContainingScope( (IASTSimpleDeclaration) parent );
|
||||
|
@ -607,12 +591,10 @@ public class CPPVisitor {
|
|||
*/
|
||||
public static IScope getContainingScope(IASTParameterDeclaration parameterDeclaration) {
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parameterDeclaration.getParent();
|
||||
IASTName name = dtor.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ) {
|
||||
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
|
||||
if( ns.length > 0 )
|
||||
return getContainingScope( ns [ ns.length - 1 ] );
|
||||
}
|
||||
ASTNodeProperty prop = dtor.getPropertyInParent();
|
||||
if( prop == IASTSimpleDeclaration.DECLARATOR || prop == IASTFunctionDefinition.DECLARATOR )
|
||||
return dtor.getFunctionScope();
|
||||
|
||||
return getContainingScope( dtor );
|
||||
}
|
||||
|
||||
|
@ -632,6 +614,8 @@ public class CPPVisitor {
|
|||
return p;
|
||||
} else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) {
|
||||
return parent;
|
||||
} else if( parent instanceof IASTFunctionDeclarator ){
|
||||
return node;
|
||||
}
|
||||
|
||||
return getContainingBlockItem( parent );
|
||||
|
|
Loading…
Add table
Reference in a new issue