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

fixing template problems

- better handling of explicit instantiations
- argument deductions from template instances
- fix bug clearing bindings on failed function template definition match
This commit is contained in:
Andrew Niefer 2005-05-31 19:25:17 +00:00
parent e5610988d7
commit f7d25b8b16
3 changed files with 93 additions and 19 deletions

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.ObjectMap;
/**
@ -154,6 +155,23 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP
return true;
if( type instanceof ITypedef )
return ((ITypedef)type).isSameType( this );
if( type instanceof ICPPTemplateInstance ){
if( getSpecializedBinding() != ((ICPPTemplateInstance)type).getTemplateDefinition() )
return false;
ObjectMap m1 = getArgumentMap(), m2 = ((ICPPTemplateInstance)type).getArgumentMap();
if( m1.size() != m2.size() )
return false;
for( int i = 0; i < m1.size(); i++ ){
IType t1 = (IType) m1.getAt( i );
IType t2 = (IType) m2.getAt( i );
if( t1 == null || ! t1.isSameType( t2 ) )
return false;
}
return true;
}
return false;
}

View file

@ -66,6 +66,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
@ -219,10 +220,33 @@ public class CPPSemantics {
p1 = p1.getParent();
}
IASTNode p2 = p1.getParent();
return ( ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) ||
( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition));
if( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration ){
return !( p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation );
}
return ( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition);
}
public boolean forExplicitInstantiation(){
if( astName == null ) return false;
if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false;
IASTName n = astName;
if( n.getParent() instanceof ICPPASTTemplateId )
n = (IASTName) n.getParent();
IASTNode p1 = n.getParent();
if( p1 instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)p1).getNames();
if( ns[ns.length - 1] != n )
return false;
p1 = p1.getParent();
}
IASTNode p2 = p1.getParent();
if( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration ){
return ( p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation );
}
return false;
}
private boolean considerConstructors(){
if( astName == null ) return false;
if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false;
@ -1944,7 +1968,7 @@ public class CPPSemantics {
//reduce our set of candidate functions to only those who have the right number of parameters
reduceToViable( data, fns );
if( data.forDefinition() ){
if( data.forDefinition() || data.forExplicitInstantiation() ){
for (int i = 0; i < fns.length; i++) {
if( fns[i] != null ){
return fns[i];

View file

@ -384,12 +384,17 @@ public class CPPTemplates {
ICPPSpecialization spec = null;
if( parent.getParent() instanceof ICPPASTExplicitTemplateInstantiation ){
spec = (ICPPSpecialization) CPPTemplates.createInstance( scope, function, (ObjectMap)map_types[0], (IType[])map_types[1] );
spec = ((ICPPInternalTemplate)function).getInstance( (IType[])map_types[1] );
if( spec == null )
spec = (ICPPSpecialization) CPPTemplates.createInstance( scope, function, (ObjectMap)map_types[0], (IType[])map_types[1] );
} else {
if( function instanceof ICPPMethod )
spec = new CPPMethodSpecialization( function, scope, (ObjectMap) map_types[0] );
else
spec = new CPPFunctionSpecialization( function, scope, (ObjectMap) map_types[0] );
spec = ((ICPPInternalTemplate)function).getInstance( (IType[])map_types[1] );
if( spec == null ) {
if( function instanceof ICPPMethod )
spec = new CPPMethodSpecialization( function, scope, (ObjectMap) map_types[0] );
else
spec = new CPPFunctionSpecialization( function, scope, (ObjectMap) map_types[0] );
}
if( parent instanceof IASTSimpleDeclaration )
((ICPPInternalBinding)spec).addDeclaration( name );
@ -471,7 +476,8 @@ public class CPPTemplates {
ICPPTemplateParameter param = params[j];
if( j < numArgs ){
arg = templateArguments[j];
}
} else
arg = null;
if( map.containsKey( param ) ) {
IType t = (IType) map.get( param );
if( arg == null )
@ -754,11 +760,23 @@ public class CPPTemplates {
this.bindings = bindings;
}
public int visit(IASTName name) {
if( name.getBinding() != null && bindings.containsKey( name.getBinding() ) ){
if( name.getBinding() != null ){
IBinding binding = name.getBinding();
if( binding instanceof ICPPInternalBinding )
((ICPPInternalBinding)binding).removeDeclaration( name );
name.setBinding( null );
boolean clear = bindings.containsKey( name.getBinding() );
if( !clear && binding instanceof ICPPTemplateInstance ){
IType [] args = ((ICPPTemplateInstance)binding).getArguments();
for( int i = 0; i < args.length; i++ ){
if( bindings.containsKey( args[i] ) ){
clear = true;
break;
}
}
}
if( clear ){
if( binding instanceof ICPPInternalBinding )
((ICPPInternalBinding)binding).removeDeclaration( name );
name.setBinding( null );
}
}
return PROCESS_CONTINUE;
}
@ -1072,6 +1090,8 @@ public class CPPTemplates {
}
} else {
while( p != null ){
while( a instanceof ITypedef )
a = ((ITypedef)a).getType();
if( p instanceof IBasicType ){
return p.isSameType( a );
} else if( p instanceof ICPPPointerToMemberType ){
@ -1124,12 +1144,24 @@ public class CPPTemplates {
ICPPTemplateInstance aInst = (ICPPTemplateInstance) a;
IType [] pArgs = createTypeArray( pInst.getArguments() );
IType [] aArgs = createTypeArray( aInst.getArguments() );
if( pArgs.length != aArgs.length )
return false;
for (int i = 0; i < pArgs.length; i++) {
if( !deduceTemplateArgument( map, pArgs[i], aArgs[i] ) )
ObjectMap aMap = aInst.getArgumentMap();
if( aMap != null && !(aInst.getTemplateDefinition() instanceof ICPPClassTemplatePartialSpecialization) ) {
ICPPTemplateParameter [] aParams = aInst.getTemplateDefinition().getTemplateParameters();
if( pArgs.length != aParams.length )
return false;
for (int i = 0; i < pArgs.length; i++) {
IType t = (IType) aMap.get( aParams[i] );
if( t == null || !deduceTemplateArgument( map, pArgs[i], t ) )
return false;
}
} else {
IType [] aArgs = createTypeArray( aInst.getArguments() );
if( aArgs.length != pArgs.length )
return false;
for (int i = 0; i < pArgs.length; i++) {
if( !deduceTemplateArgument( map, pArgs[i], aArgs[i] ) )
return false;
}
}
return true;
} else {