1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Bug Fixes for the complete AST factory

This commit is contained in:
Hoda Amer 2003-11-13 19:27:29 +00:00
parent 704e3552ab
commit 4d7450e8fb
10 changed files with 547 additions and 253 deletions

View file

@ -1,3 +1,8 @@
2003-11-13 Hoda Amer
Added CompleteParseASTTest::testBug44342(): Failure to dereference function calls after a . or an ->
Moved testErrorHandling_1() to FailedCompleteParseASTTest
Added FailedCompleteParseASTTest::testBug44340():Inline functions fail to resolve references
2003-11-06 Andrew Niefer
Remove dependancy on cdt.internal.ui.search.CSearchResultCollector in BaseSearchTest and DependencyTests

View file

@ -14,10 +14,13 @@ import java.util.Iterator;
import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTScope;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.tests.CompleteParseBaseTest;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
* @author jcamelon
@ -114,4 +117,37 @@ public class FailedCompleteParseASTTest extends CompleteParseBaseTest
assertFalse( i.hasNext() );
assertAllReferences( 4 /*should be 5 */, createTaskList( new Task( cl /* , 2 */ ), new Task( a), new Task( pm), new Task( f2)));
}
public void testErrorHandling_1() throws Exception
{
Iterator i = parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ).getDeclarations();
IASTVariable x = (IASTVariable)i.next();
assertEquals( x.getName(), "x");
IASTClassSpecifier A = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTVariable anotherA = (IASTVariable)i.next();
assertFalse(i.hasNext()); // should be true
// this variable is skipped because of wrong error handling
// IASTVariable b = (IASTVariable)i.next();
// assertEquals( b.getName(), "b");
// assertFalse(i.hasNext());
}
public void testBug44340() throws Exception {
try {
// inline function with reference to variables declared after them
IASTScope scope = parse ("class A{ int getX() {return x[1];} int x[10];};");
Iterator i = scope.getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
Iterator j = getDeclarations(classA);
IASTMethod g = (IASTMethod)j.next();
IASTField x = (IASTField)j.next();
assertFalse(j.hasNext());
assertAllReferences( 1, createTaskList( new Task( x )));
} catch (ParserException e){
// parsing fails for now
}
}
}

View file

@ -96,6 +96,7 @@ public class CompleteParseASTExpressionTest extends CompleteParseBaseTest{
IASTFunction f1 = (IASTFunction) i.next();
IASTFunction f2 = (IASTFunction) i.next();
IASTMethod m = (IASTMethod) i.next();
Iterator r = callback.getReferences().iterator();
assertAllReferences( 4, createTaskList( new Task( cl, 3 ), new Task( f2 )));
}
// Kind PRIMARY_BRACKETED_EXPRESSION : LHS

View file

@ -41,6 +41,7 @@ import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
@ -751,7 +752,7 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
}
public void testBug43503A() throws Exception {
Iterator i = parse("class SD_01 { f_SD_01() {}}; int main(){ SD_01 * a = new SD_01(); a->f_SD_01(); } ").getDeclarations();
Iterator i = parse("class SD_01 { void f_SD_01() {}}; int main(){ SD_01 * a = new SD_01(); a->f_SD_01(); } ").getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
Iterator j = getDeclarations(classA);
IASTMethod f = (IASTMethod)j.next();
@ -859,19 +860,7 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
assertFalse( i.hasNext() );
assertAllReferences( 8, createTaskList( new Task( SD_02), new Task( SD_01, 3 ), new Task( a ), new Task( f_SD_01 ), new Task( f_SD_02 ), new Task( next ) ));
}
public void testErrorHandling_1() throws Exception
{
Iterator i = parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ).getDeclarations();
IASTVariable x = (IASTVariable)i.next();
assertEquals( x.getName(), "x");
IASTClassSpecifier A = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
IASTVariable anotherA = (IASTVariable)i.next();
IASTVariable b = (IASTVariable)i.next();
assertEquals( b.getName(), "b");
assertFalse(i.hasNext());
}
public void testBug43679_A () throws Exception
{
try{ // this used to throw a null pointer exception
@ -917,7 +906,31 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
IASTMethod constructor = (IASTMethod) i.next();
assertEquals( constructor.getName(), "B" );
assertTrue( constructor.previouslyDeclared() );
}
}
public void testBug44342() throws Exception {
try{
IASTScope scope = parse("class A { void f(){} void f(int){} }; int main(){ A * a = new A(); a->f();} ");
Iterator i = scope.getDeclarations();
IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
Iterator j = getDeclarations(classA);
IASTMethod f = (IASTMethod)j.next();
IASTMethod f2 = (IASTMethod)j.next();
assertFalse(j.hasNext());
IASTFunction main = (IASTFunction) i.next();
assertFalse(i.hasNext());
Iterator k = getDeclarations(main);
assertTrue(k.hasNext());
IASTVariable a = (IASTVariable)k.next();
Iterator ref = callback.getReferences().iterator();
assertAllReferences( 4, createTaskList( new Task(classA , 2) , new Task( a ) , new Task (f) ));
}catch (ParserException e){
// parsing fails for now
fail();
}
}
public void testCDesignatedInitializers() throws Exception
{

View file

@ -2,15 +2,16 @@
#define INCLUDE_H
class Head {
Head ** array;
Head * operator *= ( int index );
Head * operator * ( int index ){ return array[ index ]; }
Head * operator += ( int index );
operator const short & ();
operator short ();
operator short int ();
Head ** array;
operator short int ();
};
class DeclsAndDefns{

View file

@ -1,3 +1,8 @@
2003-11-13 Hoda Amer
Changed the getExpressionResultType() in the complete factory to return
an object of type ExpressionResult.
Solved bug#44342: Failure to dereference function calls after a . or an ->
2003-11-07 John Camelon
Fixed Bug 39554 : _Pragma directive is not supported (ANSI C99)

View file

@ -37,7 +37,7 @@ public class ASTExpression implements IASTExpression
private final IASTTypeId typeId;
private final IASTNewExpressionDescriptor newDescriptor;
private final List references;
private List resultType;
private ExpressionResult resultType;
/**
*
*/
@ -52,7 +52,6 @@ public class ASTExpression implements IASTExpression
this.typeId = typeId;
this.newDescriptor = newDescriptor;
this.references = references;
resultType = new ArrayList();
this.idExpressionDuple = idExpression;
this.idExpression = idExpressionDuple == null ? "" : idExpressionDuple.toString();
}
@ -182,14 +181,14 @@ public class ASTExpression implements IASTExpression
/**
* @return
*/
public List getResultType() {
public ExpressionResult getResultType() {
return resultType;
}
/**
* @param i
*/
public void setResultType(List i) {
public void setResultType(ExpressionResult i) {
resultType = i;
}
/* (non-Javadoc)

View file

@ -83,6 +83,9 @@ import org.eclipse.cdt.internal.core.parser.pst.ISymbolASTExtension.ExtensionExc
/**
* @author jcamelon
*
* The CompleteParseASTFactory class creates a complete AST
* for a given parsed code.
*
*/
public class CompleteParseASTFactory extends BaseASTFactory implements IASTFactory
@ -676,7 +679,11 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
else
{
return new ASTVariableReference( offset, string, (IASTVariable)symbol.getASTExtension().getPrimaryDeclaration());
ASTSymbol s = symbol.getASTExtension().getPrimaryDeclaration();
if(s instanceof IASTVariable)
return new ASTVariableReference( offset, string, (IASTVariable)s);
else if (s instanceof IASTParameterDeclaration)
return new ASTParameterReference( offset, string, (IASTParameterDeclaration)s);
}
}
throw new ASTSemanticException();
@ -763,57 +770,21 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{
try{
List references = new ArrayList();
//look up id & add to references
IContainerSymbol startingScope = scopeToSymbol( scope );
//look up typeId & add to references
ISymbol symbol = null;
if( idExpression != null )
symbol = lookupQualifiedName( startingScope, idExpression, references, false );
ISymbol symbol = getExpressionSymbol(scope, kind, lhs, rhs, idExpression, references );
// "a.m" or "a->m : lookup m in the scope of the declaration of a
if((kind == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
|| (kind == IASTExpression.Kind.PM_DOTSTAR)
|| (kind == IASTExpression.Kind.PM_ARROWSTAR)
){
TypeInfo lhsInfo = (TypeInfo) ((ASTExpression)lhs).getResultType().iterator().next();
if(lhsInfo != null){
ISymbol firstContainingScope = (ISymbol) lhsInfo.getTypeSymbol();
if(firstContainingScope != null){
ISymbol containingScope = firstContainingScope.getTypeSymbol();
if(containingScope != null){
symbol = lookupQualifiedName((IContainerSymbol)containingScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false);
}
}
}
}
// Try to figure out the result that this expression evaluates to
ExpressionResult expressionResult = getExpressionResultType(kind, lhs, rhs, thirdExpression, typeId, literal, symbol);
// go up the scope until you hit a class
if (kind == IASTExpression.Kind.PRIMARY_THIS){
ASTScope parentScope = (ASTScope)scope;
while (!(parentScope instanceof IASTClassSpecifier) )
{
parentScope = (ASTScope)((ASTScope)parentScope).getOwnerScope();
}
if(parentScope instanceof IASTClassSpecifier)
symbol = parentScope.getSymbol();
}
// expression results could be empty, but should not be null
if(expressionResult == null)
throw new ASTSemanticException();
if (kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
ITokenDuple functionId = ((ASTExpression)lhs).getIdExpressionTokenDuple();
List parameters = ((ASTExpression)rhs).getResultType();
symbol = lookupQualifiedName(startingScope, functionId, TypeInfo.t_function, parameters, references, false);
}
ASTExpression expression = new ASTExpression( kind, lhs, rhs, thirdExpression,
typeId, idExpression, literal, newDescriptor, references);
expression.setResultType (getExpressionResultType(expression, symbol));
// create the ASTExpression
ASTExpression expression = new ASTExpression( kind, lhs, rhs, thirdExpression,
typeId, idExpression, literal, newDescriptor, references);
// Assign the result to the created expression
expression.setResultType (expressionResult);
return expression;
@ -822,6 +793,105 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
}
}
/*
* Try and dereference the symbol in the expression
*/
private ISymbol getExpressionSymbol(
IASTScope scope,
Kind kind,
IASTExpression lhs,
IASTExpression rhs,
ITokenDuple idExpression,
List references )throws ASTSemanticException
{
ISymbol symbol = null;
IContainerSymbol startingScope = scopeToSymbol( scope );
//If the expression has an id, look up id and add it to references
if( idExpression != null )
symbol = lookupQualifiedName( startingScope, idExpression, references, false );
// If the expression is lookup symbol if it is in the scope of a type after a "." or an "->"
IContainerSymbol searchScope = getSearchScope(kind, lhs, startingScope);
if (!searchScope.equals(startingScope))
symbol = lookupQualifiedName(searchScope, ((ASTExpression)rhs).getIdExpressionTokenDuple(), references, false);
// get symbol if it is the "this" pointer
// go up the scope until you hit a class
if (kind == IASTExpression.Kind.PRIMARY_THIS){
try{
symbol = startingScope.lookup("this");
}catch (ParserSymbolTableException e){
throw new ASTSemanticException();
}
}
// lookup symbol if it is a function call
if (kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
ITokenDuple functionId = getFunctionId(lhs);
IContainerSymbol functionScope = getSearchScope(lhs.getExpressionKind(), lhs.getLHSExpression(), startingScope);
ExpressionResult expResult = ((ASTExpression)rhs).getResultType();
List parameters = null;
if(expResult instanceof ExpressionResultList){
ExpressionResultList expResultList = (ExpressionResultList) expResult;
parameters = expResultList.getResultList();
}else {
parameters = new ArrayList();
parameters.add(expResult.getResult());
}
symbol = lookupQualifiedName(functionScope, functionId, TypeInfo.t_function, parameters, references, false);
}
return symbol;
}
/*
* Returns the function ID token
*/
private ITokenDuple getFunctionId (IASTExpression expression){
if((expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
|| (expression.getExpressionKind() == IASTExpression.Kind.PM_DOTSTAR)
|| (expression.getExpressionKind() == IASTExpression.Kind.PM_ARROWSTAR)
){
return ((ASTExpression)expression.getRHSExpression()).getIdExpressionTokenDuple();
}
else {
return ((ASTExpression)expression).getIdExpressionTokenDuple();
}
}
private IContainerSymbol getSearchScope (Kind kind, IASTExpression lhs, IContainerSymbol startingScope) throws ASTSemanticException{
if((kind == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
|| (kind == IASTExpression.Kind.PM_DOTSTAR)
|| (kind == IASTExpression.Kind.PM_ARROWSTAR)
){
TypeInfo lhsInfo = (TypeInfo) ((ASTExpression)lhs).getResultType().getResult();
if(lhsInfo != null){
ISymbol firstContainingScope = (ISymbol) lhsInfo.getTypeSymbol();
if(firstContainingScope != null){
ISymbol containingScope = firstContainingScope.getTypeSymbol();
if(containingScope != null){
return (IContainerSymbol)containingScope;
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
}
else {
return startingScope;
}
}
/*
* Conditional Expression conversion
*/
@ -865,8 +935,8 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
rhs = rhs.getTypeSymbol().getTypeInfo();
}
if( lhs.isType(TypeInfo.t_class, TypeInfo.t_enumeration ) ||
rhs.isType(TypeInfo.t_class, TypeInfo.t_enumeration ) )
if( !lhs.isType(TypeInfo.t_bool, TypeInfo.t_enumerator ) &&
!rhs.isType(TypeInfo.t_bool, TypeInfo.t_enumerator ) )
{
throw new ASTSemanticException();
}
@ -932,327 +1002,373 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
return info;
}
}
protected List getExpressionResultType(IASTExpression expression, ISymbol symbol)throws ASTSemanticException{
List result = new ArrayList();
private TypeInfo addToInfo(ASTExpression exp, boolean flag, int mask)
throws ASTSemanticException{
if(exp == null)
throw new ASTSemanticException();
TypeInfo info = (TypeInfo)((ASTExpression)exp).getResultType().getResult();
info.setBit(flag, mask);
return info;
}
protected ExpressionResult getExpressionResultType(
Kind kind,
IASTExpression lhs,
IASTExpression rhs,
IASTExpression thirdExpression,
IASTTypeId typeId,
String literal,
ISymbol symbol)
throws ASTSemanticException{
ExpressionResult result = null;
TypeInfo info = new TypeInfo();
try {
// types that resolve to void
if ((expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_EMPTY)
|| (expression.getExpressionKind() == IASTExpression.Kind.THROWEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_DESTRUCTOR)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_DESTRUCTOR)
|| (expression.getExpressionKind() == IASTExpression.Kind.DELETE_CASTEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION)
if ((kind == IASTExpression.Kind.PRIMARY_EMPTY)
|| (kind == IASTExpression.Kind.THROWEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_DESTRUCTOR)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_DESTRUCTOR)
|| (kind == IASTExpression.Kind.DELETE_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.DELETE_VECTORCASTEXPRESSION)
){
info.setType(TypeInfo.t_void);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that resolve to int
if ((expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_INTEGER_LITERAL)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT)
if ((kind == IASTExpression.Kind.PRIMARY_INTEGER_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_INT)
){
info.setType(TypeInfo.t_int);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// size of is always unsigned int
if ((expression.getExpressionKind() == IASTExpression.Kind.UNARY_SIZEOF_TYPEID)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION)
if ((kind == IASTExpression.Kind.UNARY_SIZEOF_TYPEID)
|| (kind == IASTExpression.Kind.UNARY_SIZEOF_UNARYEXPRESSION)
){
info.setType(TypeInfo.t_int);
info.setBit(true, TypeInfo.isUnsigned);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that resolve to char
if( (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_CHAR_LITERAL)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR)){
if( (kind == IASTExpression.Kind.PRIMARY_CHAR_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_CHAR)){
info.setType(TypeInfo.t_char);
result.add(info);
// check that this is really only one literal
if(literal.length() > 1){
// this is a string
info.addPtrOperator(new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
}
result = new ExpressionResult(info);
return result;
}
// types that resolve to string
if (kind == IASTExpression.Kind.PRIMARY_STRING_LITERAL){
info.setType(TypeInfo.t_char);
info.addPtrOperator(new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
result = new ExpressionResult(info);
return result;
}
// types that resolve to float
if( (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_FLOAT_LITERAL)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT)){
if( (kind == IASTExpression.Kind.PRIMARY_FLOAT_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_FLOAT)){
info.setType(TypeInfo.t_float);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that resolve to string
if (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_STRING_LITERAL){
info.setType(TypeInfo.t_char);
info.addPtrOperator(new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
result.add(info);
return result;
}
// types that resolve to double
if( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE){
if( kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_DOUBLE){
info.setType(TypeInfo.t_double);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that resolve to wchar
if(expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART){
if(kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_WCHART){
info.setType(TypeInfo.t_wchar_t);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that resolve to bool
if( (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL)
|| (expression.getExpressionKind() == IASTExpression.Kind.RELATIONAL_GREATERTHAN)
|| (expression.getExpressionKind() == IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO)
|| (expression.getExpressionKind() == IASTExpression.Kind.RELATIONAL_LESSTHAN)
|| (expression.getExpressionKind() == IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO)
|| (expression.getExpressionKind() == IASTExpression.Kind.EQUALITY_EQUALS)
|| (expression.getExpressionKind() == IASTExpression.Kind.EQUALITY_NOTEQUALS)
|| (expression.getExpressionKind() == IASTExpression.Kind.LOGICALANDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.LOGICALOREXPRESSION)
if( (kind == IASTExpression.Kind.PRIMARY_BOOLEAN_LITERAL)
|| (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_BOOL)
|| (kind == IASTExpression.Kind.RELATIONAL_GREATERTHAN)
|| (kind == IASTExpression.Kind.RELATIONAL_GREATERTHANEQUALTO)
|| (kind == IASTExpression.Kind.RELATIONAL_LESSTHAN)
|| (kind == IASTExpression.Kind.RELATIONAL_LESSTHANEQUALTO)
|| (kind == IASTExpression.Kind.EQUALITY_EQUALS)
|| (kind == IASTExpression.Kind.EQUALITY_NOTEQUALS)
|| (kind == IASTExpression.Kind.LOGICALANDEXPRESSION)
|| (kind == IASTExpression.Kind.LOGICALOREXPRESSION)
)
{
info.setType(TypeInfo.t_bool);
result.add(info);
result = new ExpressionResult(info);
return result;
}
// short added to a type
if (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT ){
info = (TypeInfo)((ASTExpression)expression.getLHSExpression()).getResultType().iterator().next();
info.setBit(true, TypeInfo.isShort);
result.add(info);
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SHORT ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isShort);
result = new ExpressionResult(info);
return result;
}
// long added to a type
if (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG ){
info = (TypeInfo)((ASTExpression)expression.getLHSExpression()).getResultType().iterator().next();
info.setBit(true, TypeInfo.isLong);
result.add(info);
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_LONG ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isLong);
result = new ExpressionResult(info);
return result;
}
// signed added to a type
if (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED ){
info = (TypeInfo)((ASTExpression)expression.getLHSExpression()).getResultType().iterator().next();
info.setBit(false, TypeInfo.isUnsigned);
result.add(info);
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_SIGNED ){
info = addToInfo((ASTExpression)lhs, false, TypeInfo.isUnsigned);
result = new ExpressionResult(info);
return result;
}
// unsigned added to a type
if (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED ){
info = (TypeInfo)((ASTExpression)expression.getLHSExpression()).getResultType().iterator().next();
info.setBit(true, TypeInfo.isUnsigned);
result.add(info);
if (kind == IASTExpression.Kind.POSTFIX_SIMPLETYPE_UNSIGNED ){
info = addToInfo((ASTExpression)lhs, true, TypeInfo.isUnsigned);
result = new ExpressionResult(info);
return result;
}
// Id expressions resolve to t_type, symbol already looked up
if( expression.getExpressionKind() == IASTExpression.Kind.ID_EXPRESSION )
if( kind == IASTExpression.Kind.ID_EXPRESSION )
{
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
result.add(info);
info.setTypeSymbol(symbol);
result = new ExpressionResult(info);
if (symbol == null)
result.setFailedToDereference(true);
return result;
}
// an ampersand implies a pointer operation of type reference
if (expression.getExpressionKind() == IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION){
List lhsResult = ((ASTExpression)expression.getLHSExpression()).getResultType();
if( lhsResult.iterator().hasNext())
info = (TypeInfo)lhsResult.iterator().next();
if (kind == IASTExpression.Kind.UNARY_AMPSND_CASTEXPRESSION){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null) && (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
} else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// a star implies a pointer operation of type pointer
if (expression.getExpressionKind() == IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION){
List lhsResult = ((ASTExpression)expression.getLHSExpression()).getResultType();
if( lhsResult.iterator().hasNext())
info = (TypeInfo)lhsResult.iterator().next();
if (kind == IASTExpression.Kind.UNARY_STAR_CASTEXPRESSION){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null)&& (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.indirection );
}else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// subscript
if (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_SUBSCRIPT){
List lhsResult = ((ASTExpression)expression.getLHSExpression()).getResultType();
if( lhsResult.iterator().hasNext())
info = (TypeInfo)lhsResult.iterator().next();
if (kind == IASTExpression.Kind.POSTFIX_SUBSCRIPT){
ASTExpression left =(ASTExpression)lhs;
if(left == null)
throw new ASTSemanticException();
info = (TypeInfo)left.getResultType().getResult();
if ((info != null) && (info.getTypeSymbol() != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.subscript );
}else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// the dot and the arrow resolves to the type of the member
if ((expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
if ((kind == IASTExpression.Kind.POSTFIX_DOT_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_IDEXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_DOT_TEMPL_IDEXPRESS)
|| (kind == IASTExpression.Kind.POSTFIX_ARROW_TEMPL_IDEXP)
){
if(symbol != null){
info = new TypeInfo(symbol.getTypeInfo());
}
result.add(info);
// else {
// throw new ASTSemanticException();
// }
result = new ExpressionResult(info);
return result;
}
// the dot* and the arrow* are the same as dot/arrow + unary star
if ((expression.getExpressionKind() == IASTExpression.Kind.PM_DOTSTAR)
|| (expression.getExpressionKind() == IASTExpression.Kind.PM_ARROWSTAR)
if ((kind == IASTExpression.Kind.PM_DOTSTAR)
|| (kind == IASTExpression.Kind.PM_ARROWSTAR)
){
List rhsResult = ((ASTExpression)expression.getRHSExpression()).getResultType();
if( rhsResult.iterator().hasNext())
info = (TypeInfo)rhsResult.iterator().next();
if (info != null){
ASTExpression right =(ASTExpression)rhs;
if (right == null)
throw new ASTSemanticException();
info = (TypeInfo)right.getResultType().getResult();
if ((info != null) && (symbol != null)){
info.addOperatorExpression( TypeInfo.OperatorExpression.indirection );
}
if(symbol != null){
info.setTypeSymbol(symbol);
}
result.add(info);
} else {
throw new ASTSemanticException();
}
result = new ExpressionResult(info);
return result;
}
// this
if (expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_THIS){
if (kind == IASTExpression.Kind.PRIMARY_THIS){
if(symbol != null)
{
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
info.addOperatorExpression( TypeInfo.OperatorExpression.addressof );
} else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// conditional
if (expression.getExpressionKind() == IASTExpression.Kind.CONDITIONALEXPRESSION){
ASTExpression right = (ASTExpression)expression.getRHSExpression();
ASTExpression third = (ASTExpression)expression.getThirdExpression();
if (kind == IASTExpression.Kind.CONDITIONALEXPRESSION){
ASTExpression right = (ASTExpression)rhs;
ASTExpression third = (ASTExpression)thirdExpression;
if((right != null ) && (third != null)){
TypeInfo rightType =(TypeInfo)right.getResultType().iterator().next();
TypeInfo thirdType =(TypeInfo)third.getResultType().iterator().next();
info = conditionalExpressionConversions(rightType, thirdType);
TypeInfo rightType =(TypeInfo)right.getResultType().getResult();
TypeInfo thirdType =(TypeInfo)third.getResultType().getResult();
if((rightType != null) && (thirdType != null)){
info = conditionalExpressionConversions(rightType, thirdType);
} else {
throw new ASTSemanticException();
}
} else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// new
if( ( expression.getExpressionKind() == IASTExpression.Kind.NEW_TYPEID )
|| ( expression.getExpressionKind() == IASTExpression.Kind.NEW_NEWTYPEID ) )
if( ( kind == IASTExpression.Kind.NEW_TYPEID )
|| ( kind == IASTExpression.Kind.NEW_NEWTYPEID ) )
{
try
{
info = expression.getTypeId().getTypeSymbol().getTypeInfo();
info = typeId.getTypeSymbol().getTypeInfo();
info.addPtrOperator( new TypeInfo.PtrOp(TypeInfo.PtrOp.t_pointer));
}
catch (ASTNotImplementedException e)
{
// will never happen
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// types that use the usual arithmetic conversions
if((expression.getExpressionKind() == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY)
|| (expression.getExpressionKind() == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE)
|| (expression.getExpressionKind() == IASTExpression.Kind.MULTIPLICATIVE_MODULUS)
|| (expression.getExpressionKind() == IASTExpression.Kind.ADDITIVE_PLUS)
|| (expression.getExpressionKind() == IASTExpression.Kind.ADDITIVE_MINUS)
|| (expression.getExpressionKind() == IASTExpression.Kind.ANDEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.EXCLUSIVEOREXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.INCLUSIVEOREXPRESSION)
if((kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY)
|| (kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE)
|| (kind == IASTExpression.Kind.MULTIPLICATIVE_MODULUS)
|| (kind == IASTExpression.Kind.ADDITIVE_PLUS)
|| (kind == IASTExpression.Kind.ADDITIVE_MINUS)
|| (kind == IASTExpression.Kind.ANDEXPRESSION)
|| (kind == IASTExpression.Kind.EXCLUSIVEOREXPRESSION)
|| (kind == IASTExpression.Kind.INCLUSIVEOREXPRESSION)
){
ASTExpression left = (ASTExpression)expression.getLHSExpression();
ASTExpression right = (ASTExpression)expression.getRHSExpression();
ASTExpression left = (ASTExpression)lhs;
ASTExpression right = (ASTExpression)rhs;
if((left != null ) && (right != null)){
TypeInfo leftType =(TypeInfo)left.getResultType().iterator().next();
TypeInfo rightType =(TypeInfo)right.getResultType().iterator().next();
TypeInfo leftType =(TypeInfo)left.getResultType().getResult();
TypeInfo rightType =(TypeInfo)right.getResultType().getResult();
info = usualArithmeticConversions(leftType, rightType);
}
else
else {
throw new ASTSemanticException();
result.add(info);
}
result = new ExpressionResult(info);
return result;
}
// types that resolve to LHS types
if ((expression.getExpressionKind() == IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_INCREMENT)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DECREMENT)
|| (expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_INCREMENT)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_DECREMENT)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION)
|| (expression.getExpressionKind() == IASTExpression.Kind.SHIFT_LEFT)
|| (expression.getExpressionKind() == IASTExpression.Kind.SHIFT_RIGHT)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR)
|| (expression.getExpressionKind() == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR)
if ((kind == IASTExpression.Kind.PRIMARY_BRACKETED_EXPRESSION)
|| (kind == IASTExpression.Kind.POSTFIX_INCREMENT)
|| (kind == IASTExpression.Kind.POSTFIX_DECREMENT)
|| (kind == IASTExpression.Kind.POSTFIX_TYPEID_EXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_INCREMENT)
|| (kind == IASTExpression.Kind.UNARY_DECREMENT)
|| (kind == IASTExpression.Kind.UNARY_PLUS_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_MINUS_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_NOT_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.UNARY_TILDE_CASTEXPRESSION)
|| (kind == IASTExpression.Kind.SHIFT_LEFT)
|| (kind == IASTExpression.Kind.SHIFT_RIGHT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_NORMAL)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_PLUS)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MINUS)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MULT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_DIV)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_MOD)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_LSHIFT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_RSHIFT)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_AND)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_OR)
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR)
){
ASTExpression left = (ASTExpression)expression.getLHSExpression();
ASTExpression left = (ASTExpression)lhs;
if(left != null){
info =(TypeInfo)left.getResultType().iterator().next();
info =(TypeInfo)left.getResultType().getResult();
} else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// the cast changes the types to the type looked up in typeId = symbol
if(( expression.getExpressionKind() == IASTExpression.Kind.CASTEXPRESSION )
|| ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_DYNAMIC_CAST )
|| ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_STATIC_CAST )
|| ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_REINTERPRET_CAST )
|| ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_CONST_CAST )
if(( kind == IASTExpression.Kind.CASTEXPRESSION )
|| ( kind == IASTExpression.Kind.POSTFIX_DYNAMIC_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_STATIC_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_REINTERPRET_CAST )
|| ( kind == IASTExpression.Kind.POSTFIX_CONST_CAST )
){
try{
info = new TypeInfo(expression.getTypeId().getTypeSymbol().getTypeInfo());
}catch (Exception e){
info = new TypeInfo(typeId.getTypeSymbol().getTypeInfo());
}catch (ASTNotImplementedException e)
{
// will never happen
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
// a list collects all types of left and right hand sides
if(expression.getExpressionKind() == IASTExpression.Kind.EXPRESSIONLIST){
if(expression.getLHSExpression() != null){
Iterator i = ((ASTExpression)expression.getLHSExpression()).getResultType().iterator();
while (i.hasNext()){
result.add(i.next());
}
if(kind == IASTExpression.Kind.EXPRESSIONLIST){
result = new ExpressionResultList();
if(lhs != null){
TypeInfo leftType = ((ASTExpression)lhs).getResultType().getResult();
result.setResult(leftType);
}
if(expression.getRHSExpression() != null){
Iterator i = ((ASTExpression)expression.getRHSExpression()).getResultType().iterator();
while (i.hasNext()){
result.add(i.next());
}
if(rhs != null){
TypeInfo rightType = ((ASTExpression)rhs).getResultType().getResult();
result.setResult(rightType);
}
return result;
}
// a function call type is the return type of the function
if(expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
if(kind == IASTExpression.Kind.POSTFIX_FUNCTIONCALL){
if(symbol != null){
IParameterizedSymbol psymbol = (IParameterizedSymbol) symbol;
ISymbol returnTypeSymbol = psymbol.getReturnType();
info.setType(returnTypeSymbol.getType());
info.setTypeSymbol(returnTypeSymbol);
}
result.add(info);
if(returnTypeSymbol != null){
info.setType(returnTypeSymbol.getType());
info.setTypeSymbol(returnTypeSymbol);
}else {
// this is call to a constructor
}
}
result = new ExpressionResult(info);
if(symbol == null)
result.setFailedToDereference(true);
return result;
}
if( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_TYPEID_TYPEID )
// typeid
if( kind == IASTExpression.Kind.POSTFIX_TYPEID_TYPEID )
{
IASTTypeId typeId = expression.getTypeId();
try
{
info = typeId.getTypeSymbol().getTypeInfo();
@ -1261,24 +1377,26 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
{
// will not ever happen from within CompleteParseASTFactory
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
if ( ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER )
|| ( expression.getExpressionKind() == IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID ) )
// typename
if ( ( kind == IASTExpression.Kind.POSTFIX_TYPENAME_IDENTIFIER )
|| ( kind == IASTExpression.Kind.POSTFIX_TYPENAME_TEMPLATEID ) )
{
if(symbol != null){
info.setType(TypeInfo.t_type);
info.setTypeSymbol(symbol);
} else {
throw new ASTSemanticException();
}
result.add(info);
result = new ExpressionResult(info);
return result;
}
} catch (Exception e){
throw new ASTSemanticException();
}
return result;
return null;
}
protected void getExpressionReferences(IASTExpression expression, List references)

View file

@ -0,0 +1,59 @@
/**********************************************************************
* 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:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.ast.complete;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/**
* @author hamer
*
*/
public class ExpressionResult {
private TypeInfo result;
private boolean failedToDereference = false;
ExpressionResult(){
result = new TypeInfo();
}
ExpressionResult(TypeInfo result){
this.result = result;
}
/**
* @return
*/
public TypeInfo getResult() {
return result;
}
/**
* @param info
*/
public void setResult(TypeInfo info) {
result = info;
}
/**
* @return
*/
public boolean isFailedToDereference() {
return failedToDereference;
}
/**
* @param b
*/
public void setFailedToDereference(boolean b) {
failedToDereference = b;
}
}

View file

@ -0,0 +1,57 @@
/**********************************************************************
* 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:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.ast.complete;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.internal.core.parser.pst.TypeInfo;
/**
* @author hamer
*
*/
public class ExpressionResultList extends ExpressionResult {
private List resultList = new ArrayList();
ExpressionResultList(){
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionResult#getResult()
*/
public TypeInfo getResult() {
// TODO Auto-generated method stub
return (TypeInfo)resultList.get(0);
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionResult#setResult(org.eclipse.cdt.internal.core.parser.pst.TypeInfo)
*/
public void setResult(TypeInfo info) {
// TODO Auto-generated method stub
resultList.add(info);
}
/**
* @return
*/
public List getResultList() {
return resultList;
}
/**
* @param list
*/
public void setResultList(List list) {
resultList = list;
}
}