diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 47cb165952c..f7045331929 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,12 @@ +2004-04-02 Andrew Niefer + - created CompleteParseASTTemplateTest, added it to the ParserTestSuite and moved all the template tests from + CompleteParseASTTest to it. + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testBug56834() + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testDefaultTemplateParameters() + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testBug56834WithInstantiation() + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testDefaultTemplateParameterWithDeferedInstance() + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testExplicitInstantiation() + 2004-04-02 John Camelon Added SelectionParseTest::testBaseCase_FunctionDeclaration(). Added SelectionParseTest::testBaseCase_FunctionDeclaration2(). diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java new file mode 100644 index 00000000000..0b613e6598d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java @@ -0,0 +1,646 @@ +/* + * Created on Mar 30, 2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package org.eclipse.cdt.core.parser.tests; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.Iterator; + +import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; +import org.eclipse.cdt.core.parser.ast.IASTField; +import org.eclipse.cdt.core.parser.ast.IASTFunction; +import org.eclipse.cdt.core.parser.ast.IASTMethod; +import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; +import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; +import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation; +import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter; +import org.eclipse.cdt.core.parser.ast.IASTTemplatedDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTVariable; +import org.eclipse.cdt.internal.core.parser.ParserException; + +/** + * @author aniefer + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +public class CompleteParseASTTemplateTest extends CompleteParseBaseTest { + /** + * @param name + */ + public CompleteParseASTTemplateTest(String name) { + super(name); + } + + public void testTemplateClassDeclaration() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < class T > class A { T t; }; " ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + Iterator params = template.getTemplateParameters(); + + IASTTemplateParameter T = (IASTTemplateParameter) params.next(); + assertEquals( T.getIdentifier(), "T" ); + assertFalse( params.hasNext() ); + assertFalse( i.hasNext() ); + + i = getDeclarations( template ); + + IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); + assertEquals( classA.getName(), "A" ); + + assertFalse( i.hasNext() ); + + i = getDeclarations( classA ); + + IASTField t = (IASTField) i.next(); + assertEquals( t.getName(), "t" ); + + IASTSimpleTypeSpecifier specifier = (IASTSimpleTypeSpecifier) t.getAbstractDeclaration().getTypeSpecifier(); + assertEquals( specifier.getTypename(), "T" ); + //assertEquals( specifier.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed + } + + public void testTemplateFunction() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < class T > void f( T t ){} " ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + + Iterator params = template.getTemplateParameters(); + + IASTTemplateParameter T = (IASTTemplateParameter) params.next(); + assertEquals( T.getIdentifier(), "T" ); + assertFalse( params.hasNext() ); + assertFalse( i.hasNext() ); + + i = getDeclarations( template ); + IASTFunction f = (IASTFunction) i.next(); + assertEquals( f.getName(), "f" ); + + params = f.getParameters(); + IASTParameterDeclaration t = (IASTParameterDeclaration) params.next(); + assertEquals( t.getName(), "t" ); + IASTSimpleTypeSpecifier typeSpec = (IASTSimpleTypeSpecifier) t.getTypeSpecifier(); + assertEquals( typeSpec.getTypename(), "T" ); + //assertEquals( typeSpec.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed + } + + public void testTemplateFunctionDefinition() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template void f( T t );" ); + writer.write( "template void f( U u ) { }" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + + Iterator params = template.getTemplateParameters(); + + IASTTemplateParameter T = (IASTTemplateParameter) params.next(); + assertEquals( T.getIdentifier(), "T" ); + assertFalse( params.hasNext() ); + + Iterator tempDecls = getDeclarations( template ); + IASTFunction f = (IASTFunction) tempDecls.next(); + assertEquals( f.getName(), "f" ); + assertFalse( f.hasFunctionBody() ); + assertFalse( tempDecls.hasNext() ); + + params = f.getParameters(); + IASTParameterDeclaration t = (IASTParameterDeclaration) params.next(); + assertEquals( t.getName(), "t" ); + IASTSimpleTypeSpecifier typeSpec = (IASTSimpleTypeSpecifier) t.getTypeSpecifier(); + assertEquals( typeSpec.getTypename(), "T" ); + //assertEquals( typeSpec.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed + + IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); + + params = template2.getTemplateParameters(); + + IASTTemplateParameter U = (IASTTemplateParameter) params.next(); + assertEquals( U.getIdentifier(), "U" ); + assertFalse( params.hasNext() ); + + tempDecls = getDeclarations( template2 ); + IASTFunction f2 = (IASTFunction) tempDecls.next(); + assertEquals( f2.getName(), "f" ); + assertTrue( f2.previouslyDeclared() ); + + params = f2.getParameters(); + IASTParameterDeclaration u = (IASTParameterDeclaration) params.next(); + assertEquals( u.getName(), "u" ); + typeSpec = (IASTSimpleTypeSpecifier) u.getTypeSpecifier(); + assertEquals( typeSpec.getTypename(), "U" ); + //assertEquals( typeSpec.getTypeSpecifier(), U ); //TODO uncomment when bug 54029 is fixed + + assertFalse( i.hasNext() ); + } + + public void testClassMemberTemplate() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "namespace N { " ); + writer.write( " class A { " ); + writer.write( " template < class T > T f();" ); + writer.write( " }; " ); + writer.write( "}" ); + writer.write( "template U N::A::f() {} " ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTNamespaceDefinition N = (IASTNamespaceDefinition) i.next(); + + Iterator i2 = getDeclarations( N ); + + IASTClassSpecifier A = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i2.next()).getTypeSpecifier(); + assertFalse( i2.hasNext() ); + + i2 = getDeclarations( A ); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i2.next(); + Iterator params = template.getTemplateParameters(); + IASTTemplateParameter T = (IASTTemplateParameter) params.next(); + assertFalse( params.hasNext() ); + assertFalse( i2.hasNext() ); + + i2 = getDeclarations( template ); + + IASTMethod f = (IASTMethod) i2.next(); + assertEquals( ((IASTSimpleTypeSpecifier)f.getReturnType().getTypeSpecifier()).getTypename(), "T" ); + assertFalse( i2.hasNext() ); + + IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); + params = template.getTemplateParameters(); + IASTTemplateParameter U = (IASTTemplateParameter) params.next(); + assertFalse( params.hasNext() ); + assertFalse( i.hasNext() ); + + i2 = getDeclarations( template2 ); + + IASTMethod f2 = (IASTMethod) i2.next(); + assertEquals( ((IASTSimpleTypeSpecifier)f2.getReturnType().getTypeSpecifier()).getTypename(), "U" ); + assertQualifiedName( f2.getFullyQualifiedName(), new String [] { "N", "A", "f" } ); + assertTrue( f2.previouslyDeclared() ); + assertFalse( i2.hasNext() ); + } + + public void testOverloadedFunctionTemplates() throws Exception + { + Writer writer = new StringWriter(); + writer.write( " template < class T > void f ( T ) {} " ); + writer.write( " template < class T > void f ( T * ) {} " ); + writer.write( " int * p;" ); + writer.write( " void main () {" ); + writer.write( " f( p );" ); + writer.write( " f( *p );" ); + writer.write( " }" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T1 = (IASTTemplateParameter) template1.getTemplateParameters().next(); + + IASTFunction f1 = (IASTFunction) template1.getOwnedDeclaration(); + + IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); + IASTFunction f2 = (IASTFunction) template2.getOwnedDeclaration(); + IASTTemplateParameter T2 = (IASTTemplateParameter) template2.getTemplateParameters().next(); + + IASTVariable p = (IASTVariable) i.next(); + IASTFunction main = (IASTFunction) i.next(); + assertFalse( i.hasNext() ); + + assertAllReferences( 6, createTaskList( new Task( T1 ), + new Task( T2 ), + new Task( f1, 1, false, false ), + new Task( p, 2 ), + new Task( f2, 1, false, false ) ) ); + + } + + public void testOverloadedFunctionTemplates_2() throws Exception + { + Writer writer = new StringWriter(); + writer.write("template< class T > struct A { }; \n"); + writer.write("template< class T > void h( const T & ); //#1 \n"); + writer.write("template< class T > void h( A& ); //#2 \n"); + writer.write("void foo() { \n"); + writer.write(" A z; \n"); + writer.write(" h( z ); //calls 2 \n"); + + writer.write(" const A z2; \n"); + writer.write(" h( z2 ); //calls 1 because 2 is not callable. \n"); + writer.write( "} \n"); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateh1 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateh2 = (IASTTemplateDeclaration) i.next(); + + IASTClassSpecifier A = (IASTClassSpecifier) templateA.getOwnedDeclaration(); + IASTFunction h1 = (IASTFunction) templateh1.getOwnedDeclaration(); + IASTFunction h2 = (IASTFunction) templateh2.getOwnedDeclaration(); + + IASTTemplateParameter T1 = (IASTTemplateParameter) templateA.getTemplateParameters().next(); + IASTTemplateParameter T2 = (IASTTemplateParameter) templateh1.getTemplateParameters().next(); + IASTTemplateParameter T3 = (IASTTemplateParameter) templateh2.getTemplateParameters().next(); + + IASTFunction foo = (IASTFunction) i.next(); + assertFalse( i.hasNext() ); + + i = getDeclarations( foo ); + IASTVariable z = (IASTVariable) i.next(); + IASTVariable z2 = (IASTVariable) i.next(); + assertFalse( i.hasNext() ); + + assertEquals( ((IASTSimpleTypeSpecifier)z.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A ); + assertEquals( ((IASTSimpleTypeSpecifier)z2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A ); + + assertAllReferences( 9, createTaskList( new Task( T2 ), + new Task( T3 ), + new Task( A, 3 ), + new Task( z ), + new Task( z2 ), + new Task( h1, 1, false, false ), + new Task( h2, 1, false, false ) ) ); + + + } + + public void testTemplateClassPartialSpecialization() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < class T1, class T2, int I > class A {}; //#1\n" ); + writer.write( "template < class T, int I > class A < T, T*, I > {}; //#2\n"); + writer.write( "template < class T1, class T2, int I > class A < T1*, T2, I > {}; //#3\n"); + writer.write( "template < class T > class A < int, T*, 5 > {}; //#4\n"); + writer.write( "template < class T1, class T2, int I > class A < T1, T2*, I > {}; //#5\n"); + + writer.write( "A a1; //uses #1 \n"); + writer.write( "A a2; //uses #2, T is int, I is 1 \n"); + writer.write( "A a4; //uses #4, T is char \n"); + writer.write( "A a5; //uses #5, T is int, T2 is char, I is1 \n"); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + writer.write( " A amgiguous; //ambiguous, matches #3 & #5 \n"); + + try{ + //we expect this parse to fail because of the ambiguity in the last line + parse( writer.toString() ); + assertFalse( true ); + } catch ( ParserException e ){ + assertEquals( e.getMessage(), "FAILURE" ); + } + + IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration spec2 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration spec3 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration spec4 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration spec5 = (IASTTemplateDeclaration) i.next(); + + IASTVariable a1 = (IASTVariable) i.next(); + IASTVariable a2 = (IASTVariable) i.next(); + IASTVariable a4 = (IASTVariable) i.next(); + IASTVariable a5 = (IASTVariable) i.next(); + + assertFalse( i.hasNext() ); + + IASTClassSpecifier A1 = (IASTClassSpecifier)template1.getOwnedDeclaration(); + IASTClassSpecifier A2 = (IASTClassSpecifier)spec2.getOwnedDeclaration(); + IASTClassSpecifier A3 = (IASTClassSpecifier)spec3.getOwnedDeclaration(); + IASTClassSpecifier A4 = (IASTClassSpecifier)spec4.getOwnedDeclaration(); + IASTClassSpecifier A5 = (IASTClassSpecifier)spec5.getOwnedDeclaration(); + + assertEquals( ((IASTSimpleTypeSpecifier)a1.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A1 ); + assertEquals( ((IASTSimpleTypeSpecifier)a2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A2 ); + assertEquals( ((IASTSimpleTypeSpecifier)a4.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A4 ); + assertEquals( ((IASTSimpleTypeSpecifier)a5.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A5 ); + + } + + public void testTemplateInstanceAsBaseClause() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template< class T > class A { T t; }; \n" ); + writer.write( "class B : public A< int > {}; \n" ); + writer.write( "void f( int ); \n" ); + + writer.write( "void main(){ \n" ); + writer.write( " B b; \n" ); + writer.write( " f( b.t ); \n" ); //if this function call is good, it implies that b.t is type int + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); + IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); + IASTFunction f = (IASTFunction) i.next(); + IASTFunction main = (IASTFunction) i.next(); + assertFalse( i.hasNext() ); + + IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); + i = getDeclarations( A ); + IASTField t = (IASTField) i.next(); + assertFalse( i.hasNext() ); + + i = getDeclarations( main ); + + IASTVariable b = (IASTVariable) i.next(); + assertFalse( i.hasNext() ); + + assertAllReferences( 6, createTaskList( new Task( T ), + new Task( A ), + new Task( B ), + new Task( b ), + new Task( t ), + new Task( f ) ) ); + } + + public void testTemplateParameterAsBaseClause() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < class T > class A : public T {}; \n" ); + writer.write( "class B { int i; }; \n" ); + writer.write( "void main() { \n" ); + writer.write( " A a; \n" ); + writer.write( " a.i; \n" ); + writer.write( "} \n" ); + writer.write( "\n" ); + + Iterator iter = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) iter.next(); + IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); + IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)iter.next()).getTypeSpecifier(); + IASTFunction main = (IASTFunction) iter.next(); + assertFalse( iter.hasNext() ); + + IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); + + iter = getDeclarations( B ); + IASTVariable i = (IASTVariable) iter.next(); + + iter = getDeclarations( main ); + IASTVariable a = (IASTVariable) iter.next(); + + assertAllReferences( 5, createTaskList( new Task( T ), new Task( A ), new Task( B ), new Task( a ), new Task( i ) ) ); + } + + public void testTypedefedTemplate() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > class _A{ int x; }; \n" ); + writer.write( "typedef _A < char > A; \n" ); + writer.write( "void foo() { \n" ); + writer.write( " A a; \n" ); + writer.write( " a.x; \n" ); + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration _A = (IASTTemplateDeclaration) i.next(); + IASTTypedefDeclaration A = (IASTTypedefDeclaration) i.next(); + IASTFunction foo = (IASTFunction) i.next(); + + IASTClassSpecifier classA = (IASTClassSpecifier) _A.getOwnedDeclaration(); + IASTVariable x = (IASTVariable) getDeclarations( classA ).next(); + IASTVariable a = (IASTVariable) getDeclarations( foo ).next(); + + assertAllReferences( 4, createTaskList( new Task( classA ), new Task( A ), new Task( a ), new Task( x ) ) ); + } + + public void testTypedefedTemplate_2() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > struct A { T x; }; \n" ); + writer.write( "template < class U > struct B { \n" ); + writer.write( " typedef A< U > AU; \n" ); + writer.write( " void f( U ); \n" ); + writer.write( " void f( char ); \n" ); + writer.write( " void g(){ \n" ); + writer.write( " AU au; \n" ); + writer.write( " f( au.x ); \n" ); + writer.write( " } \n" ); + writer.write( "}; \n" ); + writer.write( "void f2( int ); \n" ); + writer.write( "void f2( char ); \n" ); + writer.write( "void h(){ \n" ); + writer.write( " B< int >::AU b; \n" ); + writer.write( " f2( b.x ); \n" ); + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration tA = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T = (IASTTemplateParameter) tA.getTemplateParameters().next(); + IASTClassSpecifier A = (IASTClassSpecifier) tA.getOwnedDeclaration(); + IASTField x = (IASTField) getDeclarations( A ).next(); + IASTTemplateDeclaration tB = (IASTTemplateDeclaration) i.next(); + IASTClassSpecifier B = (IASTClassSpecifier) tB.getOwnedDeclaration(); + IASTTemplateParameter U = (IASTTemplateParameter) tB.getTemplateParameters().next(); + IASTFunction f21 = (IASTFunction) i.next(); + IASTFunction f22 = (IASTFunction) i.next(); + IASTFunction h = (IASTFunction) i.next(); + + i = getDeclarations( B ); + IASTTypedefDeclaration AU = (IASTTypedefDeclaration) i.next(); + IASTMethod f11 = (IASTMethod) i.next(); + IASTMethod f12 = (IASTMethod) i.next(); + IASTMethod g = (IASTMethod) i.next(); + + IASTVariable au = (IASTVariable) getDeclarations( g ).next(); + IASTVariable b = (IASTVariable) getDeclarations( h ).next(); + + assertAllReferences( 13, createTaskList( new Task( A ), + new Task( T ), + new Task( U, 2 ), + new Task( AU, 2 ), + new Task( au ), + new Task( x, 2 ), + new Task( f11, 1, false, false ), + new Task( B ), + new Task( b ), + new Task( f21, 1, false, false ) ) ); + } + + public void testInstantiatingDeferredInstances() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > struct A { A < T > next; }; \n" ); + writer.write( "A< int > a; \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); + IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); + IASTField next = (IASTField) getDeclarations( A ).next(); + IASTVariable a = (IASTVariable) i.next(); + + assertAllReferences( 3, createTaskList( new Task( A, 2 ), new Task( T ) ) ); + } + + public void testTemplateArgumentDeduction() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template< class T > struct B {}; \n" ); + writer.write( "template< class T > struct D : public B < T > {}; \n" ); + writer.write( "struct D2 : public B< int > {}; \n" ); + writer.write( "template< class T > T f( B & ) {} \n" ); + writer.write( "void test( int ); \n" ); + writer.write( "void test( char ); \n" ); + writer.write( "void main() { \n" ); + writer.write( " D d; \n" ); + writer.write( " D2 d2; \n" ); + writer.write( " test( f( d ) ); \n" ); + writer.write( " test( f( d2 ) ); \n" ); + writer.write( "} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration templateB = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateD = (IASTTemplateDeclaration) i.next(); + IASTClassSpecifier D2 = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); + IASTTemplateDeclaration templateF = (IASTTemplateDeclaration) i.next(); + IASTFunction test1 = (IASTFunction) i.next(); + IASTFunction test2 = (IASTFunction) i.next(); + IASTFunction main = (IASTFunction) i.next(); + + assertFalse( i.hasNext() ); + assertReferenceTask( new Task( test1, 2, false, false ) ); + } + public void testClassTemplateStaticMemberDefinition() throws Exception { + Writer writer = new StringWriter(); + writer.write( "template< class T > class A{ \n" ); + writer.write( " typedef T * PT; \n" ); + writer.write( " static T member; \n" ); + writer.write( "}; \n" ); + writer.write( "template< class T> A::PT A::member = null; \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T1 = (IASTTemplateParameter) template.getTemplateParameters().next(); + IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); + IASTTemplateParameter T2 = (IASTTemplateParameter) template2.getTemplateParameters().next(); + + IASTField member = (IASTField) getDeclarations( template2 ).next(); + assertEquals( member.getName(), "member" ); + + assertReferenceTask( new Task( T1, 2, false, false ) ); + assertReferenceTask( new Task( T2, 2, false, false ) ); + } + + public void testTemplateTemplateParameter() throws Exception{ + Writer writer = new StringWriter(); + writer.write( " template< class T > class A { "); + writer.write( " int x; "); + writer.write( " }; "); + writer.write( " template < class T > class A < T * > { "); + writer.write( " long x; "); + writer.write( " }; "); + writer.write( " template< template< class U > class V > class C{ "); + writer.write( " V< int > y; "); + writer.write( " V< int * > z; "); + writer.write( " }; "); + writer.write( " void f( int ); "); + writer.write( " void f( long ); "); + writer.write( " void main() { "); + writer.write( " C< A > c; "); + writer.write( " f( c.y.x ); "); + writer.write( " f( c.z.x ); "); + writer.write( " } "); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateA2 = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateC = (IASTTemplateDeclaration) i.next(); + + IASTFunction f1 = (IASTFunction) i.next(); + IASTFunction f2 = (IASTFunction) i.next(); + + IASTFunction main = (IASTFunction) i.next(); + IASTVariable c = (IASTVariable) getDeclarations( main ).next(); + + IASTSimpleTypeSpecifier spec = (IASTSimpleTypeSpecifier) c.getAbstractDeclaration().getTypeSpecifier(); + IASTClassSpecifier C = (IASTClassSpecifier) spec.getTypeSpecifier(); + + assertReferenceTask( new Task( f1, 1, false, false ) ); + assertReferenceTask( new Task( f2, 1, false, false ) ); + } + + public void testBug56834() throws Exception{ + Iterator i = parse( "template < class T, class U = T > class A;" ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + + assertFalse( i.hasNext() ); + + i = template.getTemplateParameters(); + + IASTTemplateParameter T = (IASTTemplateParameter) i.next(); + IASTTemplateParameter U = (IASTTemplateParameter) i.next(); + } + + public void testDefaultTemplateParameters() throws Exception { + Iterator i = parse( "template < class T = int > class A{}; A<> a;" ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTVariable a = (IASTVariable) i.next(); + } + + public void testBug56834WithInstantiation() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template< class T, class U = T > class A {};" ); + writer.write( "A< char > a;" ); + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTVariable a = (IASTVariable) i.next(); + } + + public void testDefaultTemplateParameterWithDeferedInstance() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "template < class T > class A; \n" ); + writer.write( "template < class U, class V = A< U > > class B; \n" ); + writer.write( "B< int > b;" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next(); + IASTTemplateDeclaration templateB = (IASTTemplateDeclaration) i.next(); + IASTVariable b = (IASTVariable) i.next(); + } + + public void testExplicitInstantiation() throws Exception{ + + Writer writer = new StringWriter(); + writer.write( "template < class T > class A { }; " ); + writer.write( "template class A< int >; " ); + writer.write( "A< int > a; " ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); + IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); + IASTTemplateInstantiation instance = (IASTTemplateInstantiation) i.next(); + IASTVariable var = (IASTVariable) i.next(); + + assertAllReferences( 2, createTaskList( new Task( A, 2 ) ) ); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index 6cfe482598f..ccaf7864438 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -1283,249 +1283,7 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertFalse( f2.previouslyDeclared() ); assertFalse( i.hasNext() ); } - - public void testTemplateClassDeclaration() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template < class T > class A { T t; }; " ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - Iterator params = template.getTemplateParameters(); - - IASTTemplateParameter T = (IASTTemplateParameter) params.next(); - assertEquals( T.getIdentifier(), "T" ); - assertFalse( params.hasNext() ); - assertFalse( i.hasNext() ); - - i = getDeclarations( template ); - IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - assertEquals( classA.getName(), "A" ); - - assertFalse( i.hasNext() ); - - i = getDeclarations( classA ); - - IASTField t = (IASTField) i.next(); - assertEquals( t.getName(), "t" ); - - IASTSimpleTypeSpecifier specifier = (IASTSimpleTypeSpecifier) t.getAbstractDeclaration().getTypeSpecifier(); - assertEquals( specifier.getTypename(), "T" ); - //assertEquals( specifier.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed - } - - public void testTemplateFunction() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template < class T > void f( T t ){} " ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - - Iterator params = template.getTemplateParameters(); - - IASTTemplateParameter T = (IASTTemplateParameter) params.next(); - assertEquals( T.getIdentifier(), "T" ); - assertFalse( params.hasNext() ); - assertFalse( i.hasNext() ); - - i = getDeclarations( template ); - IASTFunction f = (IASTFunction) i.next(); - assertEquals( f.getName(), "f" ); - - params = f.getParameters(); - IASTParameterDeclaration t = (IASTParameterDeclaration) params.next(); - assertEquals( t.getName(), "t" ); - IASTSimpleTypeSpecifier typeSpec = (IASTSimpleTypeSpecifier) t.getTypeSpecifier(); - assertEquals( typeSpec.getTypename(), "T" ); - //assertEquals( typeSpec.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed - } - - public void testTemplateFunctionDefinition() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template void f( T t );" ); - writer.write( "template void f( U u ) { }" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - - Iterator params = template.getTemplateParameters(); - - IASTTemplateParameter T = (IASTTemplateParameter) params.next(); - assertEquals( T.getIdentifier(), "T" ); - assertFalse( params.hasNext() ); - - Iterator tempDecls = getDeclarations( template ); - IASTFunction f = (IASTFunction) tempDecls.next(); - assertEquals( f.getName(), "f" ); - assertFalse( f.hasFunctionBody() ); - assertFalse( tempDecls.hasNext() ); - - params = f.getParameters(); - IASTParameterDeclaration t = (IASTParameterDeclaration) params.next(); - assertEquals( t.getName(), "t" ); - IASTSimpleTypeSpecifier typeSpec = (IASTSimpleTypeSpecifier) t.getTypeSpecifier(); - assertEquals( typeSpec.getTypename(), "T" ); - //assertEquals( typeSpec.getTypeSpecifier(), T ); //TODO uncomment when bug 54029 is fixed - - IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); - - params = template2.getTemplateParameters(); - - IASTTemplateParameter U = (IASTTemplateParameter) params.next(); - assertEquals( U.getIdentifier(), "U" ); - assertFalse( params.hasNext() ); - - tempDecls = getDeclarations( template2 ); - IASTFunction f2 = (IASTFunction) tempDecls.next(); - assertEquals( f2.getName(), "f" ); - assertTrue( f2.previouslyDeclared() ); - - params = f2.getParameters(); - IASTParameterDeclaration u = (IASTParameterDeclaration) params.next(); - assertEquals( u.getName(), "u" ); - typeSpec = (IASTSimpleTypeSpecifier) u.getTypeSpecifier(); - assertEquals( typeSpec.getTypename(), "U" ); - //assertEquals( typeSpec.getTypeSpecifier(), U ); //TODO uncomment when bug 54029 is fixed - - assertFalse( i.hasNext() ); - } - - public void testClassMemberTemplate() throws Exception{ - Writer writer = new StringWriter(); - writer.write( "namespace N { " ); - writer.write( " class A { " ); - writer.write( " template < class T > T f();" ); - writer.write( " }; " ); - writer.write( "}" ); - writer.write( "template U N::A::f() {} " ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTNamespaceDefinition N = (IASTNamespaceDefinition) i.next(); - - Iterator i2 = getDeclarations( N ); - - IASTClassSpecifier A = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i2.next()).getTypeSpecifier(); - assertFalse( i2.hasNext() ); - - i2 = getDeclarations( A ); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i2.next(); - Iterator params = template.getTemplateParameters(); - IASTTemplateParameter T = (IASTTemplateParameter) params.next(); - assertFalse( params.hasNext() ); - assertFalse( i2.hasNext() ); - - i2 = getDeclarations( template ); - - IASTMethod f = (IASTMethod) i2.next(); - assertEquals( ((IASTSimpleTypeSpecifier)f.getReturnType().getTypeSpecifier()).getTypename(), "T" ); - assertFalse( i2.hasNext() ); - - IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); - params = template.getTemplateParameters(); - IASTTemplateParameter U = (IASTTemplateParameter) params.next(); - assertFalse( params.hasNext() ); - assertFalse( i.hasNext() ); - - i2 = getDeclarations( template2 ); - - IASTMethod f2 = (IASTMethod) i2.next(); - assertEquals( ((IASTSimpleTypeSpecifier)f2.getReturnType().getTypeSpecifier()).getTypename(), "U" ); - assertQualifiedName( f2.getFullyQualifiedName(), new String [] { "N", "A", "f" } ); - assertTrue( f2.previouslyDeclared() ); - assertFalse( i2.hasNext() ); - } - - public void testOverloadedFunctionTemplates() throws Exception - { - Writer writer = new StringWriter(); - writer.write( " template < class T > void f ( T ) {} " ); - writer.write( " template < class T > void f ( T * ) {} " ); - writer.write( " int * p;" ); - writer.write( " void main () {" ); - writer.write( " f( p );" ); - writer.write( " f( *p );" ); - writer.write( " }" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T1 = (IASTTemplateParameter) template1.getTemplateParameters().next(); - - IASTFunction f1 = (IASTFunction) template1.getOwnedDeclaration(); - - IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); - IASTFunction f2 = (IASTFunction) template2.getOwnedDeclaration(); - IASTTemplateParameter T2 = (IASTTemplateParameter) template2.getTemplateParameters().next(); - - IASTVariable p = (IASTVariable) i.next(); - IASTFunction main = (IASTFunction) i.next(); - assertFalse( i.hasNext() ); - - assertAllReferences( 6, createTaskList( new Task( T1 ), - new Task( T2 ), - new Task( f1, 1, false, false ), - new Task( p, 2 ), - new Task( f2, 1, false, false ) ) ); - - } - - public void testOverloadedFunctionTemplates_2() throws Exception - { - Writer writer = new StringWriter(); - writer.write("template< class T > struct A { }; \n"); - writer.write("template< class T > void h( const T & ); //#1 \n"); - writer.write("template< class T > void h( A& ); //#2 \n"); - writer.write("void foo() { \n"); - writer.write(" A z; \n"); - writer.write(" h( z ); //calls 2 \n"); - - writer.write(" const A z2; \n"); - writer.write(" h( z2 ); //calls 1 because 2 is not callable. \n"); - writer.write( "} \n"); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration templateh1 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration templateh2 = (IASTTemplateDeclaration) i.next(); - - IASTClassSpecifier A = (IASTClassSpecifier) templateA.getOwnedDeclaration(); - IASTFunction h1 = (IASTFunction) templateh1.getOwnedDeclaration(); - IASTFunction h2 = (IASTFunction) templateh2.getOwnedDeclaration(); - - IASTTemplateParameter T1 = (IASTTemplateParameter) templateA.getTemplateParameters().next(); - IASTTemplateParameter T2 = (IASTTemplateParameter) templateh1.getTemplateParameters().next(); - IASTTemplateParameter T3 = (IASTTemplateParameter) templateh2.getTemplateParameters().next(); - - IASTFunction foo = (IASTFunction) i.next(); - assertFalse( i.hasNext() ); - - i = getDeclarations( foo ); - IASTVariable z = (IASTVariable) i.next(); - IASTVariable z2 = (IASTVariable) i.next(); - assertFalse( i.hasNext() ); - - assertEquals( ((IASTSimpleTypeSpecifier)z.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A ); - assertEquals( ((IASTSimpleTypeSpecifier)z2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A ); - - assertAllReferences( 9, createTaskList( new Task( T2 ), - new Task( T3 ), - new Task( A, 3 ), - new Task( z ), - new Task( z2 ), - new Task( h1, 1, false, false ), - new Task( h2, 1, false, false ) ) ); - - - } public void testBug54639() throws Exception { Writer writer = new StringWriter(); @@ -1547,129 +1305,6 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertFalse( i.hasNext() ); } - public void testTemplateClassPartialSpecialization() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template < class T1, class T2, int I > class A {}; //#1\n" ); - writer.write( "template < class T, int I > class A < T, T*, I > {}; //#2\n"); - writer.write( "template < class T1, class T2, int I > class A < T1*, T2, I > {}; //#3\n"); - writer.write( "template < class T > class A < int, T*, 5 > {}; //#4\n"); - writer.write( "template < class T1, class T2, int I > class A < T1, T2*, I > {}; //#5\n"); - - writer.write( "A a1; //uses #1 \n"); - writer.write( "A a2; //uses #2, T is int, I is 1 \n"); - writer.write( "A a4; //uses #4, T is char \n"); - writer.write( "A a5; //uses #5, T is int, T2 is char, I is1 \n"); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - writer.write( " A amgiguous; //ambiguous, matches #3 & #5 \n"); - - try{ - //we expect this parse to fail because of the ambiguity in the last line - parse( writer.toString() ); - assertFalse( true ); - } catch ( ParserException e ){ - assertEquals( e.getMessage(), "FAILURE" ); - } - - IASTTemplateDeclaration template1 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration spec2 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration spec3 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration spec4 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration spec5 = (IASTTemplateDeclaration) i.next(); - - IASTVariable a1 = (IASTVariable) i.next(); - IASTVariable a2 = (IASTVariable) i.next(); - IASTVariable a4 = (IASTVariable) i.next(); - IASTVariable a5 = (IASTVariable) i.next(); - - assertFalse( i.hasNext() ); - - IASTClassSpecifier A1 = (IASTClassSpecifier)template1.getOwnedDeclaration(); - IASTClassSpecifier A2 = (IASTClassSpecifier)spec2.getOwnedDeclaration(); - IASTClassSpecifier A3 = (IASTClassSpecifier)spec3.getOwnedDeclaration(); - IASTClassSpecifier A4 = (IASTClassSpecifier)spec4.getOwnedDeclaration(); - IASTClassSpecifier A5 = (IASTClassSpecifier)spec5.getOwnedDeclaration(); - - assertEquals( ((IASTSimpleTypeSpecifier)a1.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A1 ); - assertEquals( ((IASTSimpleTypeSpecifier)a2.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A2 ); - assertEquals( ((IASTSimpleTypeSpecifier)a4.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A4 ); - assertEquals( ((IASTSimpleTypeSpecifier)a5.getAbstractDeclaration().getTypeSpecifier()).getTypeSpecifier(), A5 ); - - } - - public void testTemplateInstanceAsBaseClause() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template< class T > class A { T t; }; \n" ); - writer.write( "class B : public A< int > {}; \n" ); - writer.write( "void f( int ); \n" ); - - writer.write( "void main(){ \n" ); - writer.write( " B b; \n" ); - writer.write( " f( b.t ); \n" ); //if this function call is good, it implies that b.t is type int - writer.write( "} \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); - IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - IASTFunction f = (IASTFunction) i.next(); - IASTFunction main = (IASTFunction) i.next(); - assertFalse( i.hasNext() ); - - IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); - i = getDeclarations( A ); - IASTField t = (IASTField) i.next(); - assertFalse( i.hasNext() ); - - i = getDeclarations( main ); - - IASTVariable b = (IASTVariable) i.next(); - assertFalse( i.hasNext() ); - - assertAllReferences( 6, createTaskList( new Task( T ), - new Task( A ), - new Task( B ), - new Task( b ), - new Task( t ), - new Task( f ) ) ); - } - - public void testTemplateParameterAsBaseClause() throws Exception - { - Writer writer = new StringWriter(); - writer.write( "template < class T > class A : public T {}; \n" ); - writer.write( "class B { int i; }; \n" ); - writer.write( "void main() { \n" ); - writer.write( " A a; \n" ); - writer.write( " a.i; \n" ); - writer.write( "} \n" ); - writer.write( "\n" ); - - Iterator iter = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) iter.next(); - IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); - IASTClassSpecifier B = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)iter.next()).getTypeSpecifier(); - IASTFunction main = (IASTFunction) iter.next(); - assertFalse( iter.hasNext() ); - - IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); - - iter = getDeclarations( B ); - IASTVariable i = (IASTVariable) iter.next(); - - iter = getDeclarations( main ); - IASTVariable a = (IASTVariable) iter.next(); - - assertAllReferences( 5, createTaskList( new Task( T ), new Task( A ), new Task( B ), new Task( a ), new Task( i ) ) ); - } - - - public void testBug55163() throws Exception { Writer writer = new StringWriter(); @@ -1691,125 +1326,6 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertAllReferences( 7, createTaskList( new Task( n ), new Task( i, 5 ), new Task( di ) ) ); } - public void testTypedefedTemplate() throws Exception{ - Writer writer = new StringWriter(); - writer.write( "template < class T > class _A{ int x; }; \n" ); - writer.write( "typedef _A < char > A; \n" ); - writer.write( "void foo() { \n" ); - writer.write( " A a; \n" ); - writer.write( " a.x; \n" ); - writer.write( "} \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration _A = (IASTTemplateDeclaration) i.next(); - IASTTypedefDeclaration A = (IASTTypedefDeclaration) i.next(); - IASTFunction foo = (IASTFunction) i.next(); - - IASTClassSpecifier classA = (IASTClassSpecifier) _A.getOwnedDeclaration(); - IASTVariable x = (IASTVariable) getDeclarations( classA ).next(); - IASTVariable a = (IASTVariable) getDeclarations( foo ).next(); - - assertAllReferences( 4, createTaskList( new Task( classA ), new Task( A ), new Task( a ), new Task( x ) ) ); - } - - public void testTypedefedTemplate_2() throws Exception{ - Writer writer = new StringWriter(); - writer.write( "template < class T > struct A { T x; }; \n" ); - writer.write( "template < class U > struct B { \n" ); - writer.write( " typedef A< U > AU; \n" ); - writer.write( " void f( U ); \n" ); - writer.write( " void f( char ); \n" ); - writer.write( " void g(){ \n" ); - writer.write( " AU au; \n" ); - writer.write( " f( au.x ); \n" ); - writer.write( " } \n" ); - writer.write( "}; \n" ); - writer.write( "void f2( int ); \n" ); - writer.write( "void f2( char ); \n" ); - writer.write( "void h(){ \n" ); - writer.write( " B< int >::AU b; \n" ); - writer.write( " f2( b.x ); \n" ); - writer.write( "} \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration tA = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T = (IASTTemplateParameter) tA.getTemplateParameters().next(); - IASTClassSpecifier A = (IASTClassSpecifier) tA.getOwnedDeclaration(); - IASTField x = (IASTField) getDeclarations( A ).next(); - IASTTemplateDeclaration tB = (IASTTemplateDeclaration) i.next(); - IASTClassSpecifier B = (IASTClassSpecifier) tB.getOwnedDeclaration(); - IASTTemplateParameter U = (IASTTemplateParameter) tB.getTemplateParameters().next(); - IASTFunction f21 = (IASTFunction) i.next(); - IASTFunction f22 = (IASTFunction) i.next(); - IASTFunction h = (IASTFunction) i.next(); - - i = getDeclarations( B ); - IASTTypedefDeclaration AU = (IASTTypedefDeclaration) i.next(); - IASTMethod f11 = (IASTMethod) i.next(); - IASTMethod f12 = (IASTMethod) i.next(); - IASTMethod g = (IASTMethod) i.next(); - - IASTVariable au = (IASTVariable) getDeclarations( g ).next(); - IASTVariable b = (IASTVariable) getDeclarations( h ).next(); - - assertAllReferences( 13, createTaskList( new Task( A ), - new Task( T ), - new Task( U, 2 ), - new Task( AU, 2 ), - new Task( au ), - new Task( x, 2 ), - new Task( f11, 1, false, false ), - new Task( B ), - new Task( b ), - new Task( f21, 1, false, false ) ) ); - } - - public void testInstantiatingDeferredInstances() throws Exception{ - Writer writer = new StringWriter(); - writer.write( "template < class T > struct A { A < T > next; }; \n" ); - writer.write( "A< int > a; \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T = (IASTTemplateParameter) template.getTemplateParameters().next(); - IASTClassSpecifier A = (IASTClassSpecifier) template.getOwnedDeclaration(); - IASTField next = (IASTField) getDeclarations( A ).next(); - IASTVariable a = (IASTVariable) i.next(); - - assertAllReferences( 3, createTaskList( new Task( A, 2 ), new Task( T ) ) ); - } - - public void testTemplateArgumentDeduction() throws Exception{ - Writer writer = new StringWriter(); - writer.write( "template< class T > struct B {}; \n" ); - writer.write( "template< class T > struct D : public B < T > {}; \n" ); - writer.write( "struct D2 : public B< int > {}; \n" ); - writer.write( "template< class T > T f( B & ) {} \n" ); - writer.write( "void test( int ); \n" ); - writer.write( "void test( char ); \n" ); - writer.write( "void main() { \n" ); - writer.write( " D d; \n" ); - writer.write( " D2 d2; \n" ); - writer.write( " test( f( d ) ); \n" ); - writer.write( " test( f( d2 ) ); \n" ); - writer.write( "} \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration templateB = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration templateD = (IASTTemplateDeclaration) i.next(); - IASTClassSpecifier D2 = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); - IASTTemplateDeclaration templateF = (IASTTemplateDeclaration) i.next(); - IASTFunction test1 = (IASTFunction) i.next(); - IASTFunction test2 = (IASTFunction) i.next(); - IASTFunction main = (IASTFunction) i.next(); - - assertFalse( i.hasNext() ); - assertReferenceTask( new Task( test1, 2, false, false ) ); - } public void testBug55673() throws Exception{ Writer writer = new StringWriter(); writer.write( "struct Example { int i; int ( * pfi ) ( int ); }; "); @@ -1836,65 +1352,4 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertEquals( thePointer.getName(), "pA" ); assertFalse( i.hasNext() ); } - - public void testClassTemplateStaticMemberDefinition() throws Exception { - Writer writer = new StringWriter(); - writer.write( "template< class T > class A{ \n" ); - writer.write( " typedef T * PT; \n" ); - writer.write( " static T member; \n" ); - writer.write( "}; \n" ); - writer.write( "template< class T> A::PT A::member = null; \n" ); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T1 = (IASTTemplateParameter) template.getTemplateParameters().next(); - IASTTemplateDeclaration template2 = (IASTTemplateDeclaration) i.next(); - IASTTemplateParameter T2 = (IASTTemplateParameter) template2.getTemplateParameters().next(); - - IASTField member = (IASTField) getDeclarations( template2 ).next(); - assertEquals( member.getName(), "member" ); - - assertReferenceTask( new Task( T1, 2, false, false ) ); - assertReferenceTask( new Task( T2, 2, false, false ) ); - } - - public void testTemplateTemplateParameter() throws Exception{ - Writer writer = new StringWriter(); - writer.write( " template< class T > class A { "); - writer.write( " int x; "); - writer.write( " }; "); - writer.write( " template < class T > class A < T * > { "); - writer.write( " long x; "); - writer.write( " }; "); - writer.write( " template< template< class U > class V > class C{ "); - writer.write( " V< int > y; "); - writer.write( " V< int * > z; "); - writer.write( " }; "); - writer.write( " void f( int ); "); - writer.write( " void f( long ); "); - writer.write( " void main() { "); - writer.write( " C< A > c; "); - writer.write( " f( c.y.x ); "); - writer.write( " f( c.z.x ); "); - writer.write( " } "); - - Iterator i = parse( writer.toString() ).getDeclarations(); - - IASTTemplateDeclaration templateA = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration templateA2 = (IASTTemplateDeclaration) i.next(); - IASTTemplateDeclaration templateC = (IASTTemplateDeclaration) i.next(); - - IASTFunction f1 = (IASTFunction) i.next(); - IASTFunction f2 = (IASTFunction) i.next(); - - IASTFunction main = (IASTFunction) i.next(); - IASTVariable c = (IASTVariable) getDeclarations( main ).next(); - - IASTSimpleTypeSpecifier spec = (IASTSimpleTypeSpecifier) c.getAbstractDeclaration().getTypeSpecifier(); - IASTClassSpecifier C = (IASTClassSpecifier) spec.getTypeSpecifier(); - - assertReferenceTask( new Task( f1, 1, false, false ) ); - assertReferenceTask( new Task( f2, 1, false, false ) ); - } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java index 4d93e393163..a5acda5afb3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTest.java @@ -365,8 +365,7 @@ public class CompleteParseBaseTest extends TestCase */ public void enterTemplateInstantiation(IASTTemplateInstantiation instantiation) { - // TODO Auto-generated method stub - + pushScope( instantiation ); } /* (non-Javadoc) @@ -427,8 +426,8 @@ public class CompleteParseBaseTest extends TestCase */ public void exitTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) { - // TODO Auto-generated method stub - + popScope(); + getCurrentScope().addDeclaration( instantiation ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java index bbf24c4a600..66537abbc05 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java @@ -41,6 +41,7 @@ public class ParserTestSuite extends TestCase { suite.addTestSuite( SelectionParseTest.class ); suite.addTestSuite( CompleteParseASTExpressionTest.class ); suite.addTestSuite( CompleteParseASTSymbolIteratorTest.class ); + suite.addTestSuite( CompleteParseASTTemplateTest.class ); return suite; } } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser index 86b73eca41f..3671630e255 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ b/core/org.eclipse.cdt.core/parser/ChangeLog-parser @@ -1,3 +1,9 @@ +2004-04-02 Andrew Niefer + - partial handling template explicit instantiations + - bug 56834 - Symbols not available until end of parameter list, fixed for templates using temporary code block + - change IASTFactory.createTemplateParameter to take an IASTTypeId for the default value + - handle instantiating templates using default value that is a deferred instance + 2004-04-02 John Camelon Updated SelectionSearch to work for functions, variables with initializers, etc. Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=39705 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java index 8b7b0352a10..ca89659dedb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java @@ -210,7 +210,7 @@ public interface IASTFactory public IASTTemplateDeclaration createTemplateDeclaration( IASTScope scope, List templateParameters, boolean exported, int startingOffset, int startingLine ) throws ASTSemanticException; - public IASTTemplateParameter createTemplateParameter( IASTTemplateParameter.ParamKind kind, String identifier, String defaultValue, IASTParameterDeclaration parameter, List parms ) throws ASTSemanticException; + public IASTTemplateParameter createTemplateParameter( IASTTemplateParameter.ParamKind kind, String identifier, IASTTypeId defaultValue, IASTParameterDeclaration parameter, List parms, IASTCodeScope parameterScope ) throws ASTSemanticException; public IASTTemplateInstantiation createTemplateInstantiation(IASTScope scope, int startingOffset, int startingLine); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateInstantiation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateInstantiation.java index e6c30e943fe..17b89080051 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateInstantiation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTTemplateInstantiation.java @@ -14,6 +14,8 @@ package org.eclipse.cdt.core.parser.ast; * @author jcamelon * */ -public interface IASTTemplateInstantiation extends IASTTemplate, IASTDeclaration, IASTOffsetableElement { - +public interface IASTTemplateInstantiation extends IASTTemplate, IASTDeclaration, IASTScope, IASTOffsetableElement { + + public IASTTemplateDeclaration getInstantiatedTemplate(); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index f2f297eadc4..5180ec6a136 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -445,7 +445,7 @@ public abstract class Parser extends ExpressionParser implements IParser throw backtrack; } templateInstantiation.enterScope( requestor ); - declaration(scope, templateInstantiation, null); + declaration(templateInstantiation, templateInstantiation, null); templateInstantiation.setEndingOffsetAndLineNumber(lastToken.getEndOffset(), lastToken.getLineNumber()); templateInstantiation.exitScope( requestor ); @@ -546,6 +546,10 @@ public abstract class Parser extends ExpressionParser implements IParser // iterate through the template parameter list List returnValue = new ArrayList(); + IASTScope parameterScope = astFactory.createNewCodeBlock( scope ); + if( parameterScope == null ) + parameterScope = scope; + for (;;) { if (LT(1) == IToken.tGT) @@ -568,7 +572,7 @@ public abstract class Parser extends ExpressionParser implements IParser if (LT(1) == IToken.tASSIGN) // optional = type-id { consume(IToken.tASSIGN); - typeId = typeId(scope, false); // type-id + typeId = typeId(parameterScope, false); // type-id } } @@ -583,9 +587,10 @@ public abstract class Parser extends ExpressionParser implements IParser astFactory.createTemplateParameter( kind, ( id == null )? "" : id.getImage(), //$NON-NLS-1$ - (typeId == null) ? null : typeId.getTypeOrClassName(), + typeId, null, - null)); + null, + ( parameterScope instanceof IASTCodeScope ) ? (IASTCodeScope) parameterScope : null )); } catch (Exception e) { @@ -598,7 +603,7 @@ public abstract class Parser extends ExpressionParser implements IParser consume(IToken.t_template); consume(IToken.tLT); - List subResult = templateParameterList(scope); + List subResult = templateParameterList(parameterScope); consume(IToken.tGT); consume(IToken.t_class); IToken optionalId = null; @@ -610,7 +615,7 @@ public abstract class Parser extends ExpressionParser implements IParser if (LT(1) == IToken.tASSIGN) // optional = type-id { consume(IToken.tASSIGN); - optionalTypeId = typeId(scope, false); + optionalTypeId = typeId(parameterScope, false); } } @@ -621,9 +626,10 @@ public abstract class Parser extends ExpressionParser implements IParser astFactory.createTemplateParameter( IASTTemplateParameter.ParamKind.TEMPLATE_LIST, ( optionalId == null )? "" : optionalId.getImage(), //$NON-NLS-1$ - ( optionalTypeId == null ) ? "" : optionalTypeId.toString(), //$NON-NLS-1$ + optionalTypeId, null, - subResult)); + subResult, + ( parameterScope instanceof IASTCodeScope ) ? (IASTCodeScope) parameterScope : null )); } catch (Exception e) { @@ -638,7 +644,7 @@ public abstract class Parser extends ExpressionParser implements IParser else { ParameterCollection c = new ParameterCollection(); - parameterDeclaration(c, scope); + parameterDeclaration(c, parameterScope); DeclarationWrapper wrapper = (DeclarationWrapper)c.getParameters().get(0); Declarator declarator = @@ -659,7 +665,8 @@ public abstract class Parser extends ExpressionParser implements IParser null, null, declarator.getName() == null ? "" //$NON-NLS-1$ : declarator.getName(), declarator.getInitializerClause(), wrapper.getStartingOffset(), wrapper.getStartingLine(), declarator.getNameStartOffset(), declarator.getNameEndOffset(), declarator.getNameLine(), wrapper.getEndOffset(), wrapper.getEndLine()), - null)); + null, + ( parameterScope instanceof IASTCodeScope ) ? (IASTCodeScope) parameterScope : null )); } catch (Exception e) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateInstantiation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateInstantiation.java index a41a5bcdcd8..d217bf423e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateInstantiation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateInstantiation.java @@ -10,25 +10,73 @@ ***********************************************************************/ package org.eclipse.cdt.internal.core.parser.ast.complete; +import java.util.Iterator; + import org.eclipse.cdt.core.parser.ISourceElementRequestor; +import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.IASTDeclaration; import org.eclipse.cdt.core.parser.ast.IASTScope; +import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation; +import org.eclipse.cdt.internal.core.parser.ast.NamedOffsets; +import org.eclipse.cdt.internal.core.parser.pst.ForewardDeclaredSymbolExtension; +import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; +import org.eclipse.cdt.internal.core.parser.pst.ISymbol; +import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension; +import org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory; +import org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol; +import org.eclipse.cdt.internal.core.parser.pst.StandardSymbolExtension; /** * @author jcamelon * */ -public class ASTTemplateInstantiation extends ASTNode implements IASTTemplateInstantiation +public class ASTTemplateInstantiation extends ASTSymbol implements IASTTemplateInstantiation { - /** - * - */ - public ASTTemplateInstantiation() - { - super(); - // TODO Auto-generated constructor stub + private ITemplateFactory factory; + private IASTScope ownerScope; + private IASTTemplateDeclaration instantiatedTemplate; + private ISymbol instance; + + private NamedOffsets offsets = new NamedOffsets(); + + public ASTTemplateInstantiation( IASTScope scope ){ + super( null ); + IContainerSymbol container = ((ASTScope)scope).getContainerSymbol(); + + factory = container.getSymbolTable().newTemplateFactory(); + factory.setContainingSymbol( container ); + + factory.setASTExtension( new StandardSymbolExtension( factory, this ) ); + + factory.pushTemplate( null ); + ownerScope = scope; } + + public IASTTemplateDeclaration getInstantiatedTemplate(){ + return instantiatedTemplate; + } + + public void releaseFactory(){ + factory = null; + } + + public void setInstanceSymbol( ISymbol sym ){ + instance = sym; + ITemplateSymbol template = (ITemplateSymbol) instance.getInstantiatedSymbol().getContainingSymbol(); + instantiatedTemplate = (IASTTemplateDeclaration) template.getASTExtension().getPrimaryDeclaration(); + setSymbol( instance.getInstantiatedSymbol().getContainingSymbol() ); + } + + public ISymbol getInstanceSymbol(){ + return instance; + } + + public IContainerSymbol getContainerSymbol() + { + return factory != null ? (IContainerSymbol) factory : ((ASTTemplateDeclaration)getInstantiatedTemplate()).getContainerSymbol(); + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTTemplate#getOwnedDeclaration() */ @@ -49,38 +97,47 @@ public class ASTTemplateInstantiation extends ASTNode implements IASTTemplateIns */ public void setStartingOffsetAndLineNumber(int offset, int lineNumber) { - // TODO Auto-generated method stub + offsets.setStartingOffsetAndLineNumber( offset, lineNumber ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#setEndingOffset(int) */ public void setEndingOffsetAndLineNumber(int offset, int lineNumber) { - // TODO Auto-generated method stub + offsets.setEndingOffsetAndLineNumber( offset, lineNumber ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingOffset() */ public int getStartingOffset() { - // TODO Auto-generated method stub - return 0; + return offsets.getStartingOffset(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingOffset() */ public int getEndingOffset() { - // TODO Auto-generated method stub - return 0; + return offsets.getEndingOffset(); } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine() + */ + public int getStartingLine() { + return offsets.getStartingLine(); + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine() + */ + public int getEndingLine() { + return offsets.getEndingLine(); + } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTScopedElement#getOwnerScope() */ public IASTScope getOwnerScope() { - // TODO Auto-generated method stub - return null; + return ownerScope; } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor) @@ -94,27 +151,35 @@ public class ASTTemplateInstantiation extends ASTNode implements IASTTemplateIns */ public void enterScope(ISourceElementRequestor requestor) { - // TODO Auto-generated method stub + try + { + requestor.enterTemplateInstantiation(this); + } + catch (Exception e) + { + /* do nothing */ + } } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate#exitScope(org.eclipse.cdt.core.parser.ISourceElementRequestor) */ public void exitScope(ISourceElementRequestor requestor) { - // TODO Auto-generated method stub + try + { + requestor.exitTemplateExplicitInstantiation(this); + } + catch (Exception e) + { + /* do nothing */ + } } + /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getStartingLine() + * @see org.eclipse.cdt.core.parser.ast.IASTScope#getDeclarations() */ - public int getStartingLine() { + public Iterator getDeclarations() throws ASTNotImplementedException { // TODO Auto-generated method stub - return 0; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.ast.IASTOffsetableElement#getEndingLine() - */ - public int getEndingLine() { - // TODO Auto-generated method stub - return 0; + return null; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateParameter.java index 79c16890be6..4833a8df7d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTTemplateParameter.java @@ -13,6 +13,7 @@ import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.ast.IASTOffsetableNamedElement; import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter; +import org.eclipse.cdt.core.parser.ast.IASTTypeId; import org.eclipse.cdt.internal.core.parser.ast.NamedOffsets; import org.eclipse.cdt.internal.core.parser.pst.ISymbol; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo; @@ -28,7 +29,7 @@ public class ASTTemplateParameter extends ASTSymbol implements IASTTemplateParam // private ParamKind kind; // private String identifier; //private ISymbol symbol; - private String defaultValue; + private IASTTypeId defaultValue; private ASTParameterDeclaration parameter; private List parms; private final NamedOffsets offsets = new NamedOffsets(); @@ -39,7 +40,7 @@ public class ASTTemplateParameter extends ASTSymbol implements IASTTemplateParam * @param parameter2 * @param parms2 */ - public ASTTemplateParameter(ISymbol sym, String defVal, IASTParameterDeclaration param, List parms ) { + public ASTTemplateParameter(ISymbol sym, IASTTypeId defVal, IASTParameterDeclaration param, List parms ) { super( sym ); symbol = sym; defaultValue = defVal; @@ -69,7 +70,7 @@ public class ASTTemplateParameter extends ASTSymbol implements IASTTemplateParam * @see org.eclipse.cdt.core.parser.ast.IASTTemplateParameter#getDefaultValueIdExpression() */ public String getDefaultValueIdExpression() { - return defaultValue; + return ( defaultValue != null ) ? defaultValue.toString() : ""; //$NON-NLS-1$ } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTTemplateParameter#getParameterDeclaration() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index b3361197c7e..637c480ef37 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -481,6 +481,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto return ((ASTScope)currentScope).getContainerSymbol(); else if ( currentScope instanceof ASTTemplateDeclaration ) return ((ASTTemplateDeclaration)currentScope).getContainerSymbol(); + else if ( currentScope instanceof ASTTemplateInstantiation ) + return ((ASTTemplateInstantiation)currentScope).getContainerSymbol(); else return scopeToSymbol(((ASTAnonymousDeclaration)currentScope).getOwnerScope()); } @@ -678,7 +680,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( name.getSegmentCount() != 1 ) // qualified name { ITokenDuple containerSymbolName = name.getLeadingSegments(); - currentScopeSymbol = (IContainerSymbol)lookupQualifiedName( currentScopeSymbol, containerSymbolName, references, true); + ISymbol temp = lookupQualifiedName( currentScopeSymbol, containerSymbolName, references, true); + if( temp instanceof IDeferredTemplateInstance ) + currentScopeSymbol = ((IDeferredTemplateInstance)temp).getTemplate().getTemplatedSymbol(); + else + currentScopeSymbol = (IContainerSymbol) temp; if( currentScopeSymbol == null ) handleProblem( IProblem.SEMANTIC_NAME_NOT_FOUND, containerSymbolName.toString(), containerSymbolName.getFirstToken().getOffset(), containerSymbolName.getLastToken().getEndOffset(), containerSymbolName.getLastToken().getLineNumber() ); @@ -689,13 +695,13 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto //template-id List [] array = name.getTemplateIdArgLists(); if( array != null ){ - isTemplateId = true; templateIdArgList = array[ array.length - 1 ]; + isTemplateId = (templateIdArgList != null); } newSymbolName = nameToken.getImage(); } - + int i = 0; ISymbol classSymbol = null; if( !newSymbolName.equals("") && !isTemplateId ){ //$NON-NLS-1$ try @@ -843,6 +849,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto */ protected IASTReference createReference(ISymbol symbol, String referenceElementName, int offset ) throws ASTSemanticException { + if( symbol.getASTExtension() == null ){ + //referenced symbol doesn't have an attached AST node, could happen say for the copy constructor added + //by the symbol table. + return null; + } + // assert (symbol != null ) : "createReference cannot be called on null symbol "; if( symbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) || symbol.getASTExtension().getPrimaryDeclaration() instanceof IASTTypedefDeclaration ) @@ -1756,7 +1768,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } catch (ParserSymbolTableException e) { - handleProblem( e.createProblemID(), image ); + handleProblem( e.createProblemID(), image,typeName.getStartOffset(), typeName.getEndOffset(), typeName.getLineNumber() ); } } s.setTypeSymbol( typeSymbol ); @@ -2360,7 +2372,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto newSymbol); setPointerOperators( newSymbol, abstractDeclaration.getPointerOperators(), abstractDeclaration.getArrayModifiers() ); - newSymbol.setIsForwardDeclaration(isStatic); + newSymbol.setIsForwardDeclaration( isStatic || isExtern ); boolean previouslyDeclared = false; if(!isStatic){ ISymbol variableDeclaration = lookupQualifiedName(ownerScope, name.toString(), new ArrayList(), false, LookupType.UNQUALIFIED); @@ -2639,9 +2651,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto public IASTTemplateParameter createTemplateParameter( ParamKind kind, String identifier, - String defaultValue, + IASTTypeId defaultValue, IASTParameterDeclaration parameter, - List parms ) throws ASTSemanticException + List parms, + IASTCodeScope parameterScope ) throws ASTSemanticException { ISymbol symbol = null; if( kind == ParamKind.TEMPLATE_LIST ){ @@ -2674,6 +2687,18 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } } + IContainerSymbol codeScope = ((ASTCodeScope)parameterScope).getContainerSymbol(); + try { + codeScope.addSymbol( symbol ); + } catch (ParserSymbolTableException e) { + } + + if( defaultValue != null ){ + try { + symbol.getTypeInfo().setDefault( defaultValue.getTypeSymbol().getTypeInfo() ); + } catch (ASTNotImplementedException e1) { + } + } ASTTemplateParameter ast = new ASTTemplateParameter( symbol, defaultValue, parameter, parms ); attachSymbolExtension( symbol, ast, false ); @@ -2687,8 +2712,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto IASTScope scope, int startingOffset, int startingLine) { - // TODO Auto-generated method stub - return new ASTTemplateInstantiation(); + return new ASTTemplateInstantiation( scope ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTScope, int) @@ -2811,7 +2835,21 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( isForewardDecl ) { - if( checkSymbol == null ) + if( scope instanceof IASTTemplateInstantiation ) + { + if( isTemplateId ){ + checkSymbol = pst.newDerivableContainerSymbol( newSymbolName, pstType ); + try { + currentScopeSymbol.addTemplateId( checkSymbol, args ); + } catch (ParserSymbolTableException e) { + handleProblem(e.createProblemID(),nameToken.getImage(), nameToken.getOffset(), nameToken.getEndOffset(), nameToken.getLineNumber() ); + } + } else { + handleProblem( IProblem.SEMANTIC_INVALID_TEMPLATE, nameToken.getImage() ); + } + checkSymbol = ((ASTTemplateInstantiation)scope).getInstanceSymbol(); + } + else if( checkSymbol == null ) { checkSymbol = pst.newDerivableContainerSymbol( newSymbolName, pstType ); checkSymbol.setIsForwardDeclaration( true ); @@ -2841,7 +2879,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto } if( checkSymbol != null ){ - if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTClassSpecifier || + if( scope instanceof IASTTemplateInstantiation ){ + addReference( references, createReference( checkSymbol, newSymbolName, nameToken.getOffset() )); + } + if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTClassSpecifier || checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTEnumerationSpecifier ) { @@ -2849,7 +2890,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto attachSymbolExtension( checkSymbol, elab, isForewardDecl ); return elab; } - + if( checkSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTElaboratedTypeSpecifier ) return (IASTElaboratedTypeSpecifier)checkSymbol.getASTExtension().getPrimaryDeclaration(); } else { @@ -2966,6 +3007,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto return TypeInfo.t__Bool; else if( type == IASTSimpleTypeSpecifier.Type.CHAR ) return TypeInfo.t_char; + else if ( type == IASTSimpleTypeSpecifier.Type.WCHAR_T ) + return TypeInfo.t_wchar_t; else if( type == IASTSimpleTypeSpecifier.Type.DOUBLE ) return TypeInfo.t_double; else if( type == IASTSimpleTypeSpecifier.Type.FLOAT ) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java index 2bbcd59c459..5ac36dcaa39 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/expression/ExpressionParseASTFactory.java @@ -754,9 +754,9 @@ public class ExpressionParseASTFactory extends BaseASTFactory implements IASTFac public IASTTemplateParameter createTemplateParameter( ParamKind kind, String identifier, - String defaultValue, + IASTTypeId defaultValue, IASTParameterDeclaration parameter, - List parms) { + List parms, IASTCodeScope parameterScope) { // TODO Auto-generated method stub return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateInstantiation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateInstantiation.java index 11f09f59f4d..fa75fafbef3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateInstantiation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/ASTTemplateInstantiation.java @@ -10,9 +10,13 @@ ***********************************************************************/ package org.eclipse.cdt.internal.core.parser.ast.quick; +import java.util.Iterator; + import org.eclipse.cdt.core.parser.ISourceElementRequestor; +import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.IASTDeclaration; import org.eclipse.cdt.core.parser.ast.IASTScope; +import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration; import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation; import org.eclipse.cdt.internal.core.parser.ast.Offsets; @@ -133,5 +137,21 @@ public class ASTTemplateInstantiation extends ASTDeclaration implements IASTTemp public int getEndingLine() { return offsets.getEndingLine(); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation#getInstantiatedTemplate() + */ + public IASTTemplateDeclaration getInstantiatedTemplate() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.parser.ast.IASTScope#getDeclarations() + */ + public Iterator getDeclarations() throws ASTNotImplementedException { + // TODO Auto-generated method stub + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java index d3b58171a9c..a14486ab62b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java @@ -256,9 +256,9 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTFactory#createTemplateParameter(org.eclipse.cdt.core.parser.ast.IASTTemplateParameter.ParameterKind, org.eclipse.cdt.core.parser.IToken, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration) */ - public IASTTemplateParameter createTemplateParameter(IASTTemplateParameter.ParamKind kind, String identifier, String defaultValue, IASTParameterDeclaration parameter, List parms) + public IASTTemplateParameter createTemplateParameter(IASTTemplateParameter.ParamKind kind, String identifier, IASTTypeId defaultValue, IASTParameterDeclaration parameter, List parms, IASTCodeScope parameterScope) { - return new ASTTemplateParameter( kind, identifier, defaultValue, parameter, parms ); + return new ASTTemplateParameter( kind, identifier, defaultValue != null ? defaultValue.getTypeOrClassName() : "", parameter, parms ); //$NON-NLS-1$ } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java index cf92879573d..1b2c4456370 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateFactory.java @@ -19,6 +19,7 @@ import java.util.Map; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateDeclaration; +import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTemplateInstantiation; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp; import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.eType; @@ -63,8 +64,11 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor ITemplateSymbol template = (ITemplateSymbol) templates.get( templates.size() - 1 ); - List params = template.getParameterList(); - if( params.size() == 0 ){ + List params = ( template != null ) ? template.getParameterList() : null; + if( params == null ){ + //explicit instantiation + addExplicitInstantiation( origTemplate, args ); + } else if( params.size() == 0 ){ //explicit specialization addExplicitSpecialization( origTemplate, symbol, args ); } else { @@ -260,6 +264,15 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor } } + private void addExplicitInstantiation( ITemplateSymbol origTemplate, List args ) throws ParserSymbolTableException { + ISymbol instance = origTemplate.instantiate( args ); + + if( getASTExtension() != null ){ + ASTTemplateInstantiation templateInstance = (ASTTemplateInstantiation) getASTExtension().getPrimaryDeclaration(); + templateInstance.releaseFactory(); + templateInstance.setInstanceSymbol( instance ); + } + } private void addExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ) throws ParserSymbolTableException { Iterator templatesIter = templates.iterator(); Iterator argsIter = arguments.iterator(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java index 8f7fdc5f9fa..80e9c95e15c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateSymbol.java @@ -122,6 +122,10 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument ); } + } else if( arg.isType( TypeInfo.t_type ) && arg.getTypeSymbol() instanceof IDeferredTemplateInstance ){ + IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) arg.getTypeSymbol(); + arg = new TypeInfo( arg ); + arg.setTypeSymbol( deferred.instantiate( this, map ) ); } } else { throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );