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 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.IASTField;
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.IASTTemplateParameter;
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.IASTVariable;
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("{ void f ( TYPE ); }; ");
//success is no stack overflow
Iterator i = parse( writer.toString() ).getDeclarations();
IASTClassSpecifier Foo = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTClassSpecifier Bar = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTTemplateDeclaration A1 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration A2 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration A3 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration T1 = (IASTTemplateDeclaration) i.next();
IASTTemplateDeclaration T2 = (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$
assertTrue( look != null );
assertTrue( look instanceof IDeferredTemplateInstance );
IDeferredTemplateInstance deferred = (IDeferredTemplateInstance) look;
assertEquals( deferred.getTemplate(), spec );
assertTrue( look.isTemplateInstance() );
assertEquals( look.getInstantiatedSymbol(), Y2 );
Iterator iter = deferred.getArguments().iterator();
TypeInfo type = (TypeInfo) iter.next();
assertTrue( type.isType( TypeInfo.t_int ) );
assertEquals( ParserSymbolTable.TypeInfoProvider.numAllocated(), 0 );
}

View file

@ -655,23 +655,16 @@ public class ParserSymbolTable {
if( wrapper.isVirtual() ){
data.visited.add( parent );
}
if( parent instanceof IDeferredTemplateInstance ){
parent = ((IDeferredTemplateInstance)parent).getTemplate().getTemplatedSymbol();
} else if( parent instanceof ITemplateSymbol ){
parent = ((ITemplateSymbol)parent).getTemplatedSymbol();
}
//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 ){
parent = ((IDeferredTemplateInstance)parent).getTemplate().getTemplatedSymbol();
} else if( parent instanceof ITemplateSymbol ){
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;
}
}
//is this name define in this scope?
if( parent instanceof IDerivableContainerSymbol ){
temp = lookupInContained( data, (IDerivableContainerSymbol) parent );
@ -952,6 +945,9 @@ public class ParserSymbolTable {
!symbol.isType( TypeInfo.t_templateParameter ) && symbol.getContainingSymbol().isType( TypeInfo.t_template ))
{
resolvedSymbol = symbol.getContainingSymbol();
if( resolvedSymbol instanceof ISpecializedSymbol ){
resolvedSymbol = ((ISpecializedSymbol)resolvedSymbol).getPrimaryTemplate();
}
} else {
resolvedSymbol = symbol;
}

View file

@ -1081,35 +1081,38 @@ public final class TemplateEngine {
*
* @param symbol
* @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 ) ){
return symbol;
}
IDeferredTemplateInstance instance = null;
ISymbol instance = null;
ITemplateSymbol template = null;
IContainerSymbol containing = container.getContainingSymbol();
boolean instantiate = false;
while( containing != null ){
if( containing == symbol ){
if( containing == symbol ||
( containing instanceof ISpecializedSymbol && ((ISpecializedSymbol)containing).getPrimaryTemplate() == symbol ) )
{
instantiate = true;
template = (ITemplateSymbol) containing;
break;
}
containing = containing.getContainingSymbol();
if( containing != null && !containing.isTemplateMember() || !containing.isType( TypeInfo.t_template ) ){
containing = null;
break;
}
}
if( instantiate ){
if( symbol instanceof ISpecializedSymbol ){
ISpecializedSymbol spec = (ISpecializedSymbol) symbol;
instance = spec.deferredInstance( spec.getArgumentList() );
if( template instanceof ISpecializedSymbol ){
ISpecializedSymbol spec = (ISpecializedSymbol) template;
instance = spec.instantiate( spec.getArgumentList() );
} else {
ITemplateSymbol template = symbol;
List params = template.getParameterList();
int size = params.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) ) );
}
instance = template.deferredInstance( args );
instance = template.instantiate( args );
}
}