From a0a40cf21f8d72671577ea022bc3f23f534e3fae Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 19 Jun 2008 12:36:21 +0000 Subject: [PATCH] Binding resolution of parameters for complex functions, bug 214482. --- .../cdt/core/parser/tests/ast2/AST2Tests.java | 15 +++++++++-- .../internal/core/dom/parser/c/CFunction.java | 8 +++--- .../core/dom/parser/cpp/CPPClassScope.java | 3 ++- .../core/dom/parser/cpp/CPPFunction.java | 8 +++--- .../dom/parser/cpp/CPPFunctionTemplate.java | 12 ++++----- .../dom/parser/cpp/CPPImplicitFunction.java | 9 ++++--- .../dom/parser/cpp/CPPTemplateDefinition.java | 10 +------- .../cpp/CPPTemplateTemplateParameter.java | 9 +------ .../parser/cpp/semantics/CPPTemplates.java | 2 +- .../dom/parser/cpp/semantics/CPPVisitor.java | 25 ++++++++----------- 10 files changed, 48 insertions(+), 53 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 88b9597d4aa..c94b11b1422 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -4917,12 +4917,12 @@ public class AST2Tests extends AST2BaseTest { assertEquals(2, tu.getDeclarationsInAST(binding).length); sdef= getDeclaration(tu, 6); - binding= sdef.getDeclarators()[0].getName().resolveBinding(); + binding= sdef.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding(); assertInstance(binding, IFunction.class); assertEquals(2, tu.getDeclarationsInAST(binding).length); sdef= getDeclaration(tu, 7); - binding= sdef.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding(); + binding= sdef.getDeclarators()[0].getNestedDeclarator().getNestedDeclarator().getName().resolveBinding(); assertInstance(binding, IFunction.class); assertEquals(2, tu.getDeclarationsInAST(binding).length); } @@ -4946,4 +4946,15 @@ public class AST2Tests extends AST2BaseTest { assertNotSame(v2, v3); } } + + // int foo(int (*ptr) (int, int)); + public void testComplexParameterBinding_Bug214482() throws Exception { + final String comment= getAboveComment(); + final boolean[] isCpps= {false, true}; + for (boolean isCpp : isCpps) { + BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp); + IParameter p= ba.assertNonProblem("ptr", 3, IParameter.class); + assertEquals("ptr", p.getName()); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index 43df9be9557..0615f83530e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -135,7 +135,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu if( size > 0 ){ for( int i = 0; i < size; i++ ){ IASTParameterDeclaration p = params[i]; - result[i] = (IParameter) p.getDeclarator().getName().resolveBinding(); + result[i] = (IParameter) CVisitor.findInnermostDeclarator(p.getDeclarator()).getName().resolveBinding(); } } } else if (dtor instanceof ICASTKnRFunctionDeclarator) { @@ -271,7 +271,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu IASTParameterDeclaration [] parameters = ((IASTStandardFunctionDeclarator)definition).getParameters(); if( parameters.length > idx ) { temp = parameters[idx]; - temp.getDeclarator().getName().setBinding( binding ); + CVisitor.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); } } else if( definition instanceof ICASTKnRFunctionDeclarator ){ fKnRDtor = (ICASTKnRFunctionDeclarator) definition; @@ -290,7 +290,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu for( int j = 0; j < declarators.length && declarators[j] != null; j++ ){ if( declarators[j].getParameters().length > idx ){ temp = declarators[j].getParameters()[idx]; - temp.getDeclarator().getName().setBinding( binding ); + CVisitor.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); } } } @@ -306,7 +306,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu if(params.length < nps.length ) return; for( int i = 0; i < nps.length; i++ ){ - IASTName name = nps[i].getDeclarator().getName(); + IASTName name = CVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); name.setBinding( params[i] ); if( params[i] instanceof CParameter ) ((CParameter)params[i]).addDeclaration( name ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index d99ecd8a58b..307d8354631 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -517,9 +517,10 @@ class ImplicitsAnalysis { */ private static boolean paramHasTypeReferenceToTheAssociatedClassType(IASTParameterDeclaration dec, String name) { boolean result= false; - IASTDeclarator pdtor= dec.getDeclarator(); + IASTDeclarator pdtor= CPPVisitor.findTypeRelevantDeclarator(dec.getDeclarator()); if (pdtor.getPointerOperators().length == 1 && pdtor.getPointerOperators()[0] instanceof ICPPASTReferenceOperator && + pdtor.getParent() == dec && dec.getDeclSpecifier() instanceof ICPPASTNamedTypeSpecifier) { ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) dec.getDeclSpecifier(); if (name == null || name.equals(nts.getName().getRawSignature())) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index c9159156ac1..7b2d17cf7f1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -220,7 +220,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt if (size > 0) { for (int i = 0; i < size; i++) { IASTParameterDeclaration p = params[i]; - final IASTName name = p.getDeclarator().getName(); + final IASTName name = CPPVisitor.findInnermostDeclarator(p.getDeclarator()).getName(); final IBinding binding= name.resolveBinding(); if (binding instanceof IParameter) { result[i]= (IParameter) binding; @@ -322,7 +322,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt IASTParameterDeclaration[] paramDecls = definition.getParameters(); if (paramDecls.length > i) { // This will be less than i if we have a void parameter temp = paramDecls[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); if (n != name) { n.setBinding(binding); ((CPPParameter)binding).addDeclaration(n); @@ -334,7 +334,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt IASTParameterDeclaration[] paramDecls = declarations[j].getParameters(); if (paramDecls.length > i) { temp = paramDecls[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); if (n != name) { n.setBinding(binding); ((CPPParameter)binding).addDeclaration(n); @@ -351,7 +351,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt IASTParameterDeclaration[] nps = fdtor.getParameters(); CPPParameter temp = null; for (int i = 0; i < ops.length; i++) { - temp = (CPPParameter) ops[i].getDeclarator().getName().getBinding(); + temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); if (temp != null && nps.length > i) { //length could be different, ie 0 or 1 with void IASTDeclarator dtor = nps[i].getDeclarator(); while (dtor.getNestedDeclarator() != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index bc943adfd1f..d8a48547b38 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -128,9 +128,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu IASTParameterDeclaration [] nps = ((ICPPASTFunctionDeclarator)paramName.getParent()).getParameters(); CPPParameter temp = null; for( int i = 0; i < nps.length; i++ ){ - temp = (CPPParameter) ops[i].getDeclarator().getName().getBinding(); + temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); if( temp != null ){ - IASTName name = nps[i].getDeclarator().getName(); + IASTName name = CPPVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); name.setBinding( temp ); temp.addDeclaration( name ); } @@ -148,7 +148,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu if( size > 0 ){ for( int i = 0; i < size; i++ ){ IASTParameterDeclaration p = params[i]; - final IASTName pname = p.getDeclarator().getName(); + final IASTName pname = CPPVisitor.findInnermostDeclarator(p.getDeclarator()).getName(); final IBinding binding= pname.resolveBinding(); if (binding instanceof IParameter) { result[i]= (IParameter) binding; @@ -212,7 +212,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu public IBinding resolveParameter(IASTParameterDeclaration param) { - IASTName name = param.getDeclarator().getName(); + IASTName name = CPPVisitor.findInnermostDeclarator(param.getDeclarator()).getName(); IBinding binding = name.getBinding(); if( binding != null ) return binding; @@ -232,7 +232,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition); if (fdecl != null) { temp = fdecl.getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); if( n != name ) { n.setBinding( binding ); ((CPPParameter)binding).addDeclaration( n ); @@ -244,7 +244,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]); if (fdecl != null) { temp = fdecl.getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); if( n != name ) { n.setBinding( binding ); ((CPPParameter)binding).addDeclaration( n ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java index 552e14dd9b4..2be423bb758 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; /** * The CPPImplicitFunction is used to represent implicit functions that exist on the translation @@ -84,7 +85,7 @@ public class CPPImplicitFunction extends CPPFunction { @Override public IBinding resolveParameter( IASTParameterDeclaration param ){ - IASTName aName = param.getDeclarator().getName(); + IASTName aName = CPPVisitor.findInnermostDeclarator(param.getDeclarator()).getName(); IParameter binding = (IParameter) aName.getBinding(); if( binding != null ) return binding; @@ -103,14 +104,14 @@ public class CPPImplicitFunction extends CPPFunction { IASTParameterDeclaration temp = null; if( definition != null ){ temp = definition.getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); n.setBinding( binding ); ((CPPParameter)binding).addDeclaration( n ); } if( declarations != null ){ for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){ temp = declarations[j].getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); + IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); n.setBinding( binding ); ((CPPParameter)binding).addDeclaration( n ); } @@ -126,7 +127,7 @@ public class CPPImplicitFunction extends CPPFunction { return; for( int i = 0; i < nps.length; i++ ){ - IASTName aName = nps[i].getDeclarator().getName(); + IASTName aName = CPPVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); aName.setBinding( parms[i] ); if( parms[i] instanceof ICPPInternalBinding ) ((ICPPInternalBinding)parms[i]).addDeclaration( aName ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 0b21d71dd5e..73f538b8793 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -32,7 +32,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; 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.ICPPASTTemplatedTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -287,14 +286,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC ICPPTemplateParameter p = null; ICPPTemplateParameter[] result = null; for (ICPPASTTemplateParameter param : params) { - if (param instanceof ICPPASTSimpleTypeTemplateParameter) { - p = (ICPPTemplateParameter) ((ICPPASTSimpleTypeTemplateParameter) param).getName().resolveBinding(); - } else if (param instanceof ICPPASTParameterDeclaration) { - p = (ICPPTemplateParameter) ((ICPPASTParameterDeclaration) param).getDeclarator().getName().resolveBinding(); - } else if (param instanceof ICPPASTTemplatedTypeTemplateParameter) { - p = (ICPPTemplateParameter) ((ICPPASTTemplatedTypeTemplateParameter) param).getName().resolveBinding(); - } - + p= (ICPPTemplateParameter) CPPTemplates.getTemplateParameterName(param).resolveBinding(); if (p != null) { result = (ICPPTemplateParameter[]) ArrayUtil.append(ICPPTemplateParameter.class, result, p); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index 94fd6e79658..b403bf159e4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -75,14 +75,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement ICPPTemplateParameter p = null; ICPPTemplateParameter[] result = null; for (ICPPASTTemplateParameter param : params) { - if (param instanceof ICPPASTSimpleTypeTemplateParameter) { - p = (ICPPTemplateParameter) ((ICPPASTSimpleTypeTemplateParameter)param).getName().resolveBinding(); - } else if (param instanceof ICPPASTParameterDeclaration) { - p = (ICPPTemplateParameter) ((ICPPASTParameterDeclaration)param).getDeclarator().getName().resolveBinding(); - } else if (param instanceof ICPPASTTemplatedTypeTemplateParameter) { - p = (ICPPTemplateParameter) ((ICPPASTTemplatedTypeTemplateParameter)param).getName().resolveBinding(); - } - + p= (ICPPTemplateParameter) CPPTemplates.getTemplateParameterName(param).resolveBinding(); if (p != null) { result = (ICPPTemplateParameter[]) ArrayUtil.append(ICPPTemplateParameter.class, result, p); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 75316103e5c..9f6f82da42c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -136,7 +136,7 @@ public class CPPTemplates { else if (param instanceof ICPPASTTemplatedTypeTemplateParameter) return ((ICPPASTTemplatedTypeTemplateParameter) param).getName(); else if (param instanceof ICPPASTParameterDeclaration) - return ((ICPPASTParameterDeclaration) param).getDeclarator().getName(); + return CPPVisitor.findInnermostDeclarator(((ICPPASTParameterDeclaration) param).getDeclarator()).getName(); return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 13219504580..9338023e7cc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -529,6 +529,12 @@ public class CPPVisitor { name= ((ICPPASTQualifiedName)name).getLastName(); } + // in case the binding was created starting from another name within the declarator. + IBinding candidate= name.getBinding(); + if (candidate != null) { + return candidate; + } + ASTNodeProperty prop = parent.getPropertyInParent(); if (parent instanceof IASTTypeId) { return CPPSemantics.resolveBinding(name); @@ -574,9 +580,11 @@ public class CPPVisitor { parent = param.getParent(); if (parent instanceof IASTStandardFunctionDeclarator) { IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent(); - if (hasNestedPointerOperator(fdtor)) - return null; - IBinding temp = fdtor.getName().resolveBinding(); + // if the fdtor does not declare a function we don't create a binding for the parameter. + if (findOutermostDeclarator(fdtor).getParent() instanceof IASTDeclaration == false || + findTypeRelevantDeclarator(fdtor) != fdtor) + return null; + IBinding temp = findInnermostDeclarator(fdtor).getName().resolveBinding(); if (temp instanceof ICPPInternalFunction) { binding = ((ICPPInternalFunction) temp).resolveParameter(param); } else if (temp instanceof IProblemBinding) { @@ -692,17 +700,6 @@ public class CPPVisitor { return binding; } - private static boolean hasNestedPointerOperator(IASTDeclarator decl) { - decl= decl.getNestedDeclarator(); - while (decl != null) { - if (decl.getPointerOperators().length > 0) { - return true; - } - decl= decl.getNestedDeclarator(); - } - return false; - } - public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) { if (containingScope == null || !(containingScope instanceof ICPPClassScope)) return false;