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 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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -656,22 +656,15 @@ public class ParserSymbolTable {
|
||||||
data.visited.add( parent );
|
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
|
//if the inheritanceChain already contains the parent, then that
|
||||||
//is circular inheritance
|
//is circular inheritance
|
||||||
if( ! data.inheritanceChain.contains( parent ) ){
|
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?
|
//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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue