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.IASTTypedefDeclaration;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
||||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author aniefer
|
* @author aniefer
|
||||||
|
@ -974,7 +973,15 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
|
||||||
try{
|
try{
|
||||||
parse( "template < class T > class A : public A< T * > {}; A<int> a;" ).getDeclarations(); //NON-NLS-1$
|
parse( "template < class T > class A : public A< T * > {}; A<int> a;" ).getDeclarations(); //NON-NLS-1$
|
||||||
assertTrue( false );
|
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 ){
|
protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){
|
||||||
if( constructor.isType( TypeInfo.t_constructor ) )
|
if( constructor.isType( TypeInfo.t_constructor ) )
|
||||||
addToConstructors( constructor );
|
addToConstructors( constructor );
|
||||||
|
|
|
@ -105,6 +105,16 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
|
||||||
setReturnType( returnType.instantiate( template, argMap ) );
|
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 ){
|
public void prepareForParameters( int numParams ){
|
||||||
if( _parameterList == Collections.EMPTY_LIST ){
|
if( _parameterList == Collections.EMPTY_LIST ){
|
||||||
|
|
|
@ -111,8 +111,15 @@ public class SpecializedSymbol extends TemplateSymbol implements ISpecializedSym
|
||||||
|
|
||||||
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
|
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
|
||||||
addInstantiation( instance, actualArgs );
|
addInstantiation( instance, actualArgs );
|
||||||
processDeferredInstantiations();
|
try{
|
||||||
|
processDeferredInstantiations();
|
||||||
|
} catch( ParserSymbolTableException e ){
|
||||||
|
if( e.reason == ParserSymbolTableException.r_RecursiveTemplate ){
|
||||||
|
//clean up some.
|
||||||
|
removeInstantiation( instance );
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
return instance;
|
return instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,18 @@ public final class TemplateEngine {
|
||||||
info.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
|
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{
|
static protected ITemplateSymbol matchTemplatePartialSpecialization( ITemplateSymbol template, List args ) throws ParserSymbolTableException{
|
||||||
if( template == null ){
|
if( template == null ){
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -150,7 +150,15 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
instance = (IContainerSymbol) symbol.instantiate( template, map );
|
instance = (IContainerSymbol) symbol.instantiate( template, map );
|
||||||
addInstantiation( instance, actualArgs );
|
addInstantiation( instance, actualArgs );
|
||||||
|
|
||||||
processDeferredInstantiations();
|
try{
|
||||||
|
processDeferredInstantiations();
|
||||||
|
} catch( ParserSymbolTableException e ){
|
||||||
|
if( e.reason == ParserSymbolTableException.r_RecursiveTemplate ){
|
||||||
|
//clean up some.
|
||||||
|
removeInstantiation( instance );
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -434,10 +442,11 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
}
|
}
|
||||||
_processingDeferred = true;
|
_processingDeferred = true;
|
||||||
int numDeferred = _deferredInstantiations.size();
|
int numDeferred = _deferredInstantiations.size();
|
||||||
|
int numProcessed = 0;
|
||||||
int loopCount = 0;
|
int loopCount = 0;
|
||||||
while( numDeferred > 0 ){
|
while( numDeferred > numProcessed ){
|
||||||
while( numDeferred > 0 ) {
|
for( int i = numProcessed; i < numDeferred; i++ ){
|
||||||
Object [] objs = (Object [])_deferredInstantiations.get(0);
|
Object [] objs = (Object [])_deferredInstantiations.get(i);
|
||||||
|
|
||||||
DeferredKind kind = (DeferredKind) objs[2];
|
DeferredKind kind = (DeferredKind) objs[2];
|
||||||
|
|
||||||
|
@ -450,17 +459,38 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
} else if( kind == DeferredKind.TYPE_SYMBOL ){
|
} else if( kind == DeferredKind.TYPE_SYMBOL ){
|
||||||
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
|
TemplateEngine.instantiateDeferredTypeInfo( (TypeInfo) objs[0], this, (Map) objs[3] );
|
||||||
}
|
}
|
||||||
|
numProcessed++;
|
||||||
_deferredInstantiations.remove( 0 );
|
|
||||||
numDeferred--;
|
|
||||||
}
|
}
|
||||||
numDeferred = _deferredInstantiations.size();
|
numDeferred = _deferredInstantiations.size();
|
||||||
if( ++loopCount > ParserSymbolTable.TEMPLATE_LOOP_THRESHOLD )
|
if( ++loopCount > ParserSymbolTable.TEMPLATE_LOOP_THRESHOLD ){
|
||||||
|
discardDeferredInstantiations();
|
||||||
|
_processingDeferred = false;
|
||||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_RecursiveTemplate );
|
throw new ParserSymbolTableException( ParserSymbolTableException.r_RecursiveTemplate );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_processingDeferred = false;
|
_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 List _specializations = Collections.EMPTY_LIST; //template specializations
|
||||||
private Map _explicitSpecializations = Collections.EMPTY_MAP; //explicit specializations
|
private Map _explicitSpecializations = Collections.EMPTY_MAP; //explicit specializations
|
||||||
private Map _defnParameterMap = Collections.EMPTY_MAP; //members could be defined with different template parameter names
|
private Map _defnParameterMap = Collections.EMPTY_MAP; //members could be defined with different template parameter names
|
||||||
|
|
Loading…
Add table
Reference in a new issue