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; package org.eclipse.cdt.core.parser.tests.ast2;
import java.util.Iterator;
import junit.framework.TestSuite; import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
@ -2056,4 +2058,20 @@ public class AST2TemplateTests extends AST2BaseTest {
assertInstance(tidSpc, ICPPSpecialization.class); assertInstance(tidSpc, ICPPSpecialization.class);
assertInstance(tidSpc, ICPPFunctionTemplate.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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/* /*
* Created on Mar 31, 2005 * 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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.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.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
@ -169,12 +169,9 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu
*/ */
public IParameter[] getParameters() { public IParameter[] getParameters() {
IASTName name = getTemplateName(); IASTName name = getTemplateName();
IASTNode parent = name.getParent(); ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(name);
if( parent instanceof ICPPASTQualifiedName ) if (fdecl != null) {
parent = parent.getParent(); IASTParameterDeclaration[] params = fdecl.getParameters();
if( parent instanceof ICPPASTFunctionDeclarator ){
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent;
IASTParameterDeclaration[] params = dtor.getParameters();
int size = params.length; int size = params.length;
IParameter [] result = new IParameter[ size ]; IParameter [] result = new IParameter[ size ];
if( size > 0 ){ if( size > 0 ){
@ -261,25 +258,27 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu
binding = new CPPParameter( name ); binding = new CPPParameter( name );
IASTParameterDeclaration temp = null; IASTParameterDeclaration temp = null;
if( definition != null ){ if( definition != null ){
IASTNode node = definition.getParent(); ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition);
if( node instanceof ICPPASTQualifiedName ) if (fdecl != null) {
node = node.getParent(); temp = fdecl.getParameters()[i];
temp = ((ICPPASTFunctionDeclarator)node).getParameters()[i]; IASTName n = temp.getDeclarator().getName();
IASTName n = temp.getDeclarator().getName(); if( n != name ) {
if( n != name ) { n.setBinding( binding );
n.setBinding( binding ); ((CPPParameter)binding).addDeclaration( n );
((CPPParameter)binding).addDeclaration( n ); }
} }
} }
if( declarations != null ){ if( declarations != null ){
for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){ for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){
temp = ((ICPPASTFunctionDeclarator)declarations[j].getParent()).getParameters()[i]; ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]);
IASTName n = temp.getDeclarator().getName(); if (fdecl != null) {
if( n != name ) { temp = fdecl.getParameters()[i];
n.setBinding( binding ); IASTName n = temp.getDeclarator().getName();
((CPPParameter)binding).addDeclaration( n ); if( n != name ) {
n.setBinding( binding );
((CPPParameter)binding).addDeclaration( n );
}
} }
} }
} }
return binding; return binding;
@ -364,19 +363,33 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu
* @see org.eclipse.cdt.core.dom.ast.IFunction#takesVarArgs() * @see org.eclipse.cdt.core.dom.ast.IFunction#takesVarArgs()
*/ */
public boolean takesVarArgs() { public boolean takesVarArgs() {
IASTName name = (IASTName) getDefinition(); ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(getDefinition());
if( name != null ){ if (fdecl == null) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) name.getParent(); IASTName [] ns = (IASTName[]) getDeclarations();
return dtor.takesVarArgs(); if( ns != null && ns.length > 0 ){
} for (int i = 0; i < ns.length && fdecl==null; i++) {
IASTName [] ns = (IASTName[]) getDeclarations(); IASTName name = ns[i];
if( ns != null && ns.length > 0 ){ fdecl= getDeclaratorByName(name);
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) ns[0].getParent(); }
return dtor.takesVarArgs(); }
} }
if (fdecl != null) {
return fdecl.takesVarArgs();
}
return false; 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) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean) * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)
*/ */

View file

@ -8,6 +8,7 @@
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/* /*
* Created on Mar 11, 2005 * Created on Mar 11, 2005
@ -798,7 +799,11 @@ public class CPPTemplates {
name = ((ICPPASTElaboratedTypeSpecifier)spec).getName(); name = ((ICPPASTElaboratedTypeSpecifier)spec).getName();
} }
} else if( nestedDecl instanceof IASTFunctionDefinition ){ } 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 != null ){
if( name instanceof ICPPASTQualifiedName ){ if( name instanceof ICPPASTQualifiedName ){

View file

@ -748,7 +748,7 @@ public class CPPVisitor {
IASTNode parent = node.getParent(); IASTNode parent = node.getParent();
if( parent instanceof ICPPASTFunctionDeclarator ){ if( parent instanceof ICPPASTFunctionDeclarator ){
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent; ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent;
if( dtor.getNestedDeclarator() == null ) { if( dtor.getNestedDeclarator() == null || dtor.getNestedDeclarator().getPointerOperators().length == 0) {
while( parent.getParent() instanceof IASTDeclarator ) while( parent.getParent() instanceof IASTDeclarator )
parent = parent.getParent(); parent = parent.getParent();
ASTNodeProperty prop = parent.getPropertyInParent(); 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.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; 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.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -83,7 +84,12 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
public int visit(IASTDeclaration decl) { public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) { if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; 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); visit(name, fDefinitionName);
push(name, decl); push(name, decl);
} }