1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Moved implementation of CPPVisitor.getExpressionType to the various expression nodes.

This commit is contained in:
Markus Schorn 2009-01-26 13:44:18 +00:00
parent 727408d5c0
commit 524acc9028
20 changed files with 473 additions and 456 deletions

View file

@ -22,7 +22,6 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.Assert;
/**
@ -59,7 +58,7 @@ public abstract class ASTAmbiguousCastVsFunctionCallExpression extends ASTAmbigu
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(getExpressions()[0]);
return fCastExpression.getExpressionType();
}
public IASTExpression[] getExpressions() {

View file

@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements
IASTAmbiguousExpression {
@ -55,7 +54,7 @@ public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
return exp[0].getExpressionType();
}
}

View file

@ -11,13 +11,19 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* @author jcamelon
@ -111,7 +117,25 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArray
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
IType t = getArrayExpression().getExpressionType();
t= SemanticUtil.getUltimateTypeUptoPointers(t);
try {
if (t instanceof ICPPClassType) {
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
if (op != null) {
return op.getType().getReturnType();
}
}
if (t instanceof IPointerType) {
return ((IPointerType) t).getType();
}
if (t instanceof IArrayType) {
return ((IArrayType) t).getType();
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
}
}

View file

@ -11,13 +11,25 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* @author jcamelon
@ -123,8 +135,84 @@ public class CPPASTBinaryExpression extends ASTNode implements
public IType getExpressionType() {
if (type == null) {
type= CPPVisitor.getExpressionType(this);
type= createExpressionType();
}
return type;
}
private IType createExpressionType() {
// Check for overloaded operator.
IType type1 = getOperand1().getExpressionType();
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
if (ultimateType1 instanceof IProblemBinding) {
return type1;
}
if (ultimateType1 instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
if (operator != null) {
try {
return operator.getType().getReturnType();
} catch (DOMException e) {
return e.getProblem();
}
}
}
IType type2 = getOperand2().getExpressionType();
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
if (ultimateType2 instanceof IProblemBinding) {
return type2;
}
if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration ||
ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) {
// If at least one of the types is user defined, the operator can be overloaded.
ICPPFunction operator = CPPSemantics.findOverloadedOperator(this);
if (operator != null) {
try {
return operator.getType().getReturnType();
} catch (DOMException e) {
return e.getProblem();
}
}
}
final int op = getOperator();
switch (op) {
case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan:
case IASTBinaryExpression.op_greaterEqual:
case IASTBinaryExpression.op_greaterThan:
case IASTBinaryExpression.op_logicalAnd:
case IASTBinaryExpression.op_logicalOr:
case IASTBinaryExpression.op_equals:
case IASTBinaryExpression.op_notequals:
CPPBasicType basicType= new CPPBasicType(ICPPBasicType.t_bool, 0);
basicType.setFromExpression(this);
return basicType;
case IASTBinaryExpression.op_plus:
if (ultimateType2 instanceof IPointerType) {
return ultimateType2;
}
break;
case IASTBinaryExpression.op_minus:
if (ultimateType2 instanceof IPointerType) {
if (ultimateType1 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(this);
}
return ultimateType1;
}
break;
case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) {
try {
return ((ICPPPointerToMemberType) type2).getType();
} catch (DOMException e) {
return e.getProblem();
}
}
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignature().toCharArray());
}
return type1;
}
}

View file

@ -14,7 +14,9 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -92,4 +94,9 @@ public class CPPASTCastExpression extends CPPASTUnaryExpression implements ICPPA
}
return true;
}
@Override
public IType getExpressionType() {
return CPPVisitor.createType(typeId.getDeclSpecifier(), typeId.getAbstractDeclarator());
}
}

View file

@ -12,10 +12,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -75,7 +76,13 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
}
IASTCompoundStatement compound = getCompoundStatement();
IASTStatement[] statements = compound.getStatements();
if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement)
return ((IASTExpressionStatement) st).getExpression().getExpressionType();
}
return null;
}
}

View file

@ -14,10 +14,10 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -134,7 +134,14 @@ public class CPPASTConditionalExpression extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
IASTExpression positiveExpression = getPositiveResultExpression();
if (positiveExpression == null) {
positiveExpression= getLogicalConditionExpression();
}
IType t2 = positiveExpression.getExpressionType();
IType t3 = getNegativeResultExpression().getExpressionType();
if (t3 instanceof IPointerType || t2 == null)
return t3;
return t2;
}
}

View file

@ -15,7 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/**
* @author jcamelon
@ -100,7 +100,6 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
return CPPSemantics.VOID_TYPE;
}
}

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -86,7 +85,11 @@ public class CPPASTExpressionList extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
for (int i = expressions.length-1; i >= 0 ; i--) {
IASTExpression expr= expressions[i];
if (expr != null)
return expr.getExpressionType();
}
return null;
}
}

View file

@ -15,18 +15,22 @@ import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -140,7 +144,24 @@ public class CPPASTFieldReference extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
IASTName name= getFieldName();
IBinding binding = name.resolvePreBinding();
try {
if (binding instanceof IVariable) {
return ((IVariable) binding).getType();
} else if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType();
} else if (binding instanceof IFunction) {
return ((IFunction) binding).getType();
} else if (binding instanceof ICPPUnknownBinding) {
return CPPUnknownClass.createUnnamedInstance();
} else if (binding instanceof IProblemBinding) {
return (IType) binding;
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
}
public IBinding[] findBindings(IASTName n, boolean isPrefix) {

View file

@ -11,13 +11,26 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* @author jcamelon
@ -110,7 +123,46 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
try {
IType t= null;
if (functionName instanceof IASTIdExpression) {
final IBinding binding= ((IASTIdExpression) functionName).getName().resolvePreBinding();
if (binding instanceof ICPPConstructor) {
IBinding owner= binding.getOwner();
if (owner instanceof ICPPClassType) {
return (ICPPClassType) owner;
}
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE, binding.getName().toCharArray());
} else if (binding instanceof IFunction) {
t = ((IFunction) binding).getType();
} else if (binding instanceof IVariable) {
t = ((IVariable) binding).getType();
} else if (binding instanceof IType) {
return (IType) binding; // constructor or simple type initializer
} else if (binding instanceof IProblemBinding) {
return (IProblemBinding) binding;
}
} else {
t= functionName.getExpressionType();
}
t= SemanticUtil.getUltimateTypeUptoPointers(t);
if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType();
} else if (t instanceof ICPPClassType) {
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
if (op != null) {
return op.getType().getReturnType();
}
} else if (t instanceof IPointerType) {
t= SemanticUtil.getUltimateTypeUptoPointers(((IPointerType) t).getType());
if (t instanceof IFunctionType) {
return ((IFunctionType) t).getReturnType();
}
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
}
}

View file

@ -12,14 +12,20 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -83,7 +89,27 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IAS
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
IBinding binding = name.resolvePreBinding();
try {
if (binding instanceof IVariable) {
return ((IVariable) binding).getType();
} else if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType();
} else if (binding instanceof IProblemBinding) {
return (IType) binding;
} else if (binding instanceof IFunction) {
return ((IFunction) binding).getType();
} else if (binding instanceof ICPPTemplateNonTypeParameter) {
return ((ICPPTemplateNonTypeParameter) binding).getType();
} else if (binding instanceof ICPPClassType) {
return ((ICPPClassType) binding);
} else if (binding instanceof ICPPUnknownBinding) {
return CPPUnknownClass.createUnnamedInstance();
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
}
public IBinding[] findBindings(IASTName n, boolean isPrefix) {

View file

@ -12,8 +12,11 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -83,9 +86,86 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
switch (getKind()) {
case lk_this: {
IScope scope = CPPVisitor.getContainingScope(this);
return CPPVisitor.getThisType(scope);
}
case lk_true:
case lk_false:
return new CPPBasicType(ICPPBasicType.t_bool, 0, this);
case lk_char_constant:
return new CPPBasicType(IBasicType.t_char, 0, this);
case lk_float_constant:
return classifyTypeOfFloatLiteral();
case lk_integer_constant:
return classifyTypeOfIntLiteral();
case lk_string_literal:
IType type = new CPPBasicType(IBasicType.t_char, 0, this);
type = new CPPQualifierType(type, true, false);
return new CPPPointerType(type);
}
return null;
}
private IType classifyTypeOfFloatLiteral() {
final char[] lit= getValue();
final int len= lit.length;
int kind= IBasicType.t_double;
int flags= 0;
if (len > 0) {
switch (lit[len - 1]) {
case 'f': case 'F':
kind= IBasicType.t_float;
break;
case 'l': case 'L':
flags |= ICPPBasicType.IS_LONG;
break;
}
}
return new CPPBasicType(kind, flags, this);
}
private IType classifyTypeOfIntLiteral() {
int makelong= 0;
boolean unsigned= false;
final char[] lit= getValue();
for (int i= lit.length - 1; i >= 0; i--) {
final char c= lit[i];
if (!(c > 'f' && c <= 'z') && !(c > 'F' && c <= 'Z')) {
break;
}
switch (c) {
case 'u':
case 'U':
unsigned = true;
break;
case 'l':
case 'L':
makelong++;
break;
}
}
int flags= 0;
if (unsigned) {
flags |= ICPPBasicType.IS_UNSIGNED;
}
if (makelong > 1) {
flags |= ICPPBasicType.IS_LONG_LONG;
GPPBasicType result = new GPPBasicType(IBasicType.t_int, flags, null);
result.setFromExpression(this);
return result;
}
if (makelong == 1) {
flags |= ICPPBasicType.IS_LONG;
}
return new CPPBasicType(IBasicType.t_int, flags, this);
}
/**
* @deprecated, use {@link #setValue(char[])}, instead.
*/

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.Assert;
@ -131,7 +132,7 @@ public class CPPASTNewExpression extends ASTNode implements
public IASTExpression [] getNewTypeIdArrayExpressions() {
if( arrayExpressions == null ) {
if (typeId != null) {
IASTDeclarator dtor= CPPVisitor.findInnermostDeclarator(typeId.getAbstractDeclarator());
IASTDeclarator dtor= ASTQueries.findInnermostDeclarator(typeId.getAbstractDeclarator());
if (dtor instanceof IASTArrayDeclarator) {
IASTArrayDeclarator ad= (IASTArrayDeclarator) dtor;
IASTArrayModifier[] ams= ad.getArrayModifiers();
@ -151,7 +152,7 @@ public class CPPASTNewExpression extends ASTNode implements
public void addNewTypeIdArrayExpression(IASTExpression expression) {
assertNotFrozen();
Assert.isNotNull(typeId);
IASTDeclarator dtor= CPPVisitor.findInnermostDeclarator(typeId.getAbstractDeclarator());
IASTDeclarator dtor= ASTQueries.findInnermostDeclarator(typeId.getAbstractDeclarator());
if (dtor instanceof IASTArrayDeclarator == false) {
Assert.isNotNull(dtor);
Assert.isTrue(dtor.getParent() == typeId);
@ -208,7 +209,6 @@ public class CPPASTNewExpression extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
return CPPVisitor.createType(getTypeId());
}
}

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
@ -83,8 +84,13 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
return true;
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
}
public IType getExpressionType() {
switch (getOperator()) {
case IASTTypeIdExpression.op_sizeof:
return CPPVisitor.get_SIZE_T(this);
case IASTTypeIdExpression.op_typeid:
return CPPVisitor.get_type_info(this);
}
return CPPVisitor.createType(getTypeId());
}
}

View file

@ -14,11 +14,11 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
* @author jcamelon
@ -129,7 +129,10 @@ public class CPPASTTypenameExpression extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
IBinding binding = getName().resolvePreBinding();
if (binding instanceof IType) {
return (IType) binding;
}
return null;
}
}

View file

@ -11,13 +11,26 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
/**
* @author jcamelon
@ -97,7 +110,66 @@ public class CPPASTUnaryExpression extends ASTNode implements
}
public IType getExpressionType() {
return CPPVisitor.getExpressionType(this);
final int op= getOperator();
switch (op) {
case IASTUnaryExpression.op_sizeof:
return CPPVisitor.get_SIZE_T(this);
case IASTUnaryExpression.op_typeid:
return CPPVisitor.get_type_info(this);
}
IType type= getOperand().getExpressionType();
type = SemanticUtil.getUltimateTypeViaTypedefs(type);
if (op == IASTUnaryExpression.op_star) {
try {
type = SemanticUtil.getUltimateTypeUptoPointers(type);
if (type instanceof IProblemBinding) {
return type;
}
if (type instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(this, (ICPPClassType) type);
if (operator != null) {
return operator.getType().getReturnType();
}
} else if (type instanceof IPointerType || type instanceof IArrayType) {
return ((ITypeContainer) type).getType();
} else if (type instanceof ICPPUnknownType) {
return CPPUnknownClass.createUnnamedInstance();
}
return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE,
this.getRawSignature().toCharArray());
} catch (DOMException e) {
return e.getProblem();
}
} else if (op == IASTUnaryExpression.op_amper) {
if (type instanceof ICPPReferenceType) {
try {
type = ((ICPPReferenceType) type).getType();
} catch (DOMException e) {
}
}
if (type instanceof ICPPFunctionType) {
ICPPFunctionType functionType = (ICPPFunctionType) type;
IPointerType thisType = functionType.getThisType();
if (thisType != null) {
IType nestedType;
try {
nestedType = thisType.getType();
while (nestedType instanceof ITypeContainer) {
nestedType = ((ITypeContainer) nestedType).getType();
}
} catch (DOMException e) {
return e.getProblem();
}
return new CPPPointerToMemberType(type, (ICPPClassType) nestedType,
thisType.isConst(), thisType.isVolatile());
}
}
return new CPPPointerType(type);
} else if (type instanceof CPPBasicType) {
((CPPBasicType) type).setFromExpression(this);
}
return type;
}
}

View file

@ -2442,8 +2442,10 @@ public class CPPSemantics {
*/
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
IASTExpression owner = fieldReference.getFieldOwner();
IType type= CPPVisitor.getExpressionType(owner);
if (owner == null)
return null;
IType type= owner.getExpressionType();
if (!fieldReference.isPointerDereference())
return type;

View file

@ -21,12 +21,9 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
@ -34,8 +31,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@ -61,7 +56,6 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
@ -82,13 +76,11 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
@ -99,7 +91,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -112,7 +103,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
@ -137,7 +127,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
@ -146,7 +135,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
@ -172,7 +160,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType;
@ -180,7 +167,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexScope;
/**
@ -1666,11 +1652,12 @@ public class CPPVisitor extends ASTQueries {
(spec.isUnsigned() ? ICPPBasicType.IS_UNSIGNED : 0);
if (spec instanceof IGPPASTSimpleDeclSpecifier) {
IGPPASTSimpleDeclSpecifier gspec = (IGPPASTSimpleDeclSpecifier) spec;
if (gspec.getTypeofExpression() != null) {
type = getExpressionType(gspec.getTypeofExpression());
final IASTExpression typeofExpression = gspec.getTypeofExpression();
if (typeofExpression != null) {
type = typeofExpression.getExpressionType();
} else {
bits |= (gspec.isLongLong() ? ICPPBasicType.IS_LONG_LONG : 0);
type = new GPPBasicType(spec.getType(), bits, getExpressionType(gspec.getTypeofExpression()));
type = new GPPBasicType(spec.getType(), bits, null);
}
} else {
type = new CPPBasicType(spec.getType(), bits);
@ -1754,350 +1741,31 @@ public class CPPVisitor extends ASTQueries {
return null;
}
public static IType getExpressionType(IASTExpression expression) {
if (expression == null)
return null;
if (expression instanceof IASTIdExpression) {
IBinding binding = resolveBinding(expression);
try {
if (binding instanceof IVariable) {
return ((IVariable) binding).getType();
} else if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType();
} else if (binding instanceof IProblemBinding) {
return (IType) binding;
} else if (binding instanceof IFunction) {
return ((IFunction) binding).getType();
} else if (binding instanceof ICPPTemplateNonTypeParameter) {
return ((ICPPTemplateNonTypeParameter) binding).getType();
} else if (binding instanceof ICPPClassType) {
return ((ICPPClassType) binding);
} else if (binding instanceof ICPPUnknownBinding) {
return CPPUnknownClass.createUnnamedInstance();
}
} catch (DOMException e) {
return e.getProblem();
}
} else if (expression instanceof IASTCastExpression) {
IASTTypeId id = ((IASTCastExpression) expression).getTypeId();
IType type = createType(id.getDeclSpecifier());
return createType(type, id.getAbstractDeclarator());
} else if (expression instanceof IASTLiteralExpression) {
IASTLiteralExpression lit= (IASTLiteralExpression) expression;
switch (lit.getKind()) {
case IASTLiteralExpression.lk_this: {
IScope scope = getContainingScope(expression);
return getThisType(scope);
}
case IASTLiteralExpression.lk_true:
case IASTLiteralExpression.lk_false:
return new CPPBasicType(ICPPBasicType.t_bool, 0, expression);
case IASTLiteralExpression.lk_char_constant:
return new CPPBasicType(IBasicType.t_char, 0, expression);
case IASTLiteralExpression.lk_float_constant:
return classifyTypeOfFloatLiteral(lit);
case IASTLiteralExpression.lk_integer_constant:
return classifyTypeOfIntLiteral(lit);
case IASTLiteralExpression.lk_string_literal:
IType type = new CPPBasicType(IBasicType.t_char, 0, expression);
type = new CPPQualifierType(type, true, false);
return new CPPPointerType(type);
}
} else if (expression instanceof IASTFunctionCallExpression) {
IBinding binding = resolveBinding(expression);
if (binding instanceof ICPPConstructor) {
try {
IBinding owner= binding.getOwner();
if (owner instanceof ICPPClassType) {
return (ICPPClassType) owner;
}
} catch (DOMException e) {
return e.getProblem();
}
return new ProblemBinding(expression, IProblemBinding.SEMANTIC_BAD_SCOPE,
binding.getName().toCharArray());
} else if (binding instanceof IFunction) {
IFunctionType fType;
try {
fType = ((IFunction) binding).getType();
if (fType != null)
return fType.getReturnType();
} catch (DOMException e) {
return e.getProblem();
}
} else if (binding instanceof IVariable) {
try {
IType t = ((IVariable) binding).getType();
while (t instanceof ITypedef) {
t = ((ITypedef) t).getType();
}
if (t instanceof IPointerType && ((IPointerType) t).getType() instanceof IFunctionType) {
IFunctionType ftype = (IFunctionType) ((IPointerType) t).getType();
if (ftype != null)
return ftype.getReturnType();
}
t= getUltimateTypeUptoPointers(t);
if (t instanceof ICPPClassType) {
ICPPFunction op = CPPSemantics.findOperator(expression, (ICPPClassType) t);
if (op != null) {
return op.getType().getReturnType();
}
}
} catch (DOMException e) {
return e.getProblem();
}
} else if (binding instanceof ITypedef) {
try {
IType type = ((ITypedef) binding).getType();
while (type instanceof ITypedef)
type = ((ITypedef) type).getType();
if (type instanceof IFunctionType) {
return ((IFunctionType) type).getReturnType();
}
return type;
} catch (DOMException e) {
return e.getProblem();
}
} else if (binding instanceof IProblemBinding) {
return (IType) binding;
}
} else if (expression instanceof IASTBinaryExpression) {
final IASTBinaryExpression binary = (IASTBinaryExpression) expression;
// Check for overloaded operator.
IType type1 = binary.getOperand1().getExpressionType();
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
if (ultimateType1 instanceof IProblemBinding) {
return type1;
}
if (ultimateType1 instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) ultimateType1);
if (operator != null) {
try {
return operator.getType().getReturnType();
} catch (DOMException e) {
return e.getProblem();
public static IType getPointerDiffType(final IASTBinaryExpression binary) {
CPPBasicType basicType;
IScope scope = getContainingScope(binary);
try {
IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, binary);
if (bs.length > 0) {
for (IBinding b : bs) {
if (b instanceof IType && CPPSemantics.declaredBefore(b, binary, false)) {
return (IType) b;
}
}
}
IType type2 = binary.getOperand2().getExpressionType();
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
if (ultimateType2 instanceof IProblemBinding) {
return type2;
}
if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration ||
ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) {
// If at least one of the types is user defined, the operator can be overloaded.
ICPPFunction operator = CPPSemantics.findOverloadedOperator(binary);
if (operator != null) {
try {
return operator.getType().getReturnType();
} catch (DOMException e) {
return e.getProblem();
}
}
}
final int op = binary.getOperator();
switch (op) {
case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan:
case IASTBinaryExpression.op_greaterEqual:
case IASTBinaryExpression.op_greaterThan:
case IASTBinaryExpression.op_logicalAnd:
case IASTBinaryExpression.op_logicalOr:
case IASTBinaryExpression.op_equals:
case IASTBinaryExpression.op_notequals:
CPPBasicType basicType= new CPPBasicType(ICPPBasicType.t_bool, 0);
basicType.setFromExpression(expression);
return basicType;
case IASTBinaryExpression.op_plus:
if (ultimateType2 instanceof IPointerType) {
return ultimateType2;
}
break;
case IASTBinaryExpression.op_minus:
if (ultimateType2 instanceof IPointerType) {
if (ultimateType1 instanceof IPointerType) {
IScope scope = getContainingScope(expression);
try {
IBinding[] bs= CPPSemantics.findBindings(scope, PTRDIFF_T, false, expression);
if (bs.length > 0) {
for (IBinding b : bs) {
if (b instanceof IType && CPPSemantics.declaredBefore(b, binary, false)) {
return (IType) b;
}
}
}
} catch (DOMException e) {
}
basicType= new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED);
basicType.setFromExpression(expression);
return basicType;
}
return ultimateType1;
}
break;
case ICPPASTBinaryExpression.op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) {
try {
return ((ICPPPointerToMemberType) type2).getType();
} catch (DOMException e) {
return e.getProblem();
}
}
return new ProblemBinding(binary, IProblemBinding.SEMANTIC_INVALID_TYPE,
expression.getRawSignature().toCharArray());
}
return type1;
} else if (expression instanceof IASTUnaryExpression) {
final int op= ((IASTUnaryExpression) expression).getOperator();
switch (op) {
case IASTUnaryExpression.op_sizeof:
return get_SIZE_T(expression);
case IASTUnaryExpression.op_typeid:
return get_type_info(expression);
}
IType type= ((IASTUnaryExpression) expression).getOperand().getExpressionType();
type = SemanticUtil.getUltimateTypeViaTypedefs(type);
if (op == IASTUnaryExpression.op_star) {
try {
type = SemanticUtil.getUltimateTypeUptoPointers(type);
if (type instanceof IProblemBinding) {
return type;
}
if (type instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type);
if (operator != null) {
return operator.getType().getReturnType();
}
} else if (type instanceof IPointerType || type instanceof IArrayType) {
return ((ITypeContainer) type).getType();
} else if (type instanceof ICPPUnknownType) {
return CPPUnknownClass.createUnnamedInstance();
}
return new ProblemBinding(expression, IProblemBinding.SEMANTIC_INVALID_TYPE,
expression.getRawSignature().toCharArray());
} catch (DOMException e) {
return e.getProblem();
}
} else if (op == IASTUnaryExpression.op_amper) {
if (type instanceof ICPPReferenceType) {
try {
type = ((ICPPReferenceType) type).getType();
} catch (DOMException e) {
}
}
if (type instanceof ICPPFunctionType) {
ICPPFunctionType functionType = (ICPPFunctionType) type;
IPointerType thisType = functionType.getThisType();
if (thisType != null) {
IType nestedType;
try {
nestedType = thisType.getType();
while (nestedType instanceof ITypeContainer) {
nestedType = ((ITypeContainer) nestedType).getType();
}
} catch (DOMException e) {
return e.getProblem();
}
return new CPPPointerToMemberType(type, (ICPPClassType) nestedType,
thisType.isConst(), thisType.isVolatile());
}
}
return new CPPPointerType(type);
} else if (type instanceof CPPBasicType) {
((CPPBasicType) type).setFromExpression(expression);
}
return type;
} else if (expression instanceof ICPPASTFieldReference) {
IASTName name = ((ICPPASTFieldReference) expression).getFieldName();
IBinding binding = name.resolveBinding();
try {
if (binding instanceof IVariable)
return ((IVariable) binding).getType();
else if (binding instanceof IFunction)
return ((IFunction) binding).getType();
else if (binding instanceof IEnumerator)
return ((IEnumerator) binding).getType();
else if (binding instanceof ICPPUnknownBinding)
return CPPUnknownClass.createUnnamedInstance();
} catch (DOMException e) {
return e.getProblem();
}
} else if (expression instanceof IASTExpressionList) {
IASTExpression[] exps = ((IASTExpressionList) expression).getExpressions();
return exps[exps.length - 1].getExpressionType();
} else if (expression instanceof ICPPASTTypeIdExpression) {
ICPPASTTypeIdExpression typeidExp = (ICPPASTTypeIdExpression) expression;
switch (typeidExp.getOperator()) {
case IASTTypeIdExpression.op_sizeof:
return get_SIZE_T(typeidExp);
case IASTTypeIdExpression.op_typeid:
return get_type_info(expression);
}
return createType(typeidExp.getTypeId());
} else if (expression instanceof IASTArraySubscriptExpression) {
IType t = ((IASTArraySubscriptExpression) expression).getArrayExpression().getExpressionType();
try {
if (t instanceof ICPPReferenceType) {
t = ((ICPPReferenceType) t).getType();
}
if (t instanceof IQualifierType) {
t = ((IQualifierType) t).getType();
}
while (t instanceof ITypedef) {
t = ((ITypedef) t).getType();
}
if (t instanceof ICPPClassType) {
ICPPFunction op = CPPSemantics.findOperator(expression, (ICPPClassType) t);
if (op != null) {
return op.getType().getReturnType();
}
}
if (t instanceof IPointerType)
return ((IPointerType) t).getType();
else if (t instanceof IArrayType)
return ((IArrayType) t).getType();
} catch (DOMException e) {
}
} else if (expression instanceof IGNUASTCompoundStatementExpression) {
IASTCompoundStatement compound = ((IGNUASTCompoundStatementExpression) expression).getCompoundStatement();
IASTStatement[] statements = compound.getStatements();
if (statements.length > 0) {
IASTStatement st = statements[statements.length - 1];
if (st instanceof IASTExpressionStatement)
return ((IASTExpressionStatement) st).getExpression().getExpressionType();
}
} else if (expression instanceof IASTConditionalExpression) {
final IASTConditionalExpression conditional = (IASTConditionalExpression) expression;
IASTExpression positiveExpression = conditional.getPositiveResultExpression();
if (positiveExpression == null) {
positiveExpression= conditional.getLogicalConditionExpression();
}
IType t2 = positiveExpression.getExpressionType();
IType t3 = conditional.getNegativeResultExpression().getExpressionType();
if (t3 instanceof IPointerType || t2 == null)
return t3;
return t2;
} else if (expression instanceof ICPPASTDeleteExpression) {
return CPPSemantics.VOID_TYPE;
} else if (expression instanceof ICPPASTTypenameExpression) {
IBinding binding = ((ICPPASTTypenameExpression) expression).getName().resolveBinding();
if (binding instanceof IType)
return (IType) binding;
} else if (expression instanceof ICPPASTNewExpression) {
ICPPASTNewExpression newExp = (ICPPASTNewExpression) expression;
return createType(newExp.getTypeId());
} catch (DOMException e) {
}
return null;
basicType= new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED);
basicType.setFromExpression(binary);
return basicType;
}
private static IType get_type_info(IASTExpression expression) {
public static IType createType(final IASTDeclSpecifier declSpecifier, final IASTDeclarator dtor) {
IType type = createType(declSpecifier);
return createType(type, dtor);
}
public static IType get_type_info(IASTExpression expression) {
try {
IBinding[] std= expression.getTranslationUnit().getScope().find(STD);
for (IBinding binding : std) {
@ -2115,7 +1783,7 @@ public class CPPVisitor extends ASTQueries {
return new CPPBasicType(IBasicType.t_int, 0);
}
private static IType get_SIZE_T(IASTNode sizeofExpr) {
public static IType get_SIZE_T(IASTNode sizeofExpr) {
IScope scope = getContainingScope(sizeofExpr);
try {
IBinding[] bs = CPPSemantics.findBindings(scope, SIZE_T, false, sizeofExpr);
@ -2127,64 +1795,6 @@ public class CPPVisitor extends ASTQueries {
return new CPPBasicType(IBasicType.t_int, ICPPBasicType.IS_LONG | ICPPBasicType.IS_UNSIGNED);
}
private static IType classifyTypeOfFloatLiteral(final IASTLiteralExpression expr) {
final char[] lit= expr.getValue();
final int len= lit.length;
int kind= IBasicType.t_double;
int flags= 0;
if (len > 0) {
switch (lit[len - 1]) {
case 'f': case 'F':
kind= IBasicType.t_float;
break;
case 'l': case 'L':
flags |= ICPPBasicType.IS_LONG;
break;
}
}
return new CPPBasicType(kind, flags, expr);
}
private static IType classifyTypeOfIntLiteral(IASTLiteralExpression expression) {
int makelong= 0;
boolean unsigned= false;
final char[] lit= expression.getValue();
for (int i= lit.length - 1; i >= 0; i--) {
final char c= lit[i];
if (!(c > 'f' && c <= 'z') && !(c > 'F' && c <= 'Z')) {
break;
}
switch (c) {
case 'u':
case 'U':
unsigned = true;
break;
case 'l':
case 'L':
makelong++;
break;
}
}
int flags= 0;
if (unsigned) {
flags |= ICPPBasicType.IS_UNSIGNED;
}
if (makelong > 1) {
flags |= ICPPBasicType.IS_LONG_LONG;
GPPBasicType result = new GPPBasicType(IBasicType.t_int, flags, null);
result.setFromExpression(expression);
return result;
}
if (makelong == 1) {
flags |= ICPPBasicType.IS_LONG;
}
return new CPPBasicType(IBasicType.t_int, flags, expression);
}
public static IASTProblem[] getProblems(IASTTranslationUnit tu) {
CollectProblemsAction action = new CollectProblemsAction();
tu.accept(action);

View file

@ -238,4 +238,16 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope {
public IIndexName getScopeName() {
return fBinding.getScopeName();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PDOMCPPClassScope)
return fBinding.equals(((PDOMCPPClassScope) obj).fBinding);
return false;
}
@Override
public int hashCode() {
return fBinding.hashCode();
}
}