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
Updated Scanner to work for Strings literals like L"this string"
Updated Scanner to work for floating points literals.

View file

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

View file

@ -760,19 +760,15 @@ public class ParserSymbolTable {
data.visited.add( wrapper.parent );
}
//HashSet.add returns false if wrapper.parent is already in the set
//this means we have circular inheritance
//if the inheritanceChain already contains the parent, then that
//is circular inheritance
if( ! data.inheritanceChain.contains( wrapper.parent ) ){
//is this name define in this scope?
temp = LookupInContained( data, wrapper.parent );
if( temp == null ){
temp = LookupInParents( data, wrapper.parent );
}
//data.inheritanceChain.remove( wrapper.parent );
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_CircularInheritance );
}
@ -799,7 +795,9 @@ public class ParserSymbolTable {
temp = null; //reset temp for next iteration
}
}
data.inheritanceChain.remove( lookIn );
return decl;
}
@ -1315,23 +1313,39 @@ public class ParserSymbolTable {
* @return int
*
*/
static private int canConvert(TypeInfo source, TypeInfo target ){
static private int canConvert(TypeInfo source, TypeInfo target ) throws ParserSymbolTableException{
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?
if( source.getType() == target.getType() &&
source.getTypeDeclaration() == target.getTypeDeclaration() )
source.getTypeDeclaration() == target.getTypeDeclaration() &&
samePtrOp )
{
return 0;
}
//no go if they have different pointer qualification
if( ! source.getPtrOperator().equals( target.getPtrOperator() ) ){
if( !samePtrOp )
{
return -1;
}
//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.
//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 ) ||
@ -1382,6 +1396,48 @@ public class ParserSymbolTable {
(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 Declaration _compilationUnit;

View file

@ -39,10 +39,20 @@ public class TypeInfo{
_typeInfo = type;
_typeDeclaration = decl;
_cvQualifier = cvQualifier;
_ptrOperator = ptrOp;
_ptrOperator = ( ptrOp != null ) ? new String( ptrOp ) : null;
_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 isAuto = 0x0020;
public static final int isRegister = 0x0040;
@ -63,21 +73,22 @@ public class TypeInfo{
// Types (maximum type is typeMask
// Note that these should be considered ordered and if you change
// the order, you should consider the ParserSymbolTable uses
public static final int t_type = 0; // Type Specifier
public static final int t_namespace = 1;
public static final int t_class = 2;
public static final int t_struct = 3;
public static final int t_union = 4;
public static final int t_enumeration = 5;
public static final int t_function = 6;
public static final int t_bool = 7;
public static final int t_char = 8;
public static final int t_wchar_t = 9;
public static final int t_int = 10;
public static final int t_float = 11;
public static final int t_double = 12;
public static final int t_void = 13;
public static final int t_enumerator = 14;
public static final int t_undef = 0; //not specified
public static final int t_type = 1; // Type Specifier
public static final int t_namespace = 2;
public static final int t_class = 3;
public static final int t_struct = 4;
public static final int t_union = 5;
public static final int t_enumeration = 6;
public static final int t_function = 7;
public static final int t_bool = 8;
public static final int t_char = 9;
public static final int t_wchar_t = 10;
public static final int t_int = 11;
public static final int t_float = 12;
public static final int t_double = 13;
public static final int t_void = 14;
public static final int t_enumerator = 15;
//Partial ordering :
// none < const
@ -158,6 +169,29 @@ public class TypeInfo{
_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(){
return _ptrOperator;
}
@ -166,6 +200,93 @@ public class TypeInfo{
_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(){
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
Added testWeirdStrings() and testNumerics() to ScannerTestCase.
Added testTemplateSpecialization(), testTemplateDeclaration(), testBug26467(),

View file

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