1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Start of bug 51485: PST Templates: Explicit Specialization

This commit is contained in:
Andrew Niefer 2004-02-24 22:09:59 +00:00
parent c80f98594b
commit b4309ac47a
8 changed files with 488 additions and 55 deletions

View file

@ -1,3 +1,10 @@
2004-02-24 Andrew Niefer
work for Bug 51485: Template Explicit Specializations
added ParserSymbolTableTemplateTests.test_14_7_3__5_ExplicitSpecialization
added ParserSymbolTableTemplateTests.test_14_7_3__11_ExplicitSpecializationArgumentDeduction
added ParserSymbolTableTemplateTests.test_14_7_3__12_ExplicitSpecializationOverloadedFunction
fixed a couple of warnings in ParserSymbolTableTemplateTests
2004-02-23 Alain Magloire 2004-02-23 Alain Magloire
Adjust the test for IPathEntry deltas. Adjust the test for IPathEntry deltas.

View file

@ -485,12 +485,10 @@ public class ParserSymbolTableTemplateTests extends TestCase {
IDerivableContainerSymbol S = table.newDerivableContainerSymbol( "S", TypeInfo.t_struct ); IDerivableContainerSymbol S = table.newDerivableContainerSymbol( "S", TypeInfo.t_struct );
f.addSymbol( S ); f.addSymbol( S );
ISymbol look = null;
List args = new LinkedList(); List args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_type, 0, S ) ); args.add( new TypeInfo( TypeInfo.t_type, 0, S ) );
try{ try{
look = f.lookupTemplate( "X", args ); f.lookupTemplate( "X", args );
assertTrue( false ); assertTrue( false );
} catch( ParserSymbolTableException e ){ } catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument ); assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
@ -499,7 +497,7 @@ public class ParserSymbolTableTemplateTests extends TestCase {
args.clear(); args.clear();
args.add( new TypeInfo( TypeInfo.t_type, 0, S, new PtrOp( PtrOp.t_pointer ), false ) ); args.add( new TypeInfo( TypeInfo.t_type, 0, S, new PtrOp( PtrOp.t_pointer ), false ) );
try{ try{
look = f.lookupTemplate( "X", args ); f.lookupTemplate( "X", args );
assertTrue( false ); assertTrue( false );
} catch( ParserSymbolTableException e ){ } catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument ); assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateArgument );
@ -1620,7 +1618,7 @@ public class ParserSymbolTableTemplateTests extends TestCase {
TypeInfo type = (TypeInfo) iter.next(); TypeInfo type = (TypeInfo) iter.next();
assertTrue( type.isType( TypeInfo.t_int ) ); assertTrue( type.isType( TypeInfo.t_int ) );
} }
/** /**
* A template-parameter shall not be redeclared within its scope. A template-parameter shall * A template-parameter shall not be redeclared within its scope. A template-parameter shall
* not have the same name as the template name. * not have the same name as the template name.
@ -1636,7 +1634,7 @@ public class ParserSymbolTableTemplateTests extends TestCase {
* *
* @throws Exception * @throws Exception
*/ */
public void test_14_6_1__4_ParameterRedeclaration() throws Exception{ public void test_14_6_1__4_ParameterRedeclaration() throws Exception{
newTable(); newTable();
ITemplateSymbol template = table.newTemplateSymbol( "Y" ); ITemplateSymbol template = table.newTemplateSymbol( "Y" );
@ -1676,8 +1674,212 @@ public class ParserSymbolTableTemplateTests extends TestCase {
assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateParameter ); assertEquals( e.reason, ParserSymbolTableException.r_BadTemplateParameter );
} }
} }
/**
* A member of an explicitly specialized class shall be explicitly defined in the same
* manner as members of normal classes
*
* template< class T > struct A {
* void f( T ) {}
* };
*
* template <> struct A< int >{
* void f( int );
* }
*
* void A< int >::f( int ){ }
*
* @throws Exception
*/
public void test_14_7_3__5_ExplicitSpecialization() throws Exception{
newTable();
ITemplateSymbol template = table.newTemplateSymbol( "A" );
ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
template.addTemplateParameter( T );
IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
template.addSymbol( A );
table.getCompilationUnit().addSymbol( template );
IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f.addParameter( T, 0, null, false );
A.addSymbol( f );
LinkedList params = new LinkedList(), args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "A", params, args );
IDerivableContainerSymbol ASpec = table.newDerivableContainerSymbol( "A", TypeInfo.t_struct );
ASpec.setIsTemplateMember( true );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( TypeInfo.t_int, 0, null, false );
f2.setIsForwardDeclaration( true );
ASpec.addSymbol( f2 );
factory.addSymbol( ASpec );
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f3.addParameter( TypeInfo.t_int, 0, null, false );
IDerivableContainerSymbol look = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
assertTrue( look.isTemplateInstance() );
assertEquals( look.getInstantiatedSymbol(), ASpec );
ISymbol flook = look.lookupMethodForDefinition( "f", args );
assertTrue( flook.isTemplateInstance() );
assertEquals( flook.getInstantiatedSymbol(), f2 );
flook.setTypeSymbol( f3 );
look.addSymbol( f3 );
look = (IDerivableContainerSymbol) table.getCompilationUnit().lookupTemplate( "A", args );
flook = look.qualifiedFunctionLookup( "f", args );
assertEquals( flook, f3 );
}
/**
* template < class T > class Array { };
* template < class T > void sort( Array< T > & );
*
* template<> void sort( Array< int > & ){} //T deduced as int
*
* @throws Exception
*/
public void test_14_7_3__11_ExplicitSpecializationArgumentDeduction() throws Exception{
newTable();
ITemplateSymbol templateArray = table.newTemplateSymbol( "Array" );
templateArray.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
IDerivableContainerSymbol array = table.newDerivableContainerSymbol( "Array", TypeInfo.t_class );
templateArray.addSymbol( array );
table.getCompilationUnit().addSymbol( templateArray );
ITemplateSymbol templateSort = table.newTemplateSymbol( "sort" );
ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
templateSort.addTemplateParameter( T );
IParameterizedSymbol sort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
List args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
ISymbol arrayLook = table.getCompilationUnit().lookupTemplate( "Array", args );
sort.addParameter( arrayLook, 0, new PtrOp( PtrOp.t_reference ), false );
templateSort.addSymbol( sort );
table.getCompilationUnit().addSymbol( templateSort );
List params = new LinkedList();
ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "sort", params, null );
IParameterizedSymbol newSort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
arrayLook = table.getCompilationUnit().lookupTemplate( "Array", args );
newSort.addParameter( arrayLook, 0, new PtrOp( PtrOp.t_reference ), false );
factory.addSymbol( newSort );
ISymbol a = table.newSymbol( "a", TypeInfo.t_type );
a.setTypeSymbol( arrayLook );
args.clear();
args.add( new TypeInfo( TypeInfo.t_type, 0, a ) );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "sort", args );
assertTrue( look.isTemplateInstance() );
assertEquals( look.getInstantiatedSymbol(), newSort );
}
/**
* It is possible for a specialization with a given function signature to be instantiated from more
* than one function-template. In such cases, explicit specification of the template arguments must be used
* to uniquely identify the function template specialization being specialized
*
* template< class T > void f( T );
* template< class T > void f( T * );
*
* template <> void f( int * ); //ambiguous
* template <> void f< int >( int * ); //OK
* template <> void f( char ); //OK
*
* @throws Exception
*/
public void test_14_7_3__12_ExplicitSpecializationOverloadedFunction() throws Exception{
newTable();
ITemplateSymbol template1 = table.newTemplateSymbol( "f" );
ISymbol T1 = table.newSymbol( "T", TypeInfo.t_templateParameter );
template1.addTemplateParameter( T1 );
IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f1.addParameter( T1, 0, null, false );
template1.addSymbol( f1 );
table.getCompilationUnit().addSymbol( template1 );
ITemplateSymbol template2 = table.newTemplateSymbol( "f" );
ISymbol T2 = table.newSymbol( "T", TypeInfo.t_templateParameter );
template2.addTemplateParameter( T2 );
IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f2.addParameter( T2, 0, new PtrOp( PtrOp.t_pointer ), false );
template2.addSymbol( f2 );
table.getCompilationUnit().addSymbol( template2 );
List params = new LinkedList();
ITemplateFactory factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "f", params, null );
IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f3.addParameter( TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer ), false );
try{
factory.addSymbol( f3 );
assertTrue( false );
} catch( ParserSymbolTableException e ){
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
}
List args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "f", params, args );
IParameterizedSymbol f4 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f4.addParameter( TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer ), false );
factory.addSymbol( f4 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
factory = table.getCompilationUnit().lookupTemplateForMemberDefinition( "f", params, args );
IParameterizedSymbol f5 = table.newParameterizedSymbol( "f", TypeInfo.t_function );
f5.addParameter( TypeInfo.t_char, 0, null, false );
factory.addSymbol( f5 );
args.clear();
args.add( new TypeInfo( TypeInfo.t_char, 0, null ) );
ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", args );
assertTrue( look.isTemplateInstance() );
assertEquals( look.getInstantiatedSymbol(), f5 );
}
/** /**
* template < class T > void f( T x, T y ) { } * template < class T > void f( T x, T y ) { }

View file

@ -1,3 +1,7 @@
2004-02-24 Andrew Niefer
Template Explicit Specializations (bug 51485)
adding basic symbol table functionality for non-nested template specializations
2004-02-24 John Camelon 2004-02-24 John Camelon
Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=52823 Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=52823

View file

@ -93,6 +93,18 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
continue; continue;
} }
if( !template.getExplicitSpecializations().isEmpty() ){
List argList = new LinkedList();
Iterator templateParams = template.getParameterList().iterator();
while( templateParams.hasNext() ){
argList.add( argMap.get( templateParams.next() ) );
}
ISymbol temp = TemplateEngine.checkForTemplateExplicitSpecialization( template, symbol, argList );
if( temp != null )
containedSymbol = temp;
}
Map instanceMap = argMap; Map instanceMap = argMap;
if( template.getDefinitionParameterMap() != null && if( template.getDefinitionParameterMap() != null &&
template.getDefinitionParameterMap().containsKey( containedSymbol ) ) template.getDefinitionParameterMap().containsKey( containedSymbol ) )
@ -727,14 +739,41 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
LookupData data = new LookupData( name, TypeInfo.t_any ); LookupData data = new LookupData( name, TypeInfo.t_any );
ParserSymbolTable.lookup( data, this ); ParserSymbolTable.lookup( data, this );
ISymbol look = ParserSymbolTable.resolveAmbiguities( data );
if( look instanceof ITemplateSymbol ){ Object look = null;
ITemplateSymbol template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) look, parameters, arguments ); try{
if( template != null ){ look = ParserSymbolTable.resolveAmbiguities( data );
return new TemplateFactory( template, parameters ); } catch ( ParserSymbolTableException e ){
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction ){
throw e;
}
if( !data.foundItems.isEmpty() ){
look = data.foundItems.get( name );
if(!( look instanceof List ) ){
throw new ParserSymbolTableError();
}
} }
} }
ITemplateSymbol template = (ITemplateSymbol) (( look instanceof ITemplateSymbol ) ? look : null);
if( template == null ){
if( look instanceof ISymbol ){
ISymbol symbol = (ISymbol) look;
if( symbol.isTemplateMember() && symbol.getContainingSymbol().isType( TypeInfo.t_template ) ){
template = (ITemplateSymbol) symbol.getContainingSymbol();
}
}
}
if( template != null ){
template = TemplateEngine.selectTemplateOrSpecialization( template, parameters, arguments );
if( template != null ){
return new TemplateFactory( template, parameters, arguments );
}
} else if ( look instanceof List ){
return new TemplateFactory( new HashSet( (List)look ), parameters, arguments );
}
return null; return null;
} }

View file

@ -38,12 +38,13 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
public Map getDefinitionParameterMap(); public Map getDefinitionParameterMap();
public ISpecializedSymbol findSpecialization(List parameters, List arguments);
public IContainerSymbol findInstantiation( List arguments ); public IContainerSymbol findInstantiation( List arguments );
public List findArgumentsFor( IContainerSymbol instance ); public List findArgumentsFor( IContainerSymbol instance );
public void addInstantiation( IContainerSymbol instance, List args ); public void addInstantiation( IContainerSymbol instance, List args );
public void addExplicitSpecialization( ISymbol symbol, List args ) throws ParserSymbolTableException;
/** /**
* *
* @param args * @param args
@ -56,5 +57,6 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
public ISymbol instantiate( List args ) throws ParserSymbolTableException; public ISymbol instantiate( List args ) throws ParserSymbolTableException;
public IDeferredTemplateInstance deferredInstance( List args ); public IDeferredTemplateInstance deferredInstance( List args );
public Map getExplicitSpecializations();
} }

View file

@ -627,7 +627,7 @@ public final class TemplateEngine {
List aList = function.getParameterList(); List aList = function.getParameterList();
LinkedList args = new LinkedList(); LinkedList args = new LinkedList();
Iterator iter = aList.iterator(); Iterator iter = aList.iterator();
while( iter.hasNext() ){ while( iter.hasNext() ){
ISymbol symbol = (ISymbol) iter.next(); ISymbol symbol = (ISymbol) iter.next();
@ -646,7 +646,7 @@ public final class TemplateEngine {
* type (A), and an attempt is made to find template argument vaules that will make P, * type (A), and an attempt is made to find template argument vaules that will make P,
* after substitution of the deduced values, compatible with A. * after substitution of the deduced values, compatible with A.
*/ */
static private Map deduceTemplateArguments( IParameterizedSymbol template, List arguments ){ static private Map deduceTemplateArguments( ITemplateSymbol template, List arguments ){
if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){ if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){
return null; return null;
} }
@ -902,18 +902,18 @@ public final class TemplateEngine {
//primary definition or specialization? //primary definition or specialization?
boolean forPrimary = true; boolean forPrimary = true;
if( arguments != null ){ if( parameters.size() == 0 ){
if( !parameters.isEmpty() ){ forPrimary = false;
if( arguments.size() != parameters.size() ){ } else if( arguments != null ){
forPrimary = false; if( arguments.size() != parameters.size() ){
} else { forPrimary = false;
Iterator pIter = parameters.iterator(); } else if( !parameters.isEmpty() ){
Iterator aIter = arguments.iterator(); Iterator pIter = parameters.iterator();
while( pIter.hasNext() ){ Iterator aIter = arguments.iterator();
if( pIter.next() != ((TypeInfo) aIter.next()).getTypeSymbol() ){ while( pIter.hasNext() ){
forPrimary = false; if( pIter.next() != ((TypeInfo) aIter.next()).getTypeSymbol() ){
break; forPrimary = false;
} break;
} }
} }
} }
@ -931,21 +931,8 @@ public final class TemplateEngine {
} }
//specialization //specialization
if( parameters.isEmpty() && !arguments.isEmpty() ){ if( parameters.isEmpty() ){
ISpecializedSymbol spec = primary.findSpecialization( parameters, arguments ); return primary;
if( spec == null ){
spec = template.getSymbolTable().newSpecializedSymbol( primary.getName() );
Iterator iter = arguments.iterator();
while( iter.hasNext() ){
spec.addArgument( (TypeInfo) iter.next() );
}
primary.addSpecialization( spec );
}
return spec;
} }
//partial specialization //partial specialization
@ -1140,4 +1127,94 @@ public final class TemplateEngine {
return true; return true;
} }
static protected List verifyExplicitArguments( ITemplateSymbol template, List arguments, ISymbol symbol ) throws ParserSymbolTableException{
List actualArgs = new LinkedList();
Iterator params = template.getParameterList().iterator();
Iterator args = arguments.iterator();
while( params.hasNext() ){
ISymbol param = (ISymbol) params.next();
if( args.hasNext() ){
TypeInfo arg = (TypeInfo) args.next();
if( matchTemplateParameterAndArgument( param, arg ) ){
actualArgs.add( arg );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
}
} else {
//14.7.3-11 a trailing template-argument can be left unspecified in the template-id naming an explicit
//function template specialization provided it can be deduced from the function argument type
if( template.getTemplatedSymbol() instanceof IParameterizedSymbol &&
symbol instanceof IParameterizedSymbol && template.getTemplatedSymbol().getName().equals( symbol.getName() ) )
{
Map map = deduceTemplateArgumentsUsingParameterList( template, (IParameterizedSymbol) symbol );
if( map != null && map.containsKey( param ) ){
actualArgs.add( map.get( param ) );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplateArgument );
}
}
}
}
return actualArgs;
}
static protected ITemplateSymbol resolveTemplateFunctions( Set functions, List args, ISymbol symbol ) throws ParserSymbolTableException{
ITemplateSymbol template = null;
Iterator iter = functions.iterator();
outer: while( iter.hasNext() ){
IParameterizedSymbol fn = (IParameterizedSymbol) iter.next();
ITemplateSymbol tmpl = (ITemplateSymbol) fn.getContainingSymbol();
Map map = deduceTemplateArgumentsUsingParameterList( tmpl, (IParameterizedSymbol) symbol );
if( map == null )
continue;
else {
Iterator pIter = tmpl.getParameterList().iterator();
Iterator aIter = args.iterator();
while( pIter.hasNext() && aIter.hasNext() ){
ISymbol param = (ISymbol) pIter.next();
TypeInfo arg = (TypeInfo) aIter.next();
if( map.containsKey( param ) ) {
if( !map.get( param ).equals( arg )){
continue outer;
}
} else if( !matchTemplateParameterAndArgument( param, arg )){
continue outer;
}
}
//made it this far, its a match
if( template != null ){
throw new ParserSymbolTableException(ParserSymbolTableException.r_Ambiguous );
} else {
template = tmpl;
}
}
}
return template;
}
static protected ISymbol checkForTemplateExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ){
if( !template.getExplicitSpecializations().isEmpty() ){
//TODO: could optimize this if we had a TypeInfo.hashCode()
Iterator iter = template.getExplicitSpecializations().keySet().iterator();
List args = null;
while( iter.hasNext() ){
args = (List) iter.next();
if( args.equals( arguments ) ){
Map explicitMap = (Map) template.getExplicitSpecializations().get( args );
if( explicitMap.containsKey( symbol ) ){
return (ISymbol) explicitMap.get( symbol );
}
}
}
}
return null;
}
} }

View file

@ -24,17 +24,32 @@ import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.LookupData;
*/ */
public class TemplateFactory implements ITemplateFactory { public class TemplateFactory implements ITemplateFactory {
protected TemplateFactory( ITemplateSymbol primary, List params ){ protected TemplateFactory( ITemplateSymbol primary, List params, List args ){
templatesList = new LinkedList(); templatesList = new LinkedList();
templatesList.add( primary ); templatesList.add( primary );
parametersList = new LinkedList(); parametersList = new LinkedList();
parametersList.add( new LinkedList( params ) ); parametersList.add( new LinkedList( params ) );
argumentsList = new LinkedList();
argumentsList.add( args != null ? new LinkedList( args ) : new LinkedList() );
} }
protected TemplateFactory( List templates, List params ){ protected TemplateFactory( List templates, List params, List args ){
templatesList = templates; templatesList = templates;
parametersList = params; parametersList = params;
argumentsList = args;
}
protected TemplateFactory( Set functions, List params, List args ){
templatesList = new LinkedList();
templateFunctions = functions;
parametersList = new LinkedList();
parametersList.add( new LinkedList( params ) );
argumentsList = new LinkedList();
argumentsList.add( args != null ? new LinkedList( args ) : new LinkedList() );
} }
public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{ public ITemplateFactory lookupTemplateForMemberDefinition( String name, List parameters, List arguments ) throws ParserSymbolTableException{
@ -55,11 +70,13 @@ public class TemplateFactory implements ITemplateFactory {
if( template != null ){ if( template != null ){
List newTemplatesList = new LinkedList( templatesList ); List newTemplatesList = new LinkedList( templatesList );
List newParamsList = new LinkedList( parametersList ); List newParamsList = new LinkedList( parametersList );
List newArgsList = new LinkedList( argumentsList );
newTemplatesList.add( template ); newTemplatesList.add( template );
newParamsList.add( new LinkedList( parameters ) ); newParamsList.add( new LinkedList( parameters ) );
newArgsList.add( arguments != null ? new LinkedList( arguments ) : new LinkedList() );
return new TemplateFactory( newTemplatesList, newParamsList ); return new TemplateFactory( newTemplatesList, newParamsList, newArgsList );
} }
} }
@ -70,6 +87,11 @@ public class TemplateFactory implements ITemplateFactory {
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol) * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/ */
public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException { public void addSymbol( ISymbol symbol ) throws ParserSymbolTableException {
if( ((List)getParametersList().get( 0 )).isEmpty() ){
addExplicitSpecialization( symbol );
return;
}
Iterator templatesIter = getTemplatesList().iterator(); Iterator templatesIter = getTemplatesList().iterator();
Iterator parametersIter = getParametersList().iterator(); Iterator parametersIter = getParametersList().iterator();
@ -106,10 +128,34 @@ public class TemplateFactory implements ITemplateFactory {
} }
} }
private void addExplicitSpecialization( ISymbol symbol ) throws ParserSymbolTableException {
Iterator templatesIter = getTemplatesList().iterator();
Iterator argsIter = getArgumentsList().iterator();
while( templatesIter.hasNext() ){
ITemplateSymbol template = (ITemplateSymbol)templatesIter.next();
template.addExplicitSpecialization( symbol, (List) argsIter.next() );
}
if( getTemplateFunctions() != null && argsIter.hasNext() ){
List args = (List) argsIter.next();
ITemplateSymbol template = TemplateEngine.resolveTemplateFunctions( getTemplateFunctions(), args, symbol );
if( template != null ){
template.addExplicitSpecialization( symbol, args );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberForDefinition(java.lang.String) * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberForDefinition(java.lang.String)
*/ */
public ISymbol lookupMemberForDefinition(String name) throws ParserSymbolTableException { public ISymbol lookupMemberForDefinition(String name) throws ParserSymbolTableException {
if( getTemplateFunctions() != null ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
}
Set keys = getPrimaryTemplate().getContainedSymbols().keySet(); Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() ); IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
@ -120,6 +166,10 @@ public class TemplateFactory implements ITemplateFactory {
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberFunctionForDefinition(java.lang.String, java.util.List) * @see org.eclipse.cdt.internal.core.parser.pst.ITemplateFactory#lookupMemberFunctionForDefinition(java.lang.String, java.util.List)
*/ */
public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params) throws ParserSymbolTableException { public IParameterizedSymbol lookupMemberFunctionForDefinition( String name, List params) throws ParserSymbolTableException {
if( getTemplateFunctions() != null ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
}
Set keys = getPrimaryTemplate().getContainedSymbols().keySet(); Set keys = getPrimaryTemplate().getContainedSymbols().keySet();
IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() ); IContainerSymbol symbol = (IContainerSymbol) getPrimaryTemplate().getContainedSymbols().get( keys.iterator().next() );
@ -157,7 +207,15 @@ public class TemplateFactory implements ITemplateFactory {
protected List getParametersList() { protected List getParametersList() {
return parametersList; return parametersList;
} }
protected List getArgumentsList(){
return argumentsList;
}
protected Set getTemplateFunctions(){
return templateFunctions;
}
private Set templateFunctions;
private List templatesList; private List templatesList;
private List parametersList; private List parametersList;
private List argumentsList;
} }

View file

@ -147,7 +147,10 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
return deferredInstance( arguments ); return deferredInstance( arguments );
} }
IContainerSymbol symbol = template.getTemplatedSymbol(); IContainerSymbol symbol = template.getTemplatedSymbol();
ISymbol temp = TemplateEngine.checkForTemplateExplicitSpecialization( template, symbol, actualArgs );
symbol = (IContainerSymbol) ( temp != null ? temp : symbol);
instance = (IContainerSymbol) symbol.instantiate( template, map ); instance = (IContainerSymbol) symbol.instantiate( template, map );
addInstantiation( instance, actualArgs ); addInstantiation( instance, actualArgs );
return instance; return instance;
@ -227,6 +230,45 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
public boolean hasSpecializations(){ public boolean hasSpecializations(){
return ( _specializations != null && !_specializations.isEmpty() ); return ( _specializations != null && !_specializations.isEmpty() );
} }
public void addExplicitSpecialization( ISymbol symbol, List args ) throws ParserSymbolTableException{
List actualArgs = TemplateEngine.verifyExplicitArguments( this, args, symbol );
Map map = getExplicitSpecializations();
Map specs = null;
if( map.containsKey( actualArgs ) ){
specs = (Map) map.get( actualArgs );
} else {
specs = new HashMap();
map.put( new LinkedList( actualArgs ), specs );
}
ISymbol found = null;
try{
if( symbol.isType( TypeInfo.t_function ) || symbol.isType( TypeInfo.t_constructor ) ){
List fnArgs = new LinkedList();
Iterator iter = ((IParameterizedSymbol)symbol).getParameterList().iterator();
while( iter.hasNext() ){
fnArgs.add( ((ISymbol)iter.next()).getTypeInfo() );
}
found = getTemplatedSymbol().lookupMethodForDefinition( symbol.getName(), fnArgs );
} else {
found = getTemplatedSymbol().lookupMemberForDefinition( symbol.getName() );
}
} catch (ParserSymbolTableException e) {
}
if( found == null && getTemplatedSymbol().getName().equals( symbol.getName() ) ){
found = getTemplatedSymbol();
}
if( found != null ){
symbol.setIsTemplateMember( true );
symbol.setContainingSymbol( found.getContainingSymbol() );
specs.put( found, symbol );
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol) * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addSpecialization(org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol)
@ -304,15 +346,17 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
public IDeferredTemplateInstance deferredInstance( List args ){ public IDeferredTemplateInstance deferredInstance( List args ){
return new DeferredTemplateInstance( getSymbolTable(), this, args ); return new DeferredTemplateInstance( getSymbolTable(), this, args );
} }
public ISpecializedSymbol findSpecialization(List parameters, List arguments) {
// TODO Auto-generated method stub
return null;
}
public Map getExplicitSpecializations() {
if( _explicitSpecializations == null ){
_explicitSpecializations = new HashMap();
}
return _explicitSpecializations;
}
private LinkedList _specializations; //template specializations private LinkedList _specializations; //template specializations
private HashMap _defnParameterMap; //members could be defined with different template parameter names private HashMap _explicitSpecializations; //explicit specializations
private HashMap _defnParameterMap; //members could be defined with different template parameter names
private HashMap _instantiations; private HashMap _instantiations;
} }