mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
address of overloaded functions
This commit is contained in:
parent
2b3b0671c9
commit
47cc24fc13
4 changed files with 374 additions and 34 deletions
|
@ -1795,5 +1795,94 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertEquals( friends.length, 1 );
|
||||
assertSame( friends[0], helper );
|
||||
}
|
||||
|
||||
public void testBug45763_1() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "void f( int ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "void f( char ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "void (*pf) (int) = &f; \n"); //$NON-NLS-1$
|
||||
buffer.append( "void foo() { \n"); //$NON-NLS-1$
|
||||
buffer.append( " pf = &f; \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);
|
||||
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IVariable pf = (IVariable) col.getName(4).resolveBinding();
|
||||
|
||||
assertInstances( col, pf, 2 );
|
||||
assertInstances( col, f1, 3 );
|
||||
assertInstances( col, f2, 1 );
|
||||
}
|
||||
|
||||
public void testBug45763_2() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "void f( char ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "void f( int ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "void g( void (*)( int ) ) {} \n"); //$NON-NLS-1$
|
||||
buffer.append( "void (*pg)( void(*)(int) ); \n"); //$NON-NLS-1$
|
||||
buffer.append( "void foo() { \n"); //$NON-NLS-1$
|
||||
buffer.append( " g( &f ); \n"); //$NON-NLS-1$
|
||||
buffer.append( " (*pg)( &f ); \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);
|
||||
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IFunction g = (IFunction) col.getName(4).resolveBinding();
|
||||
IVariable pg = (IVariable) col.getName(7).resolveBinding();
|
||||
|
||||
assertInstances( col, f1, 1 );
|
||||
assertInstances( col, f2, 3 );
|
||||
assertInstances( col, g, 2 );
|
||||
assertInstances( col, pg, 2 );
|
||||
}
|
||||
|
||||
public void testBug45763_3() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("void f( int ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void f( char ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void (* bar () ) ( int ) { \n"); //$NON-NLS-1$
|
||||
buffer.append(" return &f; \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);
|
||||
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IFunction bar = (IFunction) col.getName(4).resolveBinding();
|
||||
assertNotNull( bar );
|
||||
|
||||
assertInstances( col, f1, 2 );
|
||||
assertInstances( col, f2, 1 );
|
||||
}
|
||||
public void _testBug45763_4() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("void f( int ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void f( char ); \n"); //$NON-NLS-1$
|
||||
buffer.append("void foo () { \n"); //$NON-NLS-1$
|
||||
buffer.append(" ( void (*)(int) ) &f; \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);
|
||||
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IFunction bar = (IFunction) col.getName(4).resolveBinding();
|
||||
assertNotNull( bar );
|
||||
|
||||
assertInstances( col, f1, 2 );
|
||||
assertInstances( col, f2, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
@ -157,10 +158,16 @@ public class CPPFunction implements IFunction, ICPPBinding {
|
|||
public IScope getScope() {
|
||||
ICPPASTDeclSpecifier declSpec = null;
|
||||
if( definition != null ){
|
||||
IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent();
|
||||
IASTNode node = definition.getParent();
|
||||
while( node instanceof IASTDeclarator )
|
||||
node = node.getParent();
|
||||
IASTFunctionDefinition def = (IASTFunctionDefinition) node;
|
||||
declSpec = (ICPPASTDeclSpecifier) def.getDeclSpecifier();
|
||||
} else {
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) declarations[0].getParent();
|
||||
IASTNode node = declarations[0].getParent();
|
||||
while( node instanceof IASTDeclarator )
|
||||
node = node.getParent();
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration)node;
|
||||
declSpec = (ICPPASTDeclSpecifier) decl.getDeclSpecifier();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
|
@ -31,15 +33,18 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||
|
@ -53,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
|||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
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.c.ICASTFieldDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
|
@ -116,6 +122,7 @@ public class CPPSemantics {
|
|||
public Object [] functionParameters;
|
||||
public boolean forUserDefinedConversion;
|
||||
public ProblemBinding problem;
|
||||
public boolean forAssociatedScopes = false;
|
||||
|
||||
public LookupData( IASTName n ){
|
||||
astName = n;
|
||||
|
@ -341,12 +348,13 @@ public class CPPSemantics {
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static protected IBinding resolveBinding( IASTName name ){
|
||||
// if( name instanceof ICPPASTQualifiedName && ((ICPPASTQualifiedName)name).isFullyQualified() )
|
||||
// return ((ICPPASTTranslationUnit)name.getTranslationUnit()).resolveBinding();
|
||||
|
||||
//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, true );
|
||||
|
||||
try {
|
||||
//2: lookup
|
||||
|
@ -422,11 +430,13 @@ public class CPPSemantics {
|
|||
return binding;
|
||||
}
|
||||
|
||||
static private CPPSemantics.LookupData createLookupData( IASTName name ){
|
||||
static private CPPSemantics.LookupData createLookupData( IASTName name, boolean considerAssociatedScopes ){
|
||||
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
|
||||
IASTNode parent = name.getParent();
|
||||
if( parent instanceof ICPPASTQualifiedName ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
} else if( parent instanceof IASTIdExpression ){
|
||||
|
@ -440,20 +450,6 @@ public class CPPSemantics {
|
|||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
}
|
||||
} else if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
} else if( parent instanceof IASTIdExpression ){
|
||||
parent = parent.getParent();
|
||||
if( parent instanceof IASTFunctionCallExpression ){
|
||||
IASTExpression exp = ((IASTFunctionCallExpression)parent).getParameterExpression();
|
||||
if( exp instanceof IASTExpressionList )
|
||||
data.functionParameters = ((IASTExpressionList) exp ).getExpressions();
|
||||
else if( exp != null )
|
||||
data.functionParameters = new IASTExpression [] { exp };
|
||||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
} else if( parent instanceof ICPPASTFieldReference && parent.getParent() instanceof IASTFunctionCallExpression ){
|
||||
IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression();
|
||||
if( exp instanceof IASTExpressionList )
|
||||
|
@ -464,13 +460,19 @@ public class CPPSemantics {
|
|||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
} else if( parent instanceof ICPPASTNamedTypeSpecifier && parent.getParent() instanceof IASTTypeId ){
|
||||
IASTTypeId typeId = (IASTTypeId) parent.getParent();
|
||||
if( typeId.getAbstractDeclarator() instanceof IASTFunctionDeclarator ){
|
||||
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) typeId.getAbstractDeclarator();
|
||||
data.functionParameters = fdtor.getParameters();
|
||||
if( typeId.getParent() instanceof ICPPASTNewExpression ){
|
||||
ICPPASTNewExpression newExp = (ICPPASTNewExpression) typeId.getParent();
|
||||
IASTExpression init = newExp.getNewInitializer();
|
||||
if( init instanceof IASTExpressionList )
|
||||
data.functionParameters = ((IASTExpressionList) init ).getExpressions();
|
||||
else if( init != null )
|
||||
data.functionParameters = new IASTExpression [] { init };
|
||||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
if( !(name.getParent() instanceof ICPPASTQualifiedName) && data.functionCall() ){
|
||||
if( considerAssociatedScopes && !(name.getParent() instanceof ICPPASTQualifiedName) && data.functionCall() ){
|
||||
data.associated = getAssociatedScopes( data );
|
||||
}
|
||||
|
||||
|
@ -1045,7 +1047,7 @@ public class CPPSemantics {
|
|||
else if( bindings.length == 1 )
|
||||
return bindings[ 0 ];
|
||||
|
||||
LookupData data = createLookupData( name );
|
||||
LookupData data = createLookupData( name, false );
|
||||
data.foundItems = bindings;
|
||||
try {
|
||||
return resolveAmbiguities( data, name );
|
||||
|
@ -1246,6 +1248,11 @@ public class CPPSemantics {
|
|||
return fns[ 0 ];
|
||||
return new CPPCompositeBinding( fns );
|
||||
}
|
||||
|
||||
//we don't have any arguments with which to resolve the function
|
||||
if( data.functionParameters == null ){
|
||||
return resolveTargetedFunction( data, fns );
|
||||
}
|
||||
//reduce our set of candidate functions to only those who have the right number of parameters
|
||||
reduceToViable( data, fns );
|
||||
|
||||
|
@ -1402,6 +1409,220 @@ public class CPPSemantics {
|
|||
return bestFn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 13.4-1 A use of an overloaded function without arguments is resolved in certain contexts to a function
|
||||
* @param data
|
||||
* @param fns
|
||||
* @return
|
||||
*/
|
||||
private static IBinding resolveTargetedFunction( LookupData data, IBinding[] fns ) {
|
||||
if( fns.length == 1 )
|
||||
return fns[0];
|
||||
|
||||
if( data.forAssociatedScopes ){
|
||||
return new CPPCompositeBinding( fns );
|
||||
}
|
||||
|
||||
IBinding result = null;
|
||||
|
||||
Object o = getTargetType( data );
|
||||
IType type, types[] = null;
|
||||
int idx = -1;
|
||||
if( o instanceof IType [] ){
|
||||
types = (IType[]) o;
|
||||
type = types[ ++idx ];
|
||||
} else
|
||||
type = (IType) o;
|
||||
|
||||
while( type != null ){
|
||||
type = (type != null) ? getUltimateType( type, false ) : null;
|
||||
if( type == null || !( type instanceof IFunctionType ) )
|
||||
return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
|
||||
|
||||
for( int i = 0; i < fns.length; i++ ){
|
||||
IFunction fn = (IFunction) fns[i];
|
||||
IType ft = null;
|
||||
try {
|
||||
ft = fn.getType();
|
||||
} catch ( DOMException e ) {
|
||||
ft = e.getProblem();
|
||||
}
|
||||
if( type.equals( ft ) ){
|
||||
if( result == null )
|
||||
result = fn;
|
||||
else
|
||||
return new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
|
||||
}
|
||||
}
|
||||
|
||||
if( idx > 0 && ++idx < types.length ){
|
||||
type = types[idx];
|
||||
} else {
|
||||
type = null;
|
||||
}
|
||||
}
|
||||
|
||||
return ( result != null ) ? result : new ProblemBinding( IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name );
|
||||
}
|
||||
|
||||
private static Object getTargetType( LookupData data ){
|
||||
IASTName name = data.astName;
|
||||
|
||||
if( name.getPropertyInParent() == ICPPASTQualifiedName.SEGMENT_NAME )
|
||||
name = (IASTName) name.getParent();
|
||||
|
||||
if( name.getPropertyInParent() != IASTIdExpression.ID_NAME )
|
||||
return null;
|
||||
|
||||
IASTIdExpression idExp = (IASTIdExpression) name.getParent();
|
||||
IASTNode node = idExp.getParent();
|
||||
ASTNodeProperty prop = null;
|
||||
while( node != null ){
|
||||
prop = node.getPropertyInParent();
|
||||
//target is an object or reference being initialized
|
||||
if( prop == IASTInitializerExpression.INITIALIZER_EXPRESSION ){
|
||||
IASTInitializerExpression initExp = (IASTInitializerExpression) node.getParent();
|
||||
IASTDeclarator dtor = (IASTDeclarator) initExp.getParent();
|
||||
return CPPVisitor.createType( dtor );
|
||||
}
|
||||
//target is the left side of an assignment
|
||||
else if( prop == IASTBinaryExpression.OPERAND_TWO &&
|
||||
((IASTBinaryExpression)node.getParent()).getOperator() == IASTBinaryExpression.op_assign )
|
||||
{
|
||||
IASTBinaryExpression binaryExp = (IASTBinaryExpression) node.getParent();
|
||||
IASTExpression exp = binaryExp.getOperand1();
|
||||
return CPPVisitor.getExpressionType( exp );
|
||||
}
|
||||
//target is a parameter of a function
|
||||
else if( prop == IASTFunctionCallExpression.PARAMETERS ||
|
||||
(prop == IASTExpressionList.NESTED_EXPRESSION && node.getParent().getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS ) )
|
||||
{
|
||||
//if this function call refers to an overloaded function, there is more than one possiblity
|
||||
//for the target type
|
||||
IASTFunctionCallExpression fnCall = null;
|
||||
int idx = -1;
|
||||
if( prop == IASTFunctionCallExpression.PARAMETERS ){
|
||||
fnCall = (IASTFunctionCallExpression) node.getParent();
|
||||
idx = 0;
|
||||
} else {
|
||||
IASTExpressionList list = (IASTExpressionList) node.getParent();
|
||||
fnCall = (IASTFunctionCallExpression) list.getParent();
|
||||
IASTExpression [] exps = list.getExpressions();
|
||||
for( int i = 0; i < exps.length; i++ ){
|
||||
if( exps[i] == node ){
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
IFunctionType [] types = getPossibleFunctions( fnCall );
|
||||
if( types == null ) return null;
|
||||
IType [] result = null;
|
||||
for( int i = 0; i < types.length && types[i] != null; i++ ){
|
||||
IType [] pts = null;
|
||||
try {
|
||||
pts = types[i].getParameterTypes();
|
||||
} catch ( DOMException e ) {
|
||||
continue;
|
||||
}
|
||||
if( pts.length > idx )
|
||||
result = (IType[]) ArrayUtil.append( IType.class, result, pts[idx] );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//target is an explicit type conversion
|
||||
// else if( prop == ICPPASTSimpleTypeConstructorExpression.INITIALIZER_VALUE )
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//target is an explicit type conversion
|
||||
else if( prop == IASTCastExpression.OPERAND )
|
||||
{
|
||||
IASTCastExpression cast = (IASTCastExpression) node.getParent();
|
||||
return CPPVisitor.createType( cast.getTypeId().getAbstractDeclarator() );
|
||||
}
|
||||
//target is the return value of a function, operator or conversion
|
||||
else if( prop == IASTReturnStatement.RETURNVALUE )
|
||||
{
|
||||
while( !( node instanceof IASTFunctionDefinition ) ){
|
||||
node = node.getParent();
|
||||
}
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)node).getDeclarator();
|
||||
while( dtor.getNestedDeclarator() != null )
|
||||
dtor = dtor.getNestedDeclarator();
|
||||
IBinding binding = dtor.getName().resolveBinding();
|
||||
if( binding instanceof IFunction ){
|
||||
try {
|
||||
IFunctionType ft = ((IFunction)binding).getType();
|
||||
return ft.getReturnType();
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( prop == IASTUnaryExpression.OPERAND ){
|
||||
IASTUnaryExpression parent = (IASTUnaryExpression) node.getParent();
|
||||
if( parent.getOperator() == IASTUnaryExpression.op_bracketedPrimary ||
|
||||
parent.getOperator() == IASTUnaryExpression.op_amper)
|
||||
{
|
||||
node = parent;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static private IFunctionType [] getPossibleFunctions( IASTFunctionCallExpression call ){
|
||||
IFunctionType [] result = null;
|
||||
|
||||
IASTExpression exp = call.getFunctionNameExpression();
|
||||
if( exp instanceof IASTIdExpression ){
|
||||
IASTIdExpression idExp = (IASTIdExpression) exp;
|
||||
IASTName name = idExp.getName();
|
||||
LookupData data = createLookupData( name, false );
|
||||
try {
|
||||
lookup( data, name );
|
||||
} catch ( DOMException e1 ) {
|
||||
return null;
|
||||
}
|
||||
if( data.foundItems != null && data.foundItems.length > 0 ){
|
||||
IBinding temp = null;
|
||||
for( int i = 0; i < data.foundItems.length; i++ ){
|
||||
Object o = data.foundItems[i];
|
||||
if( o == null ) break;
|
||||
if( o instanceof IASTName )
|
||||
temp = ((IASTName) o).resolveBinding();
|
||||
else if( o instanceof IBinding ){
|
||||
temp = (IBinding) o;
|
||||
if( !declaredBefore( temp, name ) )
|
||||
continue;
|
||||
} else
|
||||
continue;
|
||||
|
||||
try {
|
||||
if( temp instanceof IFunction ){
|
||||
result = (IFunctionType[]) ArrayUtil.append( IFunctionType.class, result, ((IFunction)temp).getType() );
|
||||
} else if( temp instanceof IVariable ){
|
||||
IType type = getUltimateType( ((IVariable) temp).getType(), false );
|
||||
if( type instanceof IFunctionType )
|
||||
result = (IFunctionType[]) ArrayUtil.append( IFunctionType.class, result, type );
|
||||
}
|
||||
} catch( DOMException e ){
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
IType type = CPPVisitor.getExpressionType( exp );
|
||||
type = getUltimateType( type, false );
|
||||
if( type instanceof IFunctionType ){
|
||||
result = new IFunctionType[] { (IFunctionType) type };
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static private Cost checkStandardConversionSequence( IType source, IType target ) throws DOMException {
|
||||
Cost cost = lvalue_to_rvalue( source, target );
|
||||
|
||||
|
|
|
@ -425,6 +425,8 @@ public class CPPVisitor {
|
|||
} else if( parent instanceof IASTParameterDeclaration ){
|
||||
IASTParameterDeclaration param = (IASTParameterDeclaration) parent;
|
||||
IASTStandardFunctionDeclarator fDtor = (IASTStandardFunctionDeclarator) param.getParent();
|
||||
if( fDtor.getParent() instanceof IASTDeclarator || fDtor.getNestedDeclarator() != null )
|
||||
return null;
|
||||
IBinding temp = fDtor.getName().resolveBinding();
|
||||
if( temp instanceof IFunction ){
|
||||
CPPFunction function = (CPPFunction) temp;
|
||||
|
@ -582,12 +584,13 @@ public class CPPVisitor {
|
|||
} else if( parent instanceof IASTFunctionDefinition ){
|
||||
IASTFunctionDeclarator fnDeclarator = ((IASTFunctionDefinition) parent ).getDeclarator();
|
||||
IFunction function = (IFunction) fnDeclarator.getName().resolveBinding();
|
||||
|
||||
if( function != null ){
|
||||
try {
|
||||
scope = function.getScope();
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){
|
||||
while( !(parent instanceof IASTFunctionDefinition) ){
|
||||
|
@ -626,20 +629,33 @@ public class CPPVisitor {
|
|||
}
|
||||
|
||||
static private IBinding resolveBinding( IASTNode node ){
|
||||
IASTName name = null;
|
||||
while( node != null ) {
|
||||
if( node instanceof IASTIdExpression ){
|
||||
return CPPSemantics.resolveBinding( ((IASTIdExpression)node).getName() );
|
||||
name = ((IASTIdExpression) node).getName();
|
||||
break;
|
||||
//return CPPSemantics.resolveBinding( ((IASTIdExpression)node).getName() );
|
||||
} else if( node instanceof ICPPASTFieldReference ){
|
||||
return CPPSemantics.resolveBinding( ((ICPPASTFieldReference)node).getFieldName() );
|
||||
name = ((ICPPASTFieldReference)node).getFieldName();
|
||||
break;
|
||||
} else if( node instanceof IASTFunctionCallExpression ){
|
||||
node = ((IASTFunctionCallExpression)node).getFunctionNameExpression();
|
||||
} else if( node instanceof IASTUnaryExpression ){
|
||||
node = ((IASTUnaryExpression)node).getOperand();
|
||||
} else if( node instanceof IASTBinaryExpression ){
|
||||
node = ((IASTBinaryExpression)node).getOperand2();
|
||||
} else
|
||||
node = null;
|
||||
}
|
||||
if( name != null ){
|
||||
IBinding binding = CPPSemantics.resolveBinding( name );
|
||||
if( name instanceof ICPPASTQualifiedName ){
|
||||
IASTName ns [] = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
((CPPASTName)name).setBinding( binding );
|
||||
return binding;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1684,6 +1700,7 @@ public class CPPVisitor {
|
|||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expression
|
||||
* @return
|
||||
|
@ -1701,6 +1718,12 @@ public class CPPVisitor {
|
|||
}
|
||||
} else if( binding instanceof IProblemBinding ){
|
||||
return (IType) binding;
|
||||
} else if( binding instanceof IFunction ){
|
||||
try {
|
||||
return ((IFunction)binding).getType();
|
||||
} catch ( DOMException e ){
|
||||
return e.getProblem();
|
||||
}
|
||||
}
|
||||
} else if( expression instanceof IASTCastExpression ){
|
||||
IASTTypeId id = ((IASTCastExpression)expression).getTypeId();
|
||||
|
|
Loading…
Add table
Reference in a new issue