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:
parent
c80f98594b
commit
b4309ac47a
8 changed files with 488 additions and 55 deletions
|
@ -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.
|
||||||
|
|
|
@ -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 );
|
||||||
|
@ -1678,6 +1676,210 @@ public class ParserSymbolTableTemplateTests extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ) { }
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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{
|
||||||
|
look = ParserSymbolTable.resolveAmbiguities( data );
|
||||||
|
} 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 ){
|
if( template != null ){
|
||||||
return new TemplateFactory( template, parameters );
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -57,4 +58,5 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
|
||||||
|
|
||||||
public IDeferredTemplateInstance deferredInstance( List args );
|
public IDeferredTemplateInstance deferredInstance( List args );
|
||||||
|
|
||||||
|
public Map getExplicitSpecializations();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 +902,12 @@ 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;
|
||||||
|
} else if( arguments != null ){
|
||||||
if( arguments.size() != parameters.size() ){
|
if( arguments.size() != parameters.size() ){
|
||||||
forPrimary = false;
|
forPrimary = false;
|
||||||
} else {
|
} else if( !parameters.isEmpty() ){
|
||||||
Iterator pIter = parameters.iterator();
|
Iterator pIter = parameters.iterator();
|
||||||
Iterator aIter = arguments.iterator();
|
Iterator aIter = arguments.iterator();
|
||||||
while( pIter.hasNext() ){
|
while( pIter.hasNext() ){
|
||||||
|
@ -917,7 +918,6 @@ public final class TemplateEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ITemplateSymbol primary = template;
|
ITemplateSymbol primary = template;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,9 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -228,6 +231,45 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
|
@ -305,13 +347,15 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
return new DeferredTemplateInstance( getSymbolTable(), this, args );
|
return new DeferredTemplateInstance( getSymbolTable(), this, args );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISpecializedSymbol findSpecialization(List parameters, List arguments) {
|
public Map getExplicitSpecializations() {
|
||||||
// TODO Auto-generated method stub
|
if( _explicitSpecializations == null ){
|
||||||
return null;
|
_explicitSpecializations = new HashMap();
|
||||||
|
}
|
||||||
|
return _explicitSpecializations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private LinkedList _specializations; //template specializations
|
private LinkedList _specializations; //template specializations
|
||||||
|
private HashMap _explicitSpecializations; //explicit specializations
|
||||||
private HashMap _defnParameterMap; //members could be defined with different template parameter names
|
private HashMap _defnParameterMap; //members could be defined with different template parameter names
|
||||||
private HashMap _instantiations;
|
private HashMap _instantiations;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue