diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index e80ca2e3c21..0662478677f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -1553,4 +1553,21 @@ public class AST2TemplateTests extends AST2BaseTest { assertTrue( type.isSameType( p.getType() ) ); } + public void testDeferredFunctionTemplates() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template void f( T ); \n"); //$NON-NLS-1$ + buffer.append("template void g( T t ){ \n"); //$NON-NLS-1$ + buffer.append(" f( t ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPFunctionTemplate f = (ICPPFunctionTemplate) col.getName(1).resolveBinding(); + ICPPFunction f2 = (ICPPFunction) col.getName(8).resolveBinding(); + assertTrue( f2 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)f2).getTemplateDefinition(), f ); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java index 32444095ae2..0bc7d17c411 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java @@ -24,13 +24,18 @@ import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPFunctionTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalFunction { - + private IParameter [] parameters; private IType[] arguments; + private IFunctionType functionType; /** * @param scope @@ -40,8 +45,25 @@ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunc public CPPDeferredFunctionInstance( ICPPFunctionTemplate template, IType[] arguments ) { super( null, template, null, arguments ); this.arguments = arguments; + this.argumentMap = createArgumentMap( arguments ); } + private ObjectMap createArgumentMap( IType [] args ){ + ICPPTemplateDefinition template = getTemplateDefinition(); + ICPPTemplateParameter [] params; + try { + params = template.getTemplateParameters(); + } catch (DOMException e) { + return null; + } + ObjectMap map = new ObjectMap( params.length ); + for( int i = 0; i < params.length; i++ ){ + if( i < args.length ) + map.put( params[i], args[i] ); + } + return map; + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance#getArguments() */ @@ -53,13 +75,24 @@ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunc * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() */ public IParameter[] getParameters() throws DOMException { - return ((ICPPFunction)getTemplateDefinition()).getParameters(); + if( getArgumentMap() == null ) + return ((ICPPFunction)getTemplateDefinition()).getParameters(); + if( parameters == null ){ + IParameter [] params = ((ICPPFunction)getTemplateDefinition()).getParameters(); + parameters = new IParameter[ params.length ]; + for (int i = 0; i < params.length; i++) { + parameters[i] = new CPPParameterSpecialization( (ICPPParameter)params[i], null, getArgumentMap() ); + } + } + + return parameters; + } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() */ - public IScope getFunctionScope() throws DOMException { + public IScope getFunctionScope() { // TODO Auto-generated method stub return null; } @@ -68,64 +101,63 @@ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunc * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() */ public IFunctionType getType() throws DOMException { - // TODO Auto-generated method stub - return null; + if( functionType == null ){ + IFunctionType ft = ((ICPPFunction)getTemplateDefinition()).getType(); + IType returnType = ft.getReturnType(); + returnType = CPPTemplates.instantiateType( returnType, getArgumentMap() ); + functionType = CPPVisitor.createImplicitFunctionType( returnType, getParameters() ); + } + + return functionType; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic() */ public boolean isStatic() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isStatic(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction#isMutable() */ public boolean isMutable() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isMutable(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction#isInline() */ public boolean isInline() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isInline(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isExtern() */ public boolean isExtern() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isExtern(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isAuto() */ public boolean isAuto() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isAuto(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isRegister() */ public boolean isRegister() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).isRegister(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#takesVarArgs() */ public boolean takesVarArgs() throws DOMException { - // TODO Auto-generated method stub - return false; + return ((ICPPFunction)getTemplateDefinition()).takesVarArgs(); } /* (non-Javadoc) @@ -140,8 +172,7 @@ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunc * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean) */ public boolean isStatic( boolean resolveAll ) { - // TODO Auto-generated method stub - return false; + return ((ICPPInternalFunction)getTemplateDefinition()).isStatic( resolveAll ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index 5c92e605a16..b8c244a97e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -289,7 +289,12 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu * @see org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition#deferredInstance(org.eclipse.cdt.core.dom.ast.IType[]) */ public ICPPSpecialization deferredInstance(IType[] arguments) { - return new CPPDeferredFunctionInstance( this, arguments ); + ICPPSpecialization instance = getInstance( arguments ); + if( instance == null ){ + instance = new CPPDeferredFunctionInstance( this, arguments ); + addSpecialization( arguments, instance ); + } + return instance; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic()