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:
parent
d24ccf7f26
commit
f77eeb8c08
6 changed files with 835 additions and 400 deletions
|
@ -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
|
||||
Added callback support for namespace definitions.
|
||||
Updated Parser exception hierarchy.
|
||||
|
|
|
@ -16,6 +16,8 @@ import java.util.LinkedList;
|
|||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
|
@ -32,15 +34,20 @@ public class Declaration implements Cloneable {
|
|||
*/
|
||||
public Declaration(){
|
||||
super();
|
||||
_typeInfo = new TypeInfo();
|
||||
}
|
||||
|
||||
public Declaration( String name ){
|
||||
super();
|
||||
_name = name;
|
||||
_typeInfo = new TypeInfo();
|
||||
}
|
||||
|
||||
public Declaration( String name, Object obj ){
|
||||
super();
|
||||
_name = name;
|
||||
_object = obj;
|
||||
_typeInfo = new TypeInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,134 +84,32 @@ public class Declaration implements Cloneable {
|
|||
return copy;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
_typeInfo.setType( t );
|
||||
}
|
||||
|
||||
public int getType(){
|
||||
return _typeInfo & typeMask;
|
||||
return _typeInfo.getType();
|
||||
}
|
||||
|
||||
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 ){
|
||||
//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 );
|
||||
}
|
||||
return _typeInfo.isType( type, upperType );
|
||||
}
|
||||
|
||||
public Declaration getTypeDeclaration(){
|
||||
return _typeDeclaration;
|
||||
return _typeInfo.getTypeDeclaration();
|
||||
}
|
||||
|
||||
public void setTypeDeclaration( Declaration type ){
|
||||
_typeDeclaration = type;
|
||||
_typeInfo.setTypeDeclaration( type );
|
||||
}
|
||||
|
||||
public TypeInfo getTypeInfo(){
|
||||
return _typeInfo;
|
||||
}
|
||||
|
||||
public String getName() { return _name; }
|
||||
|
@ -252,11 +157,11 @@ public class Declaration implements Cloneable {
|
|||
_needsDefinition = need;
|
||||
}
|
||||
|
||||
public String getCVQualifier(){
|
||||
public int getCVQualifier(){
|
||||
return _cvQualifier;
|
||||
}
|
||||
|
||||
public void setCVQualifier( String cv ){
|
||||
public void setCVQualifier( int cv ){
|
||||
_cvQualifier = cv;
|
||||
}
|
||||
|
||||
|
@ -275,30 +180,22 @@ public class Declaration implements Cloneable {
|
|||
_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 ){
|
||||
_parameters = new LinkedList();
|
||||
}
|
||||
|
||||
ParameterInfo info = new ParameterInfo();
|
||||
info.typeInfo = t_type;
|
||||
info.typeDeclaration = typeDecl;
|
||||
info.ptrOperator = ptrOperator;
|
||||
info.hasDefaultValue = hasDefault;
|
||||
TypeInfo info = new TypeInfo( TypeInfo.t_type, typeDecl, cvQual, ptrOperator, hasDefault );
|
||||
|
||||
_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 ){
|
||||
_parameters = new LinkedList();
|
||||
}
|
||||
|
||||
ParameterInfo info = new ParameterInfo();
|
||||
info.typeInfo = type;
|
||||
info.typeDeclaration = null;
|
||||
info.ptrOperator = ptrOperator;
|
||||
info.hasDefaultValue = hasDefault;
|
||||
TypeInfo info = new TypeInfo(type, null, cvQual, ptrOperator, hasDefault );
|
||||
|
||||
_parameters.add( info );
|
||||
}
|
||||
|
@ -316,12 +213,12 @@ public class Declaration implements Cloneable {
|
|||
Iterator iter = _parameters.iterator();
|
||||
Iterator fIter = function._parameters.iterator();
|
||||
|
||||
ParameterInfo info = null;
|
||||
ParameterInfo fInfo = null;
|
||||
TypeInfo info = null;
|
||||
TypeInfo fInfo = null;
|
||||
|
||||
for( int i = size; i > 0; i-- ){
|
||||
info = (ParameterInfo) iter.next();
|
||||
fInfo = (ParameterInfo) fIter.next();
|
||||
info = (TypeInfo) iter.next();
|
||||
fInfo = (TypeInfo) fIter.next();
|
||||
|
||||
if( !info.equals( fInfo ) ){
|
||||
return false;
|
||||
|
@ -332,26 +229,12 @@ public class Declaration implements Cloneable {
|
|||
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 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 String _cvQualifier;
|
||||
private int _cvQualifier;
|
||||
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)
|
||||
protected LinkedList _usingDirectives; //collection of nominated namespaces
|
||||
|
@ -372,27 +255,4 @@ public class Declaration implements Cloneable {
|
|||
public boolean isVirtual = false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*
|
||||
|
@ -40,7 +42,7 @@ public class ParserSymbolTable {
|
|||
super();
|
||||
_compilationUnit = new Declaration();
|
||||
try{
|
||||
_compilationUnit.setType( Declaration.t_namespace );
|
||||
_compilationUnit.setType( TypeInfo.t_namespace );
|
||||
} catch ( ParserSymbolTableException e ){
|
||||
/*shouldn't happen*/
|
||||
}
|
||||
|
@ -96,8 +98,8 @@ public class ParserSymbolTable {
|
|||
private Declaration LookupNestedNameSpecifier(String name, Declaration inDeclaration ) throws ParserSymbolTableException{
|
||||
Declaration foundDeclaration = null;
|
||||
|
||||
LookupData data = new LookupData( name, Declaration.t_namespace );
|
||||
data.upperType = Declaration.t_union;
|
||||
LookupData data = new LookupData( name, TypeInfo.t_namespace );
|
||||
data.upperType = TypeInfo.t_union;
|
||||
|
||||
foundDeclaration = LookupInContained( data, inDeclaration );
|
||||
|
||||
|
@ -164,7 +166,7 @@ public class ParserSymbolTable {
|
|||
* @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.parameters = parameters;
|
||||
|
||||
|
@ -182,7 +184,7 @@ public class ParserSymbolTable {
|
|||
* include argument dependant scopes
|
||||
*/
|
||||
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;
|
||||
|
||||
return Lookup( data, (Declaration) _contextStack.peek() );
|
||||
|
@ -215,24 +217,26 @@ public class ParserSymbolTable {
|
|||
//during the normal lookup to avoid doing them twice
|
||||
HashSet associated = new HashSet();
|
||||
//collect associated namespaces & classes.
|
||||
int size = parameters.size();
|
||||
Iterator iter = parameters.iterator();
|
||||
Declaration.ParameterInfo param = null;
|
||||
int size = ( parameters == null ) ? 0 : parameters.size();
|
||||
Iterator iter = ( parameters == null ) ? null : parameters.iterator();
|
||||
TypeInfo param = null;
|
||||
Declaration paramType = null;
|
||||
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
|
||||
//are those associated with the member type together with those associated with X
|
||||
if( param.ptrOperator != null &&
|
||||
(param.ptrOperator.equals("*") || param.ptrOperator.equals("[]")) &&
|
||||
param.typeDeclaration._containingScope.isType( Declaration.t_class, Declaration.t_union ) )
|
||||
if( param.getPtrOperator() != null &&
|
||||
(param.getPtrOperator().equals("*") || param.getPtrOperator().equals("[]")) &&
|
||||
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.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
|
||||
//associated scopes
|
||||
if( found == null || found._containingScope.getType() != Declaration.t_class ){
|
||||
LinkedList foundList = new LinkedList();
|
||||
if( found == null || found._containingScope.getType() != TypeInfo.t_class ){
|
||||
HashSet foundSet = new HashSet();
|
||||
|
||||
if( found != null ){
|
||||
foundList.add( found );
|
||||
foundSet.add( found );
|
||||
}
|
||||
|
||||
iter = associated.iterator();
|
||||
|
||||
Declaration decl;
|
||||
Declaration temp;
|
||||
|
||||
//use while hasNext instead of forloop since the lookup might remove
|
||||
//items from the collection.
|
||||
//Actually, I think that there will be no removals, but leave it like this anyway
|
||||
while( iter.hasNext() ){
|
||||
decl = (Declaration) iter.next();
|
||||
//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();
|
||||
|
||||
size = associated.size();
|
||||
|
||||
for( int i = 0; i < size; i++ ){
|
||||
decl = (Declaration) scopes[ i ];
|
||||
if( associated.contains( decl ) ){
|
||||
data.qualified = true;
|
||||
data.ignoreUsingDirectives = true;
|
||||
temp = Lookup( data, decl );
|
||||
if( temp != null ){
|
||||
foundList.add( temp );
|
||||
foundSet.add( temp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found = ResolveAmbiguities( data, foundList );
|
||||
found = ResolveAmbiguities( data, foundSet );
|
||||
}
|
||||
|
||||
return found;
|
||||
|
@ -288,11 +296,11 @@ public class ParserSymbolTable {
|
|||
LookupData data = new LookupData( name, -1 );
|
||||
|
||||
Declaration decl = (Declaration) _contextStack.peek();
|
||||
boolean inClass = (decl.getType() == Declaration.t_class);
|
||||
boolean inClass = (decl.getType() == TypeInfo.t_class);
|
||||
|
||||
Declaration enclosing = decl._containingScope;
|
||||
while( enclosing != null && (inClass ? enclosing.getType() != Declaration.t_class
|
||||
: enclosing.getType() == Declaration.t_namespace) )
|
||||
while( enclosing != null && (inClass ? enclosing.getType() != TypeInfo.t_class
|
||||
: enclosing.getType() == TypeInfo.t_namespace) )
|
||||
{
|
||||
enclosing = enclosing._containingScope;
|
||||
}
|
||||
|
@ -303,7 +311,7 @@ public class ParserSymbolTable {
|
|||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -338,20 +346,20 @@ public class ParserSymbolTable {
|
|||
boolean okToAdd = false;
|
||||
|
||||
//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
|
||||
if( obj.getContainingScope().getType() == context.getType() ){
|
||||
okToAdd = hasBaseClass( context, obj.getContainingScope() );
|
||||
okToAdd = ( hasBaseClass( context, obj.getContainingScope() ) > 0 );
|
||||
}
|
||||
//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();
|
||||
okToAdd = hasBaseClass( context, union.getContainingScope() );
|
||||
okToAdd = ( hasBaseClass( context, union.getContainingScope() ) > 0 );
|
||||
}
|
||||
//an enumerator for an enumeration
|
||||
else if ( obj.getType() == Declaration.t_enumerator ){
|
||||
else if ( obj.getType() == TypeInfo.t_enumerator ){
|
||||
Declaration enumeration = obj.getContainingScope();
|
||||
okToAdd = hasBaseClass( context, enumeration.getContainingScope() );
|
||||
okToAdd = ( hasBaseClass( context, enumeration.getContainingScope() ) > 0 );
|
||||
}
|
||||
} else {
|
||||
okToAdd = true;
|
||||
|
@ -371,10 +379,10 @@ public class ParserSymbolTable {
|
|||
Declaration containing = (Declaration) _contextStack.peek();
|
||||
|
||||
//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
|
||||
//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
|
||||
//enumeration
|
||||
obj.setTypeDeclaration( containing );
|
||||
|
@ -431,7 +439,8 @@ public class ParserSymbolTable {
|
|||
}
|
||||
|
||||
//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 );
|
||||
}
|
||||
}
|
||||
|
@ -459,7 +468,7 @@ public class ParserSymbolTable {
|
|||
Declaration decl = (Declaration) _contextStack.peek();
|
||||
Declaration containing = decl._containingScope;
|
||||
//find innermost enclosing namespace
|
||||
while( containing != null && containing.getType() != Declaration.t_namespace ){
|
||||
while( containing != null && containing.getType() != TypeInfo.t_namespace ){
|
||||
containing = containing._containingScope;
|
||||
}
|
||||
|
||||
|
@ -482,17 +491,18 @@ public class ParserSymbolTable {
|
|||
* of this is volatile X*....
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
//of function will have them from the original declaration
|
||||
LookupData data = new LookupData( "this", -1 );
|
||||
if( LookupInContained( data, obj ) == null ){
|
||||
Declaration thisObj = new Declaration("this");
|
||||
thisObj.setType( Declaration.t_type );
|
||||
thisObj.setType( TypeInfo.t_type );
|
||||
thisObj.setTypeDeclaration( obj._containingScope );
|
||||
thisObj.setCVQualifier( obj.getCVQualifier() );
|
||||
thisObj.setPtrOperator("*");
|
||||
|
@ -513,7 +523,7 @@ public class ParserSymbolTable {
|
|||
*/
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -567,8 +577,8 @@ public class ParserSymbolTable {
|
|||
}
|
||||
}
|
||||
|
||||
decl = ResolveAmbiguities( data, foundNames );
|
||||
if( decl != null ){
|
||||
decl = ResolveAmbiguities( data, new HashSet( foundNames ) );
|
||||
if( decl != null || data.stopAt == inDeclaration ){
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
@ -664,7 +674,7 @@ public class ParserSymbolTable {
|
|||
* Look for data.name in our collection _containedDeclarations
|
||||
*/
|
||||
private static Declaration LookupInContained( LookupData data, Declaration lookIn ) throws ParserSymbolTableException{
|
||||
LinkedList found = null;
|
||||
HashSet found = null;
|
||||
Declaration temp = null;
|
||||
Object obj = null;
|
||||
|
||||
|
@ -691,7 +701,7 @@ public class ParserSymbolTable {
|
|||
return (Declaration) obj;
|
||||
}
|
||||
} else {
|
||||
found = new LinkedList();
|
||||
found = new HashSet();
|
||||
|
||||
LinkedList objList = (LinkedList)obj;
|
||||
Iterator iter = objList.iterator();
|
||||
|
@ -776,7 +786,9 @@ public class ParserSymbolTable {
|
|||
} else if ( temp != null ) {
|
||||
//it is not ambiguous if temp & decl are the same thing and it is static
|
||||
//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;
|
||||
} else {
|
||||
throw( new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName ) );
|
||||
|
@ -807,8 +819,8 @@ public class ParserSymbolTable {
|
|||
int origType = origDecl.getType();
|
||||
int newType = newDecl.getType();
|
||||
|
||||
if( (origType >= Declaration.t_class && origType <= Declaration.t_enumeration) && //class name or enumeration ...
|
||||
( newType == Declaration.t_type || (newType >= Declaration.t_function && newType <= Declaration.typeMask) ) ){
|
||||
if( (origType >= TypeInfo.t_class && origType <= TypeInfo.t_enumeration) && //class name or enumeration ...
|
||||
( newType == TypeInfo.t_type || (newType >= TypeInfo.t_function && newType <= TypeInfo.typeMask) ) ){
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -825,13 +837,13 @@ public class ParserSymbolTable {
|
|||
//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
|
||||
//considering the list
|
||||
if( newDecl.getType() != Declaration.t_function ){
|
||||
if( newDecl.getType() != TypeInfo.t_function ){
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator iter = origList.iterator();
|
||||
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 ));
|
||||
|
||||
while( valid && iter.hasNext() ){
|
||||
|
@ -847,14 +859,14 @@ public class ParserSymbolTable {
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if( origDecl.hasSameParameters( newDecl ) ){
|
||||
//functions with the same name and same parameter types cannot be overloaded if any of them
|
||||
//is static
|
||||
if( origDecl.isStatic() || newDecl.isStatic() ){
|
||||
if( origDecl._typeInfo.checkBit( TypeInfo.isStatic ) || newDecl._typeInfo.checkBit( TypeInfo.isStatic ) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -870,54 +882,197 @@ public class ParserSymbolTable {
|
|||
return true;
|
||||
}
|
||||
|
||||
static private Declaration ResolveAmbiguities( LookupData data, LinkedList items ) throws ParserSymbolTableException{
|
||||
Declaration decl = null;
|
||||
|
||||
static private Declaration ResolveAmbiguities( LookupData data, HashSet items ) throws ParserSymbolTableException{
|
||||
int size = items.size();
|
||||
Iterator iter = items.iterator();
|
||||
|
||||
if( size == 0){
|
||||
return null;
|
||||
} else if (size == 1) {
|
||||
return (Declaration) items.getFirst();
|
||||
return (Declaration) iter.next();
|
||||
} else {
|
||||
Declaration first = (Declaration)items.removeFirst();
|
||||
LinkedList functionList = null;
|
||||
|
||||
//if first one is a class-name, the next ones hide it
|
||||
if( first.getType() >= Declaration.t_class && first.getType() <= Declaration.t_enumeration ){
|
||||
return ResolveAmbiguities( data, items );
|
||||
}
|
||||
Declaration decl = null;
|
||||
Declaration obj = null;
|
||||
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-- ){
|
||||
for( int i = size; i > 0; i-- ){
|
||||
decl = (Declaration) iter.next();
|
||||
|
||||
if( needSame ){
|
||||
if( decl != first ){
|
||||
if( decl.isType( TypeInfo.t_function ) ){
|
||||
if( functionList == null){
|
||||
functionList = new LinkedList();
|
||||
}
|
||||
functionList.add( decl );
|
||||
} else {
|
||||
//if this is a class-name, other stuff hides it
|
||||
if( decl.isType( TypeInfo.t_class, TypeInfo.t_enumeration ) ){
|
||||
if( cls == null ) {
|
||||
cls = decl;
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
|
||||
}
|
||||
} else {
|
||||
if( decl.getType() != Declaration.t_function ){
|
||||
//an object, can only have one of these
|
||||
if( obj == null ){
|
||||
obj = decl;
|
||||
} else {
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( needSame ){
|
||||
return first;
|
||||
int numFunctions = ( functionList == null ) ? 0 : functionList.size();
|
||||
|
||||
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 {
|
||||
items.addFirst( first );
|
||||
return ResolveFunction( data, items );
|
||||
return obj;
|
||||
}
|
||||
} else if( numFunctions > 0 ) {
|
||||
return ResolveFunction( data, functionList );
|
||||
}
|
||||
|
||||
if( ambiguous ){
|
||||
throw new ParserSymbolTableException( ParserSymbolTableException.r_AmbiguousName );
|
||||
} else {
|
||||
return cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 num;
|
||||
|
||||
|
@ -943,30 +1098,18 @@ public class ParserSymbolTable {
|
|||
//a candidate function having more than m parameters is viable only if the (m+1)-st
|
||||
//parameter has a default argument
|
||||
else {
|
||||
ListIterator listIter = function._parameters.listIterator( num - 1 );
|
||||
Declaration.ParameterInfo param;
|
||||
for( int i = num; i > ( numParameters - num ); i-- ){
|
||||
param = (Declaration.ParameterInfo)listIter.previous();
|
||||
if( !param.hasDefaultValue ){
|
||||
ListIterator listIter = function._parameters.listIterator( num );
|
||||
TypeInfo param;
|
||||
for( int i = num; i > ( numParameters - num + 1); i-- ){
|
||||
param = (TypeInfo)listIter.previous();
|
||||
if( !param.getHasDefault() ){
|
||||
iter.remove();
|
||||
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
|
||||
|
@ -1044,13 +1187,20 @@ public class ParserSymbolTable {
|
|||
*
|
||||
* @param obj
|
||||
* @param base
|
||||
* @return boolean
|
||||
* figure out if base is a base class of obj.
|
||||
* @return int
|
||||
* 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.
|
||||
*/
|
||||
static private boolean hasBaseClass( Declaration obj, Declaration base ){
|
||||
boolean isABaseClass = false;
|
||||
static private int hasBaseClass( Declaration obj, Declaration base ){
|
||||
if( obj == base ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( obj._parentScopes != null ){
|
||||
Declaration decl;
|
||||
|
@ -1063,13 +1213,19 @@ public class ParserSymbolTable {
|
|||
wrapper = (Declaration.ParentWrapper) iter.next();
|
||||
decl = wrapper.parent;
|
||||
|
||||
if( decl == base || hasBaseClass( decl, base ) ){
|
||||
return true;
|
||||
}
|
||||
if( decl == base ){
|
||||
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 ){
|
||||
|
@ -1079,14 +1235,14 @@ public class ParserSymbolTable {
|
|||
//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
|
||||
//namespaces in which its associated classes are defined
|
||||
if( decl.getType() == Declaration.t_class ){
|
||||
if( decl.getType() == TypeInfo.t_class ){
|
||||
associated.add( decl );
|
||||
getBaseClassesAndContainingNamespaces( decl, associated );
|
||||
}
|
||||
//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
|
||||
//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 );
|
||||
}
|
||||
}
|
||||
|
@ -1099,12 +1255,14 @@ public class ParserSymbolTable {
|
|||
|
||||
Iterator iter = obj._parentScopes.iterator();
|
||||
int size = obj._parentScopes.size();
|
||||
Declaration.ParentWrapper wrapper;
|
||||
Declaration base;
|
||||
|
||||
for( int i = size; i > 0; i-- ){
|
||||
base = (Declaration) iter.next();
|
||||
wrapper = (Declaration.ParentWrapper) iter.next();
|
||||
base = (Declaration) wrapper.parent;
|
||||
classes.add( base );
|
||||
if( base._containingScope.getType() == Declaration.t_namespace ){
|
||||
if( base._containingScope.getType() == TypeInfo.t_namespace ){
|
||||
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 Declaration _compilationUnit;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
Added testDeclSpecifier(), testNamespaceDefinition(), testLinkageSpecification(),
|
||||
testUsingClauses() and testEnumSpecifier() to DOMTests.
|
||||
|
|
|
@ -20,6 +20,7 @@ import junit.framework.TestCase;
|
|||
import org.eclipse.cdt.internal.core.parser.Declaration;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserSymbolTable;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserSymbolTableException;
|
||||
import org.eclipse.cdt.internal.core.parser.util.TypeInfo;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -379,13 +380,13 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addDeclaration( d );
|
||||
|
||||
Declaration enum = new Declaration("enum");
|
||||
enum.setType( Declaration.t_enumeration );
|
||||
enum.setType( TypeInfo.t_enumeration );
|
||||
|
||||
Declaration enumerator = new Declaration( "enumerator" );
|
||||
enumerator.setType( Declaration.t_enumerator );
|
||||
enumerator.setType( TypeInfo.t_enumerator );
|
||||
|
||||
Declaration stat = new Declaration("static");
|
||||
stat.setStatic(true);
|
||||
stat.getTypeInfo().setBit( true, TypeInfo.isStatic );
|
||||
|
||||
Declaration x = new Declaration("x");
|
||||
|
||||
|
@ -438,13 +439,13 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration cls = new Declaration( "class" );
|
||||
cls.setType( Declaration.t_class );
|
||||
cls.setType( TypeInfo.t_class );
|
||||
|
||||
Declaration struct = new Declaration("struct");
|
||||
struct.setType( Declaration.t_struct );
|
||||
struct.setType( TypeInfo.t_struct );
|
||||
|
||||
Declaration union = new Declaration("union");
|
||||
union.setType( Declaration.t_union );
|
||||
union.setType( TypeInfo.t_union );
|
||||
|
||||
Declaration hideCls = new Declaration( "class" );
|
||||
Declaration hideStruct = new Declaration("struct");
|
||||
|
@ -466,11 +467,11 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addDeclaration(union);
|
||||
table.pop();
|
||||
|
||||
Declaration look = table.ElaboratedLookup( Declaration.t_class, "class" );
|
||||
Declaration look = table.ElaboratedLookup( TypeInfo.t_class, "class" );
|
||||
assertEquals( look, cls );
|
||||
look = table.ElaboratedLookup( Declaration.t_struct, "struct" );
|
||||
look = table.ElaboratedLookup( TypeInfo.t_struct, "struct" );
|
||||
assertEquals( look, struct );
|
||||
look = table.ElaboratedLookup( Declaration.t_union, "union" );
|
||||
look = table.ElaboratedLookup( TypeInfo.t_union, "union" );
|
||||
assertEquals( look, union );
|
||||
}
|
||||
|
||||
|
@ -528,19 +529,19 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration struct = new Declaration( "stat");
|
||||
struct.setType( Declaration.t_struct );
|
||||
struct.setType( TypeInfo.t_struct );
|
||||
table.addDeclaration( struct );
|
||||
|
||||
Declaration function = new Declaration( "stat" );
|
||||
function.setType( Declaration.t_function );
|
||||
function.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( function );
|
||||
|
||||
Declaration f = new Declaration("f");
|
||||
f.setType( Declaration.t_function );
|
||||
f.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f );
|
||||
table.push( f );
|
||||
|
||||
Declaration look = table.ElaboratedLookup( Declaration.t_struct, "stat" );
|
||||
Declaration look = table.ElaboratedLookup( TypeInfo.t_struct, "stat" );
|
||||
assertEquals( look, struct );
|
||||
|
||||
look = table.Lookup( "stat" );
|
||||
|
@ -582,7 +583,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsA = new Declaration("A");
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsA );
|
||||
table.push( nsA );
|
||||
|
||||
|
@ -590,12 +591,12 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addDeclaration( nsA_i );
|
||||
|
||||
Declaration nsB = new Declaration("B");
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
|
||||
Declaration nsC = new Declaration("C");
|
||||
nsC.setType( Declaration.t_namespace );
|
||||
nsC.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsC );
|
||||
table.push( nsC );
|
||||
|
||||
|
@ -607,7 +608,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addUsingDirective( look );
|
||||
|
||||
Declaration f1 = new Declaration("f");
|
||||
f1.setType( Declaration.t_function );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
table.push( f1 );
|
||||
|
||||
look = table.Lookup( "i" );
|
||||
|
@ -619,7 +620,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
assertEquals( table.peek(), nsA );
|
||||
|
||||
Declaration nsD = new Declaration("D");
|
||||
nsD.setType( Declaration.t_namespace );
|
||||
nsD.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsD );
|
||||
table.push( nsD );
|
||||
|
||||
|
@ -632,7 +633,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addUsingDirective( look );
|
||||
|
||||
Declaration f2 = new Declaration( "f2" );
|
||||
f2.setType( Declaration.t_function );
|
||||
f2.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f2 );
|
||||
table.push( f2 );
|
||||
|
||||
|
@ -650,7 +651,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop(); //end nsD
|
||||
|
||||
Declaration f3 = new Declaration ("f3");
|
||||
f3.setType( Declaration.t_function );
|
||||
f3.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f3 );
|
||||
table.push( f3 );
|
||||
|
||||
|
@ -661,7 +662,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration f4 = new Declaration ("f4");
|
||||
f4.setType( Declaration.t_function );
|
||||
f4.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f4 );
|
||||
table.push( f4 );
|
||||
|
||||
|
@ -693,7 +694,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsM = new Declaration( "M" );
|
||||
nsM.setType( Declaration.t_namespace );
|
||||
nsM.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( nsM );
|
||||
|
||||
|
@ -703,7 +704,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration nsN = new Declaration( "N" );
|
||||
nsN.setType( Declaration.t_namespace );
|
||||
nsN.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( nsN );
|
||||
|
||||
|
@ -765,7 +766,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsA = new Declaration("A");
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsA );
|
||||
table.push( nsA );
|
||||
|
||||
|
@ -774,21 +775,21 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration nsB = new Declaration("B");
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
table.addUsingDirective( nsA );
|
||||
table.pop();
|
||||
|
||||
Declaration nsC = new Declaration("C");
|
||||
nsC.setType( Declaration.t_namespace );
|
||||
nsC.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsC );
|
||||
table.push( nsC );
|
||||
table.addUsingDirective( nsA );
|
||||
table.pop();
|
||||
|
||||
Declaration nsBC = new Declaration("BC");
|
||||
nsBC.setType( Declaration.t_namespace );
|
||||
nsBC.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsBC );
|
||||
table.push( nsBC );
|
||||
table.addUsingDirective( nsB );
|
||||
|
@ -796,7 +797,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration f = new Declaration("f");
|
||||
f.setType(Declaration.t_function);
|
||||
f.setType(TypeInfo.t_function);
|
||||
table.addDeclaration( f );
|
||||
table.push(f);
|
||||
|
||||
|
@ -834,7 +835,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsB = new Declaration( "B" );
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
|
||||
|
@ -843,7 +844,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration nsA = new Declaration( "A" );
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsA );
|
||||
table.push( nsA );
|
||||
|
||||
|
@ -908,11 +909,11 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsA = new Declaration( "A" );
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsA );
|
||||
|
||||
Declaration nsB = new Declaration( "B" );
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
table.addUsingDirective( nsA );
|
||||
|
@ -961,39 +962,39 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsA = new Declaration("A");
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( nsA );
|
||||
table.push( nsA );
|
||||
|
||||
Declaration structX = new Declaration("x");
|
||||
structX.setType( Declaration.t_struct );
|
||||
structX.setType( TypeInfo.t_struct );
|
||||
table.addDeclaration( structX );
|
||||
|
||||
Declaration intX = new Declaration("x");
|
||||
intX.setType( Declaration.t_int );
|
||||
intX.setType( TypeInfo.t_int );
|
||||
table.addDeclaration( intX );
|
||||
|
||||
Declaration intY = new Declaration("y");
|
||||
intY.setType( Declaration.t_int );
|
||||
intY.setType( TypeInfo.t_int );
|
||||
table.addDeclaration( intY );
|
||||
|
||||
table.pop();
|
||||
|
||||
Declaration nsB = new Declaration("B");
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
|
||||
Declaration structY = new Declaration("y");
|
||||
structY.setType( Declaration.t_struct );
|
||||
structY.setType( TypeInfo.t_struct );
|
||||
table.addDeclaration( structY );
|
||||
|
||||
table.pop();
|
||||
|
||||
Declaration nsC = new Declaration("C");
|
||||
nsC.setType( Declaration.t_namespace);
|
||||
nsC.setType( TypeInfo.t_namespace);
|
||||
table.addDeclaration( nsC );
|
||||
|
||||
table.push( nsC );
|
||||
|
@ -1044,17 +1045,17 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration nsA = new Declaration( "A" );
|
||||
nsA.setType( Declaration.t_namespace );
|
||||
nsA.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsA );
|
||||
table.push( nsA );
|
||||
|
||||
Declaration nsB = new Declaration( "B" );
|
||||
nsB.setType( Declaration.t_namespace );
|
||||
nsB.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( nsB );
|
||||
table.push( nsB );
|
||||
|
||||
Declaration f1 = new Declaration("f1");
|
||||
f1.setType( Declaration.t_function );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f1 );
|
||||
|
||||
table.pop();
|
||||
|
@ -1102,21 +1103,21 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration B = new Declaration("B");
|
||||
B.setType( Declaration.t_struct );
|
||||
B.setType( TypeInfo.t_struct );
|
||||
table.addDeclaration( B );
|
||||
table.push( B );
|
||||
|
||||
Declaration f = new Declaration("f");
|
||||
f.setType( Declaration.t_function );
|
||||
f.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( f );
|
||||
|
||||
Declaration E = new Declaration( "E" );
|
||||
E.setType( Declaration.t_enumeration );
|
||||
E.setType( TypeInfo.t_enumeration );
|
||||
table.addDeclaration( E );
|
||||
|
||||
table.push( E );
|
||||
Declaration e = new Declaration( "e" );
|
||||
e.setType( Declaration.t_enumerator );
|
||||
e.setType( TypeInfo.t_enumerator );
|
||||
table.addDeclaration( e );
|
||||
table.pop();
|
||||
|
||||
|
@ -1125,17 +1126,17 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration C = new Declaration( "C" );
|
||||
C.setType( Declaration.t_class );
|
||||
C.setType( TypeInfo.t_class );
|
||||
table.addDeclaration( C );
|
||||
|
||||
table.push( C );
|
||||
Declaration g = new Declaration( "g" );
|
||||
g.setType( Declaration.t_function );
|
||||
g.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( g );
|
||||
table.pop();
|
||||
|
||||
Declaration D = new Declaration( "D" );
|
||||
D.setType( Declaration.t_struct );
|
||||
D.setType( TypeInfo.t_struct );
|
||||
Declaration look = table.Lookup( "B" );
|
||||
assertEquals( look, B );
|
||||
D.addParent( look );
|
||||
|
@ -1212,15 +1213,15 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration A = new Declaration( "A" );
|
||||
A.setType( Declaration.t_namespace );
|
||||
A.setType( TypeInfo.t_namespace );
|
||||
table.addDeclaration( A );
|
||||
|
||||
table.push( A );
|
||||
|
||||
Declaration f1 = new Declaration( "f" );
|
||||
f1.setType( Declaration.t_function );
|
||||
f1.setReturnType( Declaration.t_void );
|
||||
f1.addParameter( Declaration.t_int, "", false );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
f1.setReturnType( TypeInfo.t_void );
|
||||
f1.addParameter( TypeInfo.t_int, 0, "", false );
|
||||
table.addDeclaration( f1 );
|
||||
|
||||
table.pop();
|
||||
|
@ -1239,21 +1240,20 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
|
||||
table.push( look );
|
||||
Declaration f2 = new Declaration("f");
|
||||
f2.setType( Declaration.t_function );
|
||||
f2.setReturnType( Declaration.t_void );
|
||||
f2.addParameter( Declaration.t_char, "", false );
|
||||
f2.setType( TypeInfo.t_function );
|
||||
f2.setReturnType( TypeInfo.t_void );
|
||||
f2.addParameter( TypeInfo.t_char, 0, "", false );
|
||||
|
||||
table.addDeclaration( f2 );
|
||||
|
||||
table.pop();
|
||||
|
||||
Declaration foo = new Declaration("foo");
|
||||
foo.setType( Declaration.t_function );
|
||||
foo.setType( TypeInfo.t_function );
|
||||
table.addDeclaration( foo );
|
||||
table.push( foo );
|
||||
LinkedList paramList = new LinkedList();
|
||||
Declaration.ParameterInfo param = foo.new ParameterInfo();
|
||||
param.typeInfo = Declaration.t_char;
|
||||
TypeInfo param = new TypeInfo( TypeInfo.t_char, null );
|
||||
paramList.add( param );
|
||||
|
||||
look = table.UnqualifiedFunctionLookup( "f", paramList );
|
||||
|
@ -1273,11 +1273,11 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration cls = new Declaration("class");
|
||||
cls.setType( Declaration.t_class );
|
||||
cls.setType( TypeInfo.t_class );
|
||||
|
||||
Declaration fn = new Declaration("function");
|
||||
fn.setType( Declaration.t_function );
|
||||
fn.setCVQualifier("const");
|
||||
fn.setType( TypeInfo.t_function );
|
||||
fn.setCVQualifier( TypeInfo.cvConst );
|
||||
|
||||
table.addDeclaration( cls );
|
||||
table.push( cls );
|
||||
|
@ -1288,7 +1288,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
Declaration look = table.Lookup("this");
|
||||
assertTrue( look != null );
|
||||
|
||||
assertEquals( look.getType(), Declaration.t_type );
|
||||
assertEquals( look.getType(), TypeInfo.t_type );
|
||||
assertEquals( look.getTypeDeclaration(), cls );
|
||||
assertEquals( look.getPtrOperator(), "*" );
|
||||
assertEquals( look.getCVQualifier(), fn.getCVQualifier() );
|
||||
|
@ -1307,10 +1307,10 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration cls = new Declaration("class");
|
||||
cls.setType( Declaration.t_class );
|
||||
cls.setType( TypeInfo.t_class );
|
||||
|
||||
Declaration enumeration = new Declaration("enumeration");
|
||||
enumeration.setType( Declaration.t_enumeration );
|
||||
enumeration.setType( TypeInfo.t_enumeration );
|
||||
|
||||
table.addDeclaration( cls );
|
||||
table.push( cls );
|
||||
|
@ -1318,7 +1318,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.push( enumeration );
|
||||
|
||||
Declaration enumerator = new Declaration( "enumerator" );
|
||||
enumerator.setType( Declaration.t_enumerator );
|
||||
enumerator.setType( TypeInfo.t_enumerator );
|
||||
table.addDeclaration( enumerator );
|
||||
|
||||
table.pop();
|
||||
|
@ -1346,23 +1346,23 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration NS = new Declaration("NS");
|
||||
NS.setType( Declaration.t_namespace );
|
||||
NS.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( NS );
|
||||
table.push( NS );
|
||||
|
||||
Declaration T = new Declaration("T");
|
||||
T.setType( Declaration.t_class );
|
||||
T.setType( TypeInfo.t_class );
|
||||
|
||||
table.addDeclaration( T );
|
||||
|
||||
Declaration f = new Declaration("f");
|
||||
f.setType( Declaration.t_function );
|
||||
f.setReturnType( Declaration.t_void );
|
||||
f.setType( TypeInfo.t_function );
|
||||
f.setReturnType( TypeInfo.t_void );
|
||||
|
||||
Declaration look = table.Lookup( "T" );
|
||||
assertEquals( look, T );
|
||||
f.addParameter( look, "", false );
|
||||
f.addParameter( look, 0, "", false );
|
||||
|
||||
table.addDeclaration( f );
|
||||
|
||||
|
@ -1376,13 +1376,13 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.pop();
|
||||
|
||||
Declaration param = new Declaration("parm");
|
||||
param.setType( Declaration.t_type );
|
||||
param.setType( TypeInfo.t_type );
|
||||
param.setTypeDeclaration( look );
|
||||
table.addDeclaration( param );
|
||||
|
||||
Declaration main = new Declaration("main");
|
||||
main.setType( Declaration.t_function );
|
||||
main.setReturnType( Declaration.t_int );
|
||||
main.setType( TypeInfo.t_function );
|
||||
main.setReturnType( TypeInfo.t_int );
|
||||
table.addDeclaration( main );
|
||||
table.push( main );
|
||||
|
||||
|
@ -1390,11 +1390,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
look = table.Lookup( "parm" );
|
||||
assertEquals( look, param );
|
||||
|
||||
Declaration.ParameterInfo p = look.new ParameterInfo();
|
||||
p.typeInfo = look.getType();
|
||||
p.typeDeclaration = look.getTypeDeclaration();
|
||||
|
||||
paramList.add( p );
|
||||
paramList.add( look.getTypeInfo() );
|
||||
|
||||
look = table.UnqualifiedFunctionLookup( "f", paramList );
|
||||
assertEquals( look, f );
|
||||
|
@ -1427,20 +1423,20 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
newTable();
|
||||
|
||||
Declaration NS1 = new Declaration( "NS1" );
|
||||
NS1.setType( Declaration.t_namespace );
|
||||
NS1.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( NS1 );
|
||||
table.push( NS1 );
|
||||
|
||||
Declaration f1 = new Declaration( "f" );
|
||||
f1.setType( Declaration.t_function );
|
||||
f1.setReturnType( Declaration.t_void );
|
||||
f1.addParameter( Declaration.t_void, "*", false );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
f1.setReturnType( TypeInfo.t_void );
|
||||
f1.addParameter( TypeInfo.t_void, 0, "*", false );
|
||||
table.addDeclaration( f1 );
|
||||
table.pop();
|
||||
|
||||
Declaration NS2 = new Declaration( "NS2" );
|
||||
NS2.setType( Declaration.t_namespace );
|
||||
NS2.setType( TypeInfo.t_namespace );
|
||||
|
||||
table.addDeclaration( NS2 );
|
||||
table.push( NS2 );
|
||||
|
@ -1450,18 +1446,18 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.addUsingDirective( look );
|
||||
|
||||
Declaration B = new Declaration( "B" );
|
||||
B.setType( Declaration.t_class );
|
||||
B.setType( TypeInfo.t_class );
|
||||
table.addDeclaration( B );
|
||||
|
||||
Declaration f2 = new Declaration( "f" );
|
||||
f2.setType( Declaration.t_function );
|
||||
f2.setReturnType( Declaration.t_void );
|
||||
f2.addParameter( Declaration.t_void, "*", false );
|
||||
f2.setType( TypeInfo.t_function );
|
||||
f2.setReturnType( TypeInfo.t_void );
|
||||
f2.addParameter( TypeInfo.t_void, 0, "*", false );
|
||||
table.addDeclaration( f2 );
|
||||
table.pop();
|
||||
|
||||
Declaration A = new Declaration( "A" );
|
||||
A.setType( Declaration.t_class );
|
||||
A.setType( TypeInfo.t_class );
|
||||
look = table.LookupNestedNameSpecifier( "NS2" );
|
||||
assertEquals( look, NS2 );
|
||||
table.push( look );
|
||||
|
@ -1474,14 +1470,14 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
look = table.Lookup( "A" );
|
||||
assertEquals( look, A );
|
||||
Declaration a = new Declaration( "a" );
|
||||
a.setType( Declaration.t_type );
|
||||
a.setType( TypeInfo.t_type );
|
||||
a.setTypeDeclaration( look );
|
||||
table.addDeclaration( a );
|
||||
|
||||
LinkedList paramList = new LinkedList();
|
||||
look = table.Lookup( "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 );
|
||||
|
||||
look = table.UnqualifiedFunctionLookup( "f", paramList );
|
||||
|
@ -1517,24 +1513,24 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.push(C);
|
||||
|
||||
Declaration f1 = new Declaration("foo");
|
||||
f1.setType( Declaration.t_function );
|
||||
f1.setReturnType( Declaration.t_void );
|
||||
f1.addParameter( Declaration.t_int, "", false );
|
||||
f1.setType( TypeInfo.t_function );
|
||||
f1.setReturnType( TypeInfo.t_void );
|
||||
f1.addParameter( TypeInfo.t_int, 0, "", false );
|
||||
table.addDeclaration( f1 );
|
||||
|
||||
Declaration f2 = new Declaration("foo");
|
||||
f2.setType( Declaration.t_function );
|
||||
f2.setReturnType( Declaration.t_void );
|
||||
f2.addParameter( Declaration.t_int, "", false );
|
||||
f2.addParameter( Declaration.t_char, "", false );
|
||||
f2.setType( TypeInfo.t_function );
|
||||
f2.setReturnType( TypeInfo.t_void );
|
||||
f2.addParameter( TypeInfo.t_int, 0, "", false );
|
||||
f2.addParameter( TypeInfo.t_char, 0, "", false );
|
||||
table.addDeclaration( f2 );
|
||||
|
||||
Declaration f3 = new Declaration("foo");
|
||||
f3.setType( Declaration.t_function );
|
||||
f3.setReturnType( Declaration.t_void );
|
||||
f3.addParameter( Declaration.t_int, "", false );
|
||||
f3.addParameter( Declaration.t_char, "", false );
|
||||
f3.addParameter( C, "*", false );
|
||||
f3.setType( TypeInfo.t_function );
|
||||
f3.setReturnType( TypeInfo.t_void );
|
||||
f3.addParameter( TypeInfo.t_int, 0, "", false );
|
||||
f3.addParameter( TypeInfo.t_char, 0, "", false );
|
||||
f3.addParameter( C, 0, "*", false );
|
||||
table.addDeclaration( f3 );
|
||||
table.pop();
|
||||
|
||||
|
@ -1542,7 +1538,7 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
assertEquals( look, C );
|
||||
|
||||
Declaration c = new Declaration("c");
|
||||
c.setType( Declaration.t_class );
|
||||
c.setType( TypeInfo.t_class );
|
||||
c.setTypeDeclaration( look );
|
||||
table.addDeclaration( c );
|
||||
|
||||
|
@ -1552,9 +1548,9 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
table.push( look.getTypeDeclaration() );
|
||||
|
||||
LinkedList paramList = new LinkedList();
|
||||
Declaration.ParameterInfo p1 = c.new ParameterInfo(Declaration.t_int, null, "", false);
|
||||
Declaration.ParameterInfo p2 = c.new ParameterInfo(Declaration.t_char, null, "", false);
|
||||
Declaration.ParameterInfo p3 = c.new ParameterInfo(Declaration.t_class, C, "", false);
|
||||
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);
|
||||
|
||||
paramList.add( p1 );
|
||||
look = table.MemberFunctionLookup( "foo", paramList );
|
||||
|
@ -1568,4 +1564,109 @@ public class ParserSymbolTableTest extends TestCase {
|
|||
look = table.MemberFunctionLookup( "foo", paramList );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue