diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousCastVsFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousCastVsFunctionCallExpression.java index a52043da8c3..0a5044376a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousCastVsFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousCastVsFunctionCallExpression.java @@ -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() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java index 72bd23bca84..f5fce475edf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java @@ -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(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java index 78b381e42ba..65f356bf305 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index 83b3e05274c..ec2e6fa5892 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java index 8a8b9c419f7..ad49d8fe8e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java index 0b1ca787860..6ceab9d3de0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index ad12bab9f06..3388eb3a195 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java index 5c4ac063ec0..fc3192ffb54 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java index c3de2a70b20..89e5c537e2d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 4a17590ab1f..b7feb987572 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java index 05798a520e7..1367a6586a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java index bfa241f8639..fd01532a7b1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java index 7842c2ca4f9..17ce361ddb6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java @@ -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. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java index e7d5476443c..d99297e7b0f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java @@ -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()); } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java index b85669ffd8f..74c25e22573 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java index 8f3f0a15ccc..5274ad18038 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypenameExpression.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index c669f45094b..7ccb1b78135 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 027fce418e2..338bc607324 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 147293f5d19..df539d8e14a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java index 76862ec4f3a..c108010c40c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java @@ -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(); + } }