diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 8ee7b44be6e..1cde9ac8c76 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -15,6 +15,8 @@ */ package org.eclipse.cdt.core.parser.tests.ast2; +import java.util.Iterator; + import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; @@ -2056,4 +2058,20 @@ public class AST2TemplateTests extends AST2BaseTest { assertInstance(tidSpc, ICPPSpecialization.class); assertInstance(tidSpc, ICPPFunctionTemplate.class); } + + // template const T& (max)(const T& lhs, const T& rhs) { + // return (lhs < rhs ? rhs : lhs); + // } + public void testNestedFuncTemplatedDeclarator_bug190241() throws Exception { + StringBuffer buffer = getContents(1)[0]; + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP, true, true ); + + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + for (Iterator i = col.nameList.iterator(); i.hasNext();) { + IASTName name = (IASTName) i.next(); + assertFalse(name.resolveBinding() instanceof IProblemBinding); + } + } } 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 f8b955781a1..83a6198d480 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ /* * Created on Mar 31, 2005 @@ -29,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -169,12 +169,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu */ public IParameter[] getParameters() { IASTName name = getTemplateName(); - IASTNode parent = name.getParent(); - if( parent instanceof ICPPASTQualifiedName ) - parent = parent.getParent(); - if( parent instanceof ICPPASTFunctionDeclarator ){ - ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent; - IASTParameterDeclaration[] params = dtor.getParameters(); + ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(name); + if (fdecl != null) { + IASTParameterDeclaration[] params = fdecl.getParameters(); int size = params.length; IParameter [] result = new IParameter[ size ]; if( size > 0 ){ @@ -261,25 +258,27 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu binding = new CPPParameter( name ); IASTParameterDeclaration temp = null; if( definition != null ){ - IASTNode node = definition.getParent(); - if( node instanceof ICPPASTQualifiedName ) - node = node.getParent(); - temp = ((ICPPASTFunctionDeclarator)node).getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); - if( n != name ) { - n.setBinding( binding ); - ((CPPParameter)binding).addDeclaration( n ); + ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition); + if (fdecl != null) { + temp = fdecl.getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + if( n != name ) { + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } } } if( declarations != null ){ for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){ - temp = ((ICPPASTFunctionDeclarator)declarations[j].getParent()).getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); - if( n != name ) { - n.setBinding( binding ); - ((CPPParameter)binding).addDeclaration( n ); + ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]); + if (fdecl != null) { + temp = fdecl.getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + if( n != name ) { + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } } - } } return binding; @@ -364,19 +363,33 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu * @see org.eclipse.cdt.core.dom.ast.IFunction#takesVarArgs() */ public boolean takesVarArgs() { - IASTName name = (IASTName) getDefinition(); - if( name != null ){ - ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) name.getParent(); - return dtor.takesVarArgs(); - } - IASTName [] ns = (IASTName[]) getDeclarations(); - if( ns != null && ns.length > 0 ){ - ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ns[0].getParent(); - return dtor.takesVarArgs(); - } + ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(getDefinition()); + if (fdecl == null) { + IASTName [] ns = (IASTName[]) getDeclarations(); + if( ns != null && ns.length > 0 ){ + for (int i = 0; i < ns.length && fdecl==null; i++) { + IASTName name = ns[i]; + fdecl= getDeclaratorByName(name); + } + } + } + if (fdecl != null) { + return fdecl.takesVarArgs(); + } return false; } + private ICPPASTFunctionDeclarator getDeclaratorByName(IASTNode node) { + // skip qualified names and nested declarators. + while (node != null) { + node= node.getParent(); + if (node instanceof ICPPASTFunctionDeclarator) { + return ((ICPPASTFunctionDeclarator) node); + } + } + return null; + } + /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean) */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index 83e311f4fa8..11d1f29a994 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Bryan Wilkinson (QNX) + * Markus Schorn (Wind River Systems) *******************************************************************************/ /* * Created on Mar 11, 2005 @@ -798,7 +799,11 @@ public class CPPTemplates { name = ((ICPPASTElaboratedTypeSpecifier)spec).getName(); } } else if( nestedDecl instanceof IASTFunctionDefinition ){ - name = ((IASTFunctionDefinition)nestedDecl).getDeclarator().getName(); + IASTDeclarator declarator = ((IASTFunctionDefinition)nestedDecl).getDeclarator(); + while (declarator.getNestedDeclarator() != null) { + declarator= declarator.getNestedDeclarator(); + } + name = declarator.getName(); } if( name != null ){ if( name instanceof ICPPASTQualifiedName ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index 76ed6ea68a8..d4063769bea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -748,7 +748,7 @@ public class CPPVisitor { IASTNode parent = node.getParent(); if( parent instanceof ICPPASTFunctionDeclarator ){ ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent; - if( dtor.getNestedDeclarator() == null ) { + if( dtor.getNestedDeclarator() == null || dtor.getNestedDeclarator().getPointerOperators().length == 0) { while( parent.getParent() instanceof IASTDeclarator ) parent = parent.getParent(); ASTNodeProperty prop = parent.getPropertyInParent(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java index f1b2b13233a..e0204bd5016 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -83,7 +84,12 @@ abstract public class IndexerASTVisitor extends ASTVisitor { public int visit(IASTDeclaration decl) { if (decl instanceof IASTFunctionDefinition) { IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; - IASTName name = getLastInQualified(fdef.getDeclarator().getName()); + final IASTFunctionDeclarator declarator= fdef.getDeclarator(); + IASTDeclarator nestedDeclarator= declarator; + while (nestedDeclarator.getNestedDeclarator() != null) { + nestedDeclarator= nestedDeclarator.getNestedDeclarator(); + } + IASTName name= getLastInQualified(nestedDeclarator.getName()); visit(name, fDefinitionName); push(name, decl); }