1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Patch for Andrew Niefer:

- This patch contains my initial implementation of standard conversion 
sequences for function resolution in the Parser's symbol Table. 
- Also, the type information has been pulled out of the Declaration object and 
placed in util.TypeInfo
This commit is contained in:
Doug Schaefer 2003-03-27 03:29:08 +00:00
parent d24ccf7f26
commit f77eeb8c08
6 changed files with 835 additions and 400 deletions

View file

@ -1,3 +1,7 @@
2003-03-26 Andrew Niefer
Moved type information and ParameterInfo from Declaration into util.TypeInfo
Initial implementation of standard conversion sequences for function resolution
2003-03-24 John Camelon 2003-03-24 John Camelon
Added callback support for namespace definitions. Added callback support for namespace definitions.
Updated Parser exception hierarchy. Updated Parser exception hierarchy.

View file

@ -16,6 +16,8 @@ import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import java.util.Iterator; import java.util.Iterator;
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
/** /**
* @author aniefer * @author aniefer
* *
@ -32,15 +34,20 @@ public class Declaration implements Cloneable {
*/ */
public Declaration(){ public Declaration(){
super(); super();
_typeInfo = new TypeInfo();
} }
public Declaration( String name ){ public Declaration( String name ){
super();
_name = name; _name = name;
_typeInfo = new TypeInfo();
} }
public Declaration( String name, Object obj ){ public Declaration( String name, Object obj ){
super();
_name = name; _name = name;
_object = obj; _object = obj;
_typeInfo = new TypeInfo();
} }
/** /**
@ -77,134 +84,32 @@ public class Declaration implements Cloneable {
return copy; return copy;
} }
public static final int typeMask = 0x001f; public void setType(int t) throws ParserSymbolTableException{
public static final int isAuto = 0x0020; _typeInfo.setType( t );
public static final int isRegister = 0x0040;
public static final int isStatic = 0x0080;
public static final int isExtern = 0x0100;
public static final int isMutable = 0x0200;
public static final int isInline = 0x0400;
public static final int isVirtual = 0x0800;
public static final int isExplicit = 0x1000;
public static final int isTypedef = 0x2000;
public static final int isFriend = 0x4000;
public static final int isConst = 0x8000;
public static final int isVolatile = 0x10000;
public static final int isUnsigned = 0x20000;
public static final int isShort = 0x40000;
public static final int isLong = 0x80000;
public void setAuto(boolean b) { setBit(b, isAuto); }
public boolean isAuto() { return checkBit(isAuto); }
public void setRegister(boolean b) { setBit(b, isRegister); }
public boolean isRegister() { return checkBit(isRegister); }
public void setStatic(boolean b) { setBit(b, isStatic); }
public boolean isStatic() { return checkBit(isStatic); }
public void setExtern(boolean b) { setBit(b, isExtern); }
public boolean isExtern() { return checkBit(isExtern); }
public void setMutable(boolean b) { setBit(b, isMutable); }
public boolean isMutable() { return checkBit(isMutable); }
public void setInline(boolean b) { setBit(b, isInline); }
public boolean isInline() { return checkBit(isInline); }
public void setVirtual(boolean b) { setBit(b, isVirtual); }
public boolean isVirtual() { return checkBit(isVirtual); }
public void setExplicit(boolean b) { setBit(b, isExplicit); }
public boolean isExplicit() { return checkBit(isExplicit); }
public void setTypedef(boolean b) { setBit(b, isTypedef); }
public boolean isTypedef() { return checkBit(isTypedef); }
public void setFriend(boolean b) { setBit(b, isFriend); }
public boolean isFriend() { return checkBit(isFriend); }
public void setConst(boolean b) { setBit(b, isConst); }
public boolean isConst() { return checkBit(isConst); }
public void setVolatile(boolean b) { setBit(b, isVolatile); }
public boolean isVolatile() { return checkBit(isVolatile); }
public void setUnsigned(boolean b) { setBit(b, isUnsigned); }
public boolean isUnsigned() { return checkBit(isUnsigned); }
public void setShort(boolean b) { setBit(b, isShort); }
public boolean isShort() { return checkBit(isShort); }
public void setLong(boolean b) { setBit(b, isLong); }
public boolean isLong() { return checkBit(isLong); }
// Types
// 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_char = 7;
public static final int t_wchar_t = 8;
public static final int t_bool = 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 void setType(int t) throws ParserSymbolTableException{
//sanity check, t must fit in its allocated 5 bits in _typeInfo
if( t > typeMask ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
}
_typeInfo = _typeInfo & ~typeMask | t;
} }
public int getType(){ public int getType(){
return _typeInfo & typeMask; return _typeInfo.getType();
} }
public boolean isType( int type ){ public boolean isType( int type ){
return isType( type, 0 ); return _typeInfo.isType( type, 0 );
} }
/**
*
* @param type
* @param upperType
* @return boolean
*
* type checking, check that this declaration's type is between type and
* upperType (inclusive). upperType of 0 means no range and our type must
* be type.
*/
public boolean isType( int type, int upperType ){ public boolean isType( int type, int upperType ){
//type of -1 means we don't care return _typeInfo.isType( type, upperType );
if( type == -1 )
return true;
//upperType of 0 means no range
if( upperType == 0 ){
return ( getType() == type );
} else {
return ( getType() >= type && getType() <= upperType );
}
} }
public Declaration getTypeDeclaration(){ public Declaration getTypeDeclaration(){
return _typeDeclaration; return _typeInfo.getTypeDeclaration();
} }
public void setTypeDeclaration( Declaration type ){ public void setTypeDeclaration( Declaration type ){
_typeDeclaration = type; _typeInfo.setTypeDeclaration( type );
}
public TypeInfo getTypeInfo(){
return _typeInfo;
} }
public String getName() { return _name; } public String getName() { return _name; }
@ -252,11 +157,11 @@ public class Declaration implements Cloneable {
_needsDefinition = need; _needsDefinition = need;
} }
public String getCVQualifier(){ public int getCVQualifier(){
return _cvQualifier; return _cvQualifier;
} }
public void setCVQualifier( String cv ){ public void setCVQualifier( int cv ){
_cvQualifier = cv; _cvQualifier = cv;
} }
@ -275,30 +180,22 @@ public class Declaration implements Cloneable {
_returnType = type; _returnType = type;
} }
public void addParameter( Declaration typeDecl, String ptrOperator, boolean hasDefault ){ public void addParameter( Declaration typeDecl, int cvQual, String ptrOperator, boolean hasDefault ){
if( _parameters == null ){ if( _parameters == null ){
_parameters = new LinkedList(); _parameters = new LinkedList();
} }
ParameterInfo info = new ParameterInfo(); TypeInfo info = new TypeInfo( TypeInfo.t_type, typeDecl, cvQual, ptrOperator, hasDefault );
info.typeInfo = t_type;
info.typeDeclaration = typeDecl;
info.ptrOperator = ptrOperator;
info.hasDefaultValue = hasDefault;
_parameters.add( info ); _parameters.add( info );
} }
public void addParameter( int type, String ptrOperator, boolean hasDefault ){ public void addParameter( int type, int cvQual, String ptrOperator, boolean hasDefault ){
if( _parameters == null ){ if( _parameters == null ){
_parameters = new LinkedList(); _parameters = new LinkedList();
} }
ParameterInfo info = new ParameterInfo(); TypeInfo info = new TypeInfo(type, null, cvQual, ptrOperator, hasDefault );
info.typeInfo = type;
info.typeDeclaration = null;
info.ptrOperator = ptrOperator;
info.hasDefaultValue = hasDefault;
_parameters.add( info ); _parameters.add( info );
} }
@ -316,12 +213,12 @@ public class Declaration implements Cloneable {
Iterator iter = _parameters.iterator(); Iterator iter = _parameters.iterator();
Iterator fIter = function._parameters.iterator(); Iterator fIter = function._parameters.iterator();
ParameterInfo info = null; TypeInfo info = null;
ParameterInfo fInfo = null; TypeInfo fInfo = null;
for( int i = size; i > 0; i-- ){ for( int i = size; i > 0; i-- ){
info = (ParameterInfo) iter.next(); info = (TypeInfo) iter.next();
fInfo = (ParameterInfo) fIter.next(); fInfo = (TypeInfo) fIter.next();
if( !info.equals( fInfo ) ){ if( !info.equals( fInfo ) ){
return false; return false;
@ -332,26 +229,12 @@ public class Declaration implements Cloneable {
return true; return true;
} }
// Convenience methods
private void setBit(boolean b, int mask){
if( b ){
_typeInfo = _typeInfo | mask;
} else {
_typeInfo = _typeInfo & ~mask;
}
}
private boolean checkBit(int mask){
return (_typeInfo & mask) != 0;
}
private int _typeInfo; //our type info
private String _name; //our name private String _name; //our name
private Object _object; //the object associated with us private Object _object; //the object associated with us
private Declaration _typeDeclaration; //our type if _typeInfo says t_type
private boolean _needsDefinition; //this name still needs to be defined private boolean _needsDefinition; //this name still needs to be defined
private String _cvQualifier; private int _cvQualifier;
private String _ptrOperator; private String _ptrOperator;
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)
protected LinkedList _usingDirectives; //collection of nominated namespaces protected LinkedList _usingDirectives; //collection of nominated namespaces
@ -372,27 +255,4 @@ public class Declaration implements Cloneable {
public boolean isVirtual = false; public boolean isVirtual = false;
public Declaration parent = null; public Declaration parent = null;
} }
public class ParameterInfo
{
public ParameterInfo() {}
public ParameterInfo( int t, Declaration decl, String ptr, boolean def ){
typeInfo = t;
typeDeclaration = decl;
ptrOperator = ptr;
hasDefaultValue = def;
}
public boolean equals( ParameterInfo obj ){
return ( hasDefaultValue == obj.hasDefaultValue ) &&
( typeInfo == obj.typeInfo ) &&
( typeDeclaration == obj.typeDeclaration ) &&
( ptrOperator.equals( obj.ptrOperator ) );
}
public boolean hasDefaultValue;
public int typeInfo;
public Declaration typeDeclaration;
public String ptrOperator;
}
} }

View file

@ -22,6 +22,8 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
/** /**
* @author aniefer * @author aniefer
* *
@ -40,7 +42,7 @@ public class ParserSymbolTable {
super(); super();
_compilationUnit = new Declaration(); _compilationUnit = new Declaration();
try{ try{
_compilationUnit.setType( Declaration.t_namespace ); _compilationUnit.setType( TypeInfo.t_namespace );
} catch ( ParserSymbolTableException e ){ } catch ( ParserSymbolTableException e ){
/*shouldn't happen*/ /*shouldn't happen*/
} }
@ -96,8 +98,8 @@ public class ParserSymbolTable {
private Declaration LookupNestedNameSpecifier(String name, Declaration inDeclaration ) throws ParserSymbolTableException{ private Declaration LookupNestedNameSpecifier(String name, Declaration inDeclaration ) throws ParserSymbolTableException{
Declaration foundDeclaration = null; Declaration foundDeclaration = null;
LookupData data = new LookupData( name, Declaration.t_namespace ); LookupData data = new LookupData( name, TypeInfo.t_namespace );
data.upperType = Declaration.t_union; data.upperType = TypeInfo.t_union;
foundDeclaration = LookupInContained( data, inDeclaration ); foundDeclaration = LookupInContained( data, inDeclaration );
@ -164,7 +166,7 @@ public class ParserSymbolTable {
* @throws ParserSymbolTableException * @throws ParserSymbolTableException
*/ */
public Declaration QualifiedFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{ public Declaration QualifiedFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, Declaration.t_function ); LookupData data = new LookupData( name, TypeInfo.t_function );
data.qualified = true; data.qualified = true;
data.parameters = parameters; data.parameters = parameters;
@ -182,7 +184,7 @@ public class ParserSymbolTable {
* include argument dependant scopes * include argument dependant scopes
*/ */
public Declaration MemberFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{ public Declaration MemberFunctionLookup( String name, LinkedList parameters ) throws ParserSymbolTableException{
LookupData data = new LookupData( name, Declaration.t_function ); LookupData data = new LookupData( name, TypeInfo.t_function );
data.parameters = parameters; data.parameters = parameters;
return Lookup( data, (Declaration) _contextStack.peek() ); return Lookup( data, (Declaration) _contextStack.peek() );
@ -215,24 +217,26 @@ public class ParserSymbolTable {
//during the normal lookup to avoid doing them twice //during the normal lookup to avoid doing them twice
HashSet associated = new HashSet(); HashSet associated = new HashSet();
//collect associated namespaces & classes. //collect associated namespaces & classes.
int size = parameters.size(); int size = ( parameters == null ) ? 0 : parameters.size();
Iterator iter = parameters.iterator(); Iterator iter = ( parameters == null ) ? null : parameters.iterator();
Declaration.ParameterInfo param = null; TypeInfo param = null;
Declaration paramType = null;
for( int i = size; i > 0; i-- ){ for( int i = size; i > 0; i-- ){
param = (Declaration.ParameterInfo) iter.next(); param = (TypeInfo) iter.next();
paramType = param.getTypeDeclaration();
getAssociatedScopes( param.typeDeclaration, associated ); getAssociatedScopes( paramType, associated );
//if T is a pointer to a data member of class X, its associated namespaces and classes //if T is a pointer to a data member of class X, its associated namespaces and classes
//are those associated with the member type together with those associated with X //are those associated with the member type together with those associated with X
if( param.ptrOperator != null && if( param.getPtrOperator() != null &&
(param.ptrOperator.equals("*") || param.ptrOperator.equals("[]")) && (param.getPtrOperator().equals("*") || param.getPtrOperator().equals("[]")) &&
param.typeDeclaration._containingScope.isType( Declaration.t_class, Declaration.t_union ) ) paramType._containingScope.isType( TypeInfo.t_class, TypeInfo.t_union ) )
{ {
getAssociatedScopes( param.typeDeclaration._containingScope, associated ); getAssociatedScopes( paramType._containingScope, associated );
} }
} }
LookupData data = new LookupData( name, Declaration.t_function ); LookupData data = new LookupData( name, TypeInfo.t_function );
data.parameters = parameters; data.parameters = parameters;
data.associated = associated; data.associated = associated;
@ -240,33 +244,37 @@ public class ParserSymbolTable {
//if we haven't found anything, or what we found is not a class member, consider the //if we haven't found anything, or what we found is not a class member, consider the
//associated scopes //associated scopes
if( found == null || found._containingScope.getType() != Declaration.t_class ){ if( found == null || found._containingScope.getType() != TypeInfo.t_class ){
LinkedList foundList = new LinkedList(); HashSet foundSet = new HashSet();
if( found != null ){ if( found != null ){
foundList.add( found ); foundSet.add( found );
} }
iter = associated.iterator();
Declaration decl; Declaration decl;
Declaration temp; Declaration temp;
//dump the hash to an array and iterate over the array because we
//could be removing items from the collection as we go and we don't
//want to get ConcurrentModificationExceptions
Object [] scopes = associated.toArray();
//use while hasNext instead of forloop since the lookup might remove size = associated.size();
//items from the collection.
//Actually, I think that there will be no removals, but leave it like this anyway for( int i = 0; i < size; i++ ){
while( iter.hasNext() ){ decl = (Declaration) scopes[ i ];
decl = (Declaration) iter.next(); if( associated.contains( decl ) ){
data.qualified = true;
data.qualified = true; data.ignoreUsingDirectives = true;
data.ignoreUsingDirectives = true; temp = Lookup( data, decl );
temp = Lookup( data, decl ); if( temp != null ){
if( temp != null ){ foundSet.add( temp );
foundList.add( temp ); }
} }
} }
found = ResolveAmbiguities( data, foundList ); found = ResolveAmbiguities( data, foundSet );
} }
return found; return found;
@ -288,11 +296,11 @@ public class ParserSymbolTable {
LookupData data = new LookupData( name, -1 ); LookupData data = new LookupData( name, -1 );
Declaration decl = (Declaration) _contextStack.peek(); Declaration decl = (Declaration) _contextStack.peek();
boolean inClass = (decl.getType() == Declaration.t_class); boolean inClass = (decl.getType() == TypeInfo.t_class);
Declaration enclosing = decl._containingScope; Declaration enclosing = decl._containingScope;
while( enclosing != null && (inClass ? enclosing.getType() != Declaration.t_class while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
: enclosing.getType() == Declaration.t_namespace) ) : enclosing.getType() == TypeInfo.t_namespace) )
{ {
enclosing = enclosing._containingScope; enclosing = enclosing._containingScope;
} }
@ -303,7 +311,7 @@ public class ParserSymbolTable {
} }
public void addUsingDirective( Declaration namespace ) throws ParserSymbolTableException{ public void addUsingDirective( Declaration namespace ) throws ParserSymbolTableException{
if( namespace.getType() != Declaration.t_namespace ){ if( namespace.getType() != TypeInfo.t_namespace ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
} }
@ -338,20 +346,20 @@ public class ParserSymbolTable {
boolean okToAdd = false; boolean okToAdd = false;
//7.3.3-4 //7.3.3-4
if( context.isType( Declaration.t_class, Declaration.t_union ) ){ if( context.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
//a member of a base class //a member of a base class
if( obj.getContainingScope().getType() == context.getType() ){ if( obj.getContainingScope().getType() == context.getType() ){
okToAdd = hasBaseClass( context, obj.getContainingScope() ); okToAdd = ( hasBaseClass( context, obj.getContainingScope() ) > 0 );
} }
//TBD : a member of an _anonymous_ union //TBD : a member of an _anonymous_ union
else if ( obj.getContainingScope().getType() == Declaration.t_union ) { else if ( obj.getContainingScope().getType() == TypeInfo.t_union ) {
Declaration union = obj.getContainingScope(); Declaration union = obj.getContainingScope();
okToAdd = hasBaseClass( context, union.getContainingScope() ); okToAdd = ( hasBaseClass( context, union.getContainingScope() ) > 0 );
} }
//an enumerator for an enumeration //an enumerator for an enumeration
else if ( obj.getType() == Declaration.t_enumerator ){ else if ( obj.getType() == TypeInfo.t_enumerator ){
Declaration enumeration = obj.getContainingScope(); Declaration enumeration = obj.getContainingScope();
okToAdd = hasBaseClass( context, enumeration.getContainingScope() ); okToAdd = ( hasBaseClass( context, enumeration.getContainingScope() ) > 0 );
} }
} else { } else {
okToAdd = true; okToAdd = true;
@ -371,10 +379,10 @@ public class ParserSymbolTable {
Declaration containing = (Declaration) _contextStack.peek(); Declaration containing = (Declaration) _contextStack.peek();
//handle enumerators //handle enumerators
if( obj.getType() == Declaration.t_enumerator ){ if( obj.getType() == TypeInfo.t_enumerator ){
//a using declaration of an enumerator will not be contained in a //a using declaration of an enumerator will not be contained in a
//enumeration. //enumeration.
if( containing.getType() == Declaration.t_enumeration ){ if( containing.getType() == TypeInfo.t_enumeration ){
//Following the closing brace of an enum-specifier, each enumerator has the type of its //Following the closing brace of an enum-specifier, each enumerator has the type of its
//enumeration //enumeration
obj.setTypeDeclaration( containing ); obj.setTypeDeclaration( containing );
@ -431,7 +439,8 @@ public class ParserSymbolTable {
} }
//take care of the this pointer //take care of the this pointer
if( obj.getType() == Declaration.t_function && !obj.isStatic() ){ TypeInfo type = obj._typeInfo;
if( type.isType( TypeInfo.t_function ) && !type.checkBit( TypeInfo.isStatic ) ){
addThis( obj ); addThis( obj );
} }
} }
@ -459,7 +468,7 @@ public class ParserSymbolTable {
Declaration decl = (Declaration) _contextStack.peek(); Declaration decl = (Declaration) _contextStack.peek();
Declaration containing = decl._containingScope; Declaration containing = decl._containingScope;
//find innermost enclosing namespace //find innermost enclosing namespace
while( containing != null && containing.getType() != Declaration.t_namespace ){ while( containing != null && containing.getType() != TypeInfo.t_namespace ){
containing = containing._containingScope; containing = containing._containingScope;
} }
@ -482,17 +491,18 @@ public class ParserSymbolTable {
* of this is volatile X*.... * of this is volatile X*....
*/ */
private void addThis( Declaration obj ) throws ParserSymbolTableException{ private void addThis( Declaration obj ) throws ParserSymbolTableException{
if( obj.getType() != Declaration.t_function || obj.isStatic() ){ TypeInfo type = obj._typeInfo;
if( !type.isType( TypeInfo.t_function ) || type.checkBit( TypeInfo.isStatic ) ){
return; return;
} }
if( obj._containingScope.isType( Declaration.t_class, Declaration.t_union ) ){ if( obj._containingScope.isType( TypeInfo.t_class, TypeInfo.t_union ) ){
//check to see if there is already a this object, since using declarations //check to see if there is already a this object, since using declarations
//of function will have them from the original declaration //of function will have them from the original declaration
LookupData data = new LookupData( "this", -1 ); LookupData data = new LookupData( "this", -1 );
if( LookupInContained( data, obj ) == null ){ if( LookupInContained( data, obj ) == null ){
Declaration thisObj = new Declaration("this"); Declaration thisObj = new Declaration("this");
thisObj.setType( Declaration.t_type ); thisObj.setType( TypeInfo.t_type );
thisObj.setTypeDeclaration( obj._containingScope ); thisObj.setTypeDeclaration( obj._containingScope );
thisObj.setCVQualifier( obj.getCVQualifier() ); thisObj.setCVQualifier( obj.getCVQualifier() );
thisObj.setPtrOperator("*"); thisObj.setPtrOperator("*");
@ -513,7 +523,7 @@ public class ParserSymbolTable {
*/ */
static private Declaration Lookup( LookupData data, Declaration inDeclaration ) throws ParserSymbolTableException static private Declaration Lookup( LookupData data, Declaration inDeclaration ) throws ParserSymbolTableException
{ {
if( data.type != -1 && data.type < Declaration.t_class && data.upperType > Declaration.t_union ){ if( data.type != -1 && data.type < TypeInfo.t_class && data.upperType > TypeInfo.t_union ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo ); throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
} }
@ -567,8 +577,8 @@ public class ParserSymbolTable {
} }
} }
decl = ResolveAmbiguities( data, foundNames ); decl = ResolveAmbiguities( data, new HashSet( foundNames ) );
if( decl != null ){ if( decl != null || data.stopAt == inDeclaration ){
return decl; return decl;
} }
@ -664,7 +674,7 @@ public class ParserSymbolTable {
* Look for data.name in our collection _containedDeclarations * Look for data.name in our collection _containedDeclarations
*/ */
private static Declaration LookupInContained( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{ private static Declaration LookupInContained( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{
LinkedList found = null; HashSet found = null;
Declaration temp = null; Declaration temp = null;
Object obj = null; Object obj = null;
@ -691,7 +701,7 @@ public class ParserSymbolTable {
return (Declaration) obj; return (Declaration) obj;
} }
} else { } else {
found = new LinkedList(); found = new HashSet();
LinkedList objList = (LinkedList)obj; LinkedList objList = (LinkedList)obj;
Iterator iter = objList.iterator(); Iterator iter = objList.iterator();
@ -776,7 +786,9 @@ public class ParserSymbolTable {
} else if ( temp != null ) { } else if ( temp != null ) {
//it is not ambiguous if temp & decl are the same thing and it is static //it is not ambiguous if temp & decl are the same thing and it is static
//or an enumerator //or an enumerator
if( decl == temp && ( temp.isStatic() || temp.getType() == Declaration.t_enumerator) ){ TypeInfo type = temp._typeInfo;
if( decl == temp && ( type.checkBit( TypeInfo.isStatic ) || type.isType( TypeInfo.t_enumerator ) ) ){
temp = null; temp = null;
} else { } else {
throw( new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ) ); throw( new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ) );
@ -807,8 +819,8 @@ public class ParserSymbolTable {
int origType = origDecl.getType(); int origType = origDecl.getType();
int newType = newDecl.getType(); int newType = newDecl.getType();
if( (origType >= Declaration.t_class && origType <= Declaration.t_enumeration) && //class name or enumeration ... if( (origType >= TypeInfo.t_class && origType <= TypeInfo.t_enumeration) && //class name or enumeration ...
( newType == Declaration.t_type || (newType >= Declaration.t_function && newType <= Declaration.typeMask) ) ){ ( newType == TypeInfo.t_type || (newType >= TypeInfo.t_function && newType <= TypeInfo.typeMask) ) ){
return true; return true;
} }
@ -825,13 +837,13 @@ public class ParserSymbolTable {
//the first thing can be a class-name or enumeration name, but the rest //the first thing can be a class-name or enumeration name, but the rest
//must be functions. So make sure the newDecl is a function before even //must be functions. So make sure the newDecl is a function before even
//considering the list //considering the list
if( newDecl.getType() != Declaration.t_function ){ if( newDecl.getType() != TypeInfo.t_function ){
return false; return false;
} }
Iterator iter = origList.iterator(); Iterator iter = origList.iterator();
Declaration decl = (Declaration) iter.next(); Declaration decl = (Declaration) iter.next();
boolean valid = (( decl.getType() >= Declaration.t_class && decl.getType() <= Declaration.t_enumeration ) || boolean valid = (( decl.getType() >= TypeInfo.t_class && decl.getType() <= TypeInfo.t_enumeration ) ||
isValidFunctionOverload( decl, newDecl )); isValidFunctionOverload( decl, newDecl ));
while( valid && iter.hasNext() ){ while( valid && iter.hasNext() ){
@ -847,14 +859,14 @@ public class ParserSymbolTable {
} }
private static boolean isValidFunctionOverload( Declaration origDecl, Declaration newDecl ){ private static boolean isValidFunctionOverload( Declaration origDecl, Declaration newDecl ){
if( origDecl.getType() != Declaration.t_function || newDecl.getType() != Declaration.t_function ){ if( origDecl.getType() != TypeInfo.t_function || newDecl.getType() != TypeInfo.t_function ){
return false; return false;
} }
if( origDecl.hasSameParameters( newDecl ) ){ if( origDecl.hasSameParameters( newDecl ) ){
//functions with the same name and same parameter types cannot be overloaded if any of them //functions with the same name and same parameter types cannot be overloaded if any of them
//is static //is static
if( origDecl.isStatic() || newDecl.isStatic() ){ if( origDecl._typeInfo.checkBit( TypeInfo.isStatic ) || newDecl._typeInfo.checkBit( TypeInfo.isStatic ) ){
return false; return false;
} }
@ -870,54 +882,197 @@ public class ParserSymbolTable {
return true; return true;
} }
static private Declaration ResolveAmbiguities( LookupData data, LinkedList items ) throws ParserSymbolTableException{ static private Declaration ResolveAmbiguities( LookupData data, HashSet items ) throws ParserSymbolTableException{
Declaration decl = null;
int size = items.size(); int size = items.size();
Iterator iter = items.iterator();
if( size == 0){ if( size == 0){
return null; return null;
} else if (size == 1) { } else if (size == 1) {
return (Declaration) items.getFirst(); return (Declaration) iter.next();
} else { } else {
Declaration first = (Declaration)items.removeFirst(); LinkedList functionList = null;
//if first one is a class-name, the next ones hide it Declaration decl = null;
if( first.getType() >= Declaration.t_class && first.getType() <= Declaration.t_enumeration ){ Declaration obj = null;
return ResolveAmbiguities( data, items ); Declaration cls = null;
}
//else, if the first is an object (ie not a function), the rest must be the same
//declaration. otherwise (ie it is a function), the rest must be functions.
boolean needSame = ( first.getType() != Declaration.t_function );
Iterator iter = items.iterator();
for( int i = (size - 1); i > 0; i-- ){
decl = (Declaration) iter.next();
if( needSame ){ for( int i = size; i > 0; i-- ){
if( decl != first ){ decl = (Declaration) iter.next();
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
if( decl.isType( TypeInfo.t_function ) ){
if( functionList == null){
functionList = new LinkedList();
} }
functionList.add( decl );
} else { } else {
if( decl.getType() != Declaration.t_function ){ //if this is a class-name, other stuff hides it
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ); if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
if( cls == null ) {
cls = decl;
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
}
} else {
//an object, can only have one of these
if( obj == null ){
obj = decl;
} else {
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
}
} }
} }
} }
if( needSame ){ int numFunctions = ( functionList == null ) ? 0 : functionList.size();
return first;
boolean ambiguous = false;
if( cls != null ){
//the class is only hidden by other stuff if they are from the same scope
if( obj != null && cls._containingScope != obj._containingScope ){
ambiguous = true;
}
if( functionList != null ){
Iterator fnIter = functionList.iterator();
Declaration fn = null;
for( int i = numFunctions; i > 0; i-- ){
fn = (Declaration) fnIter.next();
if( cls._containingScope != fn._containingScope ){
ambiguous = true;
break;
}
}
}
}
if( obj != null && !ambiguous ){
if( numFunctions > 0 ){
ambiguous = true;
} else {
return obj;
}
} else if( numFunctions > 0 ) {
return ResolveFunction( data, functionList );
}
if( ambiguous ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
} else { } else {
items.addFirst( first ); return cls;
return ResolveFunction( data, items );
} }
} }
} }
static private Declaration ResolveFunction( LookupData data, LinkedList functions ){ static private Declaration ResolveFunction( LookupData data, LinkedList functions ) throws ParserSymbolTableException{
ReduceToViable( data, functions );
int numSourceParams = ( data.parameters == null ) ? 0 : data.parameters.size();
int numFns = functions.size();
if( numSourceParams == 0 ){
//no parameters
//if there is only 1 viable function, return it, if more than one, its ambiguous
if( numFns == 0 ){
return null;
} else if ( numFns == 1 ){
return (Declaration)functions.getFirst();
} else{
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
}
}
Declaration bestFn = null; //the best function
Declaration currFn = null; //the function currently under consideration
int [] bestFnCost = null; //the cost of the best function
int [] currFnCost = null; //the cost for the current function
Iterator iterFns = functions.iterator();
Iterator sourceParams = null;
Iterator targetParams = null;
int numTargetParams = 0;
int numParams = 0;
int cost, temp, comparison;
TypeInfo source = null;
TypeInfo target = null;
for( int i = numFns; i > 0; i-- ){
currFn = (Declaration) iterFns.next();
sourceParams = data.parameters.iterator();
targetParams = currFn._parameters.iterator();
//number of parameters in the current function
numTargetParams = currFn._parameters.size();
//we only need to look at the smaller number of parameters
//(a larger number in the Target means default parameters, a larger
//number in the source means ellipses.)
numParams = ( numTargetParams < numSourceParams ) ? numTargetParams : numSourceParams;
if( currFnCost == null ){
currFnCost = new int [ numParams ];
}
comparison = 0;
for( int j = 0; j < numParams; j++ ){
source = ( TypeInfo )sourceParams.next();
target = ( TypeInfo )targetParams.next();
if( source.equals( target ) ){
cost = 0; //exact match, no cost
} else {
if( !canDoQualificationConversion( source, target ) ){
//matching qualification is at no cost, but not matching is a failure
cost = -1;
} else if( (temp = canPromote( source, target )) >= 0 ){
cost = temp;
} else if( (temp = canConvert( source, target )) >= 0 ){
cost = temp; //cost for conversion has to do with "distance" between source and target
} else {
cost = -1; //failure
}
}
currFnCost[ j ] = cost;
//compare successes against the best function
//comparison = (-1 = worse, 0 = same, 1 = better )
if( cost >= 0 ){
if( bestFnCost != null ){
if( cost < bestFnCost[ j ] ){
comparison = 1; //better
} else if ( cost > bestFnCost[ j ] ){
comparison = -1; //worse
break; //don't bother continuing if worse
}
} else {
comparison = 1;
}
} else {
comparison = -1;
}
}
if( comparison > 0){
//the current function is better than the previous best
bestFnCost = currFnCost;
currFnCost = null;
bestFn = currFn;
} else if( comparison == 0 ){
//this is just as good as the best one, which means the best one isn't the best
bestFn = null;
}
}
return bestFn;
}
static private void ReduceToViable( LookupData data, LinkedList functions ){
int numParameters = ( data.parameters == null ) ? 0 : data.parameters.size(); int numParameters = ( data.parameters == null ) ? 0 : data.parameters.size();
int num; int num;
@ -931,7 +1086,7 @@ public class ParserSymbolTable {
//if there are m arguments in the list, all candidate functions having m parameters //if there are m arguments in the list, all candidate functions having m parameters
//are viable //are viable
if( num == numParameters ){ if( num == numParameters ){
continue; continue;
} }
//A candidate function having fewer than m parameters is viable only if it has an //A candidate function having fewer than m parameters is viable only if it has an
//ellipsis in its parameter list. //ellipsis in its parameter list.
@ -943,31 +1098,19 @@ public class ParserSymbolTable {
//a candidate function having more than m parameters is viable only if the (m+1)-st //a candidate function having more than m parameters is viable only if the (m+1)-st
//parameter has a default argument //parameter has a default argument
else { else {
ListIterator listIter = function._parameters.listIterator( num - 1 ); ListIterator listIter = function._parameters.listIterator( num );
Declaration.ParameterInfo param; TypeInfo param;
for( int i = num; i > ( numParameters - num ); i-- ){ for( int i = num; i > ( numParameters - num + 1); i-- ){
param = (Declaration.ParameterInfo)listIter.previous(); param = (TypeInfo)listIter.previous();
if( !param.hasDefaultValue ){ if( !param.getHasDefault() ){
iter.remove(); iter.remove();
break; break;
} }
} }
} }
} }
//TBD, rank implicit conversion sequences to determine which one is best.
int size = functions.size();
if( size == 0 ){
return null;
}
else if( size == 1) {
return (Declaration) functions.getFirst();
}
return null;
} }
/** /**
* function ProcessDirectives * function ProcessDirectives
* @param Declaration decl * @param Declaration decl
@ -1044,13 +1187,20 @@ public class ParserSymbolTable {
* *
* @param obj * @param obj
* @param base * @param base
* @return boolean * @return int
* figure out if base is a base class of obj. * figure out if base is a base class of obj, and return the "distance" to
* the base class.
* ie:
* A -> B -> C
* the distance from A to B is 1 and from A to C is 2. This distance is used
* to rank standard pointer conversions.
* *
* TBD: Consider rewriting iteratively for performance. * TBD: Consider rewriting iteratively for performance.
*/ */
static private boolean hasBaseClass( Declaration obj, Declaration base ){ static private int hasBaseClass( Declaration obj, Declaration base ){
boolean isABaseClass = false; if( obj == base ){
return 0;
}
if( obj._parentScopes != null ){ if( obj._parentScopes != null ){
Declaration decl; Declaration decl;
@ -1063,13 +1213,19 @@ public class ParserSymbolTable {
wrapper = (Declaration.ParentWrapper) iter.next(); wrapper = (Declaration.ParentWrapper) iter.next();
decl = wrapper.parent; decl = wrapper.parent;
if( decl == base || hasBaseClass( decl, base ) ){ if( decl == base ){
return true; return 1;
} else {
int n = hasBaseClass( decl, base );
if( n > 0 ){
return n + 1;
}
} }
} }
} }
return false; return -1;
} }
static private void getAssociatedScopes( Declaration decl, HashSet associated ){ static private void getAssociatedScopes( Declaration decl, HashSet associated ){
@ -1079,14 +1235,14 @@ public class ParserSymbolTable {
//if T is a class type, its associated classes are the class itself, //if T is a class type, its associated classes are the class itself,
//and its direct and indirect base classes. its associated Namespaces are the //and its direct and indirect base classes. its associated Namespaces are the
//namespaces in which its associated classes are defined //namespaces in which its associated classes are defined
if( decl.getType() == Declaration.t_class ){ if( decl.getType() == TypeInfo.t_class ){
associated.add( decl ); associated.add( decl );
getBaseClassesAndContainingNamespaces( decl, associated ); getBaseClassesAndContainingNamespaces( decl, associated );
} }
//if T is a union or enumeration type, its associated namespace is the namespace in //if T is a union or enumeration type, its associated namespace is the namespace in
//which it is defined. if it is a class member, its associated class is the member's //which it is defined. if it is a class member, its associated class is the member's
//class //class
else if( decl.getType() == Declaration.t_union || decl.getType() == Declaration.t_enumeration ){ else if( decl.getType() == TypeInfo.t_union || decl.getType() == TypeInfo.t_enumeration ){
associated.add( decl._containingScope ); associated.add( decl._containingScope );
} }
} }
@ -1099,12 +1255,14 @@ public class ParserSymbolTable {
Iterator iter = obj._parentScopes.iterator(); Iterator iter = obj._parentScopes.iterator();
int size = obj._parentScopes.size(); int size = obj._parentScopes.size();
Declaration.ParentWrapper wrapper;
Declaration base; Declaration base;
for( int i = size; i > 0; i-- ){ for( int i = size; i > 0; i-- ){
base = (Declaration) iter.next(); wrapper = (Declaration.ParentWrapper) iter.next();
base = (Declaration) wrapper.parent;
classes.add( base ); classes.add( base );
if( base._containingScope.getType() == Declaration.t_namespace ){ if( base._containingScope.getType() == TypeInfo.t_namespace ){
classes.add( base._containingScope ); classes.add( base._containingScope );
} }
@ -1113,6 +1271,117 @@ public class ParserSymbolTable {
} }
} }
/**
*
* @param source
* @param target
* @return int
*
* 4.5-1 char, signed char, unsigned char, short int or unsigned short int
* can be converted to int if int can represent all the values of the source
* type, otherwise they can be converted to unsigned int.
* 4.5-2 wchar_t or an enumeration can be converted to the first of the
* following that can hold it: int, unsigned int, long unsigned long.
* 4.5-4 bool can be promoted to int
* 4.6 float can be promoted to double
*/
static private int canPromote( TypeInfo source, TypeInfo target ){
//if they are the same, no promotion is necessary
if( ( source.isType( TypeInfo.t_bool, TypeInfo.t_double ) ||
source.isType( TypeInfo.t_enumeration ) ) &&
source.getType() == target.getType() )
{
return 0;
}
if( source.isType( TypeInfo.t_enumeration ) || source.isType( TypeInfo.t_bool, TypeInfo.t_int ) ){
if( target.isType( TypeInfo.t_int ) && target.canHold( source ) ){
return 1;
}
} else if( source.isType( TypeInfo.t_float ) ){
if( target.isType( TypeInfo.t_double ) ){
return 1;
}
}
return -1;
}
/**
*
* @param source
* @param target
* @return int
*
*/
static private int canConvert(TypeInfo source, TypeInfo target ){
int temp = 0;
//are they the same?
if( source.getType() == target.getType() &&
source.getTypeDeclaration() == target.getTypeDeclaration() )
{
return 0;
}
//no go if they have different pointer qualification
if( ! source.getPtrOperator().equals( target.getPtrOperator() ) ){
return -1;
}
//TBD, do a better check on the kind of ptrOperator
if( !source.getPtrOperator().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 ) ||
source.isType( TypeInfo.t_float, TypeInfo.t_double ) ||
source.isType( TypeInfo.t_enumeration ) )
{
if( target.isType( TypeInfo.t_bool, TypeInfo.t_int ) ||
target.isType( TypeInfo.t_float, TypeInfo.t_double ) )
{
return 2;
}
}
} else /*pointers*/ {
Declaration sourceDecl = source.getTypeDeclaration();
Declaration targetDecl = target.getTypeDeclaration();
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
//converted to an rvalue of type "pointer to cv void"
if( source.isType( TypeInfo.t_type ) && target.isType( TypeInfo.t_void ) ){
//use cost of MAX_VALUE since conversion to any base class, no matter how
//far away, would be better than conversion to void
return Integer.MAX_VALUE;
}
//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
// to an rvalue of type "pointer to cv B", where B is a base class of D.
else if( source.isType( TypeInfo.t_type ) && sourceDecl.isType( TypeInfo.t_class ) &&
target.isType( TypeInfo.t_type ) && targetDecl.isType( TypeInfo.t_class ) )
{
temp = hasBaseClass( sourceDecl, targetDecl );
return ( temp > -1 ) ? 1 + temp : -1;
}
//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type,
//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
//derived class of B
else if( ( source.isType( TypeInfo.t_type ) && sourceDecl._containingScope.isType( TypeInfo.t_class ) ) ||
( target.isType( TypeInfo.t_type ) && targetDecl._containingScope.isType( TypeInfo.t_class ) ) )
{
temp = hasBaseClass( targetDecl._containingScope, sourceDecl._containingScope );
return ( temp > -1 ) ? 1 + temp : -1;
}
}
return -1;
}
static private boolean canDoQualificationConversion( TypeInfo source, TypeInfo target ){
return ( source.getCVQualifier() == source.getCVQualifier() ||
(source.getCVQualifier() - source.getCVQualifier()) > 1 );
}
private Stack _contextStack = new Stack(); private Stack _contextStack = new Stack();
private Declaration _compilationUnit; private Declaration _compilationUnit;

View file

@ -0,0 +1,196 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.util;
import org.eclipse.cdt.internal.core.parser.Declaration;
import org.eclipse.cdt.internal.core.parser.ParserSymbolTableException;
/**
* @author aniefer
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/
public class TypeInfo{
public TypeInfo(){
super();
}
public TypeInfo( int type, Declaration decl ){
super();
_typeInfo = type;
_typeDeclaration = decl;
}
public TypeInfo( int type, Declaration decl, int cvQualifier, String ptrOp, boolean hasDefault ){
super();
_typeInfo = type;
_typeDeclaration = decl;
_cvQualifier = cvQualifier;
_ptrOperator = ptrOp;
_hasDefaultValue = hasDefault;
}
public static final int typeMask = 0x001f;
public static final int isAuto = 0x0020;
public static final int isRegister = 0x0040;
public static final int isStatic = 0x0080;
public static final int isExtern = 0x0100;
public static final int isMutable = 0x0200;
public static final int isInline = 0x0400;
public static final int isVirtual = 0x0800;
public static final int isExplicit = 0x1000;
public static final int isTypedef = 0x2000;
public static final int isFriend = 0x4000;
public static final int isConst = 0x8000;
public static final int isVolatile = 0x10000;
public static final int isUnsigned = 0x20000;
public static final int isShort = 0x40000;
public static final int isLong = 0x80000;
// 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;
//Partial ordering :
// none < const
// none < volatile
// none < const volatile
// const < const volatile
// volatile < const volatile
public static final int cvConst = 1;
public static final int cvVolatile = 2;
public static final int cvConstVolatile = 4;
// Convenience methods
public void setBit(boolean b, int mask){
if( b ){
_typeInfo = _typeInfo | mask;
} else {
_typeInfo = _typeInfo & ~mask;
}
}
public boolean checkBit(int mask){
return (_typeInfo & mask) != 0;
}
public void setType(int t) throws ParserSymbolTableException{
//sanity check, t must fit in its allocated 5 bits in _typeInfo
if( t > typeMask ){
throw new ParserSymbolTableException( ParserSymbolTableException.r_BadTypeInfo );
}
_typeInfo = _typeInfo & ~typeMask | t;
}
public int getType(){
return _typeInfo & typeMask;
}
public boolean isType( int type ){
return isType( type, 0 );
}
/**
*
* @param type
* @param upperType
* @return boolean
*
* type checking, check that this declaration's type is between type and
* upperType (inclusive). upperType of 0 means no range and our type must
* be type.
*/
public boolean isType( int type, int upperType ){
//type of -1 means we don't care
if( type == -1 )
return true;
//upperType of 0 means no range
if( upperType == 0 ){
return ( getType() == type );
} else {
return ( getType() >= type && getType() <= upperType );
}
}
public Declaration getTypeDeclaration(){
return _typeDeclaration;
}
public void setTypeDeclaration( Declaration type ){
_typeDeclaration = type;
}
public int getCVQualifier(){
return _cvQualifier;
}
public void setCVQualifier( int cv ){
_cvQualifier = cv;
}
public String getPtrOperator(){
return _ptrOperator;
}
public void setPtrOperator( String ptr ){
_ptrOperator = ptr;
}
public boolean getHasDefault(){
return _hasDefaultValue;
}
public void setHasDefault( boolean def ){
_hasDefaultValue = def;
}
/**
* canHold
* @param type
* @return boolean
* return true is the our type can hold all the values of the passed in
* type.
* TBD, for now return true if our type is "larger" (based on ordering of
* the type values)
*/
public boolean canHold( TypeInfo type ){
return getType() >= type.getType();
}
private int _typeInfo = 0;
private Declaration _typeDeclaration;
private int _cvQualifier = 0;
private boolean _hasDefaultValue = false;
private String _ptrOperator;
}

View file

@ -1,3 +1,8 @@
2003-03-26 Andrew Niefer
In ParserSymbolTableTest :
updated all tests to reflect TypeInfo changes
Added testFunctionResolution() & testFunctionResolution_2() in
2003-03-25 John Camelon 2003-03-25 John Camelon
Added testDeclSpecifier(), testNamespaceDefinition(), testLinkageSpecification(), Added testDeclSpecifier(), testNamespaceDefinition(), testLinkageSpecification(),
testUsingClauses() and testEnumSpecifier() to DOMTests. testUsingClauses() and testEnumSpecifier() to DOMTests.

View file

@ -20,6 +20,7 @@ import junit.framework.TestCase;
import org.eclipse.cdt.internal.core.parser.Declaration; import org.eclipse.cdt.internal.core.parser.Declaration;
import org.eclipse.cdt.internal.core.parser.ParserSymbolTable; import org.eclipse.cdt.internal.core.parser.ParserSymbolTable;
import org.eclipse.cdt.internal.core.parser.ParserSymbolTableException; import org.eclipse.cdt.internal.core.parser.ParserSymbolTableException;
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
/** /**
* @author aniefer * @author aniefer
@ -379,13 +380,13 @@ public class ParserSymbolTableTest extends TestCase {
table.addDeclaration( d ); table.addDeclaration( d );
Declaration enum = new Declaration("enum"); Declaration enum = new Declaration("enum");
enum.setType( Declaration.t_enumeration ); enum.setType( TypeInfo.t_enumeration );
Declaration enumerator = new Declaration( "enumerator" ); Declaration enumerator = new Declaration( "enumerator" );
enumerator.setType( Declaration.t_enumerator ); enumerator.setType( TypeInfo.t_enumerator );
Declaration stat = new Declaration("static"); Declaration stat = new Declaration("static");
stat.setStatic(true); stat.getTypeInfo().setBit( true, TypeInfo.isStatic );
Declaration x = new Declaration("x"); Declaration x = new Declaration("x");
@ -438,13 +439,13 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration cls = new Declaration( "class" ); Declaration cls = new Declaration( "class" );
cls.setType( Declaration.t_class ); cls.setType( TypeInfo.t_class );
Declaration struct = new Declaration("struct"); Declaration struct = new Declaration("struct");
struct.setType( Declaration.t_struct ); struct.setType( TypeInfo.t_struct );
Declaration union = new Declaration("union"); Declaration union = new Declaration("union");
union.setType( Declaration.t_union ); union.setType( TypeInfo.t_union );
Declaration hideCls = new Declaration( "class" ); Declaration hideCls = new Declaration( "class" );
Declaration hideStruct = new Declaration("struct"); Declaration hideStruct = new Declaration("struct");
@ -466,11 +467,11 @@ public class ParserSymbolTableTest extends TestCase {
table.addDeclaration(union); table.addDeclaration(union);
table.pop(); table.pop();
Declaration look = table.ElaboratedLookup( Declaration.t_class, "class" ); Declaration look = table.ElaboratedLookup( TypeInfo.t_class, "class" );
assertEquals( look, cls ); assertEquals( look, cls );
look = table.ElaboratedLookup( Declaration.t_struct, "struct" ); look = table.ElaboratedLookup( TypeInfo.t_struct, "struct" );
assertEquals( look, struct ); assertEquals( look, struct );
look = table.ElaboratedLookup( Declaration.t_union, "union" ); look = table.ElaboratedLookup( TypeInfo.t_union, "union" );
assertEquals( look, union ); assertEquals( look, union );
} }
@ -528,19 +529,19 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration struct = new Declaration( "stat"); Declaration struct = new Declaration( "stat");
struct.setType( Declaration.t_struct ); struct.setType( TypeInfo.t_struct );
table.addDeclaration( struct ); table.addDeclaration( struct );
Declaration function = new Declaration( "stat" ); Declaration function = new Declaration( "stat" );
function.setType( Declaration.t_function ); function.setType( TypeInfo.t_function );
table.addDeclaration( function ); table.addDeclaration( function );
Declaration f = new Declaration("f"); Declaration f = new Declaration("f");
f.setType( Declaration.t_function ); f.setType( TypeInfo.t_function );
table.addDeclaration( f ); table.addDeclaration( f );
table.push( f ); table.push( f );
Declaration look = table.ElaboratedLookup( Declaration.t_struct, "stat" ); Declaration look = table.ElaboratedLookup( TypeInfo.t_struct, "stat" );
assertEquals( look, struct ); assertEquals( look, struct );
look = table.Lookup( "stat" ); look = table.Lookup( "stat" );
@ -582,7 +583,7 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsA = new Declaration("A"); Declaration nsA = new Declaration("A");
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
table.push( nsA ); table.push( nsA );
@ -590,12 +591,12 @@ public class ParserSymbolTableTest extends TestCase {
table.addDeclaration( nsA_i ); table.addDeclaration( nsA_i );
Declaration nsB = new Declaration("B"); Declaration nsB = new Declaration("B");
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
Declaration nsC = new Declaration("C"); Declaration nsC = new Declaration("C");
nsC.setType( Declaration.t_namespace ); nsC.setType( TypeInfo.t_namespace );
table.addDeclaration( nsC ); table.addDeclaration( nsC );
table.push( nsC ); table.push( nsC );
@ -607,7 +608,7 @@ public class ParserSymbolTableTest extends TestCase {
table.addUsingDirective( look ); table.addUsingDirective( look );
Declaration f1 = new Declaration("f"); Declaration f1 = new Declaration("f");
f1.setType( Declaration.t_function ); f1.setType( TypeInfo.t_function );
table.push( f1 ); table.push( f1 );
look = table.Lookup( "i" ); look = table.Lookup( "i" );
@ -619,7 +620,7 @@ public class ParserSymbolTableTest extends TestCase {
assertEquals( table.peek(), nsA ); assertEquals( table.peek(), nsA );
Declaration nsD = new Declaration("D"); Declaration nsD = new Declaration("D");
nsD.setType( Declaration.t_namespace ); nsD.setType( TypeInfo.t_namespace );
table.addDeclaration( nsD ); table.addDeclaration( nsD );
table.push( nsD ); table.push( nsD );
@ -632,7 +633,7 @@ public class ParserSymbolTableTest extends TestCase {
table.addUsingDirective( look ); table.addUsingDirective( look );
Declaration f2 = new Declaration( "f2" ); Declaration f2 = new Declaration( "f2" );
f2.setType( Declaration.t_function ); f2.setType( TypeInfo.t_function );
table.addDeclaration( f2 ); table.addDeclaration( f2 );
table.push( f2 ); table.push( f2 );
@ -650,7 +651,7 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); //end nsD table.pop(); //end nsD
Declaration f3 = new Declaration ("f3"); Declaration f3 = new Declaration ("f3");
f3.setType( Declaration.t_function ); f3.setType( TypeInfo.t_function );
table.addDeclaration( f3 ); table.addDeclaration( f3 );
table.push( f3 ); table.push( f3 );
@ -661,7 +662,7 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration f4 = new Declaration ("f4"); Declaration f4 = new Declaration ("f4");
f4.setType( Declaration.t_function ); f4.setType( TypeInfo.t_function );
table.addDeclaration( f4 ); table.addDeclaration( f4 );
table.push( f4 ); table.push( f4 );
@ -693,7 +694,7 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsM = new Declaration( "M" ); Declaration nsM = new Declaration( "M" );
nsM.setType( Declaration.t_namespace ); nsM.setType( TypeInfo.t_namespace );
table.addDeclaration( nsM ); table.addDeclaration( nsM );
@ -703,7 +704,7 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration nsN = new Declaration( "N" ); Declaration nsN = new Declaration( "N" );
nsN.setType( Declaration.t_namespace ); nsN.setType( TypeInfo.t_namespace );
table.addDeclaration( nsN ); table.addDeclaration( nsN );
@ -765,7 +766,7 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsA = new Declaration("A"); Declaration nsA = new Declaration("A");
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
table.push( nsA ); table.push( nsA );
@ -774,21 +775,21 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration nsB = new Declaration("B"); Declaration nsB = new Declaration("B");
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
table.addUsingDirective( nsA ); table.addUsingDirective( nsA );
table.pop(); table.pop();
Declaration nsC = new Declaration("C"); Declaration nsC = new Declaration("C");
nsC.setType( Declaration.t_namespace ); nsC.setType( TypeInfo.t_namespace );
table.addDeclaration( nsC ); table.addDeclaration( nsC );
table.push( nsC ); table.push( nsC );
table.addUsingDirective( nsA ); table.addUsingDirective( nsA );
table.pop(); table.pop();
Declaration nsBC = new Declaration("BC"); Declaration nsBC = new Declaration("BC");
nsBC.setType( Declaration.t_namespace ); nsBC.setType( TypeInfo.t_namespace );
table.addDeclaration( nsBC ); table.addDeclaration( nsBC );
table.push( nsBC ); table.push( nsBC );
table.addUsingDirective( nsB ); table.addUsingDirective( nsB );
@ -796,7 +797,7 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration f = new Declaration("f"); Declaration f = new Declaration("f");
f.setType(Declaration.t_function); f.setType(TypeInfo.t_function);
table.addDeclaration( f ); table.addDeclaration( f );
table.push(f); table.push(f);
@ -834,7 +835,7 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsB = new Declaration( "B" ); Declaration nsB = new Declaration( "B" );
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
@ -843,7 +844,7 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration nsA = new Declaration( "A" ); Declaration nsA = new Declaration( "A" );
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
table.push( nsA ); table.push( nsA );
@ -908,11 +909,11 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsA = new Declaration( "A" ); Declaration nsA = new Declaration( "A" );
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
Declaration nsB = new Declaration( "B" ); Declaration nsB = new Declaration( "B" );
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
table.addUsingDirective( nsA ); table.addUsingDirective( nsA );
@ -961,39 +962,39 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsA = new Declaration("A"); Declaration nsA = new Declaration("A");
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
table.push( nsA ); table.push( nsA );
Declaration structX = new Declaration("x"); Declaration structX = new Declaration("x");
structX.setType( Declaration.t_struct ); structX.setType( TypeInfo.t_struct );
table.addDeclaration( structX ); table.addDeclaration( structX );
Declaration intX = new Declaration("x"); Declaration intX = new Declaration("x");
intX.setType( Declaration.t_int ); intX.setType( TypeInfo.t_int );
table.addDeclaration( intX ); table.addDeclaration( intX );
Declaration intY = new Declaration("y"); Declaration intY = new Declaration("y");
intY.setType( Declaration.t_int ); intY.setType( TypeInfo.t_int );
table.addDeclaration( intY ); table.addDeclaration( intY );
table.pop(); table.pop();
Declaration nsB = new Declaration("B"); Declaration nsB = new Declaration("B");
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
Declaration structY = new Declaration("y"); Declaration structY = new Declaration("y");
structY.setType( Declaration.t_struct ); structY.setType( TypeInfo.t_struct );
table.addDeclaration( structY ); table.addDeclaration( structY );
table.pop(); table.pop();
Declaration nsC = new Declaration("C"); Declaration nsC = new Declaration("C");
nsC.setType( Declaration.t_namespace); nsC.setType( TypeInfo.t_namespace);
table.addDeclaration( nsC ); table.addDeclaration( nsC );
table.push( nsC ); table.push( nsC );
@ -1044,17 +1045,17 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration nsA = new Declaration( "A" ); Declaration nsA = new Declaration( "A" );
nsA.setType( Declaration.t_namespace ); nsA.setType( TypeInfo.t_namespace );
table.addDeclaration( nsA ); table.addDeclaration( nsA );
table.push( nsA ); table.push( nsA );
Declaration nsB = new Declaration( "B" ); Declaration nsB = new Declaration( "B" );
nsB.setType( Declaration.t_namespace ); nsB.setType( TypeInfo.t_namespace );
table.addDeclaration( nsB ); table.addDeclaration( nsB );
table.push( nsB ); table.push( nsB );
Declaration f1 = new Declaration("f1"); Declaration f1 = new Declaration("f1");
f1.setType( Declaration.t_function ); f1.setType( TypeInfo.t_function );
table.addDeclaration( f1 ); table.addDeclaration( f1 );
table.pop(); table.pop();
@ -1102,21 +1103,21 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration B = new Declaration("B"); Declaration B = new Declaration("B");
B.setType( Declaration.t_struct ); B.setType( TypeInfo.t_struct );
table.addDeclaration( B ); table.addDeclaration( B );
table.push( B ); table.push( B );
Declaration f = new Declaration("f"); Declaration f = new Declaration("f");
f.setType( Declaration.t_function ); f.setType( TypeInfo.t_function );
table.addDeclaration( f ); table.addDeclaration( f );
Declaration E = new Declaration( "E" ); Declaration E = new Declaration( "E" );
E.setType( Declaration.t_enumeration ); E.setType( TypeInfo.t_enumeration );
table.addDeclaration( E ); table.addDeclaration( E );
table.push( E ); table.push( E );
Declaration e = new Declaration( "e" ); Declaration e = new Declaration( "e" );
e.setType( Declaration.t_enumerator ); e.setType( TypeInfo.t_enumerator );
table.addDeclaration( e ); table.addDeclaration( e );
table.pop(); table.pop();
@ -1125,17 +1126,17 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration C = new Declaration( "C" ); Declaration C = new Declaration( "C" );
C.setType( Declaration.t_class ); C.setType( TypeInfo.t_class );
table.addDeclaration( C ); table.addDeclaration( C );
table.push( C ); table.push( C );
Declaration g = new Declaration( "g" ); Declaration g = new Declaration( "g" );
g.setType( Declaration.t_function ); g.setType( TypeInfo.t_function );
table.addDeclaration( g ); table.addDeclaration( g );
table.pop(); table.pop();
Declaration D = new Declaration( "D" ); Declaration D = new Declaration( "D" );
D.setType( Declaration.t_struct ); D.setType( TypeInfo.t_struct );
Declaration look = table.Lookup( "B" ); Declaration look = table.Lookup( "B" );
assertEquals( look, B ); assertEquals( look, B );
D.addParent( look ); D.addParent( look );
@ -1212,15 +1213,15 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration A = new Declaration( "A" ); Declaration A = new Declaration( "A" );
A.setType( Declaration.t_namespace ); A.setType( TypeInfo.t_namespace );
table.addDeclaration( A ); table.addDeclaration( A );
table.push( A ); table.push( A );
Declaration f1 = new Declaration( "f" ); Declaration f1 = new Declaration( "f" );
f1.setType( Declaration.t_function ); f1.setType( TypeInfo.t_function );
f1.setReturnType( Declaration.t_void ); f1.setReturnType( TypeInfo.t_void );
f1.addParameter( Declaration.t_int, "", false ); f1.addParameter( TypeInfo.t_int, 0, "", false );
table.addDeclaration( f1 ); table.addDeclaration( f1 );
table.pop(); table.pop();
@ -1239,21 +1240,20 @@ public class ParserSymbolTableTest extends TestCase {
table.push( look ); table.push( look );
Declaration f2 = new Declaration("f"); Declaration f2 = new Declaration("f");
f2.setType( Declaration.t_function ); f2.setType( TypeInfo.t_function );
f2.setReturnType( Declaration.t_void ); f2.setReturnType( TypeInfo.t_void );
f2.addParameter( Declaration.t_char, "", false ); f2.addParameter( TypeInfo.t_char, 0, "", false );
table.addDeclaration( f2 ); table.addDeclaration( f2 );
table.pop(); table.pop();
Declaration foo = new Declaration("foo"); Declaration foo = new Declaration("foo");
foo.setType( Declaration.t_function ); foo.setType( TypeInfo.t_function );
table.addDeclaration( foo ); table.addDeclaration( foo );
table.push( foo ); table.push( foo );
LinkedList paramList = new LinkedList(); LinkedList paramList = new LinkedList();
Declaration.ParameterInfo param = foo.new ParameterInfo(); TypeInfo param = new TypeInfo( TypeInfo.t_char, null );
param.typeInfo = Declaration.t_char;
paramList.add( param ); paramList.add( param );
look = table.UnqualifiedFunctionLookup( "f", paramList ); look = table.UnqualifiedFunctionLookup( "f", paramList );
@ -1273,11 +1273,11 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration cls = new Declaration("class"); Declaration cls = new Declaration("class");
cls.setType( Declaration.t_class ); cls.setType( TypeInfo.t_class );
Declaration fn = new Declaration("function"); Declaration fn = new Declaration("function");
fn.setType( Declaration.t_function ); fn.setType( TypeInfo.t_function );
fn.setCVQualifier("const"); fn.setCVQualifier( TypeInfo.cvConst );
table.addDeclaration( cls ); table.addDeclaration( cls );
table.push( cls ); table.push( cls );
@ -1288,7 +1288,7 @@ public class ParserSymbolTableTest extends TestCase {
Declaration look = table.Lookup("this"); Declaration look = table.Lookup("this");
assertTrue( look != null ); assertTrue( look != null );
assertEquals( look.getType(), Declaration.t_type ); assertEquals( look.getType(), TypeInfo.t_type );
assertEquals( look.getTypeDeclaration(), cls ); assertEquals( look.getTypeDeclaration(), cls );
assertEquals( look.getPtrOperator(), "*" ); assertEquals( look.getPtrOperator(), "*" );
assertEquals( look.getCVQualifier(), fn.getCVQualifier() ); assertEquals( look.getCVQualifier(), fn.getCVQualifier() );
@ -1307,10 +1307,10 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration cls = new Declaration("class"); Declaration cls = new Declaration("class");
cls.setType( Declaration.t_class ); cls.setType( TypeInfo.t_class );
Declaration enumeration = new Declaration("enumeration"); Declaration enumeration = new Declaration("enumeration");
enumeration.setType( Declaration.t_enumeration ); enumeration.setType( TypeInfo.t_enumeration );
table.addDeclaration( cls ); table.addDeclaration( cls );
table.push( cls ); table.push( cls );
@ -1318,7 +1318,7 @@ public class ParserSymbolTableTest extends TestCase {
table.push( enumeration ); table.push( enumeration );
Declaration enumerator = new Declaration( "enumerator" ); Declaration enumerator = new Declaration( "enumerator" );
enumerator.setType( Declaration.t_enumerator ); enumerator.setType( TypeInfo.t_enumerator );
table.addDeclaration( enumerator ); table.addDeclaration( enumerator );
table.pop(); table.pop();
@ -1346,23 +1346,23 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration NS = new Declaration("NS"); Declaration NS = new Declaration("NS");
NS.setType( Declaration.t_namespace ); NS.setType( TypeInfo.t_namespace );
table.addDeclaration( NS ); table.addDeclaration( NS );
table.push( NS ); table.push( NS );
Declaration T = new Declaration("T"); Declaration T = new Declaration("T");
T.setType( Declaration.t_class ); T.setType( TypeInfo.t_class );
table.addDeclaration( T ); table.addDeclaration( T );
Declaration f = new Declaration("f"); Declaration f = new Declaration("f");
f.setType( Declaration.t_function ); f.setType( TypeInfo.t_function );
f.setReturnType( Declaration.t_void ); f.setReturnType( TypeInfo.t_void );
Declaration look = table.Lookup( "T" ); Declaration look = table.Lookup( "T" );
assertEquals( look, T ); assertEquals( look, T );
f.addParameter( look, "", false ); f.addParameter( look, 0, "", false );
table.addDeclaration( f ); table.addDeclaration( f );
@ -1376,13 +1376,13 @@ public class ParserSymbolTableTest extends TestCase {
table.pop(); table.pop();
Declaration param = new Declaration("parm"); Declaration param = new Declaration("parm");
param.setType( Declaration.t_type ); param.setType( TypeInfo.t_type );
param.setTypeDeclaration( look ); param.setTypeDeclaration( look );
table.addDeclaration( param ); table.addDeclaration( param );
Declaration main = new Declaration("main"); Declaration main = new Declaration("main");
main.setType( Declaration.t_function ); main.setType( TypeInfo.t_function );
main.setReturnType( Declaration.t_int ); main.setReturnType( TypeInfo.t_int );
table.addDeclaration( main ); table.addDeclaration( main );
table.push( main ); table.push( main );
@ -1390,11 +1390,7 @@ public class ParserSymbolTableTest extends TestCase {
look = table.Lookup( "parm" ); look = table.Lookup( "parm" );
assertEquals( look, param ); assertEquals( look, param );
Declaration.ParameterInfo p = look.new ParameterInfo(); paramList.add( look.getTypeInfo() );
p.typeInfo = look.getType();
p.typeDeclaration = look.getTypeDeclaration();
paramList.add( p );
look = table.UnqualifiedFunctionLookup( "f", paramList ); look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f ); assertEquals( look, f );
@ -1427,20 +1423,20 @@ public class ParserSymbolTableTest extends TestCase {
newTable(); newTable();
Declaration NS1 = new Declaration( "NS1" ); Declaration NS1 = new Declaration( "NS1" );
NS1.setType( Declaration.t_namespace ); NS1.setType( TypeInfo.t_namespace );
table.addDeclaration( NS1 ); table.addDeclaration( NS1 );
table.push( NS1 ); table.push( NS1 );
Declaration f1 = new Declaration( "f" ); Declaration f1 = new Declaration( "f" );
f1.setType( Declaration.t_function ); f1.setType( TypeInfo.t_function );
f1.setReturnType( Declaration.t_void ); f1.setReturnType( TypeInfo.t_void );
f1.addParameter( Declaration.t_void, "*", false ); f1.addParameter( TypeInfo.t_void, 0, "*", false );
table.addDeclaration( f1 ); table.addDeclaration( f1 );
table.pop(); table.pop();
Declaration NS2 = new Declaration( "NS2" ); Declaration NS2 = new Declaration( "NS2" );
NS2.setType( Declaration.t_namespace ); NS2.setType( TypeInfo.t_namespace );
table.addDeclaration( NS2 ); table.addDeclaration( NS2 );
table.push( NS2 ); table.push( NS2 );
@ -1450,18 +1446,18 @@ public class ParserSymbolTableTest extends TestCase {
table.addUsingDirective( look ); table.addUsingDirective( look );
Declaration B = new Declaration( "B" ); Declaration B = new Declaration( "B" );
B.setType( Declaration.t_class ); B.setType( TypeInfo.t_class );
table.addDeclaration( B ); table.addDeclaration( B );
Declaration f2 = new Declaration( "f" ); Declaration f2 = new Declaration( "f" );
f2.setType( Declaration.t_function ); f2.setType( TypeInfo.t_function );
f2.setReturnType( Declaration.t_void ); f2.setReturnType( TypeInfo.t_void );
f2.addParameter( Declaration.t_void, "*", false ); f2.addParameter( TypeInfo.t_void, 0, "*", false );
table.addDeclaration( f2 ); table.addDeclaration( f2 );
table.pop(); table.pop();
Declaration A = new Declaration( "A" ); Declaration A = new Declaration( "A" );
A.setType( Declaration.t_class ); A.setType( TypeInfo.t_class );
look = table.LookupNestedNameSpecifier( "NS2" ); look = table.LookupNestedNameSpecifier( "NS2" );
assertEquals( look, NS2 ); assertEquals( look, NS2 );
table.push( look ); table.push( look );
@ -1474,14 +1470,14 @@ public class ParserSymbolTableTest extends TestCase {
look = table.Lookup( "A" ); look = table.Lookup( "A" );
assertEquals( look, A ); assertEquals( look, A );
Declaration a = new Declaration( "a" ); Declaration a = new Declaration( "a" );
a.setType( Declaration.t_type ); a.setType( TypeInfo.t_type );
a.setTypeDeclaration( look ); a.setTypeDeclaration( look );
table.addDeclaration( a ); table.addDeclaration( a );
LinkedList paramList = new LinkedList(); LinkedList paramList = new LinkedList();
look = table.Lookup( "a" ); look = table.Lookup( "a" );
assertEquals( look, a ); assertEquals( look, a );
Declaration.ParameterInfo param = look.new ParameterInfo( look.getType(), look, "&", false ); TypeInfo param = new TypeInfo( look.getType(), look, 0, "&", false );
paramList.add( param ); paramList.add( param );
look = table.UnqualifiedFunctionLookup( "f", paramList ); look = table.UnqualifiedFunctionLookup( "f", paramList );
@ -1517,24 +1513,24 @@ public class ParserSymbolTableTest extends TestCase {
table.push(C); table.push(C);
Declaration f1 = new Declaration("foo"); Declaration f1 = new Declaration("foo");
f1.setType( Declaration.t_function ); f1.setType( TypeInfo.t_function );
f1.setReturnType( Declaration.t_void ); f1.setReturnType( TypeInfo.t_void );
f1.addParameter( Declaration.t_int, "", false ); f1.addParameter( TypeInfo.t_int, 0, "", false );
table.addDeclaration( f1 ); table.addDeclaration( f1 );
Declaration f2 = new Declaration("foo"); Declaration f2 = new Declaration("foo");
f2.setType( Declaration.t_function ); f2.setType( TypeInfo.t_function );
f2.setReturnType( Declaration.t_void ); f2.setReturnType( TypeInfo.t_void );
f2.addParameter( Declaration.t_int, "", false ); f2.addParameter( TypeInfo.t_int, 0, "", false );
f2.addParameter( Declaration.t_char, "", false ); f2.addParameter( TypeInfo.t_char, 0, "", false );
table.addDeclaration( f2 ); table.addDeclaration( f2 );
Declaration f3 = new Declaration("foo"); Declaration f3 = new Declaration("foo");
f3.setType( Declaration.t_function ); f3.setType( TypeInfo.t_function );
f3.setReturnType( Declaration.t_void ); f3.setReturnType( TypeInfo.t_void );
f3.addParameter( Declaration.t_int, "", false ); f3.addParameter( TypeInfo.t_int, 0, "", false );
f3.addParameter( Declaration.t_char, "", false ); f3.addParameter( TypeInfo.t_char, 0, "", false );
f3.addParameter( C, "*", false ); f3.addParameter( C, 0, "*", false );
table.addDeclaration( f3 ); table.addDeclaration( f3 );
table.pop(); table.pop();
@ -1542,7 +1538,7 @@ public class ParserSymbolTableTest extends TestCase {
assertEquals( look, C ); assertEquals( look, C );
Declaration c = new Declaration("c"); Declaration c = new Declaration("c");
c.setType( Declaration.t_class ); c.setType( TypeInfo.t_class );
c.setTypeDeclaration( look ); c.setTypeDeclaration( look );
table.addDeclaration( c ); table.addDeclaration( c );
@ -1552,9 +1548,9 @@ public class ParserSymbolTableTest extends TestCase {
table.push( look.getTypeDeclaration() ); table.push( look.getTypeDeclaration() );
LinkedList paramList = new LinkedList(); LinkedList paramList = new LinkedList();
Declaration.ParameterInfo p1 = c.new ParameterInfo(Declaration.t_int, null, "", false); TypeInfo p1 = new TypeInfo( TypeInfo.t_int, null, 0, "", false);
Declaration.ParameterInfo p2 = c.new ParameterInfo(Declaration.t_char, null, "", false); TypeInfo p2 = new TypeInfo( TypeInfo.t_char, null, 0, "", false);
Declaration.ParameterInfo p3 = c.new ParameterInfo(Declaration.t_class, C, "", 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 );
@ -1568,4 +1564,109 @@ public class ParserSymbolTableTest extends TestCase {
look = table.MemberFunctionLookup( "foo", paramList ); look = table.MemberFunctionLookup( "foo", paramList );
assertEquals( look, f3 ); assertEquals( look, f3 );
} }
/**
*
* @throws Exception
* test basic function resolution
*
* void f( int i );
* void f( char c = 'c' );
*
* f( 1 ); //calls f( int );
* f( 'b' ); //calls f( char );
* f(); //calls f( char );
*/
public void testFunctionResolution_1() throws Exception{
newTable();
Declaration f1 = new Declaration("f");
f1.setType( TypeInfo.t_function );
f1.addParameter( TypeInfo.t_int, 0, "", false );
table.addDeclaration( f1 );
Declaration f2 = new Declaration("f");
f2.setType( TypeInfo.t_function );
f2.addParameter( TypeInfo.t_char, 0, "", true );
table.addDeclaration( f2 );
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_int, null, 0, "", false );
paramList.add( p1 );
Declaration look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
paramList.clear();
TypeInfo p2 = new TypeInfo( TypeInfo.t_char, null, 0, "", false );
paramList.add( p2 );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
paramList.clear();
TypeInfo p3 = new TypeInfo( TypeInfo.t_bool, null, 0, "", false );
paramList.add( p3 );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f1 );
look = table.UnqualifiedFunctionLookup( "f", null );
assertEquals( look, f2 );
}
/**
*
* @throws Exception
*
* class A { };
* class B : public A {};
* class C : public B {};
*
* void f ( A * );
* void f ( B * );
*
* A* a = new A();
* C* c = new C();
*
* f( a ); //calls f( A * );
* f( c ); //calls f( B * );
*/
public void testFunctionResolution_2() 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_class );
B.addParent( A );
table.addDeclaration( B );
Declaration C = new Declaration( "C" );
C.setType( TypeInfo.t_class );
C.addParent( B );
table.addDeclaration( C );
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( B, 0, "*", false );
table.addDeclaration( f2 );
LinkedList paramList = new LinkedList();
TypeInfo p1 = new TypeInfo( TypeInfo.t_type, A, 0, "*", 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 );
paramList.add( p2 );
look = table.UnqualifiedFunctionLookup( "f", paramList );
assertEquals( look, f2 );
}
} }