1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-31 12:55:40 +02:00

-work on bug 50984: fix NPEs/CCEs caused by problems with typedefs and a bug in template instantiations

-fix bug 59892: completion on typedefs
-handle ASTExpression as a context for content assist
This commit is contained in:
Andrew Niefer 2004-04-26 20:33:12 +00:00
parent 7c63d5bffc
commit 6797f7dd40
14 changed files with 128 additions and 154 deletions

View file

@ -1,66 +0,0 @@
/**********************************************************************
* Copyright (c) 2002-2004 IBM Canada and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.core.parser.failedTests;
import java.io.StringWriter;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTNode.ILookupResult;
import org.eclipse.cdt.core.parser.tests.CompletionParseBaseTest;
/**
* @author johnc
*/
public class CompletionParseFailedTest extends CompletionParseBaseTest {
/**
*
*/
public CompletionParseFailedTest() {
super();
// TODO Auto-generated constructor stub
}
/**
* @param name
*/
public CompletionParseFailedTest(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public void testCompletionInTypeDef() throws Exception{
StringWriter writer = new StringWriter();
writer.write( "struct A { int name; }; \n" );
writer.write( "typedef struct A * PA; \n" );
writer.write( "int main() { \n" );
writer.write( " PA a; \n" );
writer.write( " a->SP \n" );
writer.write( "} \n" );
String code = writer.toString();
int index = code.indexOf( "SP" );
IASTCompletionNode node = parse( code, index );
ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
new IASTNode.LookupKind[]{ IASTNode.LookupKind.ALL },
node.getCompletionContext() );
//this is where the failure happens ... when the bug is fixed this line can be removed and the rest uncommented
assertEquals( result.getResultsSize(), 4 );
// assertEquals( result.getResultsSize(), 1 );
//
// Iterator iter = result.getNodes();
// IASTField name = (IASTField) iter.next();
//
// assertEquals( name.getName(), "name" );
// assertFalse( iter.hasNext() );
}
}

View file

@ -37,6 +37,7 @@ import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTReference; import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration; import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration; import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective; import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
@ -1657,4 +1658,26 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertAllReferences( 3, createTaskList( new Task( A, 2 ), new Task( a ))); assertAllReferences( 3, createTaskList( new Task( A, 2 ), new Task( a )));
} }
public void testBug50984_ASTMethod_getOwnerClassSpecifier_ClassCastException() throws Exception
{
Writer writer = new StringWriter();
writer.write( "template < typename _OutIter > " );
writer.write( "class num_put { " );
writer.write( " typedef _OutIter iter_type; " );
writer.write( " template< typename _ValueT > " );
writer.write( " iter_type _M_convert_float( iter_type ); " );
writer.write( "}; " );
writer.write( "template < typename _OutIter > " );
writer.write( "template < typename _ValueT > " );
writer.write( "_OutIter num_put<_OutIter>::_M_convert_float( _OutIter ) { } " );
Iterator i = parse( writer.toString() ).getDeclarations();
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
IASTClassSpecifier num_put = (IASTClassSpecifier) template.getOwnedDeclaration();
IASTTemplateDeclaration defn = (IASTTemplateDeclaration) i.next();
IASTMethod convert = (IASTMethod) defn.getOwnedDeclaration();
assertEquals( convert.getOwnerClassSpecifier(), num_put );
}
} }

View file

@ -812,4 +812,29 @@ public class CompletionParseTest extends CompletionParseBaseTest {
} }
} }
public void testCompletionInTypeDef() throws Exception{
StringWriter writer = new StringWriter();
writer.write( "struct A { int name; }; \n" );
writer.write( "typedef struct A * PA; \n" );
writer.write( "int main() { \n" );
writer.write( " PA a; \n" );
writer.write( " a->SP \n" );
writer.write( "} \n" );
String code = writer.toString();
int index = code.indexOf( "SP" );
IASTCompletionNode node = parse( code, index );
ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
new IASTNode.LookupKind[]{ IASTNode.LookupKind.ALL },
node.getCompletionContext() );
assertEquals( result.getResultsSize(), 1 );
Iterator iter = result.getNodes();
IASTField name = (IASTField) iter.next();
assertEquals( name.getName(), "name" );
assertFalse( iter.hasNext() );
}
} }

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.core.model.tests.BinaryTests;
import org.eclipse.cdt.core.model.tests.ElementDeltaTests; import org.eclipse.cdt.core.model.tests.ElementDeltaTests;
import org.eclipse.cdt.core.model.tests.WorkingCopyTests; import org.eclipse.cdt.core.model.tests.WorkingCopyTests;
import org.eclipse.cdt.core.parser.failedTests.ASTFailedTests; import org.eclipse.cdt.core.parser.failedTests.ASTFailedTests;
import org.eclipse.cdt.core.parser.failedTests.CompletionParseFailedTest;
import org.eclipse.cdt.core.parser.failedTests.FailedCompleteParseASTTest; import org.eclipse.cdt.core.parser.failedTests.FailedCompleteParseASTTest;
import org.eclipse.cdt.core.parser.failedTests.STLFailedTests; import org.eclipse.cdt.core.parser.failedTests.STLFailedTests;
import org.eclipse.cdt.core.parser.tests.ParserTestSuite; import org.eclipse.cdt.core.parser.tests.ParserTestSuite;
@ -68,7 +67,6 @@ public class AutomatedIntegrationSuite extends TestSuite {
suite.addTestSuite(ASTFailedTests.class); suite.addTestSuite(ASTFailedTests.class);
suite.addTestSuite(STLFailedTests.class); suite.addTestSuite(STLFailedTests.class);
suite.addTestSuite(FailedCompleteParseASTTest.class); suite.addTestSuite(FailedCompleteParseASTTest.class);
suite.addTestSuite(CompletionParseFailedTest.class);
return suite; return suite;
} }

View file

@ -17,7 +17,7 @@ import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
* @author jcamelon * @author jcamelon
* *
*/ */
public interface IASTTemplateParameter extends IASTTemplateParameterList, ISourceElementCallbackDelegate { public interface IASTTemplateParameter extends IASTTemplateParameterList, IASTTypeSpecifier, ISourceElementCallbackDelegate {
public class ParamKind extends Enum public class ParamKind extends Enum
{ {

View file

@ -20,6 +20,8 @@ import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTExpression;
import org.eclipse.cdt.core.parser.ast.IASTReference; import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTTypeId; import org.eclipse.cdt.core.parser.ast.IASTTypeId;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/** /**
* @author jcamelon * @author jcamelon
@ -308,4 +310,20 @@ public class ASTExpression extends ASTNode implements IASTExpression
} }
return stringRepresentation; return stringRepresentation;
} }
public IContainerSymbol getLookupQualificationSymbol() throws LookupError {
ExpressionResult result = getResultType();
TypeInfo type = (result != null ) ? getResultType().getResult() : null;
if( type != null ){
type = type.getFinalType();
if( type.isType( TypeInfo.t_type ) &&
type.getTypeSymbol() != null && type.getTypeSymbol() instanceof IContainerSymbol )
{
return (IContainerSymbol) type.getTypeSymbol();
}
}
return null;
}
} }

View file

@ -17,9 +17,6 @@ import java.util.ListIterator;
import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException; import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTNode; import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.internal.core.parser.ast.SymbolIterator; import org.eclipse.cdt.internal.core.parser.ast.SymbolIterator;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.IExtensibleSymbol; import org.eclipse.cdt.internal.core.parser.pst.IExtensibleSymbol;
@ -28,7 +25,6 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.pst.TypeFilter; import org.eclipse.cdt.internal.core.parser.pst.TypeFilter;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/** /**
* @author aniefer * @author aniefer
@ -40,7 +36,7 @@ public class ASTNode implements IASTNode {
*/ */
public ILookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupError, ASTNotImplementedException { public ILookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupError, ASTNotImplementedException {
if( ! ( this instanceof ISymbolOwner ) || ( context != null && !(context instanceof ISymbolOwner) ) ){ if( ! ( this instanceof ISymbolOwner ) ){
return null; return null;
} }
@ -49,7 +45,7 @@ public class ASTNode implements IASTNode {
throw new LookupError(); throw new LookupError();
} }
IContainerSymbol thisContainer = (IContainerSymbol) symbol; IContainerSymbol thisContainer = (IContainerSymbol) symbol;
IContainerSymbol qualification = getQualificationSymbol(context); IContainerSymbol qualification = ( context != null ) ? ((ASTNode)context).getLookupQualificationSymbol() : null;
if( thisContainer.getSymbolTable().getParserMode() != ParserMode.COMPLETION_PARSE ){ if( thisContainer.getSymbolTable().getParserMode() != ParserMode.COMPLETION_PARSE ){
throw new ASTNotImplementedException(); throw new ASTNotImplementedException();
@ -126,33 +122,8 @@ public class ASTNode implements IASTNode {
* @return * @return
* @throws LookupError * @throws LookupError
*/ */
protected IContainerSymbol getQualificationSymbol(IASTNode context) throws LookupError { public IContainerSymbol getLookupQualificationSymbol() throws LookupError {
if( context == null ) throw new LookupError();
return null;
ISymbol sym = null;
if( context instanceof IASTTypedefDeclaration ||
context instanceof IASTVariable ||
context instanceof IASTParameterDeclaration )
{
sym = ((ISymbolOwner)context).getSymbol();
TypeInfo info = null;
try{
info = sym.getTypeInfo().getFinalType();
} catch( ParserSymbolTableError e ){
throw new LookupError();
}
sym = info.getTypeSymbol();
}
else
{
sym = (IContainerSymbol) ((ISymbolOwner)context).getSymbol();
}
if( sym == null || !(sym instanceof IContainerSymbol) ){
throw new LookupError();
}
return (IContainerSymbol) sym;
} }
private class Result implements ILookupResult{ private class Result implements ILookupResult{

View file

@ -12,8 +12,11 @@ package org.eclipse.cdt.internal.core.parser.ast.complete;
import org.eclipse.cdt.core.parser.ast.IASTDeclaration; import org.eclipse.cdt.core.parser.ast.IASTDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbol; import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner; import org.eclipse.cdt.internal.core.parser.pst.ISymbolOwner;
import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableError;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/** /**
* @author jcamelon * @author jcamelon
@ -37,4 +40,20 @@ public abstract class ASTSymbol extends ASTSymbolOwner implements ISymbolOwner,
return null; return null;
} }
public IContainerSymbol getLookupQualificationSymbol() throws LookupError {
ISymbol sym = getSymbol();
TypeInfo info = null;
try{
info = sym.getTypeInfo().getFinalType();
} catch( ParserSymbolTableError e ){
throw new LookupError();
}
if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol() != null && info.getTypeSymbol() instanceof IContainerSymbol )
return (IContainerSymbol) info.getTypeSymbol();
else if( sym instanceof IContainerSymbol )
return (IContainerSymbol) sym;
return null;
}
} }

View file

@ -2879,14 +2879,22 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
int startingLine, int nameOffset, int nameEndOffset, int nameLine) throws ASTSemanticException int startingLine, int nameOffset, int nameEndOffset, int nameLine) throws ASTSemanticException
{ {
IContainerSymbol containerSymbol = scopeToSymbol(scope); IContainerSymbol containerSymbol = scopeToSymbol(scope);
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type); ISymbol typeSymbol = cloneSimpleTypeSymbol( name, mapping, new ArrayList() );
newSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
if( typeSymbol == null )
ISymbol typeSymbol = cloneSimpleTypeSymbol( EMPTY_STRING, mapping, new ArrayList() ); handleProblem( scope, IProblem.SEMANTICS_RELATED, name, nameOffset, nameEndOffset, nameLine );
setPointerOperators( typeSymbol, mapping.getPointerOperators(), mapping.getArrayModifiers() ); setPointerOperators( typeSymbol, mapping.getPointerOperators(), mapping.getArrayModifiers() );
newSymbol.setTypeSymbol( typeSymbol ); if( typeSymbol.getType() != TypeInfo.t_type ){
ISymbol newSymbol = pst.newSymbol( name, TypeInfo.t_type);
newSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
newSymbol.setTypeSymbol( typeSymbol );
typeSymbol = newSymbol;
} else {
typeSymbol.getTypeInfo().setBit( true,TypeInfo.isTypedef );
}
List references = new ArrayList(); List references = new ArrayList();
if( mapping.getTypeSpecifier() instanceof ASTSimpleTypeSpecifier ) if( mapping.getTypeSpecifier() instanceof ASTSimpleTypeSpecifier )
{ {
@ -2895,14 +2903,14 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
try try
{ {
containerSymbol.addSymbol( newSymbol ); containerSymbol.addSymbol( typeSymbol );
} }
catch (ParserSymbolTableException e) catch (ParserSymbolTableException e)
{ {
handleProblem(e.createProblemID(), name ); handleProblem(e.createProblemID(), name );
} }
ASTTypedef d = new ASTTypedef( newSymbol, mapping, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, references ); ASTTypedef d = new ASTTypedef( typeSymbol, mapping, startingOffset, startingLine, nameOffset, nameEndOffset, nameLine, references );
attachSymbolExtension(newSymbol, d, true ); attachSymbolExtension(typeSymbol, d, true );
return d; return d;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -14,6 +14,8 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.parser.ISourceElementRequestor; import org.eclipse.cdt.core.parser.ISourceElementRequestor;
import org.eclipse.cdt.core.parser.ast.ASTNotImplementedException;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter; import org.eclipse.cdt.core.parser.ast.IASTTemplateParameter;
@ -93,5 +95,12 @@ public class ASTTemplateParameter implements IASTTemplateParameter
*/ */
public void exitScope(ISourceElementRequestor requestor) { public void exitScope(ISourceElementRequestor requestor) {
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTNode#lookup(java.lang.String, org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind[], org.eclipse.cdt.core.parser.ast.IASTNode)
*/
public ILookupResult lookup(String prefix, LookupKind[] kind, IASTNode context) throws LookupError, ASTNotImplementedException {
// TODO Auto-generated method stub
return null;
}
} }

View file

@ -139,7 +139,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){ if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){
Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() ); Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() );
if( obj instanceof List ){ if( obj instanceof List ){
((List) obj).add( obj ); ((List) obj).add( newSymbol );
} else { } else {
List list = new LinkedList(); List list = new LinkedList();
list.add( obj ); list.add( obj );

View file

@ -95,9 +95,6 @@ public class ParserSymbolTable {
return new TemplateFactory( this ); return new TemplateFactory( this );
} }
// public ISpecializedSymbol newSpecializedSymbol( String name, TypeInfo.eType type ){
// return new Declaration( this, name, type );
// }
/** /**
* Lookup the name from LookupData starting in the inDeclaration * Lookup the name from LookupData starting in the inDeclaration
* @param data * @param data
@ -107,10 +104,6 @@ public class ParserSymbolTable {
*/ */
static protected void lookup( LookupData data, IContainerSymbol inSymbol ) throws ParserSymbolTableException static protected void lookup( LookupData data, IContainerSymbol inSymbol ) throws ParserSymbolTableException
{ {
// if( data.type != TypeInfo.t_any && data.type.compareTo(TypeInfo.t_class) < 0 && data.upperType.compareTo(TypeInfo.t_union) > 0 ){
// throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
// }
//handle namespace aliases //handle namespace aliases
if( inSymbol.isType( TypeInfo.t_namespace ) ){ if( inSymbol.isType( TypeInfo.t_namespace ) ){
ISymbol symbol = inSymbol.getTypeSymbol(); ISymbol symbol = inSymbol.getTypeSymbol();
@ -953,27 +946,6 @@ public class ParserSymbolTable {
resolvedSymbol = resolveFunction( data, functionList ); resolvedSymbol = resolveFunction( data, functionList );
} }
} }
if( resolvedSymbol != null && resolvedSymbol.getTypeInfo().checkBit( TypeInfo.isTypedef ) ){
ISymbol symbol = resolvedSymbol.getTypeSymbol();
if( symbol == null )
return resolvedSymbol;
TypeInfo info = ParserSymbolTable.getFlatTypeInfo( symbol.getTypeInfo() );
symbol = info.getTypeSymbol();
ISymbol newSymbol = null;
if( symbol != null ){
newSymbol = (ISymbol) symbol.clone();
newSymbol.setName( resolvedSymbol.getName() );
} else {
newSymbol = resolvedSymbol.getSymbolTable().newSymbol( resolvedSymbol.getName() );
newSymbol.setTypeInfo( info );
}
newSymbol.setASTExtension( resolvedSymbol.getASTExtension() );
newSymbol.setContainingSymbol( resolvedSymbol.getContainingSymbol() );
resolvedSymbol = newSymbol;
}
return resolvedSymbol; return resolvedSymbol;
} }
@ -1978,7 +1950,6 @@ public class ParserSymbolTable {
* The top level TypeInfo represents modifications to the object and the * The top level TypeInfo represents modifications to the object and the
* remaining TypeInfo's represent the object. * remaining TypeInfo's represent the object.
*/ */
// TODO move this to ITypeInfo ?
static protected TypeInfo getFlatTypeInfo( TypeInfo topInfo ){ static protected TypeInfo getFlatTypeInfo( TypeInfo topInfo ){
TypeInfo returnInfo = topInfo; TypeInfo returnInfo = topInfo;
TypeInfo info = null; TypeInfo info = null;
@ -2270,7 +2241,6 @@ public class ParserSymbolTable {
} }
if( ! (qualifyingSymbol instanceof IDerivableContainerSymbol) ){ if( ! (qualifyingSymbol instanceof IDerivableContainerSymbol) ){
// throw new ParserSymbolTableError( ParserSymbolTableError.r_InternalError ); //TODO - Andrew, why is this an error?
return ASTAccessVisibility.PUBLIC; return ASTAccessVisibility.PUBLIC;
} }

View file

@ -61,8 +61,6 @@ public final class TemplateEngine {
TypeInfo newInfo = new TypeInfo( info ); TypeInfo newInfo = new TypeInfo( info );
newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) ); newInfo.setTypeSymbol( info.getTypeSymbol().instantiate( template, argMap ) );
return newInfo; return newInfo;
} else if( info.checkBit( TypeInfo.isTypedef ) && info.getTypeSymbol() != null ){
return instantiateTypeInfo( info.getTypeSymbol().getTypeInfo(), template, argMap );
} }
return info; return info;
} }
@ -443,7 +441,7 @@ public final class TemplateEngine {
if( p.isType( TypeInfo.t_type ) ){ if( p.isType( TypeInfo.t_type ) ){
symbol = p.getTypeSymbol(); symbol = p.getTypeSymbol();
ISymbol aSymbol = a.getTypeSymbol(); ISymbol aSymbol = a.getTypeSymbol();
if( symbol == null || ( a.isType( TypeInfo.t_type) && aSymbol == null ) ) if( symbol == null || ( a.isType( TypeInfo.t_type) && aSymbol == null ) || a.isType( TypeInfo.t_undef ))
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
if( symbol instanceof IDeferredTemplateInstance || symbol.isTemplateInstance() ){ if( symbol instanceof IDeferredTemplateInstance || symbol.isTemplateInstance() ){
return deduceFromTemplateTemplateArguments(map, symbol, aSymbol); return deduceFromTemplateTemplateArguments(map, symbol, aSymbol);

View file

@ -304,17 +304,18 @@ public class TemplateSymbol extends ParameterizedSymbol implements ITemplateSymb
} }
} }
if( found != null && found.getTypeInfo().isForwardDeclaration() && found.getTypeSymbol() == symbol ){ if( found != null ){
//in defining the explicit specialization for a member function, the factory would have set //in defining the explicit specialization for a member function, the factory would have set
//the specialization as the definition of the original declaration, which it is not //the specialization as the definition of the original declaration, which it is not
found.setTypeSymbol( null ); if( found.getTypeInfo().isForwardDeclaration() && found.getTypeSymbol() == symbol )
} found.setTypeSymbol( null );
//TODO, once we can instantiate members as we need them instead of at the same time as the class //TODO, once we can instantiate members as we need them instead of at the same time as the class
//then found should stay as the instance, for now though, we need the original (not 100% correct //then found should stay as the instance, for now though, we need the original (not 100% correct
//but the best we can do for now) //but the best we can do for now)
while( found.isTemplateInstance() ){ while( found.isTemplateInstance() ){
found = found.getInstantiatedSymbol(); found = found.getInstantiatedSymbol();
}
} }
if( found != null ){ if( found != null ){