diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index 61e6d2b51d8..6f7e62e69e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 3763afe8ad5..f3c070215b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -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]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index ff067527af0..283d92031e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -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 {