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 02d25f564e8..37f1353c852 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 @@ -194,6 +194,7 @@ 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.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; +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.ProblemType; @@ -2321,11 +2322,11 @@ public class CPPVisitor extends ASTQueries { if (initClause instanceof IASTEqualsInitializer) { initClause = ((IASTEqualsInitializer) initClause).getInitializerClause(); if (initClause instanceof IASTLiteralExpression && SemanticUtil.isConst(type)) { - IType t = SemanticUtil.getNestedType(type, TDEF | ALLCVQ); - if (t instanceof CPPBasicType) { - IValue v = SemanticUtil.getValueOfInitializer(declarator.getInitializer(), t); - if (v.numberValue() != null) - ((CPPBasicType) t).setAssociatedNumericalValue(v.numberValue().longValue()); + // The check here avoids performing the computation in getValueOfInitialize() + // in cases where we wouldn't use it anyways because we don't have a CPPBasicType. + if (SemanticUtil.getNestedType(type, TDEF | ALLCVQ) instanceof CPPBasicType) { + type = associateTypeWithValue(type, + SemanticUtil.getValueOfInitializer(declarator.getInitializer(), type)); } } } @@ -2349,6 +2350,42 @@ public class CPPVisitor extends ASTQueries { } } + /** + * Returns an IType representing the same type as the argument, but + * which also knows its value. + * + * This only has an effect for built-in types (modulo cv-qualification + * and typedefs), and in cases where the a concrete numerical value + * is known. + * + * The returned IType object may be different from the argument. + */ + public static IType associateTypeWithValue(IType type, IValue value) { + Number numberValue = value.numberValue(); + if (numberValue != null) { + return associateTypeWithValue(type, numberValue.longValue()); + } + return type; + } + + private static IType associateTypeWithValue(IType type, long value) { + if (type instanceof ITypeContainer) { + ITypeContainer typeContainer = (ITypeContainer) type; + IType oldInner = typeContainer.getType(); + IType newInner = associateTypeWithValue(oldInner, value); + if (oldInner != newInner) { + ITypeContainer clone = (ITypeContainer) typeContainer.clone(); + clone.setType(newInner); + return clone; + } + } else if (type instanceof CPPBasicType) { + CPPBasicType clone = ((CPPBasicType) type).clone(); + clone.setAssociatedNumericalValue(value); + return clone; + } + return type; + } + private static IType createAutoParameterType(IASTDeclSpecifier declSpec, IASTDeclarator declarator, ICPPASTParameterDeclaration declaration, PlaceholderKind placeholder) { // decltype(auto) is not allowed in parameters. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index 429ea286340..5d8348e5ab8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -161,15 +161,8 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation { case op_sizeofParameterPack: case op_alignof: IType result = (IType) CPPVisitor.get_SIZE_T().clone(); - IType simplifiedResult = SemanticUtil.getSimplifiedType(result); - if (simplifiedResult instanceof CPPBasicType) { - CPPBasicType t = (CPPBasicType) simplifiedResult; - IValue value = getValue(); - if (value != null && value.numberValue() != null) { - t.setAssociatedNumericalValue(value.numberValue().longValue()); - } - // We're still returning 'result', which is now modified. - // This preserves the 'size_t' typedef. + if (SemanticUtil.getSimplifiedType(result) instanceof CPPBasicType) { + result = CPPVisitor.associateTypeWithValue(result, getValue()); } return result; case op_typeid: