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

better cleanup after recursive template loop.

This commit is contained in:
Andrew Niefer 2004-06-04 15:39:39 +00:00
parent effb8b9fdb
commit 88bb7ba72b
6 changed files with 99 additions and 12 deletions

View file

@ -33,7 +33,6 @@ import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.internal.core.parser.ParserException;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError;
/**
* @author aniefer
@ -974,7 +973,15 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
try{
parse( "template < class T > class A : public A< T * > {}; A<int> a;" ).getDeclarations(); //NON-NLS-1$
assertTrue( false );
} catch ( ParserSymbolTableError e ){
} catch ( ParserException e ){
assertTrue( e.getMessage().equals( "FAILURE" ) ); //$NON-NLS-1$
}
try{
parse( "template < class T > class A { A<T*> f(); }; A< int > a;" ).getDeclarations(); //NON-NLS-1$
assertTrue( false );
} catch ( ParserException e ){
assertTrue( e.getMessage().equals( "FAILURE" ) ); //$NON-NLS-1$
}
}
}

View file

@ -97,6 +97,27 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
}
}
/**
* @param symbol
* @param symbol2
* @param map
*/
public void discardDeferredParent(IDeferredTemplateInstance parent, ITemplateSymbol template, Map map) {
List parents = getParents();
int size = parents.size();
ParentWrapper w = null;
ISymbol originalParent = parent.getTemplate().getTemplatedSymbol();
for( int i = 0; i < size; i++ ){
w = (ParentWrapper) parents.get(i);
ISymbol instance = w.getParent();
if( instance.getInstantiatedSymbol() == originalParent ){
parents.remove( i );
template.removeInstantiation( (IContainerSymbol) instance );
break;
}
}
}
protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){
if( constructor.isType( TypeInfo.t_constructor ) )
addToConstructors( constructor );

View file

@ -105,6 +105,16 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
setReturnType( returnType.instantiate( template, argMap ) );
}
/**
* @param symbol
* @param symbol2
* @param map
*/
public void discardDeferredReturnType(ISymbol oldReturnType, TemplateSymbol template, Map map) {
ISymbol returnType = getReturnType();
setReturnType( null );
template.removeInstantiation( (IContainerSymbol) returnType );
}
public void prepareForParameters( int numParams ){
if( _parameterList == Collections.EMPTY_LIST ){

View file

@ -111,8 +111,15 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
addInstantiation( instance, actualArgs );
processDeferredInstantiations();
try{
processDeferredInstantiations();
} catch( ParserSymbolTableException e ){
if( e.reason == ParserSymbolTableException.r_RecursiveTemplate ){
//clean up some.
removeInstantiation( instance );
}
throw e;
}
return instance;
}

View file

@ -69,6 +69,18 @@ public final class TemplateEngine {
info.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
}
/**
* @param info
* @param symbol
* @param map
*/
public static void discardDeferredTypeInfo(TypeInfo info, TemplateSymbol template, Map map) {
ISymbol instance = info.getTypeSymbol();
if( !(instance instanceof IDeferredTemplateInstance ) )
template.removeInstantiation( (IContainerSymbol) instance );
info.setTypeSymbol( null );
}
static protected ITemplateSymbol matchTemplatePartialSpecialization( ITemplateSymbol template, List args ) throws ParserSymbolTableException{
if( template == null ){
return null;

View file

@ -150,7 +150,15 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
instance = (IContainerSymbol) symbol.instantiate( template, map );
addInstantiation( instance, actualArgs );
processDeferredInstantiations();
try{
processDeferredInstantiations();
} catch( ParserSymbolTableException e ){
if( e.reason == ParserSymbolTableException.r_RecursiveTemplate ){
//clean up some.
removeInstantiation( instance );
}
throw e;
}
return instance;
}
@ -434,10 +442,11 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
}
_processingDeferred = true;
int numDeferred = _deferredInstantiations.size();
int numProcessed = 0;
int loopCount = 0;
while( numDeferred > 0 ){
while( numDeferred > 0 ) {
Object [] objs = (Object [])_deferredInstantiations.get(0);
while( numDeferred > numProcessed ){
for( int i = numProcessed; i < numDeferred; i++ ){
Object [] objs = (Object [])_deferredInstantiations.get(i);
DeferredKind kind = (DeferredKind) objs[2];
@ -450,17 +459,38 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
} else if( kind == DeferredKind.TYPE_SYMBOL ){
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
}
_deferredInstantiations.remove( 0 );
numDeferred--;
numProcessed++;
}
numDeferred = _deferredInstantiations.size();
if( ++loopCount > ParserSymbolTable.TEMPLATE_LOOP_THRESHOLD )
if( ++loopCount > ParserSymbolTable.TEMPLATE_LOOP_THRESHOLD ){
discardDeferredInstantiations();
_processingDeferred = false;
throw new ParserSymbolTableException( ParserSymbolTableException.r_RecursiveTemplate );
}
}
_processingDeferred = false;
}
private void discardDeferredInstantiations(){
int size = _deferredInstantiations.size();
for( int i = 0; i < size; i++ ){
Object [] objs = (Object []) _deferredInstantiations.get(i);
DeferredKind kind = (DeferredKind) objs[2];
if( kind == DeferredKind.PARENT ){
DerivableContainerSymbol d = (DerivableContainerSymbol) objs[0];
d.discardDeferredParent( (IDeferredTemplateInstance) objs[1], this, (Map) objs[3] );
} else if( kind == DeferredKind.RETURN_TYPE ){
ParameterizedSymbol p = (ParameterizedSymbol) objs[0];
p.discardDeferredReturnType( (ISymbol) objs[1], this, (Map) objs[3] );
} else if( kind == DeferredKind.TYPE_SYMBOL ){
TemplateEngine.discardDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
}
}
_deferredInstantiations.clear();
}
private List _specializations = Collections.EMPTY_LIST; //template specializations
private Map _explicitSpecializations = Collections.EMPTY_MAP; //explicit specializations
private Map _defnParameterMap = Collections.EMPTY_MAP; //members could be defined with different template parameter names