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:
parent
effb8b9fdb
commit
88bb7ba72b
6 changed files with 99 additions and 12 deletions
|
@ -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$
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 ){
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue