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

template work on Explicit Specializations and Explicit argument specification

This commit is contained in:
Andrew Niefer 2004-04-20 21:16:13 +00:00
parent d72a8b3f5d
commit 3ca43539a1
11 changed files with 233 additions and 82 deletions

View file

@ -1,3 +1,8 @@
2004-04-20 Andrew Niefer
-added parser/CompleteParseASTTemplateTest.test_14_7_3__11_ExplicitSpecializationArgumentDeduction()
-added parser/CompleteParseASTTemplateTest.test_14_8_1__2_ExplicitArgumentSpecification()
-uncommented and modified parser/ParserSymbolTableTemplateTests.test_14_7_3__11_ExplicitSpecializationArgumentDeduction()
2004-04-20 John Camelon
Updated CompletionParseTest for CompletionKind updates.

View file

@ -787,4 +787,51 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
assertAllReferences( 5, createTaskList( new Task( T ), new Task( ASpec, 2 ), new Task( a ), new Task( f ) ) );
}
public void test_14_7_3__11_ExplicitSpecializationArgumentDeduction() throws Exception
{
Writer writer = new StringWriter();
writer.write("template < class T > class Array { }; ");
writer.write("template < class T > void sort( Array< T > & ); ");
writer.write("template<> void sort( Array< int > & ){} ");
writer.write("void f(){ ");
writer.write(" Array<int> a1; ");
writer.write(" Array<char> a2; ");
writer.write(" sort( a1 ); ");
writer.write(" sort( a2 ); ");
writer.write("} ");
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration templateArray = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration templateSort = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration sortSpec = (IASTTemplateDeclaration) i.next();
IASTFunction f = (IASTFunction) i.next();
IASTFunction sort1 = (IASTFunction) templateSort.getOwnedDeclaration();
IASTFunction sort2 = (IASTFunction) sortSpec.getOwnedDeclaration();
assertReferenceTask( new Task( sort1, 1, false, false ) );
assertReferenceTask( new Task( sort2, 1, false, false ) );
}
public void test_14_8_1__2_ExplicitArgumentSpecification() throws Exception{
Writer writer = new StringWriter();
writer.write("void f( int ){} //#1 \n");
writer.write("template < class T > void f( T ){} //#2 \n");
writer.write("int main(){ \n");
writer.write(" f( 1 ); //calls #1 \n");
writer.write(" f<int>( 1 ); //calls #2 \n");
writer.write(" f<> ( 1 ); //calls #2 \n");
writer.write("} \n");
Iterator i = parse( writer.toString() ).getDeclarations();
IASTFunction f1 = (IASTFunction) i.next();
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
IASTFunction f2 = (IASTFunction) template.getOwnedDeclaration();
IASTFunction main = (IASTFunction) i.next();
assertReferenceTask( new Task( f1, 1, false, false ) );
assertReferenceTask( new Task( f2, 2, false, false ) );
}
}

View file

@ -1888,63 +1888,62 @@ public class ParserSymbolTableTemplateTests extends TestCase {
* @throws Exception
*/
public void test_14_7_3__11_ExplicitSpecializationArgumentDeduction() throws Exception{
//TODO
// newTable();
//
// ITemplateSymbol templateArray = table.newTemplateSymbol( "Array" );
// templateArray.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
//
// ITemplateFactory factory = table.newTemplateFactory();
// factory.setContainingSymbol( table.getCompilationUnit() );
// factory.pushTemplate( templateArray );
//
// IDerivableContainerSymbol array = table.newDerivableContainerSymbol( "Array", TypeInfo.t_class );
// factory.addSymbol( array );
//
// ITemplateSymbol templateSort = table.newTemplateSymbol( "sort" );
// ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
// templateSort.addTemplateParameter( T );
//
// factory = table.newTemplateFactory();
// factory.setContainingSymbol( table.getCompilationUnit() );
// factory.pushTemplate( templateSort );
//
// IParameterizedSymbol sort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
//
// List args = new LinkedList();
// args.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
//
// ISymbol arrayLook = factory.lookupTemplateId( "Array", args );
// sort.addParameter( arrayLook, 0, new PtrOp( PtrOp.t_reference ), false );
//
// factory.addSymbol( sort );
//
// ITemplateSymbol temp = table.newTemplateSymbol( "" );
// factory = table.newTemplateFactory();
//
// factory.setContainingSymbol( table.getCompilationUnit() );
// factory.pushTemplate( temp );
//
// IParameterizedSymbol newSort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
// args.clear();
// args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
// arrayLook = table.getCompilationUnit().lookupTemplateId( "Array", args );
// assertTrue( arrayLook.isTemplateInstance() );
// assertEquals( arrayLook.getInstantiatedSymbol(), array );
// 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 );
newTable();
ITemplateSymbol templateArray = table.newTemplateSymbol( "Array" );
templateArray.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) );
ITemplateFactory factory = table.newTemplateFactory();
factory.setContainingSymbol( table.getCompilationUnit() );
factory.pushTemplate( templateArray );
IDerivableContainerSymbol array = table.newDerivableContainerSymbol( "Array", TypeInfo.t_class );
factory.addSymbol( array );
ITemplateSymbol templateSort = table.newTemplateSymbol( "sort" );
ISymbol T = table.newSymbol( "T", TypeInfo.t_templateParameter );
templateSort.addTemplateParameter( T );
factory = table.newTemplateFactory();
factory.setContainingSymbol( table.getCompilationUnit() );
factory.pushTemplate( templateSort );
IParameterizedSymbol sort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
List args = new LinkedList();
args.add( new TypeInfo( TypeInfo.t_type, 0, T ) );
ISymbol arrayLook = factory.lookupTemplateId( "Array", args );
sort.addParameter( arrayLook, 0, new PtrOp( PtrOp.t_reference ), false );
factory.addSymbol( sort );
ITemplateSymbol temp = table.newTemplateSymbol( "" );
factory = table.newTemplateFactory();
factory.setContainingSymbol( table.getCompilationUnit() );
factory.pushTemplate( temp );
IParameterizedSymbol newSort = table.newParameterizedSymbol( "sort", TypeInfo.t_function );
args.clear();
args.add( new TypeInfo( TypeInfo.t_int, 0, null ) );
arrayLook = table.getCompilationUnit().lookupTemplateId( "Array", args );
assertTrue( arrayLook.isTemplateInstance() );
assertEquals( arrayLook.getInstantiatedSymbol(), array );
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 );
}
/**

View file

@ -1,3 +1,8 @@
2004-04-20 Andrew Niefer
- implement IContainerSymbol.lookupFunctionTemplateId
- handle explicit template argument specification
- better handling of explicit specializations that use argument deduction
2004-04-20 John Camelon
Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=58717

View file

@ -213,7 +213,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
else {
if( arguments != null )
result = startingScope.lookupFunctionTemplateId( name, new LinkedList( parameters), new LinkedList( arguments ) );
result = startingScope.lookupFunctionTemplateId( name, new LinkedList( parameters), new LinkedList( arguments ), ( lookupType == LookupType.FORDEFINITION ) );
else if( lookupType == LookupType.QUALIFIED )
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
else if( lookupType == LookupType.UNQUALIFIED || lookupType == LookupType.FORPARENTSCOPE)

View file

@ -766,6 +766,22 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
return found;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List)
*/
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments, boolean forDefinition) throws ParserSymbolTableException {
LookupData data = new LookupData( name, TypeInfo.t_function );
data.exactFunctionsOnly = forDefinition;
data.parameters = parameters;
data.templateParameters = arguments;
ParserSymbolTable.lookup( data, this );
ISymbol found = ParserSymbolTable.resolveAmbiguities( data );
return found;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupTemplateIdForDefinition(java.lang.String, java.util.List)
*/
@ -1112,14 +1128,4 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
public void addTemplateId(ISymbol symbol, List args) throws ParserSymbolTableException {
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List)
*/
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments) throws ParserSymbolTableException {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -119,7 +119,7 @@ public interface IContainerSymbol extends ISymbol {
* r_BadTemplateArgument if (14.3.1, 14.3.2) a template argument is invalid
*/
public ISymbol lookupTemplateId( String name, List arguments ) throws ParserSymbolTableException;
public ISymbol lookupFunctionTemplateId( String name, List parameters, List arguments ) throws ParserSymbolTableException;
public ISymbol lookupFunctionTemplateId( String name, List parameters, List arguments, boolean forDefinition ) throws ParserSymbolTableException;
public IContainerSymbol lookupTemplateIdForDefinition( String name, List arguments ) throws ParserSymbolTableException;

View file

@ -566,7 +566,7 @@ public class ParserSymbolTable {
if( numTemplateFunctions > 0 ){
if( data.parameters != null && !data.exactFunctionsOnly ){
List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters );
List fns = TemplateEngine.selectTemplateFunctions( templateFunctionSet, data.parameters, data.templateParameters );
functionSet.addAll( fns );
numFunctions = functionSet.size();
} else {
@ -1163,6 +1163,18 @@ public class ParserSymbolTable {
ambiguous = false;
}
}
//we prefer normal functions over template functions, unless the specified template arguments
else if( bestFn.isTemplateInstance() && !currFn.isTemplateInstance() ){
if( data.templateParameters == null )
hasBetter = true;
else
ambiguous = false;
} else if( !bestFn.isTemplateInstance() && currFn.isTemplateInstance() ){
if( data.templateParameters == null )
ambiguous = false;
else
hasBetter = true;
}
}
if( hasBetter ){
//the new best function.

View file

@ -882,7 +882,7 @@ public final class TemplateEngine {
return info;
}
static protected List selectTemplateFunctions( Set templates, List arguments ) throws ParserSymbolTableException{
static protected List selectTemplateFunctions( Set templates, List functionArguments, List templateArguments ) throws ParserSymbolTableException{
if( templates == null || templates.size() == 0 )
return null;
@ -894,15 +894,28 @@ public final class TemplateEngine {
IParameterizedSymbol fn = (IParameterizedSymbol) iter.next();
ITemplateSymbol template = (ITemplateSymbol) fn.getContainingSymbol();
Map map = deduceTemplateArguments( template, arguments );
Map map = deduceTemplateArguments( template, functionArguments );
if( map == null )
continue;
Iterator paramIter = template.getParameterList().iterator();
Iterator argsIter = (templateArguments != null ) ? templateArguments.iterator() : null;
List instanceArgs = new LinkedList();
while( paramIter.hasNext() ){
instanceArgs.add( map.get( paramIter.next() ) );
ISymbol param = (ISymbol) paramIter.next();
TypeInfo arg = (TypeInfo) (( argsIter != null && argsIter.hasNext() )? argsIter.next() : null);
TypeInfo mapped = (TypeInfo) map.get( param );
if( arg != null && mapped != null )
if( arg.equals( mapped ) )
instanceArgs.add( arg );
else
continue;
else if( arg == null && mapped == null )
continue;
else
instanceArgs.add( (arg != null) ? arg : mapped );
}
IContainerSymbol instance = (IContainerSymbol) template.instantiate( instanceArgs );
@ -1222,6 +1235,41 @@ public final class TemplateEngine {
return template;
}
static protected List resolveTemplateFunctionArguments( List args, ITemplateSymbol template, IParameterizedSymbol fn )
{
List resultList = new LinkedList();
List params = template.getParameterList();
Map map = null;
Iterator pIter = params.iterator();
Iterator aIter = ( args != null ) ? args.iterator() : null;
while( pIter.hasNext() ){
ISymbol param = (ISymbol) pIter.next();
TypeInfo arg = null;
if( aIter != null && aIter.hasNext() ){
arg = (TypeInfo) aIter.next();
} else {
if( map == null ){
map = deduceTemplateArgumentsUsingParameterList( template, fn );
if(map == null )
return null;
}
if( map.containsKey( param ) ){
arg = (TypeInfo) map.get( param );
}
}
if( arg == null || !matchTemplateParameterAndArgument( param, arg ) )
return null;
resultList.add( arg );
}
return resultList;
}
static protected ISymbol checkForTemplateExplicitSpecialization( ITemplateSymbol template, ISymbol symbol, List arguments ){
if( !template.getExplicitSpecializations().isEmpty() ){
//TODO: could optimize this if we had a TypeInfo.hashCode()

View file

@ -56,7 +56,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addTemplateId(org.eclipse.cdt.internal.core.parser.pst.ISymbol, java.util.List)
*/
public void addTemplateId(ISymbol symbol, List args) throws ParserSymbolTableException {
ISymbol previous = findPreviousSymbol( symbol );
ISymbol previous = findPreviousSymbol( symbol, args );
ITemplateSymbol origTemplate = (previous != null ) ? (ITemplateSymbol) previous.getContainingSymbol() : null;
if( origTemplate == null ){
@ -149,7 +149,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
}
}
private ISymbol findPreviousSymbol( ISymbol symbol ) throws ParserSymbolTableException{
private ISymbol findPreviousSymbol( ISymbol symbol, List args ) throws ParserSymbolTableException{
ISymbol previous = null;
List argList = null;
@ -163,7 +163,10 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
}
if( symbol.isType( TypeInfo.t_function ) ){
previous = lookupMethodForDefinition( symbol.getName(), argList );
if( args != null )
previous = lookupFunctionTemplateId( symbol.getName(), argList, args, false );
else
previous = lookupMethodForDefinition( symbol.getName(), argList );
} else if ( symbol.isType( TypeInfo.t_constructor ) ){
previous = lookupConstructor( argList );
} else {
@ -174,10 +177,25 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
private void basicTemplateDeclaration( ISymbol symbol ) throws ParserSymbolTableException{
ITemplateSymbol template = (ITemplateSymbol)templates.get( 0 );
if( template.getParameterList().size() == 0 ){
//explicit specialization
//explicit specialization, deduce some arguments and use addTemplateId
ISymbol previous = findPreviousSymbol( symbol, new LinkedList() );
if( previous == null )
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
List args = null;
if( symbol instanceof IParameterizedSymbol ){
args = TemplateEngine.resolveTemplateFunctionArguments( null, (ITemplateSymbol)previous.getContainingSymbol(), (IParameterizedSymbol) symbol );
}
if( args != null )
addTemplateId( symbol, args );
else
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
} else {
ISymbol previous = findPreviousSymbol( symbol );
ISymbol previous = findPreviousSymbol( symbol, null );
if( previous == null ){
//new template
@ -228,7 +246,7 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
}
private void memberDeclaration( ISymbol symbol ) throws ParserSymbolTableException{
ISymbol previous = findPreviousSymbol( symbol );
ISymbol previous = findPreviousSymbol( symbol, null );
if( previous == null ) {
//??
} else {
@ -855,8 +873,14 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#lookupFunctionTemplateId(java.lang.String, java.util.List, java.util.List)
*/
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments) throws ParserSymbolTableException {
// TODO Auto-generated method stub
return null;
public ISymbol lookupFunctionTemplateId(String name, List parameters, List arguments, boolean forDefinition) throws ParserSymbolTableException {
IContainerSymbol last = getLastSymbol();
if( last != null ){
IParameterizedSymbol found = (IParameterizedSymbol) last.lookupFunctionTemplateId( name, parameters, arguments, forDefinition );
if( found != null ){
return found;
}
}
return getContainingSymbol().lookupFunctionTemplateId( name, parameters, arguments, forDefinition );
}
}

View file

@ -277,6 +277,11 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
}
if( found == null && getTemplatedSymbol().getName().equals( symbol.getName() ) ){
found = getTemplatedSymbol();
IContainerSymbol instance = findInstantiation( args );
if( instance != null ){
_instantiations.remove( findArgumentsFor( instance ) );
}
}
if( found != null ){