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:
parent
1d41aabefc
commit
d15c793d77
10 changed files with 172 additions and 18 deletions
|
@ -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().
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -113,6 +113,8 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
|
|||
|
||||
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
|
||||
addInstantiation( instance, actualArgs );
|
||||
processDeferredInstantiations();
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue