diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
index dbc2c9dc718..7324703f8f0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
@@ -425,6 +425,10 @@ private static long getApproximateSize(IBasicType type) {
/**
* Checks whether a target integral type can represent all values of a source integral type.
+ *
+ * If CPPSemantics current lookup point is set, size and alignment information is derived
+ * from predefined type size macros available through current AST. If there is no current
+ * lookup point, {@link #getApproximateSize(IBasicType)} is used to guess size of integral types.
*
* @param target the target integral type
* @param source the source integral type
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
index 420f943ff31..b18c97780af 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
@@ -30,6 +30,7 @@
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
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;
/**
* Binary expression for c
@@ -213,6 +214,15 @@ public void replace(IASTNode child, IASTNode other) {
@Override
public IType getExpressionType() {
+ CPPSemantics.pushLookupPoint(this);
+ try {
+ return getExpressionTypeImpl();
+ } finally {
+ CPPSemantics.popLookupPoint();
+ }
+ }
+
+ private IType getExpressionTypeImpl() {
final int op = getOperator();
IType originalType1 = getOperand1().getExpressionType();
IType originalType2 = getOperand2().getExpressionType();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
index 9548edf594c..e30cfce2de8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
@@ -28,6 +28,7 @@
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.ProblemType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes;
/**
@@ -163,6 +164,15 @@ public void replace(IASTNode child, IASTNode other) {
@Override
public IType getExpressionType() {
+ CPPSemantics.pushLookupPoint(this);
+ try {
+ return getExpressionTypeImpl();
+ } finally {
+ CPPSemantics.popLookupPoint();
+ }
+ }
+
+ private IType getExpressionTypeImpl() {
IASTExpression positiveExpression = getPositiveResultExpression();
if (positiveExpression == null) {
positiveExpression = getLogicalConditionExpression();
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 fe32496e653..2bb89fad3c6 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
@@ -212,6 +212,7 @@
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
+import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
@@ -323,12 +324,15 @@ public static void popLookupPoint() {
/**
* Get the current point of instantiation / point of lookup for name lookups.
- *
+ *
* NOTE: This is meant to be used primarily for "declaredBefore" purposes, that is,
* for determining whether something was declared before or after the point
* of lookup. It is NOT meant to be used as a general mechanism for accessing
* information about a call site without having to pass that information along
* the usual way (via function arguments).
+ *
+ * NOTE: This is also used to provide {@link SizeofCalculator} with access to predefined
+ * type size macros of current translation unit via AST object.
*/
public static IASTNode getCurrentLookupPoint() {
Deque lookupPoints = fLookupPoints.get();