diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog index 24408c5cd8f..40c57f4b66a 100644 --- a/core/org.eclipse.cdt.core.tests/ChangeLog +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -1,3 +1,7 @@ +2003-07-31 Andrew Niefer + Added ParserSymbolTableTest.testForwardClassDeclaration + Added ParserSymbolTableTest.testForwardDeclarationUsedAsFunctionParam + 2003-07-31 Victor Mozgin Moved testBug39540() from ASTFailedTests.java to QuickParseASTTests.java. 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 6139a4e19a7..a171c215045 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 @@ -1573,7 +1573,7 @@ public class ParserSymbolTableTest extends TestCase { * @throws Exception * * class A {}; - * typedef A * B; + * typedef B A *; * * void f( A * ); * void f( A ); @@ -1600,6 +1600,7 @@ public class ParserSymbolTableTest extends TestCase { ISymbol B = table.newSymbol( "B" ); B.setType( TypeInfo.t_type ); B.setTypeSymbol( A ); + B.getTypeInfo().setBit( true, TypeInfo.isTypedef ); B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); compUnit.addSymbol( B ); @@ -2331,5 +2332,145 @@ public class ParserSymbolTableTest extends TestCase { assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); } } + + /** + * class A; + * + * A * a; + * + * class A {}; + * + * @throws Exception + */ + public void testForwardClassDeclaration() throws Exception{ + newTable(); + + ISymbol forwardSymbol = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + forwardSymbol.setIsForwardDeclaration( true ); + + table.getCompilationUnit().addSymbol( forwardSymbol ); + + /*...*/ + + ISymbol lookup = table.getCompilationUnit().Lookup( "A" ); + ISymbol otherLookup = table.getCompilationUnit().ElaboratedLookup( TypeInfo.t_class, "A" ); + + assertEquals( lookup, otherLookup ); + assertEquals( lookup, forwardSymbol ); + + ISymbol a = table.newSymbol( "a", TypeInfo.t_type ); + a.setTypeSymbol( forwardSymbol ); + a.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + + table.getCompilationUnit().addSymbol( a ); + + /*...*/ + + lookup = table.getCompilationUnit().Lookup( "A" ); + IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + assertTrue( lookup.isForwardDeclaration() ); + lookup.setTypeSymbol( classA ); + + table.getCompilationUnit().addSymbol( classA ); + + lookup = table.getCompilationUnit().Lookup( "a" ); + assertEquals( lookup, a ); + assertEquals( a.getTypeSymbol(), classA ); + + lookup = table.getCompilationUnit().Lookup( "A" ); + assertEquals( lookup, classA ); + + lookup = table.getCompilationUnit().ElaboratedLookup( TypeInfo.t_class, "A" ); + assertEquals( lookup, classA ); + } + + /** + * class A; + * + * class B { + * static void f( A * ); + * static void f( int ); + * }; + * + * A* a1; + * + * class A {}; + * + * void B::f( A * ) {} + * void B::f( int ) {} + * + * A* a2; + * + * B::f( a1 ); + * B::f( a2 ); + * + * @throws Exception + */ + public void testForwardDeclarationUsedAsFunctionParam() throws Exception{ + newTable(); + + ISymbol forwardSymbol = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + forwardSymbol.setIsForwardDeclaration( true ); + table.getCompilationUnit().addSymbol( forwardSymbol ); + + /*...*/ + + IDerivableContainerSymbol classB = table.newDerivableContainerSymbol( "B", TypeInfo.t_class ); + + 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.getTypeInfo().setBit( true, TypeInfo.isStatic ); + classB.addSymbol( fn1 ); + + IParameterizedSymbol fn2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + fn2.addParameter( TypeInfo.t_int, 0, null, false ); + fn2.getTypeInfo().setBit( true, TypeInfo.isStatic ); + classB.addSymbol( fn2 ); + + table.getCompilationUnit().addSymbol( classB ); + + /*...*/ + + ISymbol a1 = table.newSymbol( "a1", TypeInfo.t_type ); + lookup = table.getCompilationUnit().Lookup( "A" ); + assertEquals( lookup, forwardSymbol ); + a1.setTypeSymbol( lookup ); + a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + + table.getCompilationUnit().addSymbol( a1 ); + + /*...*/ + + lookup = table.getCompilationUnit().Lookup( "A" ); + IDerivableContainerSymbol classA = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + assertTrue( lookup.isForwardDeclaration() ); + lookup.setTypeSymbol( classA ); + table.getCompilationUnit().addSymbol( classA ); + + /*..*/ + ISymbol a2 = table.newSymbol( "a2", TypeInfo.t_type ); + lookup = table.getCompilationUnit().Lookup( "A" ); + assertEquals( lookup, classA ); + a2.setTypeSymbol( lookup ); + a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + + table.getCompilationUnit().addSymbol( a2 ); + + /*..*/ + + LinkedList paramList = new LinkedList(); + TypeInfo p1 = new TypeInfo( TypeInfo.t_type, 0, a1 ); + paramList.add( p1 ); + ISymbol look = classB.MemberFunctionLookup( "f", paramList ); + assertEquals( look, fn1 ); + + paramList.clear(); + p1 = new TypeInfo( TypeInfo.t_type, 0, a2 ); + paramList.add( p1 ); + look = classB.MemberFunctionLookup( "f", paramList ); + assertEquals( look, fn1 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index a57a585740c..c964345d250 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -1,3 +1,6 @@ +2003-07-31 Andrew Niefer + Added better support to the parser symbol table for forward declarations + 2003-07-31 Victor Mozgin Fixed PR 39540 : Parser fails on const qualifier after class specifier. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java index 89d828e0c2e..78b9dd1adc7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ISymbol.java @@ -41,6 +41,9 @@ public interface ISymbol extends Cloneable { public ISymbol getTypeSymbol(); public void setTypeSymbol( ISymbol type ); + public boolean isForwardDeclaration(); + public void setIsForwardDeclaration( boolean forward ); + public int compareCVQualifiersTo( ISymbol symbol ); public LinkedList getPtrOperators(); public void addPtrOperator( TypeInfo.PtrOp ptrOp ); 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 31e1efc9573..cb730070e33 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 @@ -440,6 +440,13 @@ public class ParserSymbolTable { TypeInfo.eType origType = origSymbol.getType(); TypeInfo.eType newType = newSymbol.getType(); + //handle forward decls + if( origSymbol.getTypeInfo().isForwardDeclaration() && + origSymbol.getTypeSymbol() == newSymbol ) + { + return true; + } + if( (origType.compareTo(TypeInfo.t_class) >= 0 && origType.compareTo(TypeInfo.t_enumeration) <= 0) && //class name or enumeration ... ( newType == TypeInfo.t_type || (newType.compareTo( TypeInfo.t_function ) >= 0 /*&& newType <= TypeInfo.typeMask*/) ) ){ @@ -570,10 +577,17 @@ public class ParserSymbolTable { } else { //if this is a class-name, other stuff hides it if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){ - if( cls == null ) { + if( cls == null ){ cls = (IContainerSymbol) decl; } else { - throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + if( cls.getTypeInfo().isForwardDeclaration() && cls.getTypeSymbol() == decl ){ + //cls is a forward declaration of decl, we want decl. + cls = (IContainerSymbol) decl; + } else if( decl.getTypeInfo().isForwardDeclaration() && decl.getTypeSymbol() == cls ){ + //decl is a forward declaration of cls, we already have what we want (cls) + } else { + throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous ); + } } } else { //an object, can only have one of these @@ -1049,6 +1063,15 @@ public class ParserSymbolTable { source = getFlatTypeInfo( source ); } + if( target.isType( TypeInfo.t_type ) ){ + ISymbol symbol = target.getTypeSymbol(); + if( symbol != null && symbol.isForwardDeclaration() && symbol.getTypeSymbol() != null ){ + target = new TypeInfo( target ); + target.setType( TypeInfo.t_type ); + target.setTypeSymbol( symbol.getTypeSymbol() ); + } + } + Cost cost = new Cost( source, target ); TypeInfo.PtrOp op = null; @@ -1401,7 +1424,7 @@ public class ParserSymbolTable { info = topInfo.getTypeSymbol().getTypeInfo(); - while( info.getType() == TypeInfo.t_type ){ + while( info.getType() == TypeInfo.t_type || ( info.isForwardDeclaration() && info.getTypeSymbol() != null ) ){ typeSymbol = info.getTypeSymbol(); //returnInfo.addCVQualifier( info.getCVQualifier() ); @@ -2045,7 +2068,7 @@ public class ParserSymbolTable { { super(); _name = name; - _typeInfo = new TypeInfo( typeInfo, 0, this ); + _typeInfo = new TypeInfo( typeInfo, 0, null ); } public ParserSymbolTable getSymbolTable(){ @@ -2077,37 +2100,51 @@ public class ParserSymbolTable { } public void setType(TypeInfo.eType t){ - _typeInfo.setType( t ); + getTypeInfo().setType( t ); } public TypeInfo.eType getType(){ - return _typeInfo.getType(); + return getTypeInfo().getType(); } public boolean isType( TypeInfo.eType type ){ - return _typeInfo.isType( type, TypeInfo.t_undef ); + return getTypeInfo().isType( type, TypeInfo.t_undef ); } public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){ - return _typeInfo.isType( type, upperType ); + return getTypeInfo().isType( type, upperType ); } - public ISymbol getTypeSymbol(){ - return _typeInfo.getTypeSymbol(); + public ISymbol getTypeSymbol(){ + ISymbol symbol = getTypeInfo().getTypeSymbol(); + + if( symbol != null && symbol.getTypeInfo().isForwardDeclaration() && symbol.getTypeSymbol() != null ){ + return symbol.getTypeSymbol(); + } + + return symbol; } public void setTypeSymbol( ISymbol type ){ - _typeInfo.setTypeSymbol( type ); + getTypeInfo().setTypeSymbol( type ); } public TypeInfo getTypeInfo(){ - return _typeInfo; + return _typeInfo; } public void setTypeInfo( TypeInfo info ) { _typeInfo = info; } + public boolean isForwardDeclaration(){ + return getTypeInfo().isForwardDeclaration(); + } + + public void setIsForwardDeclaration( boolean forward ){ + getTypeInfo().setIsForwardDeclaration( forward ); + } + /** * returns 0 if same, non zero otherwise */ @@ -2141,10 +2178,10 @@ public class ParserSymbolTable { } public LinkedList getPtrOperators(){ - return _typeInfo.getPtrOperators(); + return getTypeInfo().getPtrOperators(); } public void addPtrOperator( TypeInfo.PtrOp ptrOp ){ - _typeInfo.addPtrOperator( ptrOp ); + getTypeInfo().addPtrOperator( ptrOp ); } public int getDepth(){ @@ -2391,12 +2428,6 @@ public class ParserSymbolTable { _needsDefinition = need; } - - - //public void addPtrOperator( String ptrStr, boolean isConst, boolean isVolatile ){ - // _typeInfo.addPtrOperator( ptrStr, isConst, isVolatile ); - //} - public ISymbol getReturnType(){ return _returnType; } @@ -2555,11 +2586,11 @@ public class ParserSymbolTable { if( origObj != null ) { - Declaration origDecl = null; + ISymbol origDecl = null; LinkedList origList = null; - if( origObj.getClass() == Declaration.class ){ - origDecl = (Declaration)origObj; + if( origObj instanceof ISymbol ){ + origDecl = (ISymbol)origObj; } else if( origObj.getClass() == LinkedList.class ){ origList = (LinkedList)origObj; } 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 579c5813d85..99c6192b113 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 @@ -84,6 +84,7 @@ public class TypeInfo { public static final int isUnsigned = 0x20000; public static final int isShort = 0x40000; public static final int isLong = 0x80000; + public static final int isForward = 0x100000; // Types (maximum type is typeMask // Note that these should be considered ordered and if you change @@ -378,6 +379,14 @@ public class TypeInfo { return _defaultValue; } + public boolean isForwardDeclaration(){ + return checkBit( isForward ); + } + + public void setIsForwardDeclaration( boolean forward ){ + setBit( forward, isForward ); + } + /** * canHold * @param type