diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 2c6fb3f2dc8..7f4eca185ab 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -661,23 +661,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 14.1-13): - template class X { }; - template void f(T* p = new T); - --End Example] - */ - public void test14_1s13() { // TODO raised bug 60670 - StringBuffer buffer = new StringBuffer(); - buffer.append("template class X { };\n"); //$NON-NLS-1$ - buffer.append("template void f(T* p = new T);\n"); //$NON-NLS-1$ - try { - parse(buffer.toString(), ParserLanguage.CPP, true, 0); - assertTrue(false); - } catch (Exception e) { - } - } - /** [--Start Example(CPP 14.3-2): template void f(); @@ -931,23 +914,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } - /** - [--Start Example(CPP 14.6.1-3a): - template class X { }; - template void f(T* p = new T); - --End Example] - */ - public void test14_6_1s3a() { // TODO already have bug on this one - StringBuffer buffer = new StringBuffer(); - buffer.append("template class X { };\n"); //$NON-NLS-1$ - buffer.append("template void f(T* p = new T);\n"); //$NON-NLS-1$ - try { - parse(buffer.toString(), ParserLanguage.CPP, true, 0); - assertTrue(false); - } catch (Exception e) { - } - } - /** [--Start Example(CPP 14.6.1-6): namespace N { @@ -1005,43 +971,6 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } catch (Exception e) { } } - - /** - [--Start Example(CPP 14.7-3): - template struct A { - static int x; - }; - template void g(U) { } - template<> struct A { }; // specialize for T == double - template<> struct A<> { }; // specialize for T == int - template<> void g(char) { } // specialize for U == char - // U is deduced from the parameter type - template<> void g(int) { } // specialize for U == int - template<> int A::x = 0; // specialize for T == char - template struct B { - static int x; - }; - template<> int B<>::x = 1; // specialize for T == int - --End Example] - */ - public void test14_7s3() throws Exception { - StringBuffer buffer = new StringBuffer(); - buffer.append("template struct A {\n"); //$NON-NLS-1$ - buffer.append("static int x;\n"); //$NON-NLS-1$ - buffer.append("};\n"); //$NON-NLS-1$ - buffer.append("template void g(U) { }\n"); //$NON-NLS-1$ - buffer.append("template<> struct A { }; // specialize for T == double\n"); //$NON-NLS-1$ - buffer.append("template<> struct A<> { }; // specialize for T == int\n"); //$NON-NLS-1$ - buffer.append("template<> void g(char) { } // specialize for U == char\n"); //$NON-NLS-1$ - buffer.append("// U is deduced from the parameter type\n"); //$NON-NLS-1$ - buffer.append("template<> void g(int) { } // specialize for U == int\n"); //$NON-NLS-1$ - buffer.append("template<> int A::x = 0; // specialize for T == char\n"); //$NON-NLS-1$ - buffer.append("template struct B {\n"); //$NON-NLS-1$ - buffer.append("static int x;\n"); //$NON-NLS-1$ - buffer.append("};\n"); //$NON-NLS-1$ - buffer.append("template<> int B<>::x = 1; // specialize for T == int\n"); //$NON-NLS-1$ - parse(buffer.toString(), ParserLanguage.CPP, true, 2); - } /** [--Start Example(CPP 14.7.1-5): diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index b95477aa51f..b60dada39f3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -8480,6 +8480,20 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, true, 0); } + /** + [--Start Example(CPP 14.1-13): + template class X { }; + template void f(T* p = new T); + --End Example] + */ + public void test14_1s13() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template class X { };\n"); //$NON-NLS-1$ + buffer.append("template void f(T* p = new T);\n"); //$NON-NLS-1$ + + parse(buffer.toString(), ParserLanguage.CPP, true, 0); + } + /** [--Start Example(CPP 14.1-15): template 4) > // OK @@ -9597,7 +9611,20 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, false, 0); } + /** + [--Start Example(CPP 14.6.1-3a): + template class X { }; + template void f(T* p = new T); + --End Example] + */ + public void test14_6_1s3a() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template class X { };\n"); //$NON-NLS-1$ + buffer.append("template void f(T* p = new T);\n"); //$NON-NLS-1$ + parse(buffer.toString(), ParserLanguage.CPP, true, 0); + } + /** [--Start Example(CPP 14.6.1-1): template class X { @@ -9966,6 +9993,44 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { parse(buffer.toString(), ParserLanguage.CPP, true, 0); } + /** + [--Start Example(CPP 14.7-3): + template struct A { + static int x; + }; + template void g(U) { } + template<> struct A { }; // specialize for T == double + template<> struct A<> { }; // specialize for T == int + template<> void g(char) { } // specialize for U == char + // U is deduced from the parameter type + template<> void g(int) { } // specialize for U == int + template<> int A::x = 0; // specialize for T == char + template struct B { + static int x; + }; + template<> int B<>::x = 1; // specialize for T == int + --End Example] + */ + public void test14_7s3() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template struct A {\n"); //$NON-NLS-1$ + buffer.append("static int x;\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("template void g(U) { }\n"); //$NON-NLS-1$ + buffer.append("template<> struct A { }; // specialize for T == double\n"); //$NON-NLS-1$ + buffer.append("template<> struct A<> { }; // specialize for T == int\n"); //$NON-NLS-1$ + buffer.append("template<> void g(char) { } // specialize for U == char\n"); //$NON-NLS-1$ + buffer.append("// U is deduced from the parameter type\n"); //$NON-NLS-1$ + buffer.append("template<> void g(int) { } // specialize for U == int\n"); //$NON-NLS-1$ + buffer.append("template<> int A::x = 0; // specialize for T == char\n"); //$NON-NLS-1$ + buffer.append("template struct B {\n"); //$NON-NLS-1$ + buffer.append("static int x;\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("template<> int B<>::x = 1; // specialize for T == int\n"); //$NON-NLS-1$ + + parse(buffer.toString(), ParserLanguage.CPP, true, 0); + } + /** [--Start Example(CPP 14.7.1-10): namespace N { 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 692f50c1a82..12cefa6a217 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 @@ -778,4 +778,64 @@ public class AST2TemplateTests extends AST2BaseTest { assertSame( ((ICPPTemplateInstance)f2).getOriginalBinding(), f1 ); assertSame( g1, g2 ); } + + public void testBug76951_1() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template U f( T ); \n"); //$NON-NLS-1$ + buffer.append("void g() { \n"); //$NON-NLS-1$ + buffer.append(" f( 1 ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(2).resolveBinding(); + assertSame( T, T2 ); + + ICPPFunctionTemplate f1 = (ICPPFunctionTemplate) col.getName(4).resolveBinding(); + ICPPFunction f2 = (ICPPFunction) col.getName(8).resolveBinding(); + + assertTrue( f2 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)f2).getOriginalBinding(), f1 ); + + IFunctionType ft = f2.getType(); + assertTrue( ft.getReturnType() instanceof IBasicType ); + assertEquals( ((IBasicType)ft.getReturnType()).getType(), IBasicType.t_int ); + } + public void testBug76951_2() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template class A { \n"); //$NON-NLS-1$ + buffer.append(" U u; \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("void f() { \n"); //$NON-NLS-1$ + buffer.append(" A a; \n"); //$NON-NLS-1$ + buffer.append(" a.u; \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + ICPPTemplateTypeParameter U = (ICPPTemplateTypeParameter) col.getName(1).resolveBinding(); + assertSame( U.getDefault(), T ); + + ICPPClassTemplate A = (ICPPClassTemplate) col.getName(3).resolveBinding(); + ICPPField u1 = (ICPPField) col.getName(5).resolveBinding(); + assertSame( u1.getType(), U ); + + ICPPClassType A1 = (ICPPClassType) col.getName(7).resolveBinding(); + assertTrue( A1 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)A1).getOriginalBinding(), A ); + + ICPPField u2 = (ICPPField) col.getName(11).resolveBinding(); + assertTrue( u2 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)u2).getOriginalBinding(), u1 ); + + IType type = u2.getType(); + assertTrue( type instanceof IBasicType ); + assertEquals( ((IBasicType)type).getType(), IBasicType.t_int ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java index 070dca41c16..32c048b014e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeTemplateParameter.java @@ -77,8 +77,9 @@ public class CPPASTSimpleTypeTemplateParameter extends CPPASTNode implements } } - if( typeId != null ) if( !typeId.accept( action ) ) return false; if( name != null ) if( !name.accept( action ) ) return false; + if( typeId != null ) if( !typeId.accept( action ) ) return false; + return true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index 03b1d0cf61c..7a556c8cc61 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -199,6 +199,8 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope() */ public IScope getCompositeScope() { + if( definition == null ) + checkForDefinition(); if( definition != null ){ ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) definition.getParent(); return compSpec.getScope(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index df72b382dcf..74f9a0ac674 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -138,7 +138,7 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I IType[] actualArgs = new IType[ numParams ]; for( int i = 0; i < numParams; i++ ){ - + arg = null; param = parameters[i]; if( i < numArgs ){ @@ -164,7 +164,9 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I if( map.containsKey( defaultType ) ){ arg = (IType) map.get( defaultType ); } - } + } else { + arg = defaultType; + } } else { //TODO problem return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java index ad3ae769b5a..c9d2373a822 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTypeParameter.java @@ -13,10 +13,12 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; /** @@ -35,8 +37,15 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter#getDefault() */ - public IType getDefault() throws DOMException { - // TODO Auto-generated method stub + public IType getDefault() { + IASTNode [] nds = getDeclarations(); + if( nds == null || nds.length == 0 ) + return null; + IASTName name = (IASTName) nds[0]; + ICPPASTSimpleTypeTemplateParameter simple = (ICPPASTSimpleTypeTemplateParameter) name.getParent(); + IASTTypeId typeId = simple.getDefaultType(); + if( typeId != null ) + return CPPVisitor.createType( typeId ); return null; } 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 c8bbd1059ce..5769824f983 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 @@ -703,9 +703,31 @@ public class CPPTemplates { instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, arg ); else continue outer; - else if( arg == null && mapped == null ) - continue outer; - else + else if( arg == null && mapped == null ) { + IType def = null; + try { + if( templateParams[i] instanceof ICPPTemplateTypeParameter ){ + def = ((ICPPTemplateTypeParameter)templateParams[i]).getDefault(); + } else if( templateParams[i] instanceof ICPPTemplateTemplateParameter ){ + def = ((ICPPTemplateTemplateParameter)templateParams[i]).getDefault(); + } else if( templateParams[i] instanceof ICPPTemplateNonTypeParameter ){ + def = CPPVisitor.getExpressionType( ((ICPPTemplateNonTypeParameter)templateParams[i]).getDefault() ); + } + } catch ( DOMException e ) { + continue outer; + } + if( def != null ){ + if( def instanceof ICPPTemplateParameter ){ + for ( int j = 0; j < i; j++ ) { + if( templateParams[j] == def ) { + def = instanceArgs[j]; + } + } + } + instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, def ); + } else + continue outer; + } else instanceArgs = (IType[]) ArrayUtil.append( IType.class, instanceArgs, (arg != null) ? arg : mapped ); } instanceArgs = (IType[]) ArrayUtil.trim( IType.class, instanceArgs ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index e86cceb3125..69a1bfd047c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -638,6 +638,8 @@ public class CPPVisitor { return getContainingScope( (IASTStatement) node ); } else if( node instanceof IASTTypeId ){ node = node.getParent(); + if( node instanceof ICPPASTTemplateParameter ) + return CPPTemplates.getContainingScope( node ); } else if( node instanceof IASTParameterDeclaration ){ IASTNode parent = node.getParent(); if( parent instanceof ICPPASTFunctionDeclarator ){ @@ -1366,6 +1368,8 @@ public class CPPVisitor { } public static IType createType( IASTNode node ){ + if( node == null ) + return null; if( node instanceof IASTExpression ) return getExpressionType( (IASTExpression) node ); if( node instanceof IASTTypeId )