From 8dde2f9a0e0b65939b77be783da630d360ee3975 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Fri, 26 Mar 2004 20:08:05 +0000 Subject: [PATCH] better handling of template template parameters --- core/org.eclipse.cdt.core.tests/ChangeLog | 16 +++++--- .../parser/tests/CompleteParseASTTest.java | 39 ++++++++++++++++++ .../parser/ChangeLog-parser | 3 ++ .../ast/complete/CompleteParseASTFactory.java | 40 +++++++++++++------ .../core/parser/pst/ContainerSymbol.java | 12 +++++- .../parser/pst/DeferredTemplateInstance.java | 30 ++++++++++++-- .../core/parser/pst/TemplateSymbol.java | 2 +- 7 files changed, 118 insertions(+), 24 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 0420314e266..9097949990d 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,4 +1,8 @@ -2003-04-26 Andrew Niefer +2004-03-26 Andrew Niefer + template template parameters + - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateTemplateParameter() + +2004-03-26 Andrew Niefer test references to symbols in template-ids - modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testOverloadedFunctionTemplates_2() - modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateParameterAsBaseClause() @@ -6,26 +10,26 @@ - modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testInstantiatingDeferredInstances() - modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testClassTemplateStaticMemberDefinition() -2003-04-25 Andrew Niefer +2004-03-25 Andrew Niefer -added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testClassTemplateStaticMemberDefinition() -modified parser/org/eclipse/cdt/core/parser/tests/QuickParseASTTests.testPointersToMemberFunctions -2003-03-23 Andrew Niefer +2004-03-23 Andrew Niefer bug 55673 & fix recursive loop in template instantiation -parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testInstantiatingDeferredInstances() -parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTemplateArgumentDeduction() -parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testBug55673() -2003-03-22 John Camelon +2004-03-22 John Camelon Added CompleteParseASTTest::testBug54531(). -2003-03-22 Andrew Niefer +2004-03-22 Andrew Niefer Typedefs & templates - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate() - added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testTypedefedTemplate_2() - added parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.testCompletionInTypeDef() -2003-03-18 Andrew Niefer +2004-03-18 Andrew Niefer parsing template-ids - added parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.test54778() - modified parser/org/eclipse/cdt/core/parser/tests/CompleteParseBaseTests.java 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 66cc44e52ec..6cfe482598f 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 @@ -1858,4 +1858,43 @@ public class CompleteParseASTTest extends CompleteParseBaseTest 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/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser index 0e54c2d9a52..c7a147e520b 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ b/core/org.eclipse.cdt.core/parser/ChangeLog-parser @@ -1,3 +1,6 @@ +2004-03-26 Andrew Niefer + - handle template template parameters + 2004-03-26 Andrew Niefer -report references to symbols used in a template-id. 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 27d9922f498..8f1356fe8e8 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 @@ -2615,7 +2615,6 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto { ITemplateSymbol template = pst.newTemplateSymbol( ParserSymbolTable.EMPTY_NAME ); - List functionParameters = new LinkedList(); // the lookup requires a list of type infos // instead of a list of IASTParameterDeclaration Iterator iter = templateParameters.iterator(); @@ -2644,18 +2643,35 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto IASTParameterDeclaration parameter, List parms ) throws ASTSemanticException { - ISymbol symbol = pst.newSymbol( identifier, TypeInfo.t_templateParameter ); - if( kind == ParamKind.CLASS || kind == ParamKind.TYPENAME ){ - symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_typeName ); - } else if ( kind == ParamKind.TEMPLATE_LIST ){ - symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_template ); - } else /*ParamKind.PARAMETER*/ { - symbol.setName( parameter.getName() ); - symbol.setTypeInfo( ((ASTSimpleTypeSpecifier)parameter.getTypeSpecifier()).getSymbol().getTypeInfo() ); - symbol.getTypeInfo().setTemplateParameterType( symbol.getType() ); - symbol.setType( TypeInfo.t_templateParameter ); + ISymbol symbol = null; + if( kind == ParamKind.TEMPLATE_LIST ){ + ITemplateSymbol template = pst.newTemplateSymbol( identifier ); + template.setType( TypeInfo.t_templateParameter ); + template.getTypeInfo().setTemplateParameterType( TypeInfo.t_template ); - setPointerOperators( symbol, parameter.getPointerOperators(), parameter.getArrayModifiers() ); + Iterator iter = parms.iterator(); + while (iter.hasNext()){ + ASTTemplateParameter param = (ASTTemplateParameter)iter.next(); + try { + template.addTemplateParameter( param.getSymbol() ); + } catch (ParserSymbolTableException e) { + handleProblem( e.createProblemID(), "", param.getStartingOffset(), param.getEndingOffset(), param.getStartingLine() ); //$NON-NLS-1$ + } + } + symbol = template; + } else { + symbol = pst.newSymbol( identifier, TypeInfo.t_templateParameter ); + if( kind == ParamKind.CLASS || kind == ParamKind.TYPENAME ){ + symbol.getTypeInfo().setTemplateParameterType( TypeInfo.t_typeName ); + } else /*ParamKind.PARAMETER*/ { + pst.newSymbol( identifier, TypeInfo.t_templateParameter ); + symbol.setName( parameter.getName() ); + symbol.setTypeInfo( ((ASTSimpleTypeSpecifier)parameter.getTypeSpecifier()).getSymbol().getTypeInfo() ); + symbol.getTypeInfo().setTemplateParameterType( symbol.getType() ); + symbol.setType( TypeInfo.t_templateParameter ); + + setPointerOperators( symbol, parameter.getPointerOperators(), parameter.getArrayModifiers() ); + } } ASTTemplateParameter ast = new ASTTemplateParameter( symbol, defaultValue, parameter, parms ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index 4a813c7363c..398c37a61a6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -426,7 +426,17 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { ISymbol found = ParserSymbolTable.resolveAmbiguities( data ); if( isTemplateMember() && found instanceof ITemplateSymbol ) { - return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found ); + boolean areWithinTemplate = false; + IContainerSymbol container = getContainingSymbol(); + while( container != null ){ + if( container == found ){ + areWithinTemplate = true; + break; + } + container = container.getContainingSymbol(); + } + if( areWithinTemplate ) + return TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) found ); } return found; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java index 9452129dde6..85c8af7837a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DeferredTemplateInstance.java @@ -72,21 +72,43 @@ public class DeferredTemplateInstance extends BasicSymbol implements IDeferredTe } public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){ - return _template.getTemplatedSymbol().isType( type, upperType ); + ISymbol symbol = _template.getTemplatedSymbol(); + if( symbol != null ) + return symbol.isType( type, upperType ); + else + return super.isType( type, upperType ); + } - public TypeInfo.eType getType(){ - return _template.getTemplatedSymbol().getType(); + public TypeInfo.eType getType(){ + ISymbol symbol = _template.getTemplatedSymbol(); + if( symbol != null ) + return symbol.getType(); + else + return super.getType(); } public TypeInfo getTypeInfo(){ - return _template.getTemplatedSymbol().getTypeInfo(); + ISymbol symbol = _template.getTemplatedSymbol(); + if( symbol != null ) + return symbol.getTypeInfo(); + else + return super.getTypeInfo(); } public boolean isType( TypeInfo.eType type ){ return _template.getTemplatedSymbol().isType( type ); } + public ISymbolASTExtension getASTExtension(){ + if( super.getASTExtension() != null ) + return super.getASTExtension(); + else if( _template.getTemplatedSymbol() != null ) + return _template.getTemplatedSymbol().getASTExtension(); + else + return _template.getASTExtension(); + } + private ITemplateSymbol _template; private List _arguments; } 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 205330eb9b7..8f7fdc5f9fa 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 @@ -164,7 +164,7 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb } public void addTemplateParameter( ISymbol param ) throws ParserSymbolTableException { - if( isType( TypeInfo.t_template ) ){ + if( isType( TypeInfo.t_template ) || getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ){ if( !isAllowableTemplateParameter( param ) ){ throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateParameter ); }