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
|
2003-03-22 John Camelon
|
||||||
Added CompleteParseASTTest::testBug54531().
|
Added CompleteParseASTTest::testBug54531().
|
||||||
|
|
||||||
|
|
|
@ -1771,6 +1771,59 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
||||||
new Task( f21, 1, false, false ) ) );
|
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
|
public void testBug54531() throws Exception
|
||||||
{
|
{
|
||||||
Iterator i = parse( "typedef enum _A {} A, *pA;" ).getDeclarations();
|
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
|
2004-03-22 Andrew Niefer
|
||||||
-handling of Typedefs
|
-handling of Typedefs
|
||||||
-handle unbalanced preprocessor condition in scanner
|
-handle unbalanced preprocessor condition in scanner
|
||||||
|
|
|
@ -367,10 +367,11 @@ public class DeclarationWrapper implements IDeclaratorOwner
|
||||||
|
|
||||||
Declarator d = declarator.getOwnedDeclarator();
|
Declarator d = declarator.getOwnedDeclarator();
|
||||||
Iterator i = d.getPointerOperators().iterator();
|
Iterator i = d.getPointerOperators().iterator();
|
||||||
|
boolean isWithinClass = scope instanceof IASTClassSpecifier;
|
||||||
|
boolean isFunction = (declarator.getParameters().size() != 0);
|
||||||
if( !i.hasNext() )
|
if( !i.hasNext() )
|
||||||
{
|
{
|
||||||
boolean isWithinClass = scope instanceof IASTClassSpecifier;
|
|
||||||
boolean isFunction = (declarator.getParameters().size() != 0);
|
|
||||||
if (isTypedef())
|
if (isTypedef())
|
||||||
return createTypedef(declarator, true);
|
return createTypedef(declarator, true);
|
||||||
|
|
||||||
|
@ -408,8 +409,12 @@ public class DeclarationWrapper implements IDeclaratorOwner
|
||||||
getStartingOffset(), getStartingLine(), d
|
getStartingOffset(), getStartingLine(), d
|
||||||
.getNameStartOffset(), d.getNameEndOffset(), d
|
.getNameStartOffset(), d.getNameEndOffset(), d
|
||||||
.getNameLine());
|
.getNameLine());
|
||||||
else
|
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() );
|
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
|
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() );
|
newWrapper = new ParentWrapper( wrapper.getParent(), wrapper.isVirtual(), wrapper.getAccess(), wrapper.getOffset(), wrapper.getReferences() );
|
||||||
ISymbol parent = newWrapper.getParent();
|
ISymbol parent = newWrapper.getParent();
|
||||||
if( parent instanceof IDeferredTemplateInstance ){
|
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 ) ){
|
} else if( parent.isType( TypeInfo.t_templateParameter ) && argMap.containsKey( parent ) ){
|
||||||
TypeInfo info = (TypeInfo) argMap.get( parent );
|
TypeInfo info = (TypeInfo) argMap.get( parent );
|
||||||
newWrapper.setParent( info.getTypeSymbol() );
|
newWrapper.setParent( info.getTypeSymbol() );
|
||||||
|
@ -79,19 +79,22 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
newSymbol.getParents().add( newWrapper );
|
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
|
//TODO: friends
|
||||||
|
|
||||||
return newSymbol;
|
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 {
|
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
|
||||||
super.addSymbol( symbol );
|
super.addSymbol( symbol );
|
||||||
|
|
||||||
|
@ -172,7 +175,12 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
||||||
public void addCopyConstructor() throws ParserSymbolTableException{
|
public void addCopyConstructor() throws ParserSymbolTableException{
|
||||||
List parameters = new LinkedList();
|
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 );
|
parameters.add( param );
|
||||||
|
|
||||||
IParameterizedSymbol constructor = null;
|
IParameterizedSymbol constructor = null;
|
||||||
|
|
|
@ -59,4 +59,26 @@ public interface ITemplateSymbol extends IParameterizedSymbol {
|
||||||
public IDeferredTemplateInstance deferredInstance( List args );
|
public IDeferredTemplateInstance deferredInstance( List args );
|
||||||
|
|
||||||
public Map getExplicitSpecializations();
|
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 );
|
newParameterized.getReturnType().setInstantiatedSymbol( _returnType );
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
return newParameterized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void instantiateDeferredReturnType( ISymbol returnType, ITemplateSymbol template, Map argMap ) throws ParserSymbolTableException{
|
||||||
|
setReturnType( returnType.instantiate( template, argMap ) );
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
* @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 );
|
instance = (IContainerSymbol) symbol.instantiate( this, argMap );
|
||||||
addInstantiation( instance, actualArgs );
|
addInstantiation( instance, actualArgs );
|
||||||
|
processDeferredInstantiations();
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,10 @@ public final class TemplateEngine {
|
||||||
} else {
|
} else {
|
||||||
if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol() instanceof IDeferredTemplateInstance ){
|
if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol() instanceof IDeferredTemplateInstance ){
|
||||||
IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol();
|
IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) info.getTypeSymbol();
|
||||||
|
|
||||||
TypeInfo newInfo = new TypeInfo( info );
|
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;
|
return newInfo;
|
||||||
} else if( info.isType( TypeInfo.t_type ) &&
|
} else if( info.isType( TypeInfo.t_type ) &&
|
||||||
info.getTypeSymbol().isType( TypeInfo.t_templateParameter ) &&
|
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{
|
static protected ITemplateSymbol matchTemplatePartialSpecialization( ITemplateSymbol template, List args ) throws ParserSymbolTableException{
|
||||||
if( template == null ){
|
if( template == null ){
|
||||||
return null;
|
return null;
|
||||||
|
@ -736,6 +741,7 @@ public final class TemplateEngine {
|
||||||
|
|
||||||
IParameterizedSymbol function = (IParameterizedSymbol)templatedSymbol;
|
IParameterizedSymbol function = (IParameterizedSymbol)templatedSymbol;
|
||||||
function = (IParameterizedSymbol) function.instantiate( spec1, map );
|
function = (IParameterizedSymbol) function.instantiate( spec1, map );
|
||||||
|
((TemplateSymbol)spec1).processDeferredInstantiations();
|
||||||
|
|
||||||
Map m1 = deduceTemplateArgumentsUsingParameterList( spec2, function);
|
Map m1 = deduceTemplateArgumentsUsingParameterList( spec2, function);
|
||||||
|
|
||||||
|
@ -747,6 +753,7 @@ public final class TemplateEngine {
|
||||||
|
|
||||||
function = (IParameterizedSymbol)templatedSymbol;
|
function = (IParameterizedSymbol)templatedSymbol;
|
||||||
function = (IParameterizedSymbol) function.instantiate( spec2, map );
|
function = (IParameterizedSymbol) function.instantiate( spec2, map );
|
||||||
|
((TemplateSymbol)spec2).processDeferredInstantiations();
|
||||||
|
|
||||||
Map m2 = deduceTemplateArgumentsUsingParameterList( spec1, function );
|
Map m2 = deduceTemplateArgumentsUsingParameterList( spec1, function );
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.parser.pst.DerivableContainerSymbol.ParentWrapper;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp;
|
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 );
|
instance = (IContainerSymbol) symbol.instantiate( template, map );
|
||||||
addInstantiation( instance, actualArgs );
|
addInstantiation( instance, actualArgs );
|
||||||
|
|
||||||
|
processDeferredInstantiations();
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,10 +365,45 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
|
||||||
}
|
}
|
||||||
return _explicitSpecializations;
|
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 LinkedList _specializations; //template specializations
|
||||||
private HashMap _explicitSpecializations; //explicit specializations
|
private HashMap _explicitSpecializations; //explicit specializations
|
||||||
private HashMap _defnParameterMap; //members could be defined with different template parameter names
|
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