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:
parent
c261e3177e
commit
34877663fe
6 changed files with 323 additions and 40 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue