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

- fix bug 55673

This commit is contained in:
Andrew Niefer 2004-03-23 16:46:12 +00:00
parent 1d41aabefc
commit d15c793d77
10 changed files with 172 additions and 18 deletions

View file

@ -1,3 +1,9 @@
2003-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
Added CompleteParseASTTest::testBug54531().

View file

@ -1771,6 +1771,59 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
new Task( f21, 1, false, false ) ) );
}
public void testInstantiatingDeferredInstances() throws Exception{
Writer writer = new StringWriter();
writer.write( "template < class T > struct A { A < T > next; }; \n" );
writer.write( "A< int > a; \n" );
Iterator i = parse( writer.toString() ).getDeclarations();
}
public void testTemplateArgumentDeduction() throws Exception{
Writer writer = new StringWriter();
writer.write( "template< class T > struct B {}; \n" );
writer.write( "template< class T > struct D : public B < T > {}; \n" );
writer.write( "struct D2 : public B< int > {}; \n" );
writer.write( "template< class T > T f( B<T> & ) {} \n" );
writer.write( "void test( int ); \n" );
writer.write( "void test( char ); \n" );
writer.write( "void main() { \n" );
writer.write( " D<int> d; \n" );
writer.write( " D2 d2; \n" );
writer.write( " test( f( d ) ); \n" );
writer.write( " test( f( d2 ) ); \n" );
writer.write( "} \n" );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration templateB = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration templateD = (IASTTemplateDeclaration) i.next();
IASTClassSpecifier D2 = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTTemplateDeclaration templateF = (IASTTemplateDeclaration) i.next();
IASTFunction test1 = (IASTFunction) i.next();
IASTFunction test2 = (IASTFunction) i.next();
IASTFunction main = (IASTFunction) i.next();
assertFalse( i.hasNext() );
assertReferenceTask( new Task( test1, 2, false, false ) );
}
public void testBug55673() throws Exception{
Writer writer = new StringWriter();
writer.write( "struct Example { int i; int ( * pfi ) ( int ); }; ");
Iterator iter = parse( writer.toString() ).getDeclarations();
IASTClassSpecifier example = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)iter.next()).getTypeSpecifier();
assertFalse( iter.hasNext() );
iter = getDeclarations( example );
IASTField i = (IASTField) iter.next();
IASTField pfi = (IASTField) iter.next();
assertFalse( iter.hasNext() );
}
public void testBug54531() throws Exception
{
Iterator i = parse( "typedef enum _A {} A, *pA;" ).getDeclarations();

View file

@ -1,3 +1,8 @@
2004-03-23 Andrew Niefer
-fix recursive loop leading to StackOverFlowException during template instantiation
-fix copy constructors for templated classes
-fix bug 55673
2004-03-22 Andrew Niefer
-handling of Typedefs
-handle unbalanced preprocessor condition in scanner

View file

@ -367,10 +367,11 @@ public class DeclarationWrapper implements IDeclaratorOwner
Declarator d = declarator.getOwnedDeclarator();
Iterator i = d.getPointerOperators().iterator();
boolean isWithinClass = scope instanceof IASTClassSpecifier;
boolean isFunction = (declarator.getParameters().size() != 0);
if( !i.hasNext() )
{
boolean isWithinClass = scope instanceof IASTClassSpecifier;
boolean isFunction = (declarator.getParameters().size() != 0);
if (isTypedef())
return createTypedef(declarator, true);
@ -408,8 +409,12 @@ public class DeclarationWrapper implements IDeclaratorOwner
getStartingOffset(), getStartingLine(), d
.getNameStartOffset(), d.getNameEndOffset(), d
.getNameLine());
else
return astFactory.createVariable( scope, name, auto, d.getInitializerClause(), d.getBitFieldExpression(), abs, mutable, extern, register, staticc, getStartingOffset(), getStartingLine(), d.getNameStartOffset(), d.getNameEndOffset(), d.getNameLine(), d.getConstructorExpression() );
else {
if( isWithinClass )
return astFactory.createField( scope, name, auto, d.getInitializerClause(), d.getBitFieldExpression(), abs, mutable, extern, register, staticc, getStartingOffset(), getStartingLine(), d.getNameStartOffset(), d.getNameEndOffset(), d.getNameLine(), d.getConstructorExpression(), ((IASTClassSpecifier)scope).getCurrentVisibilityMode() );
else
return astFactory.createVariable( scope, name, auto, d.getInitializerClause(), d.getBitFieldExpression(), abs, mutable, extern, register, staticc, getStartingOffset(), getStartingLine(), d.getNameStartOffset(), d.getNameEndOffset(), d.getNameLine(), d.getConstructorExpression() );
}
}
else

View file

@ -70,7 +70,7 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
newWrapper = new ParentWrapper( wrapper.getParent(), wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
ISymbol parent = newWrapper.getParent();
if( parent instanceof IDeferredTemplateInstance ){
newWrapper.setParent( ((IDeferredTemplateInstance)parent).instantiate( template, argMap ) );
template.registerDeferredInstatiation( newSymbol, newWrapper, ITemplateSymbol.DeferredKind.PARENT, argMap );
} else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){
TypeInfo info = (TypeInfo) argMap.get( parent );
newWrapper.setParent( info.getTypeSymbol() );
@ -79,19 +79,22 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
newSymbol.getParents().add( newWrapper );
}
// Iterator constructors = getConstructors().iterator();
// newSymbol.getConstructors().clear();
// IParameterizedSymbol constructor = null;
// while( constructors.hasNext() ){
// constructor = (IParameterizedSymbol) constructors.next();
// newSymbol.getConstructors().add( constructor.instantiate( template, argMap ) );
// }
//TODO: friends
return newSymbol;
}
public void instantiateDeferredParent( ParentWrapper wrapper, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
Iterator parents = getParents().iterator();
ParentWrapper w = null;
while( parents.hasNext() ) {
w = (ParentWrapper) parents.next();
if( w == wrapper ){
wrapper.setParent( wrapper.getParent().instantiate( template, argMap ) );
}
}
}
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
super.addSymbol( symbol );
@ -172,7 +175,12 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
public void addCopyConstructor() throws ParserSymbolTableException{
List parameters = new LinkedList();
TypeInfo param = new TypeInfo( TypeInfo.t_type, TypeInfo.isConst, this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, false, false ), false );
ISymbol paramType = this;
if( getContainingSymbol() instanceof ITemplateSymbol ){
paramType = TemplateEngine.instantiateWithinTemplateScope( this, (ITemplateSymbol) getContainingSymbol() );
}
TypeInfo param = new TypeInfo( TypeInfo.t_type, TypeInfo.isConst, paramType, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, false, false ), false );
parameters.add( param );
IParameterizedSymbol constructor = null;

View file

@ -59,4 +59,26 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
public IDeferredTemplateInstance deferredInstance( List args );
public Map getExplicitSpecializations();
/**
* @param symbol
* @param type
* @param kind
*/
public void registerDeferredInstatiation( Object obj0, Object obj1, DeferredKind kind, Map argMap );
public static class DeferredKind{
private DeferredKind( int v ){
_val = v;
}
private int _val;
public static final DeferredKind RETURN_TYPE = new DeferredKind( 1 );
public static final DeferredKind PARENT = new DeferredKind( 2 );
public static final DeferredKind TYPE_SYMBOL = new DeferredKind( 3 );
}
}

View file

@ -73,7 +73,10 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
newParameterized.getReturnType().setInstantiatedSymbol( _returnType );
}
} else {
newParameterized.setReturnType( _returnType.instantiate( template, argMap ) );
if( _returnType instanceof IDeferredTemplateInstance )
template.registerDeferredInstatiation( newParameterized, _returnType, ITemplateSymbol.DeferredKind.RETURN_TYPE, argMap );
else
newParameterized.setReturnType( _returnType.instantiate( template, argMap ) );
}
}
@ -97,6 +100,10 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
return newParameterized;
}
public void instantiateDeferredReturnType( ISymbol returnType, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
setReturnType( returnType.instantiate( template, argMap ) );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
*/

View file

@ -113,6 +113,8 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
addInstantiation( instance, actualArgs );
processDeferredInstantiations();
return instance;
}
}

View file

@ -33,9 +33,10 @@ public final class TemplateEngine {
} else {
if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol() instanceof IDeferredTemplateInstance ){
IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol();
TypeInfo newInfo = new TypeInfo( info );
newInfo.setTypeSymbol( deferred.instantiate( template, argMap ) );
//newInfo.setTypeSymbol( deferred.instantiate( template, argMap ) );
template.registerDeferredInstatiation( newInfo, deferred, ITemplateSymbol.DeferredKind.TYPE_SYMBOL, argMap );
newInfo.setTypeSymbol( deferred );
return newInfo;
} else if( info.isType( TypeInfo.t_type ) &&
info.getTypeSymbol().isType( TypeInfo.t_templateParameter ) &&
@ -65,6 +66,10 @@ public final class TemplateEngine {
}
}
static protected void instantiateDeferredTypeInfo( TypeInfo info, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException {
info.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
}
static protected ITemplateSymbol matchTemplatePartialSpecialization( ITemplateSymbol template, List args ) throws ParserSymbolTableException{
if( template == null ){
return null;
@ -736,6 +741,7 @@ public final class TemplateEngine {
IParameterizedSymbol function = (IParameterizedSymbol)templatedSymbol;
function = (IParameterizedSymbol) function.instantiate( spec1, map );
((TemplateSymbol)spec1).processDeferredInstantiations();
Map m1 = deduceTemplateArgumentsUsingParameterList( spec2, function);
@ -747,6 +753,7 @@ public final class TemplateEngine {
function = (IParameterizedSymbol)templatedSymbol;
function = (IParameterizedSymbol) function.instantiate( spec2, map );
((TemplateSymbol)spec2).processDeferredInstantiations();
Map m2 = deduceTemplateArgumentsUsingParameterList( spec1, function );

View file

@ -16,6 +16,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.core.parser.pst.DerivableContainerSymbol.ParentWrapper;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
/**
@ -150,6 +151,9 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
instance = (IContainerSymbol) symbol.instantiate( template, map );
addInstantiation( instance, actualArgs );
processDeferredInstantiations();
return instance;
}
}
@ -361,10 +365,45 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
}
return _explicitSpecializations;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol#registerDeferredInstatiation(org.eclipse.cdt.internal.core.parser.pst.ParameterizedSymbol, org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.ITemplateSymbol.DeferredKind)
*/
public void registerDeferredInstatiation( Object obj0, Object obj1, DeferredKind kind, Map argMap ) {
if( _deferredInstantiations == null )
_deferredInstantiations = new LinkedList();
_deferredInstantiations.add( new Object [] { obj0, obj1, kind, argMap } );
}
protected void processDeferredInstantiations() throws ParserSymbolTableException{
if( _deferredInstantiations == null )
return;
Iterator iter = _deferredInstantiations.iterator();
while( iter.hasNext() ){
Object [] objs = (Object [])iter.next();
DeferredKind kind = (DeferredKind) objs[2];
if( kind == DeferredKind.PARENT ){
DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0];
d.instantiateDeferredParent( (ParentWrapper) objs[ 1 ], this, (Map) objs[3] );
} else if( kind == DeferredKind.RETURN_TYPE ){
ParameterizedSymbol p = (ParameterizedSymbol) objs[0];
p.instantiateDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] );
} else if( kind == DeferredKind.TYPE_SYMBOL ){
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
}
}
}
private LinkedList _specializations; //template specializations
private HashMap _explicitSpecializations; //explicit specializations
private HashMap _defnParameterMap; //members could be defined with different template parameter names
private HashMap _instantiations;
private HashMap _instantiations;
private LinkedList _deferredInstantiations; //used to avoid recursive loop
}