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 d092f6dfb71..c4137094d44 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 @@ -7028,4 +7028,20 @@ public class AST2Tests extends AST2BaseTest { f= bh.assertNonProblem("f2", 2); assertEquals("const int *", ASTTypeUtil.getType(f.getParameters()[0].getType())); } + + // typedef int f(); + // f ff; + // int ff() { return 0;} + public void testFunctionDeclViaTypedef_86495() throws Exception { + final String code = getAboveComment(); +// for(ParserLanguage lang : ParserLanguage.values()) { +// IASTTranslationUnit tu = parseAndCheckBindings(code, lang); + IASTTranslationUnit tu = parseAndCheckBindings(code, ParserLanguage.C); + IASTSimpleDeclaration decl= getDeclaration(tu, 1); + IASTFunctionDefinition def= getDeclaration(tu, 2); + IBinding ffDecl= decl.getDeclarators()[0].getName().resolveBinding(); + IBinding ffDef= def.getDeclarator().getName().resolveBinding(); + assertSame(ffDecl, ffDef); +// } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java index 88cd9b604b0..9977fb6f5ac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/ArrayUtil.java @@ -17,7 +17,7 @@ package org.eclipse.cdt.core.parser.util; import java.lang.reflect.Array; /** - * @noextend This interface is not intended to be extended by clients. + * @noextend This class is not intended to be subclassed by clients. */ public abstract class ArrayUtil { private static final int DEFAULT_LENGTH = 2; 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 f9e9d0aa026..2c6e4819084 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 @@ -42,7 +42,7 @@ import org.eclipse.core.runtime.PlatformObject; * Represents a function. */ public class CFunction extends PlatformObject implements IFunction, ICInternalFunction { - private IASTStandardFunctionDeclarator [] declarators = null; + private IASTDeclarator[] declarators = null; private IASTFunctionDeclarator definition; private static final int FULLY_RESOLVED = 1; @@ -51,52 +51,40 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu protected IFunctionType type = null; - public CFunction( IASTFunctionDeclarator declarator ){ - if( declarator != null ) { - if( declarator.getParent() instanceof IASTFunctionDefinition || declarator instanceof ICASTKnRFunctionDeclarator ) - definition = declarator; - else { - declarators = new IASTStandardFunctionDeclarator [] { (IASTStandardFunctionDeclarator) declarator }; - } + public CFunction(IASTDeclarator declarator) { + storeDeclarator(declarator); + } + + private void storeDeclarator(IASTDeclarator declarator) { + if (declarator != null) { + if (declarator instanceof ICASTKnRFunctionDeclarator) { + definition = (IASTFunctionDeclarator) declarator; + } else if (declarator instanceof IASTFunctionDeclarator + && ASTQueries.findOutermostDeclarator(declarator).getParent() instanceof IASTFunctionDefinition) { + definition = (IASTFunctionDeclarator) declarator; + } else { + declarators = (IASTDeclarator[]) ArrayUtil.append(IASTDeclarator.class, declarators, declarator); + } } } - public IASTNode getPhysicalNode(){ - if( definition != null ) - return definition; - else if( declarators != null && declarators.length > 0 ) - return declarators[0]; - return null; - } - public void addDeclarator( IASTFunctionDeclarator fnDeclarator ){ - if (!fnDeclarator.isActive()) - return; - - if( fnDeclarator.getParent() instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator ) { - if (definition == fnDeclarator) { - // recursion? - return; - } - updateParameterBindings( fnDeclarator ); - definition = fnDeclarator; - return; - } - updateParameterBindings( fnDeclarator ); - if( declarators == null ){ - declarators = new IASTStandardFunctionDeclarator[] { (IASTStandardFunctionDeclarator) fnDeclarator }; + public IASTDeclarator getPhysicalNode() { + if (definition != null) + return definition; + else if (declarators != null && declarators.length > 0) + return declarators[0]; + return null; + } + + public void addDeclarator(IASTDeclarator fnDeclarator) { + if (!fnDeclarator.isActive()) return; + + if (fnDeclarator instanceof IASTFunctionDeclarator) { + updateParameterBindings((IASTFunctionDeclarator) fnDeclarator); } - for( int i = 0; i < declarators.length; i++ ){ - if( declarators[i] == null ){ - declarators[i] = (IASTStandardFunctionDeclarator) fnDeclarator; - return; - } - } - IASTStandardFunctionDeclarator tmp [] = new IASTStandardFunctionDeclarator [ declarators.length * 2 ]; - System.arraycopy( declarators, 0, tmp, 0, declarators.length ); - tmp[ declarators.length ] = (IASTStandardFunctionDeclarator) fnDeclarator; - declarators = tmp; - } + storeDeclarator(fnDeclarator); + } protected IASTTranslationUnit getTranslationUnit() { if( definition != null ) @@ -113,7 +101,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu if( tu != null ){ CVisitor.getDeclarations( tu, this ); } - declarators = (IASTStandardFunctionDeclarator[]) ArrayUtil.trim( IASTStandardFunctionDeclarator.class, declarators ); + declarators = (IASTDeclarator[]) ArrayUtil.trim(IASTDeclarator.class, declarators); bits |= FULLY_RESOLVED; bits &= ~RESOLUTION_IN_PROGRESS; } @@ -123,41 +111,53 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() */ public IParameter[] getParameters() { - IParameter [] result = IParameter.EMPTY_PARAMETER_ARRAY; - - IASTFunctionDeclarator dtor = (IASTFunctionDeclarator) getPhysicalNode(); - if( dtor == null && (bits & FULLY_RESOLVED) == 0){ - resolveAllDeclarations(); - dtor = (IASTFunctionDeclarator) getPhysicalNode(); - } - - if (dtor instanceof IASTStandardFunctionDeclarator) { - IASTParameterDeclaration[] params = ((IASTStandardFunctionDeclarator)dtor).getParameters(); - int size = params.length; - result = new IParameter[ size ]; - if( size > 0 ){ - for( int i = 0; i < size; i++ ){ - IASTParameterDeclaration p = params[i]; - result[i] = (IParameter) ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName().resolveBinding(); - } + int j=-1; + int len = declarators != null ? declarators.length : 0; + for (IASTDeclarator dtor = definition; j < len; j++) { + if (j >= 0) { + dtor = declarators[j]; } - } else if (dtor instanceof ICASTKnRFunctionDeclarator) { - IASTName[] names = ((ICASTKnRFunctionDeclarator)dtor).getParameterNames(); - result = new IParameter[ names.length ]; - if( names.length > 0 ){ - // ensures that the List of parameters is created in the same order as the K&R C parameter names - for( int i=0; i 0) { + for (int i = 0; i < size; i++) { + IASTParameterDeclaration p = params[i]; + result[i] = (IParameter) ASTQueries.findInnermostDeclarator(p.getDeclarator()) + .getName().resolveBinding(); + } } + return result; + } + if (dtor instanceof ICASTKnRFunctionDeclarator) { + IASTName[] names = ((ICASTKnRFunctionDeclarator) dtor).getParameterNames(); + IParameter[] result = new IParameter[names.length]; + if (names.length > 0) { + // Ensures that the list of parameters is created in the same order as the K&R C parameter + // names + for (int i = 0; i < names.length; i++) { + IASTDeclarator decl = CVisitor.getKnRParameterDeclarator( + (ICASTKnRFunctionDeclarator) dtor, names[i]); + if (decl != null) { + result[i] = (IParameter) decl.getName().resolveBinding(); + } else { + result[i] = new CParameter.CParameterProblem(names[i], + IProblemBinding.SEMANTIC_KNR_PARAMETER_DECLARATION_NOT_FOUND, names[i] + .toCharArray()); + } + } + } + return result; } } - return result; + if ((bits & (FULLY_RESOLVED | RESOLUTION_IN_PROGRESS)) == 0) { + resolveAllDeclarations(); + return getParameters(); + } + + return IParameter.EMPTY_PARAMETER_ARRAY; } /* (non-Javadoc) @@ -172,22 +172,16 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu } private IASTName getASTName() { - IASTDeclarator dtor = ( definition != null ) ? definition : declarators[0]; - IASTDeclarator nested= dtor.getNestedDeclarator(); - while (nested != null && nested.getPointerOperators().length == 0) { - dtor= nested; - nested= nested.getNestedDeclarator(); - } - return dtor.getName(); + return ASTQueries.findInnermostDeclarator(getPhysicalNode()).getName(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() */ public IScope getScope() { - IASTFunctionDeclarator dtor = (IASTFunctionDeclarator) getPhysicalNode(); - if( dtor != null ) - return CVisitor.getContainingScope( dtor.getParent() ); + IASTDeclarator dtor = getPhysicalNode(); + if (dtor != null) + return CVisitor.getContainingScope(ASTQueries.findOutermostDeclarator(dtor).getParent()); return null; } @@ -195,7 +189,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() */ public IScope getFunctionScope() { - if( definition != null ){ + if (definition != null) { IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent(); return def.getScope(); } @@ -205,25 +199,21 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() */ - public IFunctionType getType() { - if( type == null ) { - IASTDeclarator functionDtor = (IASTDeclarator) getPhysicalNode(); - if( functionDtor == null && (bits & FULLY_RESOLVED) == 0){ - resolveAllDeclarations(); - functionDtor = (IASTDeclarator) getPhysicalNode(); - } - if( functionDtor != null ) { - while (functionDtor.getNestedDeclarator() != null) - functionDtor = functionDtor.getNestedDeclarator(); - - IType tempType = CVisitor.createType( functionDtor ); - if (tempType instanceof IFunctionType) - type = (IFunctionType)tempType; - } - } - - return type; - } + public IFunctionType getType() { + if (type == null) { + IASTDeclarator declarator = getPhysicalNode(); + if (declarator == null && (bits & FULLY_RESOLVED) == 0) { + resolveAllDeclarations(); + declarator = getPhysicalNode(); + } + if (declarator != null) { + IType tempType = CVisitor.unwrapTypedefs(CVisitor.createType(declarator)); + if (tempType instanceof IFunctionType) + type = (IFunctionType) tempType; + } + } + return type; + } public IBinding resolveParameter( IASTName paramName ){ if( paramName.getBinding() != null ) @@ -289,12 +279,15 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu } } } - if( declarators != null ){ - for( int j = 0; j < declarators.length && declarators[j] != null; j++ ){ - if( declarators[j].getParameters().length > idx ){ - temp = declarators[j].getParameters()[idx]; - ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); - } + if (declarators != null) { + for (IASTDeclarator dtor : declarators) { + if (dtor instanceof IASTStandardFunctionDeclarator) { + IASTStandardFunctionDeclarator fdtor= (IASTStandardFunctionDeclarator) dtor; + if( fdtor.getParameters().length > idx ){ + temp = fdtor.getParameters()[idx]; + ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); + } + } } } return binding; @@ -437,22 +430,26 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu } - public boolean takesVarArgs() { - if( (bits & FULLY_RESOLVED) == 0 ){ - resolveAllDeclarations(); - } - - if( definition != null ){ - if( definition instanceof IASTStandardFunctionDeclarator ) - return ((IASTStandardFunctionDeclarator)definition).takesVarArgs(); - return false; - } + public boolean takesVarArgs() { + if ((bits & FULLY_RESOLVED) == 0) { + resolveAllDeclarations(); + } - if( declarators != null && declarators.length > 0 ){ - return declarators[0].takesVarArgs(); - } - return false; - } + if (definition != null) { + if (definition instanceof IASTStandardFunctionDeclarator) + return ((IASTStandardFunctionDeclarator) definition).takesVarArgs(); + return false; + } + + if (declarators != null) { + for (IASTDeclarator dtor : declarators) { + if (dtor instanceof IASTStandardFunctionDeclarator) { + return ((IASTStandardFunctionDeclarator) dtor).takesVarArgs(); + } + } + } + return false; + } public void setFullyResolved(boolean resolved) { if( resolved ) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index ae81f8d85b3..c89d88c2067 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -689,7 +689,7 @@ public class CVisitor extends ASTQueries { } if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) { if (binding instanceof ICInternalFunction) - ((ICInternalFunction)binding).addDeclarator((ICASTKnRFunctionDeclarator) declarator); + ((ICInternalFunction)binding).addDeclarator(declarator); else binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD, name.toCharArray()); } else { @@ -708,17 +708,9 @@ public class CVisitor extends ASTQueries { } private static IBinding createBinding(IASTDeclarator declarator) { - IASTNode parent = declarator.getParent(); - while (parent instanceof IASTDeclarator) { - parent = parent.getParent(); - } - - declarator= ASTQueries.findInnermostDeclarator(declarator); + IASTNode parent = ASTQueries.findOutermostDeclarator(declarator).getParent(); + declarator= ASTQueries.findInnermostDeclarator(declarator); IASTDeclarator typeRelevant= ASTQueries.findTypeRelevantDeclarator(declarator); - IASTFunctionDeclarator funcDeclarator= null; - if (typeRelevant instanceof IASTFunctionDeclarator) { - funcDeclarator= (IASTFunctionDeclarator) typeRelevant; - } IScope scope= getContainingScope(parent); ASTNodeProperty prop = parent.getPropertyInParent(); @@ -736,7 +728,8 @@ public class CVisitor extends ASTQueries { binding = (scope != null) ? scope.getBinding(name, false) : null; } catch (DOMException e1) { } - + + boolean isFunction= false; if (parent instanceof IASTParameterDeclaration || parent.getPropertyInParent() == ICASTKnRFunctionDeclarator.FUNCTION_PARAMETER) { IASTDeclarator fdtor = (IASTDeclarator) parent.getParent(); if (ASTQueries.findTypeRelevantDeclarator(fdtor) instanceof IASTFunctionDeclarator) { @@ -750,50 +743,59 @@ public class CVisitor extends ASTQueries { } return binding; } - } else if (funcDeclarator != null) { - if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) { - if (binding instanceof IFunction) { - IFunction function = (IFunction) binding; - if (function instanceof CFunction) { - ((CFunction)function).addDeclarator(funcDeclarator); - } - return function; - } - binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD, name.toCharArray()); - } else if (parent instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) parent).getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) - binding = new CTypedef(name); - else - binding = new CFunction(funcDeclarator); + } else if (parent instanceof IASTFunctionDefinition) { + isFunction= true; } else if (parent instanceof IASTSimpleDeclaration) { IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; if (simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) { binding = new CTypedef(name); } else { - IType t1 = null, t2 = null; - if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) { - if (binding instanceof IParameter) { - return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); - } else if (binding instanceof IVariable) { - t1 = createType(declarator); - try { - t2 = ((IVariable)binding).getType(); - } catch (DOMException e1) { - } - if (t1 != null && t2 != null && ( - t1.isSameType(t2) || isCompatibleArray(t1, t2) != null)) { - if (binding instanceof CVariable) - ((CVariable)binding).addDeclaration(name); - } else { - return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); - } - } - } else if (simpleDecl.getParent() instanceof ICASTCompositeTypeSpecifier) { - binding = new CField(name); - } else { - binding = new CVariable(name); + isFunction= typeRelevant instanceof IASTFunctionDeclarator; + if (!isFunction) { + IType t1 = createType(declarator), t2 = null; + if (CVisitor.unwrapTypedefs(t1) instanceof IFunctionType) { + isFunction= true; + } else { + if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) { + if (binding instanceof IParameter) { + return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); + } else if (binding instanceof IVariable) { + try { + t2 = ((IVariable)binding).getType(); + } catch (DOMException e1) { + } + if (t1 != null && t2 != null && ( + t1.isSameType(t2) || isCompatibleArray(t1, t2) != null)) { + if (binding instanceof CVariable) + ((CVariable)binding).addDeclaration(name); + } else { + return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); + } + } + } else if (simpleDecl.getParent() instanceof ICASTCompositeTypeSpecifier) { + binding = new CField(name); + } else { + binding = new CVariable(name); + } + } } } } + if (isFunction) { + if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) { + if (binding instanceof IFunction) { + IFunction function = (IFunction) binding; + if (function instanceof CFunction) { + ((CFunction)function).addDeclarator(typeRelevant); + } + return function; + } + binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD, name.toCharArray()); + } else { + binding = new CFunction(typeRelevant); + } + + } return binding; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICInternalFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICInternalFunction.java index e9205da4f2d..0dee9aac6c3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICInternalFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICInternalFunction.java @@ -12,19 +12,21 @@ package org.eclipse.cdt.internal.core.dom.parser.c; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; /** * Interface for ast-internal implementations of function bindings. */ public interface ICInternalFunction extends ICInternalBinding { - public void setFullyResolved( boolean resolved ); - - public void addDeclarator( IASTFunctionDeclarator fnDeclarator ); - - /** - * Returns whether there is a static declaration for this function. - * @param resolveAll checks for names that are not yet resolved to this binding. - */ - public boolean isStatic(boolean resolveAll); + public void setFullyResolved(boolean resolved); + + public void addDeclarator(IASTDeclarator fnDeclarator); + + /** + * Returns whether there is a static declaration for this function. + * + * @param resolveAll + * checks for names that are not yet resolved to this binding. + */ + public boolean isStatic(boolean resolveAll); }