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:
parent
e5610988d7
commit
f7d25b8b16
3 changed files with 93 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue