1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

Patch for Andrew Niefer:

Core: (patch_03.31.03(cdt.core).txt)
Modifications to function resolution to better support pointers, references and typedefs.

Tests: (patch_03.31.03(cdt.ui.tests).txt)
Renamed testFunctionResolution_2 to testfunctionResolution_PointersAndBaseClasses.
Modified function tests to reflect changes made to the handling of parameters. Added testFunctionResolution_TypedefsAndPointers.
This commit is contained in:
Doug Schaefer 2003-03-31 20:43:07 +00:00
parent c261e3177e
commit 34877663fe
6 changed files with 323 additions and 40 deletions

View file

@ -1,3 +1,7 @@
2003-03-31 Andrew Niefer
Parser Symbol Table, better support for function resolution with pointers and
references as parameters. Also support for typedefs as function parameters
2003-03-31 John Camelon 2003-03-31 John Camelon
Updated Scanner to work for Strings literals like L"this string" Updated Scanner to work for Strings literals like L"this string"
Updated Scanner to work for floating points literals. Updated Scanner to work for floating points literals.

View file

@ -166,10 +166,10 @@ public class Declaration implements Cloneable {
} }
public String getPtrOperator(){ public String getPtrOperator(){
return _ptrOperator; return _typeInfo.getPtrOperator();
} }
public void setPtrOperator( String ptrOp ){ public void setPtrOperator( String ptrOp ){
_ptrOperator = ptrOp; _typeInfo.setPtrOperator( ptrOp );
} }
public int getReturnType(){ public int getReturnType(){
@ -233,7 +233,7 @@ public class Declaration implements Cloneable {
private Object _object; //the object associated with us private Object _object; //the object associated with us
private boolean _needsDefinition; //this name still needs to be defined private boolean _needsDefinition; //this name still needs to be defined
private int _cvQualifier; private int _cvQualifier;
private String _ptrOperator; //private String _ptrOperator;
protected TypeInfo _typeInfo; //our type info protected TypeInfo _typeInfo; //our type info
protected Declaration _containingScope; //the scope that contains us protected Declaration _containingScope; //the scope that contains us
protected LinkedList _parentScopes; //inherited scopes (is base classes) protected LinkedList _parentScopes; //inherited scopes (is base classes)

View file

@ -760,19 +760,15 @@ public class ParserSymbolTable {
data.visited.add( wrapper.parent ); data.visited.add( wrapper.parent );
} }
//HashSet.add returns false if wrapper.parent is already in the set //if the inheritanceChain already contains the parent, then that
//this means we have circular inheritance //is circular inheritance
if( ! data.inheritanceChain.contains( wrapper.parent ) ){ if( ! data.inheritanceChain.contains( wrapper.parent ) ){
//is this name define in this scope? //is this name define in this scope?
temp = LookupInContained( data, wrapper.parent ); temp = LookupInContained( data, wrapper.parent );
if( temp == null ){ if( temp == null ){
temp = LookupInParents( data, wrapper.parent ); temp = LookupInParents( data, wrapper.parent );
} }
//data.inheritanceChain.remove( wrapper.parent );
} else { } else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_CircularInheritance ); throw new ParserSymbolTableException( ParserSymbolTableException.r_CircularInheritance );
} }
@ -799,7 +795,9 @@ public class ParserSymbolTable {
temp = null; //reset temp for next iteration temp = null; //reset temp for next iteration
} }
} }
data.inheritanceChain.remove( lookIn);
data.inheritanceChain.remove( lookIn );
return decl; return decl;
} }
@ -1315,23 +1313,39 @@ public class ParserSymbolTable {
* @return int * @return int
* *
*/ */
static private int canConvert(TypeInfo source, TypeInfo target ){ static private int canConvert(TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
int temp = 0; int temp = 0;
source = getFlatTypeInfo( source );
String sourcePtr = source.getPtrOperator();
String targetPtr = target.getPtrOperator();
if( sourcePtr != null && sourcePtr.equals("") ){
sourcePtr = null;
}
if( targetPtr != null && targetPtr.equals("") ){
targetPtr = null;
}
boolean samePtrOp = ( ( sourcePtr == targetPtr ) ||
( sourcePtr != null && targetPtr != null && sourcePtr.equals( targetPtr ) ) );
//are they the same? //are they the same?
if( source.getType() == target.getType() && if( source.getType() == target.getType() &&
source.getTypeDeclaration() == target.getTypeDeclaration() ) source.getTypeDeclaration() == target.getTypeDeclaration() &&
samePtrOp )
{ {
return 0; return 0;
} }
//no go if they have different pointer qualification //no go if they have different pointer qualification
if( ! source.getPtrOperator().equals( target.getPtrOperator() ) ){ if( !samePtrOp )
{
return -1; return -1;
} }
//TBD, do a better check on the kind of ptrOperator //TBD, do a better check on the kind of ptrOperator
if( !source.getPtrOperator().equals("*") ){ if( sourcePtr == null || !sourcePtr.equals("*") ){
//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type. //4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
//An rvalue of an enumeration type can be converted to an rvalue of an integer type. //An rvalue of an enumeration type can be converted to an rvalue of an integer type.
if( source.isType( TypeInfo.t_bool, TypeInfo.t_int ) || if( source.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
@ -1382,6 +1396,48 @@ public class ParserSymbolTable {
(source.getCVQualifier() - source.getCVQualifier()) > 1 ); (source.getCVQualifier() - source.getCVQualifier()) > 1 );
} }
/**
*
* @param decl
* @return TypeInfo
* @throws ParserSymbolTableException
* The top level TypeInfo represents modifications to the object and the
* remaining TypeInfo's represent the object.
*/
static private TypeInfo getFlatTypeInfo( TypeInfo topInfo ) throws ParserSymbolTableException {
TypeInfo returnInfo = topInfo;
TypeInfo info = null;
if( topInfo.getType() == TypeInfo.t_type ){
returnInfo = new TypeInfo();
Declaration typeDecl = null;
info = topInfo.getTypeDeclaration().getTypeInfo();
while( info.getType() == TypeInfo.t_type ){
typeDecl = info.getTypeDeclaration();
returnInfo.addCVQualifier( info.getCVQualifier() );
returnInfo.addPtrOperator( info.getPtrOperator() );
info = info.getTypeDeclaration().getTypeInfo();
}
returnInfo.setType( TypeInfo.t_type );
returnInfo.setTypeDeclaration( typeDecl );
String ptrOp = returnInfo.getPtrOperator();
returnInfo.setPtrOperator( topInfo.getInvertedPtrOperator() );
if( ptrOp != null ){
returnInfo.addPtrOperator( ptrOp );
}
}
return returnInfo;
}
private Stack _contextStack = new Stack(); private Stack _contextStack = new Stack();
private Declaration _compilationUnit; private Declaration _compilationUnit;

View file

@ -39,10 +39,20 @@ public class TypeInfo{
_typeInfo = type; _typeInfo = type;
_typeDeclaration = decl; _typeDeclaration = decl;
_cvQualifier = cvQualifier; _cvQualifier = cvQualifier;
_ptrOperator = ptrOp; _ptrOperator = ( ptrOp != null ) ? new String( ptrOp ) : null;
_hasDefaultValue = hasDefault; _hasDefaultValue = hasDefault;
} }
public TypeInfo( TypeInfo info ){
super();
_typeInfo = info._typeInfo;
_typeDeclaration = info._typeDeclaration;
_cvQualifier = info._cvQualifier;
_ptrOperator = ( info._ptrOperator == null ) ? null : new String( info._ptrOperator );
_hasDefaultValue = info._hasDefaultValue;
}
public static final int typeMask = 0x001f; public static final int typeMask = 0x001f;
public static final int isAuto = 0x0020; public static final int isAuto = 0x0020;
public static final int isRegister = 0x0040; public static final int isRegister = 0x0040;
@ -63,21 +73,22 @@ public class TypeInfo{
// 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
// the order, you should consider the ParserSymbolTable uses // the order, you should consider the ParserSymbolTable uses
public static final int t_type = 0; // Type Specifier public static final int t_undef = 0; //not specified
public static final int t_namespace = 1; public static final int t_type = 1; // Type Specifier
public static final int t_class = 2; public static final int t_namespace = 2;
public static final int t_struct = 3; public static final int t_class = 3;
public static final int t_union = 4; public static final int t_struct = 4;
public static final int t_enumeration = 5; public static final int t_union = 5;
public static final int t_function = 6; public static final int t_enumeration = 6;
public static final int t_bool = 7; public static final int t_function = 7;
public static final int t_char = 8; public static final int t_bool = 8;
public static final int t_wchar_t = 9; public static final int t_char = 9;
public static final int t_int = 10; public static final int t_wchar_t = 10;
public static final int t_float = 11; public static final int t_int = 11;
public static final int t_double = 12; public static final int t_float = 12;
public static final int t_void = 13; public static final int t_double = 13;
public static final int t_enumerator = 14; public static final int t_void = 14;
public static final int t_enumerator = 15;
//Partial ordering : //Partial ordering :
// none < const // none < const
@ -158,6 +169,29 @@ public class TypeInfo{
_cvQualifier = cv; _cvQualifier = cv;
} }
public void addCVQualifier( int cv ){
switch( _cvQualifier ){
case 0:
_cvQualifier = cv;
break;
case cvConst:
if( cv != cvConst ){
_cvQualifier = cvConstVolatile;
}
break;
case cvVolatile:
if( cv != cvVolatile ){
_cvQualifier = cvConstVolatile;
}
break;
case cvConstVolatile:
break; //nothing to do
}
}
public String getPtrOperator(){ public String getPtrOperator(){
return _ptrOperator; return _ptrOperator;
} }
@ -166,6 +200,93 @@ public class TypeInfo{
_ptrOperator = ptr; _ptrOperator = ptr;
} }
public void addPtrOperator( String ptr ){
if( ptr == null ){
return;
}
char chars[] = ( _ptrOperator == null ) ? ptr.toCharArray() : ( ptr + _ptrOperator ).toCharArray();
int nChars = ( _ptrOperator == null ) ? ptr.length() : ptr.length() + _ptrOperator.length();
char dest[] = new char [ nChars ];
int j = 0;
char currChar, nextChar, tempChar;
for( int i = 0; i < nChars; i++ ){
currChar = chars[ i ];
nextChar = ( i + 1 < nChars ) ? chars[ i + 1 ] : 0;
switch( currChar ){
case '&':{
switch( nextChar ){
case '[':
tempChar = ( i + 2 < nChars ) ? chars[ i + 2 ] : 0;
if( tempChar == ']' ){
i++;
nextChar = '*';
}
//fall through to '*'
case '*':
i++;
break;
case '&':
default:
dest[ j++ ] = currChar;
break;
}
break;
}
case '[':{
if( nextChar == ']' ){
i++;
currChar = '*';
nextChar = ( i + 2 < nChars ) ? chars[ i + 2 ] : 0;
}
//fall through to '*'
}
case '*':{
if( nextChar == '&' ){
i++;
} else {
dest[ j++ ] = currChar;
}
break;
}
default:
break;
}
}
_ptrOperator = new String( dest, 0, j );
}
public String getInvertedPtrOperator(){
if( _ptrOperator == null ){
return null;
}
char chars[] = _ptrOperator.toCharArray();
int nChars = _ptrOperator.length();
char dest[] = new char [ nChars ];
char currChar;
for( int i = 0; i < nChars; i++ ){
currChar = chars[ i ];
switch( currChar ){
case '*' : dest[ i ] = '&'; break;
case '&' : dest[ i ] = '*'; break;
default: dest[ i ] = currChar; break;
}
}
return new String( dest );
}
public boolean getHasDefault(){ public boolean getHasDefault(){
return _hasDefaultValue; return _hasDefaultValue;
} }

View file

@ -1,3 +1,8 @@
2003-03-31 Andrew Niefer
In ParserSymbolTableTest, renamed testFunctionResolution_2() to testFunctionResolution_PointersAndBaseClasses(),
and modified to reflect changes in function resolution.
Added testFunctionResolution_TypedefsAndPointers().
2003-03-31 John Camelon 2003-03-31 John Camelon
Added testWeirdStrings() and testNumerics() to ScannerTestCase. Added testWeirdStrings() and testNumerics() to ScannerTestCase.
Added testTemplateSpecialization(), testTemplateDeclaration(), testBug26467(), Added testTemplateSpecialization(), testTemplateDeclaration(), testBug26467(),

View file

@ -1508,7 +1508,7 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration C = new Declaration( "C" ); Declaration C = new Declaration( "C" );
C.setType( TypeInfo.t_class );
table.addDeclaration(C); table.addDeclaration(C);
table.push(C); table.push(C);
@ -1538,8 +1538,9 @@ public class ParserSymbolTableTest extends TestCase {
assertEquals( look, C ); assertEquals( look, C );
Declaration c = new Declaration("c"); Declaration c = new Declaration("c");
c.setType( TypeInfo.t_class ); c.setType( TypeInfo.t_type );
c.setTypeDeclaration( look ); c.setTypeDeclaration( look );
c.setPtrOperator( "*" );
table.addDeclaration( c ); table.addDeclaration( c );
look = table.Lookup( "c" ); look = table.Lookup( "c" );
@ -1550,7 +1551,7 @@ public class ParserSymbolTableTest extends TestCase {
LinkedList paramList = new LinkedList(); LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, null, 0, "", false); TypeInfo p1 = new TypeInfo( TypeInfo.t_int, null, 0, "", false);
TypeInfo p2 = new TypeInfo( TypeInfo.t_char, null, 0, "", false); TypeInfo p2 = new TypeInfo( TypeInfo.t_char, null, 0, "", false);
TypeInfo p3 = new TypeInfo( TypeInfo.t_type, C, 0, "*", false); TypeInfo p3 = new TypeInfo( TypeInfo.t_type, c, 0, "", false);
paramList.add( p1 ); paramList.add( p1 );
look = table.MemberFunctionLookup( "foo", paramList ); look = table.MemberFunctionLookup( "foo", paramList );
@ -1577,7 +1578,7 @@ public class ParserSymbolTableTest extends TestCase {
* f( 'b' ); //calls f( char ); * f( 'b' ); //calls f( char );
* f(); //calls f( char ); * f(); //calls f( char );
*/ */
public void testFunctionResolution_1() throws Exception{ public void testFunctionResolution() throws Exception{
newTable(); newTable();
Declaration f1 = new Declaration("f"); Declaration f1 = new Declaration("f");
@ -1630,7 +1631,7 @@ public class ParserSymbolTableTest extends TestCase {
* f( a ); //calls f( A * ); * f( a ); //calls f( A * );
* f( c ); //calls f( B * ); * f( c ); //calls f( B * );
*/ */
public void testFunctionResolution_2() throws Exception{ public void testFunctionResolution_PointersAndBaseClasses() throws Exception{
newTable(); newTable();
Declaration A = new Declaration( "A" ); Declaration A = new Declaration( "A" );
@ -1657,16 +1658,112 @@ public class ParserSymbolTableTest extends TestCase {
f2.addParameter( B, 0, "*", false ); f2.addParameter( B, 0, "*", false );
table.addDeclaration( f2 ); table.addDeclaration( f2 );
Declaration a = new Declaration( "a" );
a.setType( TypeInfo.t_type );
a.setTypeDeclaration( A );
a.setPtrOperator( "*" );
Declaration c = new Declaration( "c" );
c.setType( TypeInfo.t_type );
c.setTypeDeclaration( C );
c.setPtrOperator( "*" );
LinkedList paramList = new LinkedList(); LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, A, 0, "*", false ); TypeInfo p1 = new TypeInfo( TypeInfo.t_type, a, 0, null, false );
paramList.add( p1 ); paramList.add( p1 );
Declaration look = table.UnqualifiedFunctionLookup( "f", paramList ); Declaration look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 ); assertEquals( look, f1 );
paramList.clear(); paramList.clear();
TypeInfo p2 = new TypeInfo( TypeInfo.t_type, C, 0, "*", false ); TypeInfo p2 = new TypeInfo( TypeInfo.t_type, c, 0, "", false );
paramList.add( p2 ); paramList.add( p2 );
look = table.UnqualifiedFunctionLookup( "f", paramList ); look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 ); assertEquals( look, f2 );
} }
/**
*
* @throws Exception
*
* class A {};
* typedef A * B;
*
* void f( A * );
* void f( A );
*
* A a;
* B b;
* A [] array;
*
* f( a ); //calls f( A );
* f( &a ); //calls f( A * );
* f( b ); //calls f( A * );
* f( *b ); //calls f( A );
* f( array ); //calls f( A * );
*/
public void testFunctionResolution_TypedefsAndPointers() throws Exception{
newTable();
Declaration A = new Declaration( "A" );
A.setType( TypeInfo.t_class );
table.addDeclaration( A );
Declaration B = new Declaration( "B" );
B.setType( TypeInfo.t_type );
B.setTypeDeclaration( A );
B.setPtrOperator( "*" );
table.addDeclaration( B );
Declaration f1 = new Declaration( "f" );
f1.setType( TypeInfo.t_function );
f1.addParameter( A, 0, "*", false );
table.addDeclaration( f1 );
Declaration f2 = new Declaration( "f" );
f2.setType( TypeInfo.t_function );
f2.addParameter( A, 0, null, false );
table.addDeclaration( f2 );
Declaration a = new Declaration( "a" );
a.setType( TypeInfo.t_type );
a.setTypeDeclaration( A );
table.addDeclaration( a );
Declaration b = new Declaration( "b" );
b.setType( TypeInfo.t_type );
b.setTypeDeclaration( B );
table.addDeclaration( b );
Declaration array = new Declaration( "array" );
array.setType( TypeInfo.t_type );
array.setTypeDeclaration( A );
array.setPtrOperator( "[]" );
LinkedList paramList = new LinkedList();
TypeInfo p = new TypeInfo( TypeInfo.t_type, a, 0, null, false );
paramList.add( p );
Declaration look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
p.setPtrOperator( "&" );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
p.setTypeDeclaration( b );
p.setPtrOperator( null );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
p.setPtrOperator( "*" );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
p.setTypeDeclaration( array );
p.setPtrOperator( null );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
}
} }