mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-20 22:55:51 +02:00
Patch for Andrew Niefer
This patch improves support in the parser symbol table for forward declarations
This commit is contained in:
parent
8513838955
commit
87e177ade2
6 changed files with 215 additions and 24 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2003-07-31 Andrew Niefer
|
||||||
|
Added ParserSymbolTableTest.testForwardClassDeclaration
|
||||||
|
Added ParserSymbolTableTest.testForwardDeclarationUsedAsFunctionParam
|
||||||
|
|
||||||
2003-07-31 Victor Mozgin
|
2003-07-31 Victor Mozgin
|
||||||
Moved testBug39540() from ASTFailedTests.java to QuickParseASTTests.java.
|
Moved testBug39540() from ASTFailedTests.java to QuickParseASTTests.java.
|
||||||
|
|
||||||
|
|
|
@ -1573,7 +1573,7 @@ public class ParserSymbolTableTest extends TestCase {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*
|
*
|
||||||
* class A {};
|
* class A {};
|
||||||
* typedef A * B;
|
* typedef B A *;
|
||||||
*
|
*
|
||||||
* void f( A * );
|
* void f( A * );
|
||||||
* void f( A );
|
* void f( A );
|
||||||
|
@ -1600,6 +1600,7 @@ public class ParserSymbolTableTest extends TestCase {
|
||||||
ISymbol B = table.newSymbol( "B" );
|
ISymbol B = table.newSymbol( "B" );
|
||||||
B.setType( TypeInfo.t_type );
|
B.setType( TypeInfo.t_type );
|
||||||
B.setTypeSymbol( A );
|
B.setTypeSymbol( A );
|
||||||
|
B.getTypeInfo().setBit( true, TypeInfo.isTypedef );
|
||||||
B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
|
B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) );
|
||||||
compUnit.addSymbol( B );
|
compUnit.addSymbol( B );
|
||||||
|
|
||||||
|
@ -2331,5 +2332,145 @@ public class ParserSymbolTableTest extends TestCase {
|
||||||
assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous );
|
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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
2003-07-31 Victor Mozgin
|
||||||
Fixed PR 39540 : Parser fails on const qualifier after class specifier.
|
Fixed PR 39540 : Parser fails on const qualifier after class specifier.
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,9 @@ public interface ISymbol extends Cloneable {
|
||||||
public ISymbol getTypeSymbol();
|
public ISymbol getTypeSymbol();
|
||||||
public void setTypeSymbol( ISymbol type );
|
public void setTypeSymbol( ISymbol type );
|
||||||
|
|
||||||
|
public boolean isForwardDeclaration();
|
||||||
|
public void setIsForwardDeclaration( boolean forward );
|
||||||
|
|
||||||
public int compareCVQualifiersTo( ISymbol symbol );
|
public int compareCVQualifiersTo( ISymbol symbol );
|
||||||
public LinkedList getPtrOperators();
|
public LinkedList getPtrOperators();
|
||||||
public void addPtrOperator( TypeInfo.PtrOp ptrOp );
|
public void addPtrOperator( TypeInfo.PtrOp ptrOp );
|
||||||
|
|
|
@ -440,6 +440,13 @@ public class ParserSymbolTable {
|
||||||
TypeInfo.eType origType = origSymbol.getType();
|
TypeInfo.eType origType = origSymbol.getType();
|
||||||
TypeInfo.eType newType = newSymbol.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 ...
|
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*/) ) ){
|
( newType == TypeInfo.t_type || (newType.compareTo( TypeInfo.t_function ) >= 0 /*&& newType <= TypeInfo.typeMask*/) ) ){
|
||||||
|
|
||||||
|
@ -570,10 +577,17 @@ public class ParserSymbolTable {
|
||||||
} else {
|
} else {
|
||||||
//if this is a class-name, other stuff hides it
|
//if this is a class-name, other stuff hides it
|
||||||
if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
|
if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
|
||||||
if( cls == null ) {
|
if( cls == null ){
|
||||||
cls = (IContainerSymbol) decl;
|
cls = (IContainerSymbol) decl;
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
//an object, can only have one of these
|
//an object, can only have one of these
|
||||||
|
@ -1049,6 +1063,15 @@ public class ParserSymbolTable {
|
||||||
source = getFlatTypeInfo( source );
|
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 );
|
Cost cost = new Cost( source, target );
|
||||||
TypeInfo.PtrOp op = null;
|
TypeInfo.PtrOp op = null;
|
||||||
|
|
||||||
|
@ -1401,7 +1424,7 @@ public class ParserSymbolTable {
|
||||||
|
|
||||||
info = topInfo.getTypeSymbol().getTypeInfo();
|
info = topInfo.getTypeSymbol().getTypeInfo();
|
||||||
|
|
||||||
while( info.getType() == TypeInfo.t_type ){
|
while( info.getType() == TypeInfo.t_type || ( info.isForwardDeclaration() && info.getTypeSymbol() != null ) ){
|
||||||
typeSymbol = info.getTypeSymbol();
|
typeSymbol = info.getTypeSymbol();
|
||||||
|
|
||||||
//returnInfo.addCVQualifier( info.getCVQualifier() );
|
//returnInfo.addCVQualifier( info.getCVQualifier() );
|
||||||
|
@ -2045,7 +2068,7 @@ public class ParserSymbolTable {
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
_name = name;
|
_name = name;
|
||||||
_typeInfo = new TypeInfo( typeInfo, 0, this );
|
_typeInfo = new TypeInfo( typeInfo, 0, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParserSymbolTable getSymbolTable(){
|
public ParserSymbolTable getSymbolTable(){
|
||||||
|
@ -2077,27 +2100,33 @@ public class ParserSymbolTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(TypeInfo.eType t){
|
public void setType(TypeInfo.eType t){
|
||||||
_typeInfo.setType( t );
|
getTypeInfo().setType( t );
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeInfo.eType getType(){
|
public TypeInfo.eType getType(){
|
||||||
return _typeInfo.getType();
|
return getTypeInfo().getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isType( TypeInfo.eType type ){
|
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 ){
|
public boolean isType( TypeInfo.eType type, TypeInfo.eType upperType ){
|
||||||
return _typeInfo.isType( type, upperType );
|
return getTypeInfo().isType( type, upperType );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISymbol getTypeSymbol(){
|
public ISymbol getTypeSymbol(){
|
||||||
return _typeInfo.getTypeSymbol();
|
ISymbol symbol = getTypeInfo().getTypeSymbol();
|
||||||
|
|
||||||
|
if( symbol != null && symbol.getTypeInfo().isForwardDeclaration() && symbol.getTypeSymbol() != null ){
|
||||||
|
return symbol.getTypeSymbol();
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTypeSymbol( ISymbol type ){
|
public void setTypeSymbol( ISymbol type ){
|
||||||
_typeInfo.setTypeSymbol( type );
|
getTypeInfo().setTypeSymbol( type );
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeInfo getTypeInfo(){
|
public TypeInfo getTypeInfo(){
|
||||||
|
@ -2108,6 +2137,14 @@ public class ParserSymbolTable {
|
||||||
_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
|
* returns 0 if same, non zero otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -2141,10 +2178,10 @@ public class ParserSymbolTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedList getPtrOperators(){
|
public LinkedList getPtrOperators(){
|
||||||
return _typeInfo.getPtrOperators();
|
return getTypeInfo().getPtrOperators();
|
||||||
}
|
}
|
||||||
public void addPtrOperator( TypeInfo.PtrOp ptrOp ){
|
public void addPtrOperator( TypeInfo.PtrOp ptrOp ){
|
||||||
_typeInfo.addPtrOperator( ptrOp );
|
getTypeInfo().addPtrOperator( ptrOp );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDepth(){
|
public int getDepth(){
|
||||||
|
@ -2391,12 +2428,6 @@ public class ParserSymbolTable {
|
||||||
_needsDefinition = need;
|
_needsDefinition = need;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//public void addPtrOperator( String ptrStr, boolean isConst, boolean isVolatile ){
|
|
||||||
// _typeInfo.addPtrOperator( ptrStr, isConst, isVolatile );
|
|
||||||
//}
|
|
||||||
|
|
||||||
public ISymbol getReturnType(){
|
public ISymbol getReturnType(){
|
||||||
return _returnType;
|
return _returnType;
|
||||||
}
|
}
|
||||||
|
@ -2555,11 +2586,11 @@ public class ParserSymbolTable {
|
||||||
|
|
||||||
if( origObj != null )
|
if( origObj != null )
|
||||||
{
|
{
|
||||||
Declaration origDecl = null;
|
ISymbol origDecl = null;
|
||||||
LinkedList origList = null;
|
LinkedList origList = null;
|
||||||
|
|
||||||
if( origObj.getClass() == Declaration.class ){
|
if( origObj instanceof ISymbol ){
|
||||||
origDecl = (Declaration)origObj;
|
origDecl = (ISymbol)origObj;
|
||||||
} else if( origObj.getClass() == LinkedList.class ){
|
} else if( origObj.getClass() == LinkedList.class ){
|
||||||
origList = (LinkedList)origObj;
|
origList = (LinkedList)origObj;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -84,6 +84,7 @@ public class TypeInfo {
|
||||||
public static final int isUnsigned = 0x20000;
|
public static final int isUnsigned = 0x20000;
|
||||||
public static final int isShort = 0x40000;
|
public static final int isShort = 0x40000;
|
||||||
public static final int isLong = 0x80000;
|
public static final int isLong = 0x80000;
|
||||||
|
public static final int isForward = 0x100000;
|
||||||
|
|
||||||
// Types (maximum type is typeMask
|
// Types (maximum type is typeMask
|
||||||
// Note that these should be considered ordered and if you change
|
// Note that these should be considered ordered and if you change
|
||||||
|
@ -378,6 +379,14 @@ public class TypeInfo {
|
||||||
return _defaultValue;
|
return _defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isForwardDeclaration(){
|
||||||
|
return checkBit( isForward );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsForwardDeclaration( boolean forward ){
|
||||||
|
setBit( forward, isForward );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* canHold
|
* canHold
|
||||||
* @param type
|
* @param type
|
||||||
|
|
Loading…
Add table
Reference in a new issue