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

Fix for 190241, ClassCastException in template parameter resolution.

This commit is contained in:
Markus Schorn 2007-06-04 15:32:25 +00:00
parent f152c91817
commit 4f99b62ebd
5 changed files with 77 additions and 35 deletions

View file

@ -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<class T> 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);
}
}
}

View file

@ -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)
*/

View file

@ -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 ){

View file

@ -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();

View file

@ -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);
}