1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Patch for Andrew Niefer.

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
This commit is contained in:
John Camelon 2004-01-09 16:59:30 +00:00
parent 7d3eaf190b
commit 51fc347c92
10 changed files with 2443 additions and 2274 deletions

File diff suppressed because it is too large Load diff

View file

@ -1116,6 +1116,51 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
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(); }; " );

View file

@ -3355,5 +3355,83 @@ public class ParserSymbolTableTest extends TestCase {
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 );
}
}

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,7 @@ public class ASTFunction extends ASTScope implements IASTFunction
* @param ownerTemplate
* @param references
*/
public ASTFunction(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared, boolean hasFunctionTryBlock, boolean hasVarArgs)
public ASTFunction(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared, boolean hasFunctionTryBlock )
{
super( symbol );
this.parameters = parameters;
@ -70,7 +70,6 @@ public class ASTFunction extends ASTScope implements IASTFunction
qualifiedName = new ASTQualifiedNamedElement( getOwnerScope(), symbol.getName() );
this.previouslyDeclared =previouslyDeclared;
this.hasFunctionTryBlock = hasFunctionTryBlock;
this.varArgs = hasVarArgs;
}
@ -306,7 +305,7 @@ public class ASTFunction extends ASTScope implements IASTFunction
private boolean hasFunctionTryBlock = false;
private final boolean varArgs;
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#setHasFunctionTryBlock(boolean)
*/
@ -337,6 +336,6 @@ public class ASTFunction extends ASTScope implements IASTFunction
* @see org.eclipse.cdt.core.parser.ast.IASTFunction#takesVarArgs()
*/
public boolean takesVarArgs() {
return varArgs;
return ((IParameterizedSymbol)getSymbol()).hasVariableArgs();
}
}

View file

@ -46,7 +46,7 @@ public class ASTMethod extends ASTFunction implements IASTMethod
* @param references
*/
public ASTMethod(IParameterizedSymbol symbol, int nameEndOffset, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, int startOffset, int nameOffset, IASTTemplate ownerTemplate, List references, boolean previouslyDeclared,
boolean isConstructor, boolean isDestructor, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean hasFunctionTryBlock, boolean hasVariableArguments )
boolean isConstructor, boolean isDestructor, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean hasFunctionTryBlock )
{
super(
symbol,
@ -57,7 +57,7 @@ public class ASTMethod extends ASTFunction implements IASTMethod
startOffset,
nameOffset,
ownerTemplate,
references, previouslyDeclared, hasFunctionTryBlock, hasVariableArguments );
references, previouslyDeclared, hasFunctionTryBlock );
this.visibility = visibility;
this.isConstructor = isConstructor;
this.isDestructor = isDestructor;

View file

@ -1654,6 +1654,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
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() );
@ -1690,7 +1692,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{
throw new ASTSemanticException();
}
ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, hasFunctionTryBlock, hasVariableArguments );
ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, hasFunctionTryBlock );
try
{
attachSymbolExtension(symbol, function);
@ -1935,6 +1937,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
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();
@ -2027,7 +2031,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
resolveLeftoverConstructorInitializerMembers( symbol, constructorChain );
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, hasVariableArguments );
ASTMethod method = new ASTMethod( symbol, nameEndOffset, parameters, returnType, exception, startOffset, nameOffset, ownerTemplate, references, previouslyDeclared, isConstructor, isDestructor, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock );
try
{
attachSymbolExtension( symbol, method );

View file

@ -45,6 +45,9 @@ public interface IParameterizedSymbol extends IContainerSymbol {
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();

View file

@ -240,6 +240,13 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
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 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz
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
}

View file

@ -850,10 +850,10 @@ public class ParserSymbolTable {
}
}
}
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 @@ public class ParserSymbolTable {
Iterator targetParams = null;
int numTargetParams = 0;
int numParams = 0;
int comparison;
Cost cost = null;
Cost temp = null;
@ -880,6 +879,16 @@ public class ParserSymbolTable {
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 @@ public class ParserSymbolTable {
}
}
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 @@ public class ParserSymbolTable {
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 @@ public class ParserSymbolTable {
//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 @@ public class ParserSymbolTable {
//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 class ParserSymbolTable {
{
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;