[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Bug43110 - Parser support needed for functions with ellipses
|
This patch modifies the symbol table (and a little bit in the parser) to
address bug 43110, handling of functions with ellipses (var args)
Core:
Added IParameterizedSymbol.setHasVariableArgs() &
hasVariableArgs()
Modified ParserSymbolTable.resolveFunction & reduceToViable
Modified CompleteParseASTFactory.createMethod & createFunction
Tests:
Added CompleteParseASTTest.testBug43110_XRef
Added ParserSymbolTableTest.testBug43110_Ellipses
Added ParserSymbolTableTest.testBug43110_EllipsesRanking
Added ParserSymbolTableTest.testBug43110_EllipsesRanking_2
Tested on windows
-Andrew
Index: parser/ChangeLog-parser
===================================================================
retrieving revision 1.15
diff -u -r1.15 ChangeLog-parser
--- parser/ChangeLog-parser 8 Jan 2004 16:57:48 -0000 1.15
+++ parser/ChangeLog-parser 8 Jan 2004 22:56:00 -0000
@@ -1,4 +1,10 @@
2004-01-08 Andrew Niefer
+ fixing bug 43110 - Parser support needed for functions with ellipses
+ Added IParameterizedSymbol.setHasVariableArgs() & hasVariableArgs()
+ Modified ParserSymbolTable.resolveFunction & reduceToViable
+ Modified CompleteParseASTFactory.createMethod & createFunction
+
+2004-01-08 Andrew Niefer
Fixing 48307 - PST: Friendship needs to be handled better
Added IDerivableContainerSymbol.lookupFunctionForFriendship.
Modified IASTFactory.createMethod to take an ITokenDuple for the method name.
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java
===================================================================
retrieving revision 1.63
diff -u -r1.63 CompleteParseASTFactory.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 8 Jan 2004 16:57:48 -0000 1.63
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 8 Jan 2004 22:56:05 -0000
@@ -1654,6 +1654,8 @@
IParameterizedSymbol symbol = pst.newParameterizedSymbol( name.getLastToken().getImage(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
+ symbol.setHasVariableArgs( hasVariableArguments );
+
setParameter( symbol, returnType, false, references );
setParameters( symbol, references, parameters.iterator() );
@@ -1935,6 +1937,8 @@
IParameterizedSymbol symbol = pst.newParameterizedSymbol( nameDuple.toString(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
setMethodTypeInfoBits( symbol, isConst, isVolatile, isVirtual, isExplicit );
+ symbol.setHasVariableArgs( hasVariableArguments );
+
if(references == null)
references = new ArrayList();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java
===================================================================
retrieving revision 1.5
diff -u -r1.5 IParameterizedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java 20 Nov 2003 15:22:56 -0000 1.5
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java 8 Jan 2004 22:56:07 -0000
@@ -45,6 +45,9 @@
public void setReturnType( ISymbol type );
public ISymbol getReturnType();
+ public void setHasVariableArgs( boolean var );
+ public boolean hasVariableArgs( );
+
public boolean hasSpecializations();
public void addSpecialization( IParameterizedSymbol spec );
public List getSpecializations();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java
===================================================================
retrieving revision 1.1
diff -u -r1.1 ParameterizedSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java 20 Nov 2003 15:22:56 -0000 1.1
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java 8 Jan 2004 22:56:07 -0000
@@ -240,6 +240,13 @@
return _specializations;
}
+ public void setHasVariableArgs( boolean var ){
+ _hasVarArgs = var;
+ }
+
+ public boolean hasVariableArgs( ){
+ return _hasVarArgs;
+ }
static private class AddParameterCommand extends Command{
public AddParameterCommand( IParameterizedSymbol container, ISymbol parameter ){
@@ -279,4 +286,5 @@
private LinkedList _specializations; //template specializations
private LinkedList _argumentList; //template specialization arguments
private ISymbol _returnType;
+ private boolean _hasVarArgs = false; //whether or not this function has variable arguments
}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
===================================================================
retrieving revision 1.32
diff -u -r1.32 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 7 Jan 2004 02:00:17 -0000 1.32
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java 8 Jan 2004 22:56:08 -0000
@@ -850,10 +850,10 @@
}
}
}
- throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
- }else{
- throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
}
+
+ if( data.parameters == null )
+ throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
}
IParameterizedSymbol bestFn = null; //the best function
@@ -866,7 +866,6 @@
Iterator targetParams = null;
int numTargetParams = 0;
- int numParams = 0;
int comparison;
Cost cost = null;
Cost temp = null;
@@ -880,6 +879,16 @@
boolean currHasAmbiguousParam = false;
boolean bestHasAmbiguousParam = false;
+ List parameters = null;
+
+ if( numSourceParams == 0 ){
+ parameters = new LinkedList();
+ parameters.add( new TypeInfo( TypeInfo.t_void, 0, null ) );
+ numSourceParams = 1;
+ } else {
+ parameters = data.parameters;
+ }
+
for( int i = numFns; i > 0; i-- ){
currFn = (IParameterizedSymbol) iterFns.next();
@@ -892,15 +901,14 @@
}
}
- sourceParams = data.parameters.iterator();
+ sourceParams = parameters.iterator();
List parameterList = null;
- if( currFn.getParameterList().isEmpty() ){
+ if( currFn.getParameterList().isEmpty() && !currFn.hasVariableArgs() ){
//the only way we get here and have no parameters, is if we are looking
//for a function that takes void parameters ie f( void )
parameterList = new LinkedList();
parameterList.add( currFn.getSymbolTable().newSymbol( "", TypeInfo.t_void ) );
- targetParams = parameterList.iterator();
} else {
parameterList = currFn.getParameterList();
}
@@ -908,24 +916,33 @@
targetParams = parameterList.iterator();
numTargetParams = parameterList.size();
- //we only need to look at the smaller number of parameters
- //(a larger number in the Target means default parameters, a larger
- //number in the source means ellipses.)
- numParams = ( numTargetParams < numSourceParams ) ? numTargetParams : numSourceParams;
-
if( currFnCost == null ){
- currFnCost = new Cost [ numParams ];
+ currFnCost = new Cost [ numSourceParams ];
}
comparison = 0;
+ boolean varArgs = false;
- for( int j = 0; j < numParams; j++ ){
+ for( int j = 0; j < numSourceParams; j++ ){
source = (TypeInfo) sourceParams.next();
- target = ((ISymbol)targetParams.next()).getTypeInfo();
- if( source.equals( target ) ){
+
+ if( targetParams.hasNext() )
+ target = ((ISymbol)targetParams.next()).getTypeInfo();
+ else
+ varArgs = true;
+
+ if( varArgs ){
+ cost = new Cost( source, null );
+ cost.rank = Cost.ELLIPSIS_CONVERSION;
+ } else if ( target.getHasDefault() && source.isType( TypeInfo.t_void ) && !source.hasPtrOperators() ){
+ //source is just void, ie no parameter, if target had a default, then use that
+ cost = new Cost( source, target );
+ cost.rank = Cost.IDENTITY_RANK;
+ } else if( source.equals( target ) ){
cost = new Cost( source, target );
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
} else {
+
cost = checkStandardConversionSequence( source, target );
//12.3-4 At most one user-defined conversion is implicitly applied to
@@ -947,7 +964,7 @@
//In order for this function to be better than the previous best, it must
//have at least one parameter match that is better that the corresponding
//match for the other function, and none that are worse.
- for( int j = 0; j < numParams; j++ ){
+ for( int j = 0; j < numSourceParams; j++ ){
if( currFnCost[ j ].rank < 0 ){
hasWorse = true;
hasBetter = false;
@@ -1021,10 +1038,13 @@
//A candidate function having fewer than m parameters is viable only if it has an
//ellipsis in its parameter list.
- if( num < numParameters ) {
- //TODO ellipsis
- //not enough parameters, remove it
- iter.remove();
+ if( num < numParameters ){
+ if( function.hasVariableArgs() ) {
+ continue;
+ } else {
+ //not enough parameters, remove it
+ iter.remove();
+ }
}
//a candidate function having more than m parameters is viable only if the (m+1)-st
//parameter has a default argument
@@ -2287,8 +2307,8 @@
{
public Cost( TypeInfo s, TypeInfo t ){
- source = new TypeInfo( s );
- target = new TypeInfo( t );
+ source = ( s != null ) ? new TypeInfo( s ) : new TypeInfo();
+ target = ( t != null ) ? new TypeInfo( t ) : new TypeInfo();
}
public TypeInfo source;
Index: ChangeLog
===================================================================
retrieving revision 1.162
diff -u -r1.162 ChangeLog
--- ChangeLog 8 Jan 2004 16:57:54 -0000 1.162
+++ ChangeLog 8 Jan 2004 22:58:20 -0000
@@ -1,4 +1,10 @@
2004-01-08 Andrew Niefer
+ Added CompleteParseASTTest.testBug43110_XRef
+ Added ParserSymbolTableTest.testBug43110_Ellipses
+ Added ParserSymbolTableTest.testBug43110_EllipsesRanking
+ Added ParserSymbolTableTest.testBug43110_EllipsesRanking_2
+
+2004-01-08 Andrew Niefer
Added CompleteParseASTTest::testBug48307_FriendFunction_1
Added CompleteParseASTTest::testBug48307_FriendFunction_2
Index: parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java
===================================================================
retrieving revision 1.46
diff -u -r1.46 CompleteParseASTTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 8 Jan 2004 16:57:54 -0000 1.46
+++ parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 8 Jan 2004 22:58:23 -0000
@@ -1116,6 +1116,51 @@
assertTrue( ((IASTFunction)i.next()).takesVarArgs() );
}
+ public void testBug43110_XRef() throws Exception
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append( "void foo( ... ) {}\n" );
+ buffer.append( "void main( ){ foo( 1 ); }\n" );
+
+ Iterator i = parse( buffer.toString() ).getDeclarations();
+ IASTFunction foo = (IASTFunction)i.next();
+ assertTrue( foo.takesVarArgs() );
+ assertAllReferences( 1, createTaskList( new Task( foo ) ) );
+
+ buffer = new StringBuffer();
+ buffer.append( "void foo( ... ) {}\n" );
+ buffer.append( "void foo( int x ) {}\n" );
+ buffer.append( "void main( ){ foo( 1 ); }\n" );
+
+ i = parse( buffer.toString() ).getDeclarations();
+ IASTFunction foo1 = (IASTFunction)i.next();
+ IASTFunction foo2 = (IASTFunction)i.next();
+ assertTrue( foo1.takesVarArgs() );
+ assertFalse( foo2.takesVarArgs() );
+ assertAllReferences( 1, createTaskList( new Task( foo2 ) ) );
+
+ buffer = new StringBuffer();
+ buffer.append( "void foo( ... ) {}\n" );
+ buffer.append( "void foo( int x = 1) {}\n" );
+ buffer.append( "void main( ){ foo(); }\n" );
+
+ i = parse( buffer.toString() ).getDeclarations();
+ foo1 = (IASTFunction)i.next();
+ foo2 = (IASTFunction)i.next();
+ assertTrue( foo1.takesVarArgs() );
+ assertFalse( foo2.takesVarArgs() );
+ assertAllReferences( 1, createTaskList( new Task( foo2 ) ) );
+
+ buffer = new StringBuffer();
+ buffer.append( "void foo( int x ... ) {}\n" );
+ buffer.append( "void main( ){ foo( 1, 2, 'a' ); }\n" );
+
+ i = parse( buffer.toString() ).getDeclarations();
+ foo = (IASTFunction)i.next();
+ assertTrue( foo.takesVarArgs() );
+ assertAllReferences( 1, createTaskList( new Task( foo ) ) );
+ }
+
public void testBug48307_FriendFunction_1() throws Exception {
StringWriter writer = new StringWriter();
writer.write( "class A{ public : void foo(); }; " );
Index: parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java
===================================================================
retrieving revision 1.28
diff -u -r1.28 ParserSymbolTableTest.java
--- parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 17 Dec 2003 20:51:30 -0000 1.28
+++ parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java 8 Jan 2004 22:58:26 -0000
@@ -3355,5 +3355,83 @@
assertTrue( results.contains( a3_int ) );
};
+ /**
+ * void foo( ... ){ }
+ *
+ * foo( 1 );
+ *
+ * @throws Exception
+ */
+ public void testBug43110_Ellipses() throws Exception{
+ newTable();
+
+ IParameterizedSymbol foo = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+ foo.setHasVariableArgs( true );
+
+ table.getCompilationUnit().addSymbol( foo );
+
+ List params = new LinkedList();
+
+ TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
+ params.add( p1 );
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
+
+ assertEquals( foo, look );
+ }
+
+ /**
+ * void foo( ... ) {}; //#1
+ * void foo( int i ) {}; //#2
+ *
+ * foo( 1 ); // calls foo #2
+ * @throws Exception
+ */
+ public void testBug43110_EllipsesRanking() throws Exception{
+ newTable();
+
+ IParameterizedSymbol foo1 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+ foo1.setHasVariableArgs( true );
+
+ table.getCompilationUnit().addSymbol( foo1 );
+
+ IParameterizedSymbol foo2 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+ foo2.addParameter( TypeInfo.t_int, 0, null, false );
+ table.getCompilationUnit().addSymbol( foo2 );
+
+ List params = new LinkedList();
+
+ TypeInfo p1 = new TypeInfo( TypeInfo.t_int, 0, null );
+ params.add( p1 );
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
+
+ assertEquals( foo2, look );
+ }
+
+ /**
+ * void foo( int i = 0 ) {}; //#1
+ * void foo( ... ) {}; //#2
+ *
+ * foo(); //calls #1
+ * @throws Exception
+ */
+ public void testBug43110_ElipsesRanking_2() throws Exception{
+ newTable();
+
+ IParameterizedSymbol foo1 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+ foo1.addParameter( TypeInfo.t_int, 0, null, true );
+ table.getCompilationUnit().addSymbol( foo1 );
+
+ IParameterizedSymbol foo2 = table.newParameterizedSymbol( "foo", TypeInfo.t_function );
+ foo2.setHasVariableArgs( true );
+ table.getCompilationUnit().addSymbol( foo2 );
+
+ List params = new LinkedList();
+
+ ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "foo", params );
+
+ assertEquals( foo1, look );
+ }
}