mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-04 15:45:25 +02:00
fix bug 57754, fix instantiating constructors, fix some problems with explicit specialization
This commit is contained in:
parent
03d56777ac
commit
32abdb30e8
14 changed files with 197 additions and 39 deletions
|
@ -1,3 +1,9 @@
|
|||
2004-04-09 Andrew Niefer
|
||||
fixed bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=57754
|
||||
added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.testBug57754()
|
||||
added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testBug57754()
|
||||
added parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTemplateTest.testContructorsAndExplicitSpecialization()
|
||||
|
||||
2004-04-08 John Camelon
|
||||
Removed warnings from CompletionTests.
|
||||
Added CompleteParseASTTest::testBug57800().
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier;
|
|||
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.IASTTemplatedDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTTypedefDeclaration;
|
||||
import org.eclipse.cdt.core.parser.ast.IASTVariable;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||
|
@ -699,4 +699,40 @@ public class CompleteParseASTTemplateTest extends CompleteParseBaseTest {
|
|||
assertTrue( e.getMessage().equals( "FAILURE" ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void testBug57754() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write("template < class T > class A{ ");
|
||||
writer.write(" typedef int _type; ");
|
||||
writer.write(" void f( _type, T ); ");
|
||||
writer.write("}; ");
|
||||
writer.write("template < class T > void A< T >::f( _type, T ) {} ");
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
|
||||
IASTClassSpecifier cls = (IASTClassSpecifier) template.getOwnedDeclaration();
|
||||
|
||||
i = getDeclarations( cls );
|
||||
IASTTypedefDeclaration _type = (IASTTypedefDeclaration) i.next();
|
||||
|
||||
assertReferenceTask( new Task( _type, 2 ) );
|
||||
}
|
||||
|
||||
public void testContructorsAndExplicitSpecialization() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write("template < class T > class A { ");
|
||||
writer.write(" A(); ");
|
||||
writer.write(" A( int ); ");
|
||||
writer.write(" ~A(); ");
|
||||
writer.write("}; ");
|
||||
writer.write("template <> A< char >::~A(); ");
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTTemplateDeclaration template = (IASTTemplateDeclaration) i.next();
|
||||
IASTTemplateSpecialization spec = (IASTTemplateSpecialization) i.next();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1412,6 +1412,28 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
|||
assertAllReferences( 2, createTaskList( new Task( outerS ), new Task( innerS ) ) );
|
||||
}
|
||||
|
||||
public void testBug57754() throws Exception
|
||||
{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write( "struct X { " );
|
||||
writer.write( " typedef int T; " );
|
||||
writer.write( " void f( T ); " );
|
||||
writer.write( "}; " );
|
||||
writer.write( "void X::f( T ) { } " );
|
||||
|
||||
Iterator i = parse( writer.toString() ).getDeclarations();
|
||||
|
||||
IASTClassSpecifier X = (IASTClassSpecifier) ((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
|
||||
IASTMethod f = (IASTMethod) i.next();
|
||||
|
||||
assertTrue( f.previouslyDeclared() );
|
||||
|
||||
i = getDeclarations( X );
|
||||
IASTTypedefDeclaration T = (IASTTypedefDeclaration) i.next();
|
||||
|
||||
assertAllReferences( 3, createTaskList( new Task( X ), new Task( T, 2 ) ) );
|
||||
}
|
||||
|
||||
public void testBug57800() throws Exception
|
||||
{
|
||||
Writer writer= new StringWriter();
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2004-04-09 Andrew Niefer
|
||||
fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=57754
|
||||
Fixed problems found after parsing iostream with discovered symbols, once 57754 was fixed:
|
||||
fixed some problems with explicit specializations
|
||||
handle using declarations of templates
|
||||
handle typedefs in ASTCompleteParseFactory.queryIsTypeName
|
||||
fixed instantiating constructors
|
||||
|
||||
2004-04-08 John Camelon
|
||||
Fixed https://bugs.eclipse.org/bugs/show_bug.cgi?id=57800.
|
||||
|
||||
|
|
|
@ -251,6 +251,13 @@ public interface IASTFactory
|
|||
*/
|
||||
public void setLogger(IParserLogService log);
|
||||
|
||||
/**
|
||||
* @param scope
|
||||
* @param duple
|
||||
* @return
|
||||
*/
|
||||
public IASTScope getDeclaratorScope(IASTScope scope, ITokenDuple duple);
|
||||
|
||||
/**
|
||||
* @param scope TODO
|
||||
* @param expression
|
||||
|
|
|
@ -2043,6 +2043,7 @@ public abstract class Parser extends ExpressionParser implements IParser
|
|||
case IToken.tLPAREN :
|
||||
|
||||
boolean failed = false;
|
||||
IASTScope parameterScope = astFactory.getDeclaratorScope( scope, d.getNameDuple() );
|
||||
// temporary fix for initializer/function declaration ambiguity
|
||||
if ( queryLookaheadCapability(2) && !LA(2).looksLikeExpression() && strategy != SimpleDeclarationStrategy.TRY_VARIABLE )
|
||||
{
|
||||
|
@ -2055,7 +2056,7 @@ public abstract class Parser extends ExpressionParser implements IParser
|
|||
{
|
||||
try
|
||||
{
|
||||
if( ! astFactory.queryIsTypeName( scope, name(scope, CompletionKind.TYPE_REFERENCE ) ) )
|
||||
if( ! astFactory.queryIsTypeName( parameterScope, name(parameterScope, CompletionKind.TYPE_REFERENCE ) ) )
|
||||
failed = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -2084,7 +2085,7 @@ public abstract class Parser extends ExpressionParser implements IParser
|
|||
{
|
||||
case IToken.tRPAREN :
|
||||
consume();
|
||||
setCompletionValues( scope, CompletionKind.NO_SUCH_KIND, KeywordSets.Key.FUNCTION_MODIFIER );
|
||||
setCompletionValues( parameterScope, CompletionKind.NO_SUCH_KIND, KeywordSets.Key.FUNCTION_MODIFIER );
|
||||
break parameterDeclarationLoop;
|
||||
case IToken.tELLIPSIS :
|
||||
consume();
|
||||
|
@ -2092,13 +2093,13 @@ public abstract class Parser extends ExpressionParser implements IParser
|
|||
break;
|
||||
case IToken.tCOMMA :
|
||||
consume();
|
||||
setCompletionValues( scope, CompletionKind.ARGUMENT_TYPE, Key.DECL_SPECIFIER_SEQUENCE );
|
||||
setCompletionValues( parameterScope, CompletionKind.ARGUMENT_TYPE, Key.DECL_SPECIFIER_SEQUENCE );
|
||||
seenParameter = false;
|
||||
break;
|
||||
default :
|
||||
if (seenParameter)
|
||||
throw backtrack;
|
||||
parameterDeclaration(d, scope);
|
||||
parameterDeclaration(d, parameterScope);
|
||||
seenParameter = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -369,7 +369,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
if( result != null ){
|
||||
if( lookup == LookupType.FORPARENTSCOPE && startingScope instanceof ITemplateFactory ){
|
||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||
if( templateArgLists != null && templateArgLists[idx] != null )
|
||||
((ITemplateFactory)startingScope).pushTemplateId( result, getTemplateArgList( templateArgLists[idx] ) );
|
||||
else
|
||||
((ITemplateFactory)startingScope).pushSymbol( result );
|
||||
}
|
||||
addReference( references, createReference( result, image, offset ));
|
||||
if( templateArgLists != null && templateArgLists[idx] != null )
|
||||
|
@ -501,11 +504,15 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
IUsingDeclarationSymbol endResult = null;
|
||||
|
||||
if( name.length() != 1 )
|
||||
if(name.getSegmentCount() > 1)
|
||||
{
|
||||
ITokenDuple duple = name.getSubrange(0,name.length() - 3 );
|
||||
IContainerSymbol containerSymbol = (IContainerSymbol) lookupQualifiedName( scopeToSymbol(scope), duple, references, true );
|
||||
|
||||
ITokenDuple duple = name.getLeadingSegments();
|
||||
ISymbol symbol = lookupQualifiedName( scopeToSymbol(scope), duple, references, true );
|
||||
IContainerSymbol containerSymbol = null;
|
||||
if( symbol instanceof IContainerSymbol )
|
||||
containerSymbol = (IContainerSymbol) symbol;
|
||||
else if ( symbol instanceof IDeferredTemplateInstance )
|
||||
containerSymbol = ((IDeferredTemplateInstance)symbol).getTemplate().getTemplatedSymbol();
|
||||
try
|
||||
{
|
||||
endResult = scopeToSymbol(scope).addUsingDeclaration( name.getLastToken().getImage(), containerSymbol );
|
||||
|
@ -2993,6 +3000,40 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
return codeScope;
|
||||
}
|
||||
|
||||
public IASTScope getDeclaratorScope(IASTScope scope, ITokenDuple duple){
|
||||
if( duple != null && duple.getSegmentCount() > 1){
|
||||
List refs = new ArrayList();
|
||||
|
||||
IContainerSymbol ownerScope = scopeToSymbol( scope );
|
||||
ISymbol symbol;
|
||||
|
||||
try {
|
||||
symbol = lookupQualifiedName( ownerScope, duple.getLeadingSegments(), refs, false, LookupType.FORDEFINITION );
|
||||
} catch (ASTSemanticException e) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
IContainerSymbol parentScope = null;
|
||||
|
||||
if( symbol instanceof IContainerSymbol )
|
||||
parentScope = (IContainerSymbol) symbol;
|
||||
else if( symbol instanceof IDeferredTemplateInstance )
|
||||
parentScope = ((IDeferredTemplateInstance) symbol).getTemplate().getTemplatedSymbol();
|
||||
|
||||
if( parentScope != null && parentScope.getASTExtension() != null ){
|
||||
if( scope instanceof IASTTemplateDeclaration || scope instanceof IASTTemplateSpecialization ){
|
||||
symbol = scopeToSymbol( scope );
|
||||
if( symbol instanceof ITemplateFactory ){
|
||||
symbol.setContainingSymbol( parentScope );
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
return (IASTScope)parentScope.getASTExtension().getPrimaryDeclaration();
|
||||
}
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#queryIsTypeName(org.eclipse.cdt.core.parser.ITokenDuple)
|
||||
*/
|
||||
|
@ -3010,8 +3051,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
}
|
||||
if( lookupSymbol == null ) return false;
|
||||
if( lookupSymbol.isType( TypeInfo.t_type, TypeInfo.t_enumeration ) ||
|
||||
( lookupSymbol.isType( TypeInfo.t_templateParameter ) &&
|
||||
lookupSymbol.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ) )
|
||||
(lookupSymbol.isType( TypeInfo.t_templateParameter ) && lookupSymbol.getTypeInfo().getTemplateParameterType() == TypeInfo.t_typeName ) ||
|
||||
(lookupSymbol.getASTExtension() != null && lookupSymbol.getASTExtension().getPrimaryDeclaration() instanceof IASTTypedefDeclaration ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -922,5 +922,12 @@ public class ExpressionParseASTFactory extends BaseASTFactory implements IASTFac
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#getDeclaratorScope(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple)
|
||||
*/
|
||||
public IASTScope getDeclaratorScope(IASTScope scope, ITokenDuple duple) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -364,6 +364,13 @@ public class QuickParseASTFactory extends BaseASTFactory implements IASTFactory
|
|||
throw new ASTNotImplementedException();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#getDeclaratorScope(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ITokenDuple)
|
||||
*/
|
||||
public IASTScope getDeclaratorScope(IASTScope scope, ITokenDuple duple) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#getNodeForThisExpression(org.eclipse.cdt.core.parser.ast.IASTExpression)
|
||||
*/
|
||||
|
|
|
@ -121,22 +121,25 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
|||
}
|
||||
|
||||
newSymbol = ((ISymbol)containedSymbol).instantiate( template, instanceMap );
|
||||
|
||||
newSymbol.setContainingSymbol( newContainer );
|
||||
newContainer._contents.add( newSymbol );
|
||||
|
||||
if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){
|
||||
Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() );
|
||||
if( obj instanceof List ){
|
||||
((List) obj).add( obj );
|
||||
} else {
|
||||
List list = new LinkedList();
|
||||
list.add( obj );
|
||||
list.add( newSymbol );
|
||||
newContainer.getContainedSymbols().put( newSymbol.getName(), list );
|
||||
}
|
||||
|
||||
if( newSymbol instanceof IParameterizedSymbol && newSymbol.isType( TypeInfo.t_constructor ) ){
|
||||
collectInstantiatedConstructor( (IParameterizedSymbol) containedSymbol );
|
||||
} else {
|
||||
newContainer.getContainedSymbols().put( newSymbol.getName(), newSymbol );
|
||||
if( newContainer.getContainedSymbols().containsKey( newSymbol.getName() ) ){
|
||||
Object obj = newContainer.getContainedSymbols().get( newSymbol.getName() );
|
||||
if( obj instanceof List ){
|
||||
((List) obj).add( obj );
|
||||
} else {
|
||||
List list = new LinkedList();
|
||||
list.add( obj );
|
||||
list.add( newSymbol );
|
||||
newContainer.getContainedSymbols().put( newSymbol.getName(), list );
|
||||
}
|
||||
} else {
|
||||
newContainer.getContainedSymbols().put( newSymbol.getName(), newSymbol );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,6 +148,9 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
|
|||
return newContainer;
|
||||
}
|
||||
|
||||
protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){
|
||||
throw new ParserSymbolTableError();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol#addSymbol(org.eclipse.cdt.internal.core.parser.pst.ISymbol)
|
||||
*/
|
||||
|
|
|
@ -95,6 +95,11 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva
|
|||
}
|
||||
}
|
||||
|
||||
protected void collectInstantiatedConstructor( IParameterizedSymbol constructor ){
|
||||
if( constructor.isType( TypeInfo.t_constructor ) )
|
||||
getConstructors().add( constructor );
|
||||
}
|
||||
|
||||
public void addSymbol(ISymbol symbol) throws ParserSymbolTableException {
|
||||
super.addSymbol( symbol );
|
||||
|
||||
|
|
|
@ -327,11 +327,12 @@ public class ParserSymbolTable {
|
|||
while( name != null ) {
|
||||
if( nameMatches( data, name ) ){
|
||||
obj = ( declarations != null ) ? declarations.get( name ) : null;
|
||||
|
||||
obj = collectSymbol( data, obj );
|
||||
|
||||
if( obj != null )
|
||||
found.put( name, obj );
|
||||
if( obj != null ){
|
||||
obj = collectSymbol( data, obj );
|
||||
|
||||
if( obj != null )
|
||||
found.put( name, obj );
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -847,8 +848,8 @@ public class ParserSymbolTable {
|
|||
while( valid && iter.hasNext() ){
|
||||
symbol = (ISymbol) iter.next();
|
||||
if( symbol.isType( TypeInfo.t_template ) ){
|
||||
IParameterizedSymbol template = (IParameterizedSymbol) symbol;
|
||||
symbol = (ISymbol) template.getContainedSymbols().get( template.getName() );
|
||||
ITemplateSymbol template = (ITemplateSymbol) symbol;
|
||||
symbol = (ISymbol) template.getTemplatedSymbol();
|
||||
}
|
||||
valid = ( symbol instanceof IParameterizedSymbol) && isValidFunctionOverload( (IParameterizedSymbol)symbol, (IParameterizedSymbol)newSymbol );
|
||||
}
|
||||
|
|
|
@ -667,8 +667,8 @@ public final class TemplateEngine {
|
|||
if( template.getContainedSymbols() == null || template.getContainedSymbols().size() != 1 ){
|
||||
return null;
|
||||
}
|
||||
Iterator iter = template.getContainedSymbols().keySet().iterator();
|
||||
ISymbol templateSymbol = (ISymbol) template.getContainedSymbols().get( iter.next() );
|
||||
|
||||
ISymbol templateSymbol = (ISymbol) template.getTemplatedSymbol();
|
||||
if( !templateSymbol.isType( TypeInfo.t_function ) ){
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -106,15 +106,19 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
ListIterator tIter = templates.listIterator();
|
||||
|
||||
ISymbol sym = null;
|
||||
ISymbol container = null;
|
||||
boolean templateParamState = false;
|
||||
while( iter.hasNext() ){
|
||||
sym = (ISymbol) iter.next();
|
||||
if( !sym.getContainingSymbol().isType( TypeInfo.t_template ) ){
|
||||
iter.remove();
|
||||
} else if( tIter.hasNext() ) {
|
||||
// ITemplateSymbol template = (ITemplateSymbol) tIter.next();
|
||||
// List args = (List) argMap.get( sym );
|
||||
// template = TemplateEngine.selectTemplateOrSpecialization( (ITemplateSymbol) sym.getContainingSymbol(), template.getParameterList(), args );
|
||||
// tIter.set( template );
|
||||
ITemplateSymbol template = (ITemplateSymbol) tIter.next();
|
||||
if( template.getParameterList().size() == 0 ){
|
||||
templateParamState = true;
|
||||
container = sym;
|
||||
} else if( templateParamState )
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTemplate );
|
||||
}
|
||||
|
@ -123,6 +127,13 @@ public class TemplateFactory extends ExtensibleSymbol implements ITemplateFactor
|
|||
int numTemplates = templates.size();
|
||||
int numSymbols = symbols.size();
|
||||
|
||||
if( templateParamState ){
|
||||
ITemplateSymbol template = (ITemplateSymbol) container.getContainingSymbol();
|
||||
List args = (List) argMap.get( container );
|
||||
addExplicitSpecialization( (ITemplateSymbol) container.getContainingSymbol(), symbol, args );
|
||||
return;
|
||||
}
|
||||
|
||||
if( numTemplates == numSymbols + 1 ){
|
||||
//basic template declaration or Definition
|
||||
basicTemplateDeclaration( symbol );
|
||||
|
|
Loading…
Add table
Reference in a new issue