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 2fdcdd38bc0..0f285e18463 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 @@ -1120,4 +1120,58 @@ public class AST2TemplateTests extends AST2BaseTest { assertSame( ((ICPPDelegate)A4).getBinding(), A1 ); } + public void testTemplateTemplateParameter() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template class A { \n"); //$NON-NLS-1$ + buffer.append(" int x; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("template class A { \n"); //$NON-NLS-1$ + buffer.append(" char x; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("template class V> class C { \n"); //$NON-NLS-1$ + buffer.append(" V y; \n"); //$NON-NLS-1$ + buffer.append(" V z; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("void f() { \n"); //$NON-NLS-1$ + buffer.append(" C c; \n"); //$NON-NLS-1$ + buffer.append(" c.y.x; c.z.x; \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPClassTemplate A1 = (ICPPClassTemplate) col.getName(1).resolveBinding(); + ICPPField x1 = (ICPPField) col.getName(2).resolveBinding(); + ICPPClassTemplatePartialSpecialization A2 = (ICPPClassTemplatePartialSpecialization) col.getName(4).resolveBinding(); + ICPPField x2 = (ICPPField) col.getName(7).resolveBinding(); + + ICPPClassTemplate C = (ICPPClassTemplate) col.getName(10).resolveBinding(); + ICPPField y = (ICPPField) col.getName(13).resolveBinding(); + ICPPField z = (ICPPField) col.getName(16).resolveBinding(); + + ICPPClassType C1 = (ICPPClassType) col.getName(18).resolveBinding(); + assertTrue( C1 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)C1).getTemplateDefinition(), C ); + + ICPPField y2 = (ICPPField) col.getName(23).resolveBinding(); + assertTrue( y2 instanceof ICPPSpecialization ); + assertSame( ((ICPPSpecialization)y2).getSpecializedBinding(), y ); + IType t = y2.getType(); + assertTrue( t instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)t).getTemplateDefinition(), A1 ); + ICPPField x3 = (ICPPField) col.getName(24).resolveBinding(); + assertTrue( x3 instanceof ICPPSpecialization ); + assertEquals( ((ICPPSpecialization)x3).getSpecializedBinding(), x1 ); + + ICPPField z2 = (ICPPField) col.getName(26).resolveBinding(); + assertTrue( z2 instanceof ICPPSpecialization ); + assertSame( ((ICPPSpecialization)z2).getSpecializedBinding(), z ); + t = z2.getType(); + assertTrue( t instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)t).getTemplateDefinition(), A2 ); + ICPPField x4 = (ICPPField) col.getName(27).resolveBinding(); + assertTrue( x4 instanceof ICPPSpecialization ); + assertEquals( ((ICPPSpecialization)x4).getSpecializedBinding(), x2 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index 1d43e566d62..34190074a8e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -45,7 +45,7 @@ public class CPPDeferredClassInstance extends CPPInstance implements ICPPClassTy /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases() */ - public ICPPBase[] getBases() throws DOMException { + public ICPPBase[] getBases() { return ICPPBase.EMPTY_BASE_ARRAY; } @@ -154,6 +154,10 @@ public class CPPDeferredClassInstance extends CPPInstance implements ICPPClassTy newArgs[i] = CPPTemplates.instantiateType( arguments[i], argMap ); } + if( argMap.containsKey( classTemplate ) ){ + classTemplate = (ICPPClassTemplate) argMap.get( classTemplate ); + } + return (IType) ((ICPPInternalTemplate)classTemplate).instantiate( newArgs ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index 545fa7cbce6..2a01faab389 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer @@ -44,6 +45,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement ICPPTemplateTemplateParameter, ICPPClassType, ICPPInternalTemplate { private ICPPTemplateParameter [] templateParameters = null; + private ObjectMap instances = null; /** * @param name @@ -243,19 +245,47 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; } - public void addSpecialization(IType[] arguments, ICPPSpecialization specialization) { - } - public IBinding instantiate(IType[] arguments) { return deferredInstance( arguments ); } public ICPPSpecialization deferredInstance(IType[] arguments) { - // TODO Auto-generated method stub - return null; + ICPPSpecialization instance = getInstance( arguments ); + if( instance == null ){ + instance = new CPPDeferredClassInstance( this, arguments ); + addSpecialization( arguments, instance ); + } + return instance; } - public ICPPSpecialization getInstance(IType[] arguments) { + public ICPPSpecialization getInstance( IType [] arguments ) { + if( instances == null ) + return null; + + int found = -1; + for( int i = 0; i < instances.size(); i++ ){ + IType [] args = (IType[]) instances.keyAt( i ); + if( args.length == arguments.length ){ + int j = 0; + for(; j < args.length; j++) { + if( !( args[j].isSameType( arguments[j] ) ) ) + break; + } + if( j == args.length ){ + found = i; + break; + } + } + } + if( found != -1 ){ + return (ICPPSpecialization) instances.getAt(found); + } return null; } + + public void addSpecialization( IType [] types, ICPPSpecialization spec ){ + if( instances == null ) + instances = new ObjectMap( 2 ); + instances.put( types, spec ); + } }