1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

using declarations

This commit is contained in:
Andrew Niefer 2004-12-20 18:09:05 +00:00
parent 0d24c79313
commit 1d28de7fde
7 changed files with 306 additions and 122 deletions

View file

@ -738,6 +738,36 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals( ft.getParameterTypes().length, 1 ); assertEquals( ft.getParameterTypes().length, 1 );
} }
public void testUsingDeclaration_1() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("void f(); \n"); //$NON-NLS-1$
buffer.append("namespace A { \n"); //$NON-NLS-1$
buffer.append(" void g(); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("namespace X { \n"); //$NON-NLS-1$
buffer.append(" using ::f; \n"); //$NON-NLS-1$
buffer.append(" using A::g; \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
buffer.append("void h() { \n"); //$NON-NLS-1$
buffer.append(" X::f(); \n"); //$NON-NLS-1$
buffer.append(" X::g(); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector collector = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, collector );
IFunction f = (IFunction) collector.getName(0).resolveBinding();
ICPPNamespace A = (ICPPNamespace) collector.getName(1).resolveBinding();
IFunction g = (IFunction) collector.getName(2).resolveBinding();
ICPPNamespace X = (ICPPNamespace) collector.getName(3).resolveBinding();
assertInstances( collector, f, 5 );
assertInstances( collector, A, 2 );
assertInstances( collector, X, 3 );
assertInstances( collector, g, 5 );
}
public void testFunctionDeclarations() throws Exception { public void testFunctionDeclarations() throws Exception {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
buffer.append("typedef int Int; \n"); //$NON-NLS-1$ buffer.append("typedef int Int; \n"); //$NON-NLS-1$

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* 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 Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 16, 2004
*/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
/**
* @author aniefer
*/
public interface ICPPASTTranslationUnit extends IASTTranslationUnit {
public IBinding resolveBinding();
}

View file

@ -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 Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 16, 2004
*/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding;
/**
* @author aniefer
*/
public interface ICPPCompositeBinding extends IBinding {
IBinding [] getBindings();
}

View file

@ -18,9 +18,10 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation; import org.eclipse.cdt.internal.core.dom.parser.IRequiresLocationInformation;
import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
@ -29,8 +30,9 @@ import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
* @author jcamelon * @author jcamelon
*/ */
public class CPPASTTranslationUnit extends CPPASTNode implements public class CPPASTTranslationUnit extends CPPASTNode implements
IASTTranslationUnit, IRequiresLocationInformation { ICPPASTTranslationUnit, IRequiresLocationInformation {
private IASTDeclaration [] decls = null; private IASTDeclaration [] decls = null;
private ICPPNamespace binding = null;
private ICPPScope scope = null; private ICPPScope scope = null;
private static final int DEFAULT_CHILDREN_LIST_SIZE = 8; private static final int DEFAULT_CHILDREN_LIST_SIZE = 8;
private int currentIndex = 0; private int currentIndex = 0;
@ -168,4 +170,14 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
return selectNodesForLocation( resolver.getTranslationUnitPath(), offset, length ); //$NON-NLS-1$ return selectNodesForLocation( resolver.getTranslationUnitPath(), offset, length ); //$NON-NLS-1$
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit#resolveBinding()
*/
public IBinding resolveBinding() {
if( binding == null )
binding = new CPPNamespace( this );
return binding;
}
} }

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* 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 Corporation - initial API and implementation
*******************************************************************************/
/*
* Created on Dec 16, 2004
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding;
/**
* @author aniefer
*/
public class CPPCompositeBinding implements ICPPCompositeBinding {
IBinding [] bindings = null;
public CPPCompositeBinding( List bindingList ){
bindings = new IBinding[ bindingList.size() ];
bindingList.toArray( bindings );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return bindings[0].getName();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return bindings[0].getNameCharArray();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return bindings[0].getScope();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding#getBindings()
*/
public IBinding[] getBindings() {
return bindings;
}
}

View file

@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
@ -23,13 +24,24 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
* @author aniefer * @author aniefer
*/ */
public class CPPNamespace implements ICPPNamespace { public class CPPNamespace implements ICPPNamespace {
ICPPASTNamespaceDefinition [] namespaceDefinitions = null; private static final char[] EMPTY_CHAR_ARRAY = { };
ICPPASTNamespaceDefinition [] namespaceDefinitions = null;
ICPPASTTranslationUnit tu = null;
public CPPNamespace( ICPPASTNamespaceDefinition nsDef ){ public CPPNamespace( ICPPASTNamespaceDefinition nsDef ){
namespaceDefinitions = new ICPPASTNamespaceDefinition[] { nsDef }; namespaceDefinitions = new ICPPASTNamespaceDefinition[] { nsDef };
} }
/**
* @param unit
*/
public CPPNamespace(CPPASTTranslationUnit unit) {
tu = unit;
}
public void addDefinition( ICPPASTNamespaceDefinition nsDef ){ public void addDefinition( ICPPASTNamespaceDefinition nsDef ){
if( namespaceDefinitions == null )
return;
for( int i = 0; i < namespaceDefinitions.length; i++ ){ for( int i = 0; i < namespaceDefinitions.length; i++ ){
if( namespaceDefinitions[i] == null ){ if( namespaceDefinitions[i] == null ){
namespaceDefinitions[i] = nsDef; namespaceDefinitions[i] = nsDef;
@ -45,35 +57,36 @@ public class CPPNamespace implements ICPPNamespace {
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace#getNamespaceScope() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace#getNamespaceScope()
*/ */
public ICPPNamespaceScope getNamespaceScope() { public ICPPNamespaceScope getNamespaceScope() {
return (ICPPNamespaceScope) namespaceDefinitions[0].getScope();
return (ICPPNamespaceScope) ( tu != null ? tu.getScope() : namespaceDefinitions[0].getScope() );
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName() * @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/ */
public String getName() { public String getName() {
return namespaceDefinitions[0].getName().toString(); return tu != null ? null : namespaceDefinitions[0].getName().toString(); //$NON-NLS-1$
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/ */
public char[] getNameCharArray() { public char[] getNameCharArray() {
return namespaceDefinitions[0].getName().toCharArray(); return tu != null ? EMPTY_CHAR_ARRAY : namespaceDefinitions[0].getName().toCharArray();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/ */
public IScope getScope() { public IScope getScope() {
return CPPVisitor.getContainingScope( namespaceDefinitions[0] ); return tu != null ? null : CPPVisitor.getContainingScope( namespaceDefinitions[0] );
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/ */
public IASTNode getPhysicalNode() { public IASTNode getPhysicalNode() {
return namespaceDefinitions[0]; return ( tu != null ? (IASTNode) tu : namespaceDefinitions[0] );
} }
} }

View file

@ -41,26 +41,28 @@ import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; 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.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
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.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; 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.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; 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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCompositeBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
@ -78,6 +80,7 @@ import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo;
public class CPPSemantics { public class CPPSemantics {
public static final char[] EMPTY_NAME_ARRAY = new char[0]; public static final char[] EMPTY_NAME_ARRAY = new char[0];
public static final IType VOID_TYPE = new CPPBasicType( IBasicType.t_void, 0 );
static protected class LookupData static protected class LookupData
{ {
@ -94,6 +97,7 @@ public class CPPSemantics {
public List foundItems = null; public List foundItems = null;
public Object [] functionParameters; public Object [] functionParameters;
public boolean forUserDefinedConversion; public boolean forUserDefinedConversion;
public boolean forUsingDeclaration;
public LookupData( char[] n ){ public LookupData( char[] n ){
name = n; name = n;
@ -223,8 +227,20 @@ public class CPPSemantics {
} }
} }
static protected IBinding resolveBinding( IASTName name ){ static protected IBinding resolveBinding( IASTName name ){
if( name.toCharArray().length == 0 ) if( name.toCharArray().length == 0 ){
return null; IASTNode node = name.getParent();
if( node instanceof ICPPASTQualifiedName ){
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) node;
if( qname.getNames()[0] == name ){
//translation unit
while( ! (node instanceof ICPPASTTranslationUnit ) ){
node = node.getParent();
}
return ((ICPPASTTranslationUnit) node).resolveBinding();
}
}
return null;
}
//1: get some context info off of the name to figure out what kind of lookup we want //1: get some context info off of the name to figure out what kind of lookup we want
LookupData data = createLookupData( name ); LookupData data = createLookupData( name );
@ -233,15 +249,11 @@ public class CPPSemantics {
lookup( data, name ); lookup( data, name );
//3: resolve ambiguities //3: resolve ambiguities
IASTName found = resolveAmbiguities( data, name ); IBinding binding = resolveAmbiguities( data, name );
if( found != null ) { if( binding != null && data.forDefinition ){
IBinding binding = found.resolveBinding(); addDefinition( binding, name );
if( binding != null && data.forDefinition ){
addDefinition( binding, name );
}
return binding;
} }
return null; return binding;
} }
static private CPPSemantics.LookupData createLookupData( IASTName name ){ static private CPPSemantics.LookupData createLookupData( IASTName name ){
@ -252,6 +264,9 @@ public class CPPSemantics {
parent = parent.getParent(); parent = parent.getParent();
if( parent instanceof IASTDeclarator ){ if( parent instanceof IASTDeclarator ){
data.forDefinition = true; data.forDefinition = true;
if( parent instanceof ICPPASTFunctionDeclarator ){
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
}
} else if( parent instanceof IASTIdExpression ){ } else if( parent instanceof IASTIdExpression ){
parent = parent.getParent(); parent = parent.getParent();
if( parent instanceof IASTFunctionCallExpression ){ if( parent instanceof IASTFunctionCallExpression ){
@ -260,7 +275,11 @@ public class CPPSemantics {
data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); data.functionParameters = ((IASTExpressionList) exp ).getExpressions();
else if( exp != null ) else if( exp != null )
data.functionParameters = new IASTExpression [] { exp }; data.functionParameters = new IASTExpression [] { exp };
else
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
} }
} else if( parent instanceof ICPPASTUsingDeclaration ){
data.forUsingDeclaration = true;
} }
} else if( parent instanceof IASTDeclarator ){ } else if( parent instanceof IASTDeclarator ){
if( parent.getParent() instanceof IASTSimpleDeclaration ) if( parent.getParent() instanceof IASTSimpleDeclaration )
@ -277,9 +296,13 @@ public class CPPSemantics {
data.functionParameters = ((IASTExpressionList) exp ).getExpressions(); data.functionParameters = ((IASTExpressionList) exp ).getExpressions();
else if( exp != null ) else if( exp != null )
data.functionParameters = new IASTExpression [] { exp }; data.functionParameters = new IASTExpression [] { exp };
else
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
} }
} else if( parent instanceof ICPPASTFieldReference ){ } else if( parent instanceof ICPPASTFieldReference ){
data.qualified = true; data.qualified = true;
} else if( parent instanceof ICPPASTUsingDeclaration ){
data.forUsingDeclaration = true;
} }
return data; return data;
} }
@ -646,6 +669,17 @@ public class CPPSemantics {
} }
} }
} }
} else if( declaration instanceof ICPPASTUsingDeclaration ){
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
IASTName name = using.getName();
if( name instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
name = ns[ ns.length - 1 ];
}
if( CharArrayUtils.equals( name.toCharArray(), data.name ) ){
return name;
}
} }
if( data.typesOnly ) if( data.typesOnly )
return null; return null;
@ -702,30 +736,44 @@ public class CPPSemantics {
return (IBinding) bindings.get( 0 ); return (IBinding) bindings.get( 0 );
LookupData data = createLookupData( name ); LookupData data = createLookupData( name );
data.foundItems = bindings;
return resolveAmbiguities( data, name );
}
static private IBinding resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) {
if( data.foundItems == null || data.foundItems.size() == 0 )
return null;
IBinding type = null; IBinding type = null;
IBinding obj = null; IBinding obj = null;
IBinding temp = null;
List fns = null; List fns = null;
for( int i = 0; i < data.foundItems.size(); i++ ){
IBinding b = (IBinding) bindings.get( i );
if( b instanceof IFunction ){ for( int i = 0; i < data.foundItems.size(); i++ ){
IASTName n = (IASTName) data.foundItems.get( i );
temp = n.resolveBinding();
if( temp instanceof ICPPCompositeBinding ){
IBinding [] bindings = ((ICPPCompositeBinding) temp).getBindings();
for( int j = 0; j < bindings.length; j++ )
data.foundItems.add( bindings[j] );
continue;
} else if( temp instanceof IType ){
if( type == null ){
type = temp;
} else {
//TODO
}
} else if( temp instanceof IFunction ){
if( fns == null ) if( fns == null )
fns = new ArrayList(2); fns = new ArrayList(2);
IASTName n = ((IASTFunctionDeclarator) ((IFunction)b).getPhysicalNode() ).getName(); fns.add( temp );
fns.add( n );
} else if( b instanceof IVariable ){
if( obj == null ){
obj = b;
} else {
//TODO
}
} else { } else {
if( type == null ){ if( obj == null )
type = b; obj = temp;
} else { else {
//TODO //TODO
} }
} }
} }
@ -742,65 +790,6 @@ public class CPPSemantics {
} }
} }
} }
if( fns != null){
if( obj != null )
return null; //ambiguous
IASTName n = resolveFunction( data, fns );
return ( n != null ) ? n.resolveBinding() : null;
}
return obj;
}
static private IASTName resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) {
if( data.foundItems == null || data.foundItems.size() == 0 )
return null;
if( data.foundItems.size() == 1 ){
return (IASTName) data.foundItems.get(0);
}
IASTName type = null;
IASTName obj = null;
List fns = null;
for( int i = 0; i < data.foundItems.size(); i++ ){
IASTName n = (IASTName) data.foundItems.get( i );
IASTNode parent = n.getParent();
if( parent instanceof IASTFunctionDeclarator ){
if( fns == null )
fns = new ArrayList(2);
fns.add( n );
} else if( parent instanceof IASTDeclarator ){
if( obj == null ){
obj = n;
} else {
//TODO
}
} else if( parent instanceof ICPPASTElaboratedTypeSpecifier ||
parent instanceof IASTEnumerationSpecifier ||
parent instanceof ICPPASTCompositeTypeSpecifier )
{
if( type == null ){
type = n;
} else {
//TODO
}
}
}
if( type != null ) {
if( obj == null && fns == null )
return type;
IScope typeScope = type.resolveBinding().getScope();
if( obj != null && obj.resolveBinding().getScope() != typeScope ){
return null;//ambiguous
} else if( fns != null ){
for( int i = 0; i < fns.size(); i++ ){
if( ((IASTName)fns.get(i)).resolveBinding().getScope() != typeScope )
return null; //ambiguous
}
}
}
if( fns != null){ if( fns != null){
if( obj != null ) if( obj != null )
return null; //ambiguous return null; //ambiguous
@ -810,33 +799,38 @@ public class CPPSemantics {
return obj; return obj;
} }
static private boolean functionHasParameters( ICPPASTFunctionDeclarator function, ICPPASTParameterDeclaration [] params ){ static private boolean functionHasParameters( ICPPASTFunctionDeclarator function, IASTParameterDeclaration [] params ){
return false; IFunctionType ftype = (IFunctionType) CPPVisitor.createType( function );
if( params.length == 0 ){
return ftype.getParameterTypes().length == 0;
}
IASTNode node = params[0].getParent();
if( node instanceof ICPPASTFunctionDeclarator ){
IFunctionType t2 = (IFunctionType) CPPVisitor.createType( (ICPPASTFunctionDeclarator) node );
return ftype.equals( t2 );
}
return false;
} }
static private void reduceToViable( LookupData data, List functions ){ static private void reduceToViable( LookupData data, List functions ){
Object [] fParams = data.functionParameters; Object [] fParams = data.functionParameters;
int numParameters = ( fParams != null ) ? fParams.length : 0; int numParameters = ( fParams != null ) ? fParams.length : 0;
int num; int num;
//Trim the list down to the set of viable functions //Trim the list down to the set of viable functions
IASTName fName; IFunction fName;
ICPPASTFunctionDeclarator function = null; ICPPASTFunctionDeclarator function = null;
int size = functions.size(); int size = functions.size();
for( int i = 0; i < size; i++ ){ for( int i = 0; i < size; i++ ){
fName = (IASTName) functions.get(i); fName = (IFunction) functions.get(i);
//sanity check function = (ICPPASTFunctionDeclarator) fName.getPhysicalNode();
if( !( fName.getParent() instanceof IASTFunctionDeclarator ) ){
functions.remove( i-- );
size--;
continue;
}
function = (ICPPASTFunctionDeclarator) fName.getParent();
num = function.getParameters().length; num = function.getParameters().length;
//if there are m arguments in the list, all candidate functions having m parameters //if there are m arguments in the list, all candidate functions having m parameters
//are viable //are viable
if( num == numParameters ){ if( num == numParameters ){
if( data.forDefinition && !functionHasParameters( function, (ICPPASTParameterDeclaration[]) data.functionParameters ) ){ if( data.forDefinition && !functionHasParameters( function, (IASTParameterDeclaration[]) data.functionParameters ) ){
functions.remove( i-- ); functions.remove( i-- );
size--; size--;
} }
@ -883,16 +877,29 @@ public class CPPSemantics {
static private IType getSourceParameterType( Object [] params, int idx ){ static private IType getSourceParameterType( Object [] params, int idx ){
if( params instanceof IASTExpression [] ){ if( params instanceof IASTExpression [] ){
IASTExpression [] exps = (IASTExpression[]) params; IASTExpression [] exps = (IASTExpression[]) params;
return CPPVisitor.getExpressionType( exps[ idx ] ); if( idx < exps.length)
} return CPPVisitor.getExpressionType( exps[ idx ] );
return ( idx == 0 ) ? VOID_TYPE : null;
} else if( params instanceof IASTParameterDeclaration[] ){
IASTParameterDeclaration [] decls = (IASTParameterDeclaration[]) params;
if( idx < decls.length)
return CPPVisitor.createType( decls[idx].getDeclarator() );
return ( idx == 0 ) ? VOID_TYPE : null;
} else if( params == null && idx == 0 )
return VOID_TYPE;
return null; return null;
} }
static private IASTName resolveFunction( CPPSemantics.LookupData data, List fns ){ static private IBinding resolveFunction( CPPSemantics.LookupData data, List fns ){
if( data.forUsingDeclaration ){
if( fns.size() == 1 )
return (IBinding) fns.get( 0 );
return new CPPCompositeBinding( fns );
}
//reduce our set of candidate functions to only those who have the right number of parameters //reduce our set of candidate functions to only those who have the right number of parameters
reduceToViable( data, fns ); reduceToViable( data, fns );
IASTName bestFn = null; //the best function IFunction bestFn = null; //the best function
IASTName currFn = null; //the function currently under consideration IFunction currFn = null; //the function currently under consideration
Cost [] bestFnCost = null; //the cost of the best function Cost [] bestFnCost = null; //the cost of the best function
Cost [] currFnCost = null; //the cost for the current function Cost [] currFnCost = null; //the cost for the current function
@ -915,34 +922,39 @@ public class CPPSemantics {
int numFns = fns.size(); int numFns = fns.size();
int numSourceParams = ( data.functionParameters != null ) ? data.functionParameters.length : 0; int numSourceParams = ( data.functionParameters != null ) ? data.functionParameters.length : 0;
if( data.functionParameters != null && numSourceParams == 0 )
numSourceParams = 1;
sourceParameters = data.functionParameters; sourceParameters = data.functionParameters;
for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){ for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){
currFn = (IASTName) fns.get( fnIdx ); currFn = (IFunction) fns.get( fnIdx );
if( bestFn != null ){ if( bestFn != null ){
if( bestFn.resolveBinding() == currFn.resolveBinding() ) if( bestFn == currFn )
continue; continue;
} }
ICPPASTFunctionDeclarator currDtor = (ICPPASTFunctionDeclarator) currFn.getParent(); ICPPASTFunctionDeclarator currDtor = (ICPPASTFunctionDeclarator) currFn.getPhysicalNode();
targetParameters = currDtor.getParameters(); targetParameters = currDtor.getParameters();
int numTargetParams = targetParameters.length; int numTargetParams = ( targetParameters.length == 0 ) ? 1 : targetParameters.length;
if( currFnCost == null ){ if( currFnCost == null ){
currFnCost = new Cost [ numSourceParams ]; currFnCost = new Cost [ (numSourceParams == 0) ? 1 : numSourceParams ];
} }
comparison = 0; comparison = 0;
boolean varArgs = false; boolean varArgs = false;
for( int j = 0; j < numSourceParams; j++ ){ for( int j = 0; j < numSourceParams || j == 0; j++ ){
source = getSourceParameterType( sourceParameters, j ); source = getSourceParameterType( sourceParameters, j );
if( j < numTargetParams ){ if( j < numTargetParams ){
if( targetParameters.length == 0 && j == 0 ){
target = VOID_TYPE;
} else {
IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding(); IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding();
target = param.getType(); target = param.getType();
}
} else } else
varArgs = true; varArgs = true;