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

fix up handling of defered template instances (a better fix for 64919)

This commit is contained in:
Andrew Niefer 2004-06-01 20:16:15 +00:00
parent d7be8043d6
commit 441bdd65c8
4 changed files with 41 additions and 35 deletions

View file

@ -18,6 +18,7 @@ import java.io.Writer;
import java.util.Iterator; import java.util.Iterator;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration; import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTBaseSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTField; import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction; import org.eclipse.cdt.core.parser.ast.IASTFunction;
@ -29,6 +30,7 @@ import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation; import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter; import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter;
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization; import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
import org.eclipse.cdt.core.parser.ast.IASTTypeSpecifier;
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;
@ -948,13 +950,22 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
writer.write("template < class X > class A < X, Foo > : public A< X, X > "); writer.write("template < class X > class A < X, Foo > : public A< X, X > ");
writer.write("{ void f ( TYPE ); }; "); writer.write("{ void f ( TYPE ); }; ");
//success is no stack overflow
Iterator i = parse( writer.toString() ).getDeclarations(); Iterator i = parse( writer.toString() ).getDeclarations();
IASTClassSpecifier Foo = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); IASTClassSpecifier Foo = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTClassSpecifier Bar = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier(); IASTClassSpecifier Bar = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTTemplateDeclaration A1 = (IASTTemplateDeclaration) i.next(); IASTTemplateDeclaration T1 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration A2 = (IASTTemplateDeclaration) i.next(); IASTTemplateDeclaration T2 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration A3 = (IASTTemplateDeclaration) i.next(); IASTTemplateDeclaration T3 = (IASTTemplateDeclaration) i.next();
IASTClassSpecifier A1 = (IASTClassSpecifier) T1.getOwnedDeclaration();
IASTClassSpecifier A2 = (IASTClassSpecifier) T2.getOwnedDeclaration();
IASTClassSpecifier A3 = (IASTClassSpecifier) T3.getOwnedDeclaration();
IASTBaseSpecifier parent = (IASTBaseSpecifier) A2.getBaseClauses().next();
assertEquals( parent.getParentClassSpecifier(), A1 );
parent = (IASTBaseSpecifier) A3.getBaseClauses().next();
assertEquals( parent.getParentClassSpecifier(), A2 );
} }
} }

View file

@ -1756,13 +1756,9 @@ public class ParserSymbolTableTemplateTests extends TestCase {
ISymbol look = Y2.lookup( "Y" ); //$NON-NLS-1$ ISymbol look = Y2.lookup( "Y" ); //$NON-NLS-1$
assertTrue( look != null ); assertTrue( look != null );
assertTrue( look instanceof IDeferredTemplateInstance ); assertTrue( look.isTemplateInstance() );
IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) look; assertEquals( look.getInstantiatedSymbol(), Y2 );
assertEquals( deferred.getTemplate(), spec );
Iterator iter = deferred.getArguments().iterator();
TypeInfo type = (TypeInfo) iter.next();
assertTrue( type.isType( TypeInfo.t_int ) );
assertEquals( ParserSymbolTable.TypeInfoProvider.numAllocated(), 0 ); assertEquals( ParserSymbolTable.TypeInfoProvider.numAllocated(), 0 );
} }

View file

@ -656,22 +656,15 @@ public class ParserSymbolTable {
data.visited.add( parent ); data.visited.add( parent );
} }
//if the inheritanceChain already contains the parent, then that
//is circular inheritance
if( ! data.inheritanceChain.contains( parent ) ){
if( parent instanceof IDeferredTemplateInstance || parent instanceof ITemplateSymbol ){
if( parent instanceof IDeferredTemplateInstance ){ if( parent instanceof IDeferredTemplateInstance ){
parent = ((IDeferredTemplateInstance)parent).getTemplate().getTemplatedSymbol(); parent = ((IDeferredTemplateInstance)parent).getTemplate().getTemplatedSymbol();
} else if( parent instanceof ITemplateSymbol ){ } else if( parent instanceof ITemplateSymbol ){
parent = ((ITemplateSymbol)parent).getTemplatedSymbol(); parent = ((ITemplateSymbol)parent).getTemplatedSymbol();
} }
if( data.inheritanceChain.contains( parent ) ){
//bug 64919, might not really be circular inheritance, it just looks that way
//don't throw an exception, just ignore this parent.
continue;
}
}
//if the inheritanceChain already contains the parent, then that
//is circular inheritance
if( ! data.inheritanceChain.contains( parent ) ){
//is this name define in this scope? //is this name define in this scope?
if( parent instanceof IDerivableContainerSymbol ){ if( parent instanceof IDerivableContainerSymbol ){
temp = lookupInContained( data, (IDerivableContainerSymbol) parent ); temp = lookupInContained( data, (IDerivableContainerSymbol) parent );
@ -952,6 +945,9 @@ public class ParserSymbolTable {
!symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template )) !symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ))
{ {
resolvedSymbol = symbol.getContainingSymbol(); resolvedSymbol = symbol.getContainingSymbol();
if( resolvedSymbol instanceof ISpecializedSymbol ){
resolvedSymbol = ((ISpecializedSymbol)resolvedSymbol).getPrimaryTemplate();
}
} else { } else {
resolvedSymbol = symbol; resolvedSymbol = symbol;
} }

View file

@ -1081,35 +1081,38 @@ public final class TemplateEngine {
* *
* @param symbol * @param symbol
* @return * @return
* @throws ParserSymbolTableException
*/ */
static protected ISymbol instantiateWithinTemplateScope( IContainerSymbol container, ITemplateSymbol symbol ) static protected ISymbol instantiateWithinTemplateScope( IContainerSymbol container, ITemplateSymbol symbol ) throws ParserSymbolTableException
{ {
if( symbol.getTemplatedSymbol().isType( TypeInfo.t_function ) ){ if( symbol.getTemplatedSymbol().isType( TypeInfo.t_function ) ){
return symbol; return symbol;
} }
IDeferredTemplateInstance instance = null; ISymbol instance = null;
ITemplateSymbol template = null;
IContainerSymbol containing = container.getContainingSymbol(); IContainerSymbol containing = container.getContainingSymbol();
boolean instantiate = false; boolean instantiate = false;
while( containing != null ){ while( containing != null ){
if( containing == symbol ){ if( containing == symbol ||
( containing instanceof ISpecializedSymbol && ((ISpecializedSymbol)containing).getPrimaryTemplate() == symbol ) )
{
instantiate = true; instantiate = true;
template = (ITemplateSymbol) containing;
break; break;
} }
containing = containing.getContainingSymbol(); containing = containing.getContainingSymbol();
if( containing != null && !containing.isTemplateMember() || !containing.isType( TypeInfo.t_template ) ){ if( containing != null && !containing.isTemplateMember() || !containing.isType( TypeInfo.t_template ) ){
containing = null; break;
} }
} }
if( instantiate ){ if( instantiate ){
if( symbol instanceof ISpecializedSymbol ){ if( template instanceof ISpecializedSymbol ){
ISpecializedSymbol spec = (ISpecializedSymbol) symbol; ISpecializedSymbol spec = (ISpecializedSymbol) template;
instance = spec.deferredInstance( spec.getArgumentList() ); instance = spec.instantiate( spec.getArgumentList() );
} else { } else {
ITemplateSymbol template = symbol;
List params = template.getParameterList(); List params = template.getParameterList();
int size = params.size(); int size = params.size();
List args = new ArrayList( size ); List args = new ArrayList( size );
@ -1117,7 +1120,7 @@ public final class TemplateEngine {
args.add( new TypeInfo( TypeInfo.t_type, 0, (ISymbol) params.get(i) ) ); args.add( new TypeInfo( TypeInfo.t_type, 0, (ISymbol) params.get(i) ) );
} }
instance = template.deferredInstance( args ); instance = template.instantiate( args );
} }
} }