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.ICPPField;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
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.ICPPScope;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,6 +155,23 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP
|
||||||
return true;
|
return true;
|
||||||
if( type instanceof ITypedef )
|
if( type instanceof ITypedef )
|
||||||
return ((ITypedef)type).isSameType( this );
|
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;
|
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.ICPPASTConstructorChainInitializer;
|
||||||
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.ICPPASTElaboratedTypeSpecifier;
|
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.ICPPASTFieldReference;
|
||||||
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.ICPPASTLinkageSpecification;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
|
||||||
|
@ -219,10 +220,33 @@ public class CPPSemantics {
|
||||||
p1 = p1.getParent();
|
p1 = p1.getParent();
|
||||||
}
|
}
|
||||||
IASTNode p2 = p1.getParent();
|
IASTNode p2 = p1.getParent();
|
||||||
|
if( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration ){
|
||||||
return ( ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) ||
|
return !( p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation );
|
||||||
( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition));
|
}
|
||||||
|
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(){
|
private boolean considerConstructors(){
|
||||||
if( astName == null ) return false;
|
if( astName == null ) return false;
|
||||||
if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) 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
|
//reduce our set of candidate functions to only those who have the right number of parameters
|
||||||
reduceToViable( data, fns );
|
reduceToViable( data, fns );
|
||||||
|
|
||||||
if( data.forDefinition() ){
|
if( data.forDefinition() || data.forExplicitInstantiation() ){
|
||||||
for (int i = 0; i < fns.length; i++) {
|
for (int i = 0; i < fns.length; i++) {
|
||||||
if( fns[i] != null ){
|
if( fns[i] != null ){
|
||||||
return fns[i];
|
return fns[i];
|
||||||
|
|
|
@ -384,12 +384,17 @@ public class CPPTemplates {
|
||||||
|
|
||||||
ICPPSpecialization spec = null;
|
ICPPSpecialization spec = null;
|
||||||
if( parent.getParent() instanceof ICPPASTExplicitTemplateInstantiation ){
|
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 {
|
} else {
|
||||||
if( function instanceof ICPPMethod )
|
spec = ((ICPPInternalTemplate)function).getInstance( (IType[])map_types[1] );
|
||||||
spec = new CPPMethodSpecialization( function, scope, (ObjectMap) map_types[0] );
|
if( spec == null ) {
|
||||||
else
|
if( function instanceof ICPPMethod )
|
||||||
spec = new CPPFunctionSpecialization( function, scope, (ObjectMap) map_types[0] );
|
spec = new CPPMethodSpecialization( function, scope, (ObjectMap) map_types[0] );
|
||||||
|
else
|
||||||
|
spec = new CPPFunctionSpecialization( function, scope, (ObjectMap) map_types[0] );
|
||||||
|
}
|
||||||
|
|
||||||
if( parent instanceof IASTSimpleDeclaration )
|
if( parent instanceof IASTSimpleDeclaration )
|
||||||
((ICPPInternalBinding)spec).addDeclaration( name );
|
((ICPPInternalBinding)spec).addDeclaration( name );
|
||||||
|
@ -471,7 +476,8 @@ public class CPPTemplates {
|
||||||
ICPPTemplateParameter param = params[j];
|
ICPPTemplateParameter param = params[j];
|
||||||
if( j < numArgs ){
|
if( j < numArgs ){
|
||||||
arg = templateArguments[j];
|
arg = templateArguments[j];
|
||||||
}
|
} else
|
||||||
|
arg = null;
|
||||||
if( map.containsKey( param ) ) {
|
if( map.containsKey( param ) ) {
|
||||||
IType t = (IType) map.get( param );
|
IType t = (IType) map.get( param );
|
||||||
if( arg == null )
|
if( arg == null )
|
||||||
|
@ -754,11 +760,23 @@ public class CPPTemplates {
|
||||||
this.bindings = bindings;
|
this.bindings = bindings;
|
||||||
}
|
}
|
||||||
public int visit(IASTName name) {
|
public int visit(IASTName name) {
|
||||||
if( name.getBinding() != null && bindings.containsKey( name.getBinding() ) ){
|
if( name.getBinding() != null ){
|
||||||
IBinding binding = name.getBinding();
|
IBinding binding = name.getBinding();
|
||||||
if( binding instanceof ICPPInternalBinding )
|
boolean clear = bindings.containsKey( name.getBinding() );
|
||||||
((ICPPInternalBinding)binding).removeDeclaration( name );
|
if( !clear && binding instanceof ICPPTemplateInstance ){
|
||||||
name.setBinding( null );
|
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;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
@ -1072,6 +1090,8 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while( p != null ){
|
while( p != null ){
|
||||||
|
while( a instanceof ITypedef )
|
||||||
|
a = ((ITypedef)a).getType();
|
||||||
if( p instanceof IBasicType ){
|
if( p instanceof IBasicType ){
|
||||||
return p.isSameType( a );
|
return p.isSameType( a );
|
||||||
} else if( p instanceof ICPPPointerToMemberType ){
|
} else if( p instanceof ICPPPointerToMemberType ){
|
||||||
|
@ -1124,12 +1144,24 @@ public class CPPTemplates {
|
||||||
ICPPTemplateInstance aInst = (ICPPTemplateInstance) a;
|
ICPPTemplateInstance aInst = (ICPPTemplateInstance) a;
|
||||||
|
|
||||||
IType [] pArgs = createTypeArray( pInst.getArguments() );
|
IType [] pArgs = createTypeArray( pInst.getArguments() );
|
||||||
IType [] aArgs = createTypeArray( aInst.getArguments() );
|
ObjectMap aMap = aInst.getArgumentMap();
|
||||||
if( pArgs.length != aArgs.length )
|
if( aMap != null && !(aInst.getTemplateDefinition() instanceof ICPPClassTemplatePartialSpecialization) ) {
|
||||||
return false;
|
ICPPTemplateParameter [] aParams = aInst.getTemplateDefinition().getTemplateParameters();
|
||||||
for (int i = 0; i < pArgs.length; i++) {
|
if( pArgs.length != aParams.length )
|
||||||
if( !deduceTemplateArgument( map, pArgs[i], aArgs[i] ) )
|
|
||||||
return false;
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Reference in a new issue