1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-30 21:55:31 +02:00

fix bug 86470 - various issues with using declarations

This commit is contained in:
Andrew Niefer 2005-02-25 22:39:46 +00:00
parent b9dc18ad86
commit 23013c436d
4 changed files with 253 additions and 33 deletions

View file

@ -55,6 +55,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -2399,5 +2400,133 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame( decls[2], col.getName(3) );
assertSame( decls[3], col.getName(5) );
}
public void testBug86470_1() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" void f( char ); \n"); //$NON-NLS-1$
buffer.append(" void f( int ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("using A::f; \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.getVisitor().visitTranslationUnit(col);
IBinding b = col.getName(7).resolveBinding();
IASTName [] decls = tu.getDeclarations( b );
assertEquals( decls.length, 2 );
assertSame( decls[0], col.getName(1) );
assertSame( decls[1], col.getName(3) );
}
public void testBug86470_2() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" void f( int ); \n"); //$NON-NLS-1$
buffer.append(" void f( double ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("namespace B { \n"); //$NON-NLS-1$
buffer.append(" void f( int ); \n"); //$NON-NLS-1$
buffer.append(" void f( double ); \n"); //$NON-NLS-1$
buffer.append(" void f( char ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("void g() { \n"); //$NON-NLS-1$
buffer.append(" using A::f; \n"); //$NON-NLS-1$
buffer.append(" using B::f; \n"); //$NON-NLS-1$
buffer.append(" f( 'c' ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.getVisitor().visitTranslationUnit(col);
IFunction f_decl = (IFunction) col.getName(10).resolveBinding();
IFunction f_ref = (IFunction) col.getName(19).resolveBinding();
assertSame( f_decl, f_ref );
}
public void testBug86470_3() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" struct g {}; \n"); //$NON-NLS-1$
buffer.append(" void g ( char ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" using A::g; \n"); //$NON-NLS-1$
buffer.append(" g('a'); \n"); //$NON-NLS-1$
buffer.append(" struct g gg; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.getVisitor().visitTranslationUnit(col);
IBinding ref1 = col.getName(8).resolveBinding();
IBinding ref2 = col.getName(9).resolveBinding();
ICPPClassType g_struct = (ICPPClassType) col.getName(1).resolveBinding();
IFunction g_func = (IFunction) col.getName(2).resolveBinding();
assertSame( g_struct, ref2 );
assertSame( g_func, ref1 );
ICPPCompositeBinding comp = (ICPPCompositeBinding) col.getName(7).resolveBinding();
IASTName [] decls = tu.getDeclarations(comp);
assertEquals( decls.length, 2 );
assertSame( decls[0], col.getName(1) );
assertSame( decls[1], col.getName(2) );
}
public void testBug86470_4() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" int x; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("namespace B { \n"); //$NON-NLS-1$
buffer.append(" struct x {}; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" using A::x; \n"); //$NON-NLS-1$
buffer.append(" using B::x; \n"); //$NON-NLS-1$
buffer.append(" x = 1; \n"); //$NON-NLS-1$
buffer.append(" struct x xx; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.getVisitor().visitTranslationUnit(col);
IBinding ref1 = col.getName(11).resolveBinding();
IBinding ref2 = col.getName(12).resolveBinding();
ICPPClassType x_struct = (ICPPClassType) col.getName(3).resolveBinding();
IVariable x_var = (IVariable) col.getName(1).resolveBinding();
assertSame( x_struct, ref2 );
assertSame( x_var, ref1 );
}
public void testBug86470_5() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" void f( int ); \n"); //$NON-NLS-1$
buffer.append(" void f( double ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("void g() { \n"); //$NON-NLS-1$
buffer.append(" void f( char ); \n"); //$NON-NLS-1$
buffer.append(" using A::f; \n"); //$NON-NLS-1$
buffer.append(" f( 3.5 ); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector();
tu.getVisitor().visitTranslationUnit(col);
IFunction f = (IFunction) col.getName(3).resolveBinding();
assertInstances( col, f, 2 );
}
}

View file

@ -160,4 +160,11 @@ public class ArrayUtil {
}
return array;
}
public static boolean contains( Object [] array, Object obj ){
if( array == null ) return false;
for( int i = 0; i < array.length; i++ )
if( array[i] == obj ) return true;
return false;
}
}

View file

@ -161,9 +161,17 @@ public class CPPSemantics {
public boolean forUsingDeclaration(){
if( astName == null ) return false;
IASTNode p1 = astName.getParent();
IASTNode p2 = p1.getParent();
return ( ( p1 instanceof ICPPASTUsingDeclaration ) ||
( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTUsingDeclaration ) );
if( p1 instanceof ICPPASTUsingDeclaration )
return true;
if( p1 instanceof ICPPASTQualifiedName ){
IASTNode p2 = p1.getParent();
if( p2 instanceof ICPPASTUsingDeclaration ){
IASTName [] ns = ((ICPPASTQualifiedName) p1 ).getNames();
return (ns[ ns.length - 1 ] == astName);
}
}
return false;
}
public boolean forDefinition(){
if( astName == null ) return false;
@ -445,7 +453,7 @@ public class CPPSemantics {
if( binding instanceof ICPPCompositeBinding ){
IBinding [] bs = ((ICPPCompositeBinding)binding).getBindings();
for( int i = 0; i < bs.length; i++ ) {
scope.addBinding( binding );
scope.addBinding( bs[i] );
}
} else {
scope.addBinding( binding );
@ -1200,6 +1208,7 @@ public class CPPSemantics {
IBinding [] bindings = ((ICPPCompositeBinding) temp).getBindings();
//data.foundItems = ArrayUtil.addAll( Object.class, data.foundItems, bindings );
mergeResults( data, bindings, false );
items = (Object[]) data.foundItems;
continue;
} else if( temp instanceof IType ){
if( type == null ){
@ -1217,19 +1226,36 @@ public class CPPSemantics {
}
}
}
if( data.forUsingDeclaration() ){
IBinding [] bindings = null;
if( obj != null ){
if( fns != null ) return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
if( type == null ) return obj;
bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, obj );
bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, type );
} else {
if( fns == null ) return type;
bindings = (IBinding[]) ArrayUtil.addAll( IBinding.class, bindings, fns );
bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, type );
}
bindings = (IBinding[]) ArrayUtil.trim( IBinding.class, bindings );
if( bindings.length == 1 ) return bindings[0];
ICPPCompositeBinding composite = new CPPCompositeBinding( bindings );
return composite;
}
if( type != null ) {
if( data.typesOnly() || (obj == null && fns == null) )
return type;
IScope typeScope = type.getScope();
if( obj != null && obj.getScope() != typeScope ){
return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
} else if( fns != null ){
for( int i = 0; i < fns.length && fns[i] != null; i++ ){
if( ((IBinding)fns[i]).getScope() != typeScope )
return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
}
}
// IScope typeScope = type.getScope();
// if( obj != null && obj.getScope() != typeScope ){
// return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
// } else if( fns != null ){
// for( int i = 0; i < fns.length && fns[i] != null; i++ ){
// if( ((IBinding)fns[i]).getScope() != typeScope )
// return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
// }
// }
}
if( fns != null){
if( obj != null )

View file

@ -121,6 +121,7 @@ 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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding;
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;
@ -783,6 +784,7 @@ public class CPPVisitor implements ICPPASTVisitor {
private static final int KIND_OBJ_FN = 2;
private static final int KIND_TYPE = 3;
private static final int KIND_NAMESPACE = 4;
private static final int KIND_COMPOSITE = 5;
public CollectDeclarationsAction( IBinding binding ){
@ -800,7 +802,10 @@ public class CPPVisitor implements ICPPASTVisitor {
}
else if( binding instanceof ICPPNamespace) {
kind = KIND_NAMESPACE;
} else
}
else if( binding instanceof ICPPCompositeBinding )
kind = KIND_COMPOSITE;
else
kind = KIND_OBJ_FN;
}
@ -817,6 +822,7 @@ public class CPPVisitor implements ICPPASTVisitor {
break;
return PROCESS_CONTINUE;
case KIND_TYPE:
case KIND_COMPOSITE:
if( prop == IASTCompositeTypeSpecifier.TYPE_NAME ||
prop == IASTEnumerationSpecifier.ENUMERATION_NAME )
{
@ -837,8 +843,8 @@ public class CPPVisitor implements ICPPASTVisitor {
}
}
return PROCESS_CONTINUE;
if( kind == KIND_TYPE )
return PROCESS_CONTINUE;
case KIND_OBJ_FN:
if( prop == IASTDeclarator.DECLARATOR_NAME ||
prop == IASTEnumerationSpecifier.IASTEnumerator.ENUMERATOR_NAME )
@ -855,14 +861,28 @@ public class CPPVisitor implements ICPPASTVisitor {
return PROCESS_CONTINUE;
}
if( binding != null && name.resolveBinding() == binding )
if( binding != null )
{
if( decls.length == idx ){
IASTName [] temp = new IASTName[ decls.length * 2 ];
System.arraycopy( decls, 0, temp, 0, decls.length );
decls = temp;
}
decls[idx++] = name;
IBinding candidate = name.resolveBinding();
boolean found = false;
if( binding instanceof ICPPCompositeBinding ){
try {
found = ArrayUtil.contains( ((ICPPCompositeBinding)binding).getBindings(), candidate );
} catch ( DOMException e ) {
}
} else {
found = ( binding == candidate );
}
if( found ){
if( decls.length == idx ){
IASTName [] temp = new IASTName[ decls.length * 2 ];
System.arraycopy( decls, 0, temp, 0, decls.length );
decls = temp;
}
decls[idx++] = name;
}
}
return PROCESS_CONTINUE;
}
@ -887,6 +907,7 @@ public class CPPVisitor implements ICPPASTVisitor {
private static final int KIND_OBJ_FN = 2;
private static final int KIND_TYPE = 3;
private static final int KIND_NAMESPACE = 4;
private static final int KIND_COMPOSITE = 5;
public CollectReferencesAction( IBinding binding ){
@ -904,7 +925,9 @@ public class CPPVisitor implements ICPPASTVisitor {
}
else if( binding instanceof ICPPNamespace) {
kind = KIND_NAMESPACE;
} else
} else if( binding instanceof ICPPCompositeBinding )
kind = KIND_COMPOSITE;
else
kind = KIND_OBJ_FN;
}
@ -924,6 +947,7 @@ public class CPPVisitor implements ICPPASTVisitor {
break;
return PROCESS_CONTINUE;
case KIND_TYPE:
case KIND_COMPOSITE:
if( prop == IASTNamedTypeSpecifier.NAME ||
prop == ICPPASTPointerToMember.NAME ||
prop == ICPPASTTypenameExpression.TYPENAME ||
@ -942,7 +966,8 @@ public class CPPVisitor implements ICPPASTVisitor {
break;
}
}
return PROCESS_CONTINUE;
if( kind == KIND_TYPE )
return PROCESS_CONTINUE;
case KIND_OBJ_FN:
if( prop == IASTIdExpression.ID_NAME ||
prop == IASTFieldReference.FIELD_NAME ||
@ -966,13 +991,46 @@ public class CPPVisitor implements ICPPASTVisitor {
return PROCESS_CONTINUE;
}
if( binding != null && name.resolveBinding() == binding ){
if( refs.length == idx ){
IASTName [] temp = new IASTName[ refs.length * 2 ];
System.arraycopy( refs, 0, temp, 0, refs.length );
refs = temp;
}
refs[idx++] = name;
if( binding != null ){
IBinding potential = name.resolveBinding();
IBinding [] bs = null;
IBinding candidate = null;
int n = -1;
if( potential instanceof ICPPCompositeBinding ){
try {
bs = ((ICPPCompositeBinding)potential).getBindings();
} catch ( DOMException e ) {
return PROCESS_CONTINUE;
}
candidate = bs[ ++n ];
} else {
candidate = potential;
}
while( candidate != null ) {
boolean found = false;
if( binding instanceof ICPPCompositeBinding ){
try {
found = ArrayUtil.contains( ((ICPPCompositeBinding)binding).getBindings(), candidate );
} catch ( DOMException e ) {
}
} else {
found = ( binding == candidate );
}
if( found ){
if( refs.length == idx ){
IASTName [] temp = new IASTName[ refs.length * 2 ];
System.arraycopy( refs, 0, temp, 0, refs.length );
refs = temp;
}
refs[idx++] = name;
break;
}
if( n > -1 && ++n < bs.length ){
candidate = bs[n];
} else break;
}
}
return PROCESS_CONTINUE;
}