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:
parent
d7be8043d6
commit
441bdd65c8
4 changed files with 41 additions and 35 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -656,22 +656,15 @@ public class ParserSymbolTable {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue