From b416d5f3b91a9ba8919dec6f5cd139d424a6ad19 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Fri, 13 Feb 2004 15:40:08 +0000 Subject: [PATCH] Patch for Andrew Niefer. This patch fixes the way the symbol table handles const & volatile. It also fixes the following bugs: 47628 - signed char is parsed as char 47636 - char * and char[] are treated as different types 45697 - Parser/Symbol Table: Mismatched declarations & definition --- core/org.eclipse.cdt.core.tests/ChangeLog | 10 ++ .../parser/tests/CompleteParseASTTest.java | 105 ++++++++++---- .../tests/ParserSymbolTableTemplateTests.java | 39 +++--- .../parser/tests/ParserSymbolTableTest.java | 132 ++++++++++++++---- .../parser/ChangeLog-parser | 6 + .../ast/complete/ASTSimpleTypeSpecifier.java | 2 +- .../ast/complete/CompleteParseASTFactory.java | 66 +++++---- .../core/parser/pst/ContainerSymbol.java | 1 + .../parser/pst/DerivableContainerSymbol.java | 11 +- .../core/parser/pst/IParameterizedSymbol.java | 2 +- .../core/parser/pst/ParameterizedSymbol.java | 54 ++++++- .../core/parser/pst/ParserSymbolTable.java | 88 ++++++------ .../core/parser/pst/TemplateEngine.java | 108 +++++++------- .../internal/core/parser/pst/TypeInfo.java | 17 --- 14 files changed, 414 insertions(+), 227 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 1eefdfd0ed4..f7b51f2b7e8 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,13 @@ +2004-02-12 Andrew Niefer + UnCommented CompleteParseASTTest.testBug47628 + Added CompleteParseASTTest.testBug47636 + Added CompleteParseASTTest.testBug45697 + Updated ParserSymbolTableTests & ParserSymbolTableTemplateTests for proper use of const & volatile + Added ParserSymbolTableTests.testbug47636FunctionParameterComparisons_1 + Added ParserSymbolTableTests.testbug47636FunctionParameterComparisons_2 + Added ParserSymbolTableTests.testbug47636FunctionParameterComparisons_3 + Added ParserSymbolTableTests.testbug47636FunctionParameterComparisons_4 + 2004-02-11 John Camelon Updated tests to accommodate for new Parser class hierarchy and factories. diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index 05404a9d21b..a8caf327867 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -1203,35 +1203,82 @@ public class CompleteParseASTTest extends CompleteParseBaseTest assertAllReferences( 1, createTaskList( new Task( x ))); } -// public void testBug47628() throws Exception -// { -// Writer writer = new StringWriter(); -// writer.write( "void h(char) { }\n"); -// writer.write( "void h(unsigned char) { }\n"); -// writer.write( "void h(signed char) { } // not shown in outline, parsed as char\n"); -// Iterator i = parse( writer.toString() ).getDeclarations(); -// IASTFunction h1 = (IASTFunction) i.next(); -// assertEquals( h1.getName(), "h"); -// Iterator parms = h1.getParameters(); -// IASTParameterDeclaration parm = (IASTParameterDeclaration) parms.next(); -// assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); -// assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "char" ); -// IASTFunction h2 = (IASTFunction) i.next(); -// assertEquals( h2.getName(), "h"); -// parms = h2.getParameters(); -// parm = (IASTParameterDeclaration) parms.next(); -// assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); -// assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "unsigned char" ); -// -// IASTFunction h3 = (IASTFunction) i.next(); -// assertEquals( h3.getName(), "h"); -// parms = h3.getParameters(); -// parm = (IASTParameterDeclaration) parms.next(); -// assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); -// assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "signed char" ); -// -// assertFalse( i.hasNext() ); -// } + public void testBug47628() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void h(char) { }\n"); + writer.write( "void h(unsigned char) { }\n"); + writer.write( "void h(signed char) { } // not shown in outline, parsed as char\n"); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTFunction h1 = (IASTFunction) i.next(); + assertEquals( h1.getName(), "h"); + Iterator parms = h1.getParameters(); + IASTParameterDeclaration parm = (IASTParameterDeclaration) parms.next(); + assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); + assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "char" ); + + IASTFunction h2 = (IASTFunction) i.next(); + assertEquals( h2.getName(), "h"); + parms = h2.getParameters(); + parm = (IASTParameterDeclaration) parms.next(); + assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); + assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "unsigned char" ); + + IASTFunction h3 = (IASTFunction) i.next(); + assertEquals( h3.getName(), "h"); + parms = h3.getParameters(); + parm = (IASTParameterDeclaration) parms.next(); + assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); + assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "signed char" ); + + assertFalse( i.hasNext() ); + } + public void testBug47636() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void f( char [] ); \n" ); + writer.write( "void f( char * ){} \n" ); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTFunction fDec = (IASTFunction) i.next(); + assertEquals( fDec.getName(), "f"); + + + IASTFunction fDef = (IASTFunction) i.next(); + assertEquals( fDef.getName(), "f"); + + assertTrue( fDef.previouslyDeclared() ); + + assertFalse( i.hasNext() ); + } + + public void testBug45697() throws Exception + { + Writer writer = new StringWriter(); + writer.write( " int f( bool ); \n"); + writer.write( " int f( char ){ } "); + + Iterator i = parse( writer.toString() ).getDeclarations(); + + IASTFunction f1 = (IASTFunction) i.next(); + assertEquals( f1.getName(), "f"); + Iterator parms = f1.getParameters(); + IASTParameterDeclaration parm = (IASTParameterDeclaration) parms.next(); + assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); + assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "bool" ); + + IASTFunction f2 = (IASTFunction) i.next(); + assertEquals( f2.getName(), "f"); + parms = f2.getParameters(); + parm = (IASTParameterDeclaration) parms.next(); + assertTrue( parm.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ); + assertEquals( ((IASTSimpleTypeSpecifier)parm.getTypeSpecifier()).getTypename(), "char" ); + assertFalse( f2.previouslyDeclared() ); + assertFalse( i.hasNext() ); + } } 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 ad609b6a205..2d3a2f2fd6f 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 @@ -275,7 +275,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { table.getCompilationUnit().addSymbol( f1 ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f2.addParameter( lookA, null, false ); + f2.addParameter( lookA, 0, null, false ); table.getCompilationUnit().addSymbol( f2 ); IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); @@ -1060,7 +1060,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { IParameterizedSymbol compare = table.newParameterizedSymbol( "compare", TypeInfo.t_function ); compare.setIsForwardDeclaration( true ); - compare.addParameter( T2, new PtrOp( PtrOp.t_reference, true, false ), false ); + compare.addParameter( T2, 0, new PtrOp( PtrOp.t_reference, true, false ), false ); compare.setReturnType( T2 ); template2.addSymbol( compare ); @@ -1083,7 +1083,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { IParameterizedSymbol compareDef = table.newParameterizedSymbol( "compare", TypeInfo.t_function ); ISymbol look = factory.lookupParam( "V" ); assertEquals( look, V ); - compareDef.addParameter( look, new PtrOp( PtrOp.t_reference, true, false ), false ); + compareDef.addParameter( look, 0, new PtrOp( PtrOp.t_reference, true, false ), false ); compareDef.setReturnType( look ); compare.setTypeSymbol( compareDef ); factory.addSymbol( compareDef ); @@ -1142,7 +1142,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { memberTemplate.addTemplateParameter( C ); IParameterizedSymbol g = table.newParameterizedSymbol( "g", TypeInfo.t_function ); - g.addParameter( C, null, false ); + g.addParameter( C, 0, null, false ); g.getTypeInfo().setBit( true, TypeInfo.isVirtual ); memberTemplate.addSymbol( g ); @@ -1400,7 +1400,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); ISymbol T = template1.lookup( "T" ); IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f1.addParameter( T, null, false ); + f1.addParameter( T, 0, null, false ); template1.addSymbol( f1 ); table.getCompilationUnit().addSymbol( template1 ); @@ -1408,7 +1408,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template2.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); T = template2.lookup( "T" ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f2.addParameter( T, new PtrOp( PtrOp.t_pointer ), false ); + f2.addParameter( T, 0, new PtrOp( PtrOp.t_pointer ), false ); template2.addSymbol( f2 ); table.getCompilationUnit().addSymbol( template2 ); @@ -1417,12 +1417,13 @@ public class ParserSymbolTableTemplateTests extends TestCase { template3.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); T = template3.lookup( "T" ); IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f3.addParameter( T, new PtrOp( PtrOp.t_pointer, true, false ), false ); + f3.addParameter( T, TypeInfo.isConst, new PtrOp( PtrOp.t_pointer, false, false ), false ); template3.addSymbol( f3 ); table.getCompilationUnit().addSymbol( template3 ); ISymbol p = table.newSymbol( "p", TypeInfo.t_int ); - p.addPtrOperator( new PtrOp( PtrOp.t_pointer, true, false ) ); + p.getTypeInfo().setBit( true, TypeInfo.isConst ); + p.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); table.getCompilationUnit().addSymbol( p ); List params = new LinkedList(); @@ -1449,7 +1450,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); ISymbol T = template1.lookup( "T" ); IParameterizedSymbol g1 = table.newParameterizedSymbol( "g", TypeInfo.t_function ); - g1.addParameter( T, null, false ); + g1.addParameter( T, 0, null, false ); template1.addSymbol( g1 ); table.getCompilationUnit().addSymbol( template1 ); @@ -1457,7 +1458,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template2.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); T = template2.lookup( "T" ); IParameterizedSymbol g2 = table.newParameterizedSymbol( "g", TypeInfo.t_function ); - g2.addParameter( T, new PtrOp( PtrOp.t_reference ), false ); + g2.addParameter( T, 0, new PtrOp( PtrOp.t_reference ), false ); template2.addSymbol( g2 ); table.getCompilationUnit().addSymbol( template2 ); @@ -1465,7 +1466,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { List params = new LinkedList(); params.add( new TypeInfo( TypeInfo.t_type, 0, x ) ); try{ - ISymbol look = table.getCompilationUnit().unqualifiedFunctionLookup( "g", params ); + table.getCompilationUnit().unqualifiedFunctionLookup( "g", params ); assertTrue( false ); } catch( ParserSymbolTableException e ){ assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); @@ -1500,7 +1501,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template1.addTemplateParameter( table.newSymbol( "T", TypeInfo.t_templateParameter ) ); ISymbol T = template1.lookup( "T" ); IParameterizedSymbol h1 = table.newParameterizedSymbol( "h", TypeInfo.t_function ); - h1.addParameter( T, new PtrOp( PtrOp.t_reference, true, false ), false ); + h1.addParameter( T, TypeInfo.isConst, new PtrOp( PtrOp.t_reference, false, false ),false ); template1.addSymbol( h1 ); table.getCompilationUnit().addSymbol( template1 ); @@ -1511,7 +1512,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { IParameterizedSymbol h2 = table.newParameterizedSymbol( "h", TypeInfo.t_function ); List argList = new LinkedList(); argList.add( new TypeInfo( TypeInfo.t_type, 0, T ) ); - h2.addParameter( templateA.instantiate( argList ), new PtrOp( PtrOp.t_reference ), false ); + h2.addParameter( templateA.instantiate( argList ), 0, new PtrOp( PtrOp.t_reference ), false ); template2.addSymbol( h2 ); table.getCompilationUnit().addSymbol( template2 ); @@ -1535,7 +1536,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { assertTrue( look.isTemplateInstance() ); assertEquals( look.getInstantiatedSymbol(), A ); z2.setTypeSymbol( look ); - z2.addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) ); + z2.getTypeInfo().setBit( true, TypeInfo.isConst ); params.clear(); params.add( new TypeInfo( TypeInfo.t_type, 0, z2 ) ); @@ -1789,12 +1790,12 @@ public class ParserSymbolTableTemplateTests extends TestCase { ISymbol U = template.lookup( "U" ); paramFunction.setReturnType( T ); - paramFunction.addParameter( T, null, false ); - paramFunction.addParameter( U, null, false ); - paramFunction.addParameter( U, null, false ); + paramFunction.addParameter( T, 0, null, false ); + paramFunction.addParameter( U, 0, null, false ); + paramFunction.addParameter( U, 0, null, false ); IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f.addParameter( paramFunction, null, false ); + f.addParameter( paramFunction, 0, null, false ); template.addSymbol( f ); @@ -1857,7 +1858,7 @@ public class ParserSymbolTableTemplateTests extends TestCase { template.addTemplateParameter( T ); IParameterizedSymbol f = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f.addParameter( T, new PtrOp( PtrOp.t_pointer, true, false ), false ); + f.addParameter( T, 0, new PtrOp( PtrOp.t_pointer, true, false ), false ); template.addSymbol( f ); table.getCompilationUnit().addSymbol( template ); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java index 57903d84526..eadd3617de3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -1188,10 +1188,9 @@ public class ParserSymbolTableTest extends TestCase { IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class", TypeInfo.t_class ); - IParameterizedSymbol fn = table.newParameterizedSymbol("function"); + IParameterizedSymbol fn = table.newParameterizedSymbol("function", TypeInfo.t_function ); fn.setType( TypeInfo.t_function ); - fn.getTypeInfo().addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) ); - //fn.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst ); + fn.getTypeInfo().setBit( true, TypeInfo.isConst ); table.getCompilationUnit().addSymbol( cls ); cls.addSymbol( fn ); @@ -1201,8 +1200,9 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( look.getType(), TypeInfo.t_type ); assertEquals( look.getTypeSymbol(), cls ); + assertTrue( look.getTypeInfo().checkBit( TypeInfo.isConst ) ); assertEquals( ((PtrOp)look.getPtrOperators().iterator().next()).getType(), TypeInfo.PtrOp.t_pointer ); - assertTrue( ((PtrOp)look.getPtrOperators().iterator().next()).isConst() ); + assertEquals( look.getContainingSymbol(), fn ); } @@ -1270,7 +1270,7 @@ public class ParserSymbolTableTest extends TestCase { ISymbol look = NS.lookup( "T" ); assertEquals( look, T ); - f.addParameter( look, null, false ); + f.addParameter( look, 0, null, false ); NS.addSymbol( f ); @@ -1433,7 +1433,7 @@ public class ParserSymbolTableTest extends TestCase { f3.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); f3.addParameter( TypeInfo.t_int, 0, null, false ); f3.addParameter( TypeInfo.t_char, 0, null, false ); - f3.addParameter( C, new PtrOp( PtrOp.t_pointer ), false ); + f3.addParameter( C, 0, new PtrOp( PtrOp.t_pointer ), false ); C.addSymbol( f3 ); ISymbol look = compUnit.lookup("C"); @@ -1556,12 +1556,12 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); f1.setType( TypeInfo.t_function ); - f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false ); + f1.addParameter( A, 0, new PtrOp( PtrOp.t_pointer ), false ); compUnit.addSymbol( f1 ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); f2.setType( TypeInfo.t_function ); - f2.addParameter( B, new PtrOp( PtrOp.t_pointer ), false ); + f2.addParameter( B, 0, new PtrOp( PtrOp.t_pointer ), false ); compUnit.addSymbol( f2 ); ISymbol a = table.newSymbol( "a" ); @@ -1625,12 +1625,12 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); f1.setType( TypeInfo.t_function ); - f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false ); + f1.addParameter( A, 0, new PtrOp( PtrOp.t_pointer ), false ); compUnit.addSymbol( f1 ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); f2.setType( TypeInfo.t_function ); - f2.addParameter( A, null, false ); + f2.addParameter( A, 0, null, false ); compUnit.addSymbol( f2 ); ISymbol a = table.newSymbol( "a" ); @@ -1706,12 +1706,12 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol constructor = table.newParameterizedSymbol("B"); constructor.setType( TypeInfo.t_constructor ); - constructor.addParameter( A, null, false ); + constructor.addParameter( A, 0, null, false ); B.addConstructor( constructor ); IParameterizedSymbol f = table.newParameterizedSymbol( "f" ); f.setType( TypeInfo.t_function ); - f.addParameter( B, null, false ); + f.addParameter( B, 0, null, false ); compUnit.addSymbol( f ); ISymbol a = table.newSymbol( "a" ); @@ -1744,7 +1744,7 @@ public class ParserSymbolTableTest extends TestCase { * //and 1L->short and 1L->int are indistinguishable * f( &i, 'c' ); //calls f( int*, int) because &i->int * is better than &i->const int * * //and c->int is better than c->short - * f( (const)&i, 1L ); //calls f(const int *, short ) because const &i->int* is better than &i->int * + * f( (const int *)&i, 1L ); //calls f(const int *, short ) because const &i->int* is better than &i->int * * //and 1L->short and 1L->int are indistinguishable * } */ @@ -1755,7 +1755,7 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); f1.setType( TypeInfo.t_function ); - f1.addParameter( TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer, true, false ), false ); + f1.addParameter( TypeInfo.t_int, TypeInfo.isConst, new PtrOp( PtrOp.t_pointer, false, false ), false ); f1.addParameter( TypeInfo.t_int, TypeInfo.isShort, null, false ); compUnit.addSymbol( f1 ); @@ -1810,13 +1810,12 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( look, f2 ); params.clear(); - p1.addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) ); - //((PtrOp)p1.getPtrOperators().iterator().next()).setConst( true ); + p1 = new TypeInfo( TypeInfo.t_int, TypeInfo.isConst, null, new PtrOp( PtrOp.t_pointer, false, false ), false ); + params.add( p1 ); params.add( p3 ); look = main.unqualifiedFunctionLookup( "f", params ); assertEquals( look, f1 ); - } /** @@ -1859,7 +1858,7 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol constructA = table.newParameterizedSymbol( "A" ); constructA.setType( TypeInfo.t_constructor ); - constructA.addParameter( B, new PtrOp( PtrOp.t_reference ), false ); + constructA.addParameter( B, 0, new PtrOp( PtrOp.t_reference ), false ); A.addConstructor( constructA ); IParameterizedSymbol operator = table.newParameterizedSymbol( "operator A" ); @@ -1868,7 +1867,7 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); f1.setType( TypeInfo.t_function ); - f1.addParameter( A, null, false ); + f1.addParameter( A, 0, null, false ); compUnit.addSymbol( f1 ); ISymbol b = table.newSymbol( "b" ); @@ -1894,12 +1893,12 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol constructC = table.newParameterizedSymbol("C"); constructC.setType( TypeInfo.t_constructor ); - constructC.addParameter( B, new PtrOp( PtrOp.t_reference ), false ); + constructC.addParameter( B, 0, new PtrOp( PtrOp.t_reference ), false ); C.addConstructor( constructC ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); f2.setType( TypeInfo.t_function ); - f2.addParameter( C, null, false ); + f2.addParameter( C, 0, null, false ); compUnit.addSymbol( f2 ); try{ @@ -1911,7 +1910,7 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol f3 = table.newParameterizedSymbol( "f" ); f3.setType( TypeInfo.t_function ); - f3.addParameter( B, null, false ); + f3.addParameter( B, 0, null, false ); compUnit.addSymbol( f3 ); look = compUnit.unqualifiedFunctionLookup( "f", params ); @@ -2056,7 +2055,7 @@ public class ParserSymbolTableTest extends TestCase { IParameterizedSymbol fn1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); ISymbol lookup = table.getCompilationUnit().lookup( "A" ); assertEquals( lookup, forwardSymbol ); - fn1.addParameter( lookup, new PtrOp( PtrOp.t_pointer ), false ); + fn1.addParameter( lookup, 0, new PtrOp( PtrOp.t_pointer ), false ); fn1.getTypeInfo().setBit( true, TypeInfo.isStatic ); classB.addSymbol( fn1 ); @@ -2115,7 +2114,7 @@ public class ParserSymbolTableTest extends TestCase { IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); IParameterizedSymbol constructor1 = table.newParameterizedSymbol( "A", TypeInfo.t_constructor ); - constructor1.addParameter( classA, new PtrOp( PtrOp.t_reference ), false ); + constructor1.addParameter( classA, 0, new PtrOp( PtrOp.t_reference ), false ); IParameterizedSymbol constructor2 = table.newParameterizedSymbol( "A", TypeInfo.t_constructor ); constructor2.addParameter( TypeInfo.t_int, 0, null, false ); @@ -2234,7 +2233,7 @@ public class ParserSymbolTableTest extends TestCase { IDerivableContainerSymbol a = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); table.getCompilationUnit().addSymbol( a ); - f.addParameter( a, null, false ); + f.addParameter( a, 0, null, false ); table.getCompilationUnit().addSymbol( f ); @@ -2313,11 +2312,11 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( returned, null ); IParameterizedSymbol constructorA = table.newParameterizedSymbol( "A", TypeInfo.t_constructor ); - constructorA.addParameter( clsC, null, false ); + constructorA.addParameter( clsC, 0, null, false ); clsA.addConstructor( constructorA ); IParameterizedSymbol constructorC = table.newParameterizedSymbol( "C", TypeInfo.t_constructor ); - constructorC.addParameter( clsA, null, false ); + constructorC.addParameter( clsA, 0, null, false ); clsC.addConstructor( constructorC ); secondOp.getOperatorExpressions().clear(); @@ -2369,7 +2368,7 @@ public class ParserSymbolTableTest extends TestCase { table.getCompilationUnit().addSymbol( c ); IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f1.addParameter( clsA, new PtrOp( PtrOp.t_reference ), false ); + f1.addParameter( clsA, 0, new PtrOp( PtrOp.t_reference ), false ); table.getCompilationUnit().addSymbol( f1 ); LinkedList parameters = new LinkedList(); @@ -2380,7 +2379,7 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( look, f1 ); IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); - f2.addParameter( clsB, new PtrOp( PtrOp.t_reference ), false ); + f2.addParameter( clsB, 0, new PtrOp( PtrOp.t_reference ), false ); table.getCompilationUnit().addSymbol( f2 ); look = table.getCompilationUnit().unqualifiedFunctionLookup( "f", parameters ); @@ -3281,5 +3280,80 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( look, f ); } + + /** + * typedef int Int; + * void f( int i ); + * void f( Int i ); + * + * + * @throws Exception + */ + public void testBug47636FunctionParameterComparisons_1() throws Exception{ + newTable(); + + ISymbol Int = table.newSymbol( "Int", TypeInfo.t_type ); + Int.getTypeInfo().setBit( true, TypeInfo.isTypedef ); + Int.setTypeSymbol( table.newSymbol( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_int ) ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f1.addParameter( TypeInfo.t_int, 0, null, false ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f2.addParameter( Int, 0, null, false ); + + assertTrue( f1.hasSameParameters( f2 ) ); + } + + /** + * void g( char * ); + * void g( char [] ); + */ + public void testBug47636FunctionParameterComparisons_2() throws Exception{ + newTable(); + + IParameterizedSymbol g1 = table.newParameterizedSymbol( "g", TypeInfo.t_function ); + g1.addParameter( TypeInfo.t_char, 0, new PtrOp( PtrOp.t_pointer ), false ); + + IParameterizedSymbol g2 = table.newParameterizedSymbol( "g", TypeInfo.t_function ); + g2.addParameter( TypeInfo.t_char, 0, new PtrOp( PtrOp.t_array ), false ); + + assertTrue( g1.hasSameParameters( g2 ) ); + } + + /** + * void h( int() ); + * void h( int (*) () ); + */ + public void testBug47636FunctionParameterComparisons_3() throws Exception{ + newTable(); + + IParameterizedSymbol f = table.newParameterizedSymbol( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_function ); + f.setReturnType( table.newSymbol( ParserSymbolTable.EMPTY_NAME, TypeInfo.t_int ) ); + + IParameterizedSymbol h1 = table.newParameterizedSymbol( "h", TypeInfo.t_function ); + h1.addParameter( f, 0, null, false ); + + IParameterizedSymbol h2 = table.newParameterizedSymbol( "h", TypeInfo.t_function ); + h2.addParameter( f, 0, new PtrOp( PtrOp.t_pointer ), false ); + + assertTrue( h1.hasSameParameters( h2 ) ); + } + + /** + * f( int ); + * f( const int ); + */ + public void testBug47636FunctionParameterComparisons_4() throws Exception{ + newTable(); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f1.addParameter( TypeInfo.t_int, 0, null, false ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f2.addParameter( TypeInfo.t_int, TypeInfo.isConst, null, false ); + + assertTrue( f1.hasSameParameters( f2 ) ); + } } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog-parser b/core/org.eclipse.cdt.core/parser/ChangeLog-parser index aef2da48c7a..3c689f6d425 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog-parser +++ b/core/org.eclipse.cdt.core/parser/ChangeLog-parser @@ -1,3 +1,9 @@ +2004-02-12 Andrew Niefer + Fixed up symbol table handling of const & volatile + fixed bug 47628 - signed char is parsed as char + fixed bug 47636 - char* and char[] are treated as different types + fixed bug 45697 - Parser/Symbol table: Mismatched declaration & definition + 2004-02-12 John Camelon Removed IASTCompletionKind.SCOPED_REFERENCE as it was obsolete. Did preliminary work to support content assist within qualified names. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTSimpleTypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTSimpleTypeSpecifier.java index 3e08bec8735..3cd3ca22cf6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTSimpleTypeSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTSimpleTypeSpecifier.java @@ -94,7 +94,7 @@ public class ASTSimpleTypeSpecifier extends ASTNode implements IASTSimpleTypeSpe */ public boolean isSigned() { - return ! symbol.getTypeInfo().checkBit( TypeInfo.isUnsigned); + return symbol.getTypeInfo().checkBit( TypeInfo.isSigned); } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier#isUnsigned() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index 362b25fd199..0aea6ad95f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.parser.ast.ASTSemanticException; import org.eclipse.cdt.core.parser.ast.IASTASMDefinition; import org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration; import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration; +import org.eclipse.cdt.core.parser.ast.IASTArrayModifier; import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier; import org.eclipse.cdt.core.parser.ast.IASTCodeScope; import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit; @@ -1590,6 +1591,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto s.getTypeInfo().setBit( isUnsigned, TypeInfo.isUnsigned ); s.getTypeInfo().setBit( isComplex, TypeInfo.isComplex ); s.getTypeInfo().setBit( isImaginary, TypeInfo.isImaginary ); + s.getTypeInfo().setBit( isSigned, TypeInfo.isSigned ); return new ASTSimpleTypeSpecifier( s, false, typeName.toString(), references ); @@ -1675,37 +1677,42 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto symbol.setIsForwardDeclaration(!isFunctionDefinition); boolean previouslyDeclared = false; - if( isFunctionDefinition ) - { - List functionParameters = new LinkedList(); - // the lookup requires a list of type infos - // instead of a list of IASTParameterDeclaration - Iterator p = parameters.iterator(); - while (p.hasNext()){ - ASTParameterDeclaration param = (ASTParameterDeclaration)p.next(); - functionParameters.add(param.getSymbol().getTypeInfo()); - } - - IParameterizedSymbol functionDeclaration = null; - - functionDeclaration = - (IParameterizedSymbol) lookupQualifiedName(ownerScope, name.getLastToken().getImage(), TypeInfo.t_function, functionParameters, 0, new ArrayList(), false, LookupType.UNQUALIFIED ); - if( functionDeclaration != null ) - { + List functionParameters = new LinkedList(); + // the lookup requires a list of type infos + // instead of a list of IASTParameterDeclaration + Iterator p = parameters.iterator(); + while (p.hasNext()){ + ASTParameterDeclaration param = (ASTParameterDeclaration)p.next(); + functionParameters.add(param.getSymbol().getTypeInfo()); + } + + IParameterizedSymbol functionDeclaration = null; + + functionDeclaration = + (IParameterizedSymbol) lookupQualifiedName(ownerScope, name.getLastToken().getImage(), TypeInfo.t_function, functionParameters, 0, new ArrayList(), false, LookupType.FORDEFINITION ); + + if( functionDeclaration != null ){ + previouslyDeclared = true; + + if( isFunctionDefinition ){ functionDeclaration.setTypeSymbol( symbol ); - previouslyDeclared = true; } } - try - { - ownerScope.addSymbol( symbol ); - } - catch (ParserSymbolTableException e) - { - throw new ASTSemanticException(); + if( previouslyDeclared == false || isFunctionDefinition ){ + try + { + ownerScope.addSymbol( symbol ); + } + catch (ParserSymbolTableException e) + { + throw new ASTSemanticException(); + } + } else { + symbol = functionDeclaration; } + ASTFunction function = new ASTFunction( symbol, nameEndOffset, parameters, returnType, exception, startOffset, startLine, nameOffset, nameLine, ownerTemplate, references, previouslyDeclared, hasFunctionTryBlock ); try { @@ -1823,6 +1830,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto ISymbol xrefSymbol = null; List newReferences = null; + int infoBits = 0; if( absDecl.getTypeSpecifier() instanceof IASTSimpleTypeSpecifier ) { if( ((IASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getType() == IASTSimpleTypeSpecifier.Type.CLASS_OR_TYPENAME ) @@ -1830,6 +1838,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto xrefSymbol = ((ASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getSymbol(); newReferences = ((ASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getReferences(); } + + infoBits = ((ASTSimpleTypeSpecifier)absDecl.getTypeSpecifier()).getSymbol().getTypeInfo().getTypeInfo(); } else if( absDecl.getTypeSpecifier() instanceof ASTElaboratedTypeSpecifier ) { @@ -1849,6 +1859,10 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto if( xrefSymbol != null ) paramSymbol.setTypeSymbol( xrefSymbol.getTypeSymbol() ); + paramSymbol.getTypeInfo().setTypeInfo( infoBits ); + paramSymbol.getTypeInfo().setBit( absDecl.isConst(), TypeInfo.isConst ); + paramSymbol.getTypeInfo().setBit( absDecl.isVolatile(), TypeInfo.isVolatile ); + setPointerOperators( paramSymbol, absDecl.getPointerOperators(), absDecl.getArrayModifiers() ); if( isParameter) @@ -2317,6 +2331,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto newSymbol.getTypeInfo().setBit( isRegister, TypeInfo.isRegister ); newSymbol.getTypeInfo().setBit( isStatic, TypeInfo.isStatic ); newSymbol.getTypeInfo().setBit( abstractDeclaration.isConst(), TypeInfo.isConst ); + newSymbol.getTypeInfo().setBit( abstractDeclaration.isVolatile(), TypeInfo.isVolatile ); } protected ISymbol cloneSimpleTypeSymbol( @@ -2779,6 +2794,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto result.getTypeInfo().setBit( id.isShort(), TypeInfo.isShort); result.getTypeInfo().setBit( id.isLong(), TypeInfo.isLong); result.getTypeInfo().setBit( id.isUnsigned(), TypeInfo.isUnsigned); + result.getTypeInfo().setBit( id.isSigned(), TypeInfo.isSigned ); List refs = new ArrayList(); if( result.getType() == TypeInfo.t_type ) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index 359ee806bc6..9aab6009c05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -444,6 +444,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol { LookupData data = new LookupData( name, TypeInfo.t_any ); data.qualified = true; data.parameters = ( parameters == null ) ? new LinkedList() : parameters; + data.exactFunctionsOnly = true; IContainerSymbol container = this; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java index 43febbce569..fc2c3d92a73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java @@ -170,14 +170,15 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva public void addCopyConstructor() throws ParserSymbolTableException{ List parameters = new LinkedList(); - TypeInfo param = new TypeInfo( TypeInfo.t_type, 0, this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false ); + TypeInfo param = new TypeInfo( TypeInfo.t_type, TypeInfo.isConst, this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, false, false ), false ); parameters.add( param ); IParameterizedSymbol constructor = lookupConstructor( parameters ); if( constructor == null ){ constructor = getSymbolTable().newParameterizedSymbol( getName(), TypeInfo.t_constructor ); - constructor.addParameter( this, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, true, false ), false ); + constructor.addParameter( this, TypeInfo.isConst, new TypeInfo.PtrOp( TypeInfo.PtrOp.t_reference, false, false ), false ); + addConstructor( constructor ); } } @@ -248,10 +249,8 @@ public class DerivableContainerSymbol extends ContainerSymbol implements IDeriva //thisObj.setCVQualifier( obj.getCVQualifier() ); TypeInfo.PtrOp ptr = new TypeInfo.PtrOp(); ptr.setType( TypeInfo.PtrOp.t_pointer ); - if( obj.getTypeInfo().hasPtrOperators() ){ - ptr.setConst( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isConst() ); - ptr.setVolatile( ((TypeInfo.PtrOp) obj.getPtrOperators().iterator().next()).isVolatile() ); - } + thisObj.getTypeInfo().setBit( obj.getTypeInfo().checkBit( TypeInfo.isConst ), TypeInfo.isConst ); + thisObj.getTypeInfo().setBit( obj.getTypeInfo().checkBit( TypeInfo.isVolatile ), TypeInfo.isVolatile ); thisObj.addPtrOperator(ptr); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java index 3d04d75af63..8560a621c41 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/IParameterizedSymbol.java @@ -30,7 +30,7 @@ public interface IParameterizedSymbol extends IContainerSymbol { public void addParameter( ISymbol param ); public void addParameter( TypeInfo.eType type, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ); - public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ); + public void addParameter( ISymbol typeSymbol, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ); public Map getParameterMap(); public List getParameterList(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java index 411f1175f08..57e95883168 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParameterizedSymbol.java @@ -17,11 +17,13 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.TreeMap; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Command; +import org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp; /** * @author aniefer @@ -137,14 +139,15 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz /* (non-Javadoc) * @see org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol#addParameter(org.eclipse.cdt.internal.core.parser.pst.ISymbol, org.eclipse.cdt.internal.core.parser.pst.TypeInfo.PtrOp, boolean) */ - public void addParameter( ISymbol typeSymbol, TypeInfo.PtrOp ptrOp, boolean hasDefault ){ + public void addParameter( ISymbol typeSymbol, int info, TypeInfo.PtrOp ptrOp, boolean hasDefault ){ BasicSymbol param = new BasicSymbol(getSymbolTable(), ParserSymbolTable.EMPTY_NAME); - TypeInfo info = param.getTypeInfo(); - info.setType( TypeInfo.t_type ); - info.setTypeSymbol( typeSymbol ); - info.addPtrOperator( ptrOp ); - info.setHasDefault( hasDefault ); + TypeInfo nfo = param.getTypeInfo(); + nfo.setTypeInfo( info ); + nfo.setType( TypeInfo.t_type ); + nfo.setTypeSymbol( typeSymbol ); + nfo.addPtrOperator( ptrOp ); + nfo.setHasDefault( hasDefault ); addParameter( param ); } @@ -204,7 +207,44 @@ public class ParameterizedSymbol extends ContainerSymbol implements IParameteriz for( int i = size; i > 0; i-- ){ info = ((BasicSymbol)iter.next()).getTypeInfo(); fInfo = ((BasicSymbol) fIter.next()).getTypeInfo(); - + + //parameters that differ only in the use of equivalent typedef types are equivalent. + info = ParserSymbolTable.getFlatTypeInfo( info ); + fInfo = ParserSymbolTable.getFlatTypeInfo( fInfo ); + + for( TypeInfo nfo = info; nfo != null; nfo = fInfo ){ + //an array declaration is adjusted to become a pointer declaration + //only the second and subsequent array dimensions are significant in parameter types + ListIterator ptrs = nfo.getPtrOperators().listIterator(); + if( ptrs.hasNext() ){ + PtrOp op = (PtrOp) ptrs.next(); + if( op.getType() == PtrOp.t_array ){ + ptrs.remove(); + ptrs.add( new PtrOp( PtrOp.t_pointer, op.isConst(), op.isVolatile() ) ); + } + } + + //a function type is adjusted to become a pointer to function type + if( nfo.isType( TypeInfo.t_type ) && nfo.getTypeSymbol().isType( TypeInfo.t_function ) ){ + if( nfo.getPtrOperators().size() == 0 ){ + nfo.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + } + } + + //const and volatile type-specifiers are ignored (only the outermost level) + if( nfo.getPtrOperators().size() == 0 ){ + nfo.setBit( false, TypeInfo.isConst ); + nfo.setBit( false, TypeInfo.isVolatile ); + } else { + PtrOp op = (PtrOp) nfo.getPtrOperators().listIterator( nfo.getPtrOperators().size() ).previous(); + op.setConst( false ); + op.setVolatile( false ); + } + + if( nfo == fInfo ) + break; + } + if( !info.equals( fInfo ) ){ return false; } 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 d2a9bb03c91..efad34de6ec 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 @@ -1105,7 +1105,9 @@ public class ParserSymbolTable { int order = TemplateEngine.orderTemplateFunctions( t1, t2 ); if ( order < 0 ){ hasBetter = true; - } + } else if( order > 0 ){ + ambiguous = false; + } } } if( hasBetter ){ @@ -1126,6 +1128,23 @@ public class ParserSymbolTable { return bestFn; } + static private boolean functionHasParameters( IParameterizedSymbol function, List params ){ + if( params == null ){ + return function.getParameterList().isEmpty(); + } + //create a new function that has params as its parameters, then use IParameterizedSymbol.hasSameParameters + IParameterizedSymbol tempFn = function.getSymbolTable().newParameterizedSymbol( EMPTY_NAME, TypeInfo.t_function ); + + Iterator i = params.iterator(); + while( i.hasNext() ){ + ISymbol param = function.getSymbolTable().newSymbol( EMPTY_NAME ); + param.setTypeInfo( (TypeInfo) i.next() ); + tempFn.addParameter( param ); + } + + return function.hasSameParameters( tempFn ); + } + static private void reduceToViable( LookupData data, List functions ){ int numParameters = ( data.parameters == null ) ? 0 : data.parameters.size(); int num; @@ -1140,6 +1159,9 @@ public class ParserSymbolTable { //if there are m arguments in the list, all candidate functions having m parameters //are viable if( num == numParameters ){ + if( data.exactFunctionsOnly && !functionHasParameters( function, data.parameters ) ){ + iter.remove(); + } continue; } //check for void @@ -1455,11 +1477,7 @@ public class ParserSymbolTable { TypeInfo.PtrOp ptr = (TypeInfo.PtrOp)iterator.next(); if( ptr.getType() == TypeInfo.PtrOp.t_reference ){ - if( ptr.isConst() || ptr.isVolatile() ){ - iterator.set( new PtrOp( PtrOp.t_undef, ptr.isConst(), ptr.isVolatile() ) ); - } else { - iterator.remove(); - } + iterator.remove(); cost.targetHadReference = true; } int size = targetPtrs.size(); @@ -1491,30 +1509,9 @@ public class ParserSymbolTable { Iterator iter1 = cost.source.getPtrOperators().iterator(); Iterator iter2 = cost.target.getPtrOperators().iterator(); - + if( size != size2 ){ - if( size2 - size == 1 ){ - op2 = (PtrOp) iter2.next(); - if( op2.isConst() || op2.isVolatile() ){ - canConvert = true; - } else { - canConvert = false; - } - } else { - canConvert = false; - } - } else if ( size == 1 ){ - op1 = (TypeInfo.PtrOp) iter1.next(); - op2 = (TypeInfo.PtrOp) iter2.next(); - - //can only convert if op2 is more qualified - if( ( op1.isConst() && !op2.isConst() ) || - ( op1.isVolatile() && !op2.isVolatile() ) ) - { - cost.qualification = 0; - return; - } - canConvert = true; + canConvert = false; } else if( size > 0 ){ op1 = (TypeInfo.PtrOp) iter1.next(); op2 = (TypeInfo.PtrOp) iter2.next(); @@ -1548,6 +1545,12 @@ public class ParserSymbolTable { } } + if( ( cost.source.checkBit( TypeInfo.isConst ) && !cost.target.checkBit( TypeInfo.isConst ) ) || + ( cost.source.checkBit( TypeInfo.isVolatile ) && !cost.target.checkBit( TypeInfo.isVolatile ) ) ) + { + canConvert = false; + } + if( canConvert == true ){ cost.qualification = 1; cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK; @@ -1574,7 +1577,7 @@ public class ParserSymbolTable { TypeInfo src = cost.source; TypeInfo trg = cost.target; - int mask = TypeInfo.isShort | TypeInfo.isLong | TypeInfo.isUnsigned | TypeInfo.isLongLong; + int mask = TypeInfo.isShort | TypeInfo.isLong | TypeInfo.isUnsigned | TypeInfo.isLongLong | TypeInfo.isSigned; if( (src.isType( TypeInfo.t__Bool, TypeInfo.t_float ) || src.isType( TypeInfo.t_enumeration )) && (trg.isType( TypeInfo.t_int ) || trg.isType( TypeInfo.t_double )) ) @@ -1737,8 +1740,11 @@ public class ParserSymbolTable { } } } + } else if( cost.source.getType() == cost.target.getType() && + (cost.source.getTypeInfo() & ~TypeInfo.isConst & ~TypeInfo.isVolatile) == (cost.target.getTypeInfo() & ~TypeInfo.isConst & ~TypeInfo.isVolatile) ) + { + return cost; } - promotion( cost ); if( cost.promotion > 0 || cost.rank > -1 ){ return cost; @@ -1904,7 +1910,7 @@ public class ParserSymbolTable { if( topInfo.getType() == TypeInfo.t_type && topInfo.getTypeSymbol() != null ){ returnInfo = new TypeInfo(); - + returnInfo.setTypeInfo( topInfo.getTypeInfo() ); ISymbol typeSymbol = topInfo.getTypeSymbol(); info = typeSymbol.getTypeInfo(); @@ -1913,7 +1919,7 @@ public class ParserSymbolTable { typeSymbol = info.getTypeSymbol(); returnInfo.addPtrOperator( info.getPtrOperators() ); - + returnInfo.setTypeInfo( ( returnInfo.getTypeInfo() | info.getTypeInfo() ) & ~TypeInfo.isTypedef & ~TypeInfo.isForward ); info = typeSymbol.getTypeInfo(); } @@ -1921,7 +1927,7 @@ public class ParserSymbolTable { returnInfo.setType( TypeInfo.t_type ); returnInfo.setTypeSymbol( typeSymbol ); } else { - returnInfo.setTypeInfo( info.getTypeInfo() ); + returnInfo.setTypeInfo( ( returnInfo.getTypeInfo() | info.getTypeInfo() ) & ~TypeInfo.isTypedef & ~TypeInfo.isForward ); returnInfo.setType( info.getType() ); returnInfo.setTypeSymbol( null ); returnInfo.addPtrOperator( info.getPtrOperators() ); @@ -1931,17 +1937,8 @@ public class ParserSymbolTable { if( topInfo.hasPtrOperators() ){ TypeInfo.PtrOp topPtr = (PtrOp) topInfo.getPtrOperators().iterator().next(); - TypeInfo.PtrOp ptr = null; - if( returnInfo.hasPtrOperators() && topPtr.getType() == PtrOp.t_undef ){ - ptr = (PtrOp)returnInfo.getPtrOperators().iterator().next(); - } else { - ptr = new PtrOp(); - returnInfo.addPtrOperator( ptr ); - ptr.setType( topPtr.getType() ); - } - - ptr.setConst( topPtr.isConst() ); - ptr.setVolatile( topPtr.isVolatile() ); + TypeInfo.PtrOp ptr = new PtrOp( topPtr.getType(), topPtr.isConst(), topPtr.isVolatile() ); + returnInfo.addPtrOperator( ptr ); } } else { returnInfo = new TypeInfo( topInfo ); @@ -2046,6 +2043,7 @@ public class ParserSymbolTable { public boolean ignoreUsingDirectives = false; public boolean usingDirectivesOnly = false; public boolean forUserDefinedConversion = false; + public boolean exactFunctionsOnly = false; public Map foundItems = null; 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 04a50f86e72..63238b716de 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 @@ -44,22 +44,15 @@ public final class TemplateEngine { TypeInfo targetInfo = new TypeInfo( (TypeInfo) argMap.get( info.getTypeSymbol() ) ); if( info.hasPtrOperators() ){ List infoOperators = new LinkedList( info.getPtrOperators() ); - - if( targetInfo.hasPtrOperators() ){ - List targetOperators = targetInfo.getPtrOperators(); - - PtrOp lastTargetOp = (PtrOp) targetOperators.get( targetOperators.size() - 1 ); - if( lastTargetOp.getType() == PtrOp.t_undef ){ - targetOperators.remove( targetOperators.size() - 1 ); - PtrOp infoOp = (PtrOp) infoOperators.get( 0 ); - infoOp = new PtrOp( infoOp.getType(), infoOp.isConst() || lastTargetOp.isConst(), - infoOp.isVolatile() || lastTargetOp.isVolatile() ); - infoOperators.set( 0, infoOp ); - } - } - targetInfo.addPtrOperator( infoOperators ); } + + if( info.checkBit( TypeInfo.isConst ) ) + targetInfo.setBit( true, TypeInfo.isConst ); + + if( info.checkBit( TypeInfo.isVolatile ) ) + targetInfo.setBit( true, TypeInfo.isVolatile ); + return targetInfo; } else if( info.isType( TypeInfo.t_type ) && info.getTypeSymbol().isType( TypeInfo.t_function ) ){ TypeInfo newInfo = new TypeInfo( info ); @@ -291,40 +284,48 @@ public final class TemplateEngine { PtrOp newOp = new PtrOp( pOp.getType(), false, false ); pPtrs.set( 0, newOp ); } + } else { + p.setBit( false, TypeInfo.isConst ); + p.setBit( false, TypeInfo.isVolatile ); } + return p; } /** * 14.8.2.1-2 + * if P is not a reference type * - If A is an array type, the pointer type produced by the array-to-pointer conversion is used instead * - If A is a function type, the pointer type produced by the function-to-pointer conversion is used instead * - If A is a cv-qualified type, the top level cv-qualifiers are ignored for type deduction * @param aInfo * @return */ - static private TypeInfo getArgumentTypeForDeduction( TypeInfo aInfo ){ + static private TypeInfo getArgumentTypeForDeduction( TypeInfo aInfo, boolean pIsAReferenceType ){ TypeInfo a = ParserSymbolTable.getFlatTypeInfo( aInfo ); - List aPtrs = a.getPtrOperators(); - ISymbol aSymbol = a.getTypeSymbol(); - - if( a.getType() == TypeInfo.t_type && aSymbol.isType( TypeInfo.t_function ) ){ - if( aPtrs.size() == 0 ){ - aPtrs.add( new PtrOp( PtrOp.t_pointer ) ); - } - } - if( aPtrs.size() > 0 ){ - PtrOp pOp = (PtrOp) aPtrs.get( 0 ); + if( !pIsAReferenceType ){ + List aPtrs = a.getPtrOperators(); + ISymbol aSymbol = a.getTypeSymbol(); - if( pOp.getType() == PtrOp.t_array ){ - aPtrs.set( 0, new PtrOp( PtrOp.t_pointer, false, false ) ); - } else if( pOp.getType() == PtrOp.t_undef ){ - aPtrs.remove( 0 ); + if( a.getType() == TypeInfo.t_type && aSymbol.isType( TypeInfo.t_function ) ){ + if( aPtrs.size() == 0 ){ + aPtrs.add( new PtrOp( PtrOp.t_pointer ) ); + } + } + if( aPtrs.size() > 0 ){ + PtrOp pOp = (PtrOp) aPtrs.get( 0 ); + + if( pOp.getType() == PtrOp.t_array ){ + aPtrs.set( 0, new PtrOp( PtrOp.t_pointer, false, false ) ); + } else { + aPtrs.set( 0, new PtrOp( pOp.getType(), false, false ) ); + } } else { - aPtrs.set( 0, new PtrOp( pOp.getType(), false, false ) ); + a.setBit( false, TypeInfo.isConst ); + a.setBit( false, TypeInfo.isVolatile ); } } @@ -415,8 +416,16 @@ public final class TemplateEngine { static private boolean deduceTemplateArgument( Map map, ISymbol pSymbol, TypeInfo a ){//, Map argumentMap ){ ISymbol symbol; + boolean pIsAReferenceType = false; + + Iterator i = pSymbol.getPtrOperators().iterator(); + if( i.hasNext() && ((PtrOp)i.next()).getType() == TypeInfo.PtrOp.t_reference ){ + pIsAReferenceType = true; + } + TypeInfo p = getParameterTypeForDeduction( pSymbol ); - a = getArgumentTypeForDeduction( a ); + + a = getArgumentTypeForDeduction( a, pIsAReferenceType ); if( p.isType( TypeInfo.t_type ) ){ symbol = p.getTypeSymbol(); @@ -429,7 +438,7 @@ public final class TemplateEngine { //a = getFlatTypeInfo( a ); List aPtrs = a.getPtrOperators(); List pPtrs = p.getPtrOperators(); - //TODO cvlist T + if( pPtrs != null && pPtrs.size() > 0){ if( aPtrs == null ){ return false; @@ -447,28 +456,31 @@ public final class TemplateEngine { aOp = (PtrOp) aIter.next(); if( pOp.getType() == aOp.getType() ){ if( !pOp.equals( aOp ) ){ - if( pIter.hasNext() || pOp.compareCVTo( aOp ) > 0 ){ - return false; - } else { - PtrOp newOp = new PtrOp( PtrOp.t_undef ); - newOp.setConst( aOp.isConst() ); - newOp.setVolatile( aOp.isVolatile() ); - aIter.set( newOp ); - } + return false; } else { aIter.remove(); - } - + } } else { return false; } } - } - return deduceArgument( map, symbol, a ); - } else { - //T - return deduceArgument( map, symbol, a ); - } + } + } + //cvlist T + if( p.checkBit( TypeInfo.isConst ) ){ + if( !a.checkBit( TypeInfo.isConst ) ) + return false; + a.setBit( false, TypeInfo.isConst); + } + if( p.checkBit( TypeInfo.isVolatile ) ){ + if( !a.checkBit( TypeInfo.isVolatile ) ) + return false; + a.setBit( false, TypeInfo.isVolatile); + } + + //T + return deduceArgument( map, symbol, a ); + } else if ( symbol.getTypeInfo().getTemplateParameterType() == TypeInfo.t_template ){ } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java index 992dfd3e147..72f481a3993 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/TypeInfo.java @@ -341,23 +341,6 @@ public class TypeInfo { Iterator iter1 = getPtrOperators().iterator(); Iterator iter2 = type.getPtrOperators().iterator(); TypeInfo.PtrOp ptr1 = null, ptr2 = null; - if( size2 < size ) { - for( int i = size; i > size2; i-- ){ - ptr2 = (PtrOp) iter1.next(); - if( ptr2.getType() != PtrOp.t_undef ){ - return false; - } - } - size = size2; - } else if ( size < size2 ){ - for( int i = size2; i > size; i-- ){ - ptr1 = (PtrOp)iter2.next(); - if( ptr1.getType() != PtrOp.t_undef ){ - return false; - } - } - size2 = size; - } if( size == size2 ){ if( size > 0 ){