diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java index e3f55436731..d713ad41c16 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.java @@ -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 ); } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java index 345c1669b55..904fbe99992 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTemplateTests.java @@ -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 ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index 23f6b038292..464d1c4b3c0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java index 621d8c27e4c..c9cfd463db4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TemplateEngine.java @@ -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 ); } }