diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 19613597846..de894db0350 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -8251,4 +8251,21 @@ public class AST2TemplateTests extends AST2TestBase { public void testStrayFriends_419301() throws Exception { parseAndCheckBindings(); } + + // template + // constexpr T t(T) { + // return 0; + // } + // + // template <> + // constexpr unsigned t(unsigned) { + // return 1 + 1; + // } + // + // constexpr unsigned waldo = t(0u); + public void testSpecializationOfConstexprFunction_420995() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + ICPPVariable waldo = helper.assertNonProblem("waldo"); + assertEquals(2, waldo.getInitialValue().numericalValue().longValue()); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 1209dfc9783..b1624fb67ca 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -2454,4 +2454,19 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testFriendFunctionOfClassSpecialization_419301b() throws Exception { checkBindings(); } + + // template + // constexpr T t(T) { + // return 0; + // } + // + // template <> + // constexpr unsigned t(unsigned) { + // return 1 + 1; + // } + + // // empty source file + public void testSpecializationOfConstexprFunction_420995() throws Exception { + checkBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index ba209e681cb..b84c4bdbaed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -422,7 +422,7 @@ public class Value implements IValue { if (expr instanceof ICPPASTInitializerClause) { ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation(); - return new Value(null, evaluation); + return evaluation.getValue(expr); } return UNKNOWN; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java index 866ecda85e2..88217c5a00f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java @@ -35,8 +35,14 @@ public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument { evaluation.isTypeDependent() || evaluation.isValueDependent()) { fEvaluation= evaluation; } else { - fEvaluation= new EvalFixed(evaluation.getTypeOrFunctionSet(point), - evaluation.getValueCategory(point), evaluation.getValue(point)); + IValue value = evaluation.getValue(point); + // Avoid nesting EvalFixed's as nesting causes the signature to be different. + if (value.getEvaluation() instanceof EvalFixed) { + fEvaluation = value.getEvaluation(); + } else { + fEvaluation= new EvalFixed(evaluation.getTypeOrFunctionSet(point), + evaluation.getValueCategory(point), value); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 59b4730766d..5a791eb818c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; @@ -149,12 +148,10 @@ public class EvalFunctionCall extends CPPDependentEvaluation { @Override public IValue getValue(IASTNode point) { ICPPEvaluation eval = computeForFunctionCall(Value.MAX_RECURSION_DEPTH, point); - if (eval != this) { - if (eval instanceof EvalFixed) - return ((EvalFixed) eval).getValue(); - eval = new EvalFixed(getTypeOrFunctionSet(point), PRVALUE, eval.getValue(point)); - } - return Value.create(eval); + if (eval == this) { + return Value.create(eval); + } + return eval.getValue(point); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorInstance.java index 7af275ab856..988a9f6b71f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorInstance.java @@ -28,7 +28,7 @@ public class PDOMCPPConstructorInstance extends PDOMCPPMethodInstance implements @SuppressWarnings("hiding") protected static final int RECORD_SIZE = PDOMCPPMethodInstance.RECORD_SIZE + 0; - public PDOMCPPConstructorInstance(PDOMLinkage linkage, PDOMNode parent, ICPPMethod method, + public PDOMCPPConstructorInstance(PDOMCPPLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding instantiated) throws CoreException { super(linkage, parent, method, instantiated); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java index d3e5e21bafd..37697394e6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPConstructorSpecialization.java @@ -27,7 +27,7 @@ class PDOMCPPConstructorSpecialization extends PDOMCPPMethodSpecialization imple @SuppressWarnings("hiding") protected static final int RECORD_SIZE = PDOMCPPMethodSpecialization.RECORD_SIZE + 0; - public PDOMCPPConstructorSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPConstructor constructor, PDOMBinding specialized) throws CoreException { + public PDOMCPPConstructorSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPConstructor constructor, PDOMBinding specialized) throws CoreException { super(linkage, parent, constructor, specialized); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java index 7cea5740b6a..358d6ccfaf1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionInstance.java @@ -38,7 +38,7 @@ class PDOMCPPFunctionInstance extends PDOMCPPFunctionSpecialization implements I @SuppressWarnings("hiding") protected static final int RECORD_SIZE = PDOMCPPFunctionSpecialization.RECORD_SIZE + 8; - public PDOMCPPFunctionInstance(PDOMLinkage linkage, PDOMNode parent, ICPPFunction function, PDOMBinding orig) + public PDOMCPPFunctionInstance(PDOMCPPLinkage linkage, PDOMNode parent, ICPPFunction function, PDOMBinding orig) throws CoreException { super(linkage, parent, function, orig); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java index 8698367b01b..1f50d3ad20f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionSpecialization.java @@ -23,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; @@ -84,7 +83,7 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization private short fAnnotation= -1; private int fRequiredArgCount= -1; - public PDOMCPPFunctionSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPFunction astFunction, + public PDOMCPPFunctionSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPFunction astFunction, PDOMBinding specialized) throws CoreException { super(linkage, parent, (ICPPSpecialization) astFunction, specialized); @@ -123,10 +122,6 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization fAnnotation = getAnnotation(astFunction); db.putShort(record + ANNOTATION, fAnnotation); db.putShort(record + REQUIRED_ARG_COUNT , (short) astFunction.getRequiredArgumentCount()); - ICPPEvaluation returnExpression = CPPFunction.getReturnExpression(astFunction); - if (returnExpression != null) { - linkage.storeEvaluation(record + RETURN_EXPRESSION, returnExpression); - } long typelist= 0; if (astFunction instanceof ICPPMethod && ((ICPPMethod) astFunction).isImplicit()) { // Don't store the exception specification, it is computed on demand. @@ -134,6 +129,7 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization typelist = PDOMCPPTypeList.putTypes(this, astFunction.getExceptionSpecification()); } db.putRecPtr(record + EXCEPTION_SPEC, typelist); + linkage.new ConfigureFunctionSpecialization(astFunction, this); } private short getAnnotation(ICPPFunction astFunction) { @@ -154,6 +150,16 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization super(linkage, bindingRecord); } + public void initData(ICPPEvaluation returnExpression) { + if (returnExpression == null) + return; + try { + getLinkage().storeEvaluation(record + RETURN_EXPRESSION, returnExpression); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + @Override protected int getRecordSize() { return RECORD_SIZE; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionTemplateSpecialization.java index 6a2341f1b11..b0c257d7f7a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPFunctionTemplateSpecialization.java @@ -31,7 +31,7 @@ import org.eclipse.core.runtime.CoreException; class PDOMCPPFunctionTemplateSpecialization extends PDOMCPPFunctionSpecialization implements ICPPFunctionTemplate, ICPPInstanceCache, IPDOMMemberOwner { - public PDOMCPPFunctionTemplateSpecialization(PDOMLinkage linkage, PDOMNode parent, + public PDOMCPPFunctionTemplateSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPFunctionTemplate template, PDOMBinding specialized) throws CoreException { super(linkage, parent, template, specialized); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 6d7ae1ed05a..48b114c94db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -251,6 +251,22 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { fReturnExpression); } } + + class ConfigureFunctionSpecialization implements Runnable { + private final PDOMCPPFunctionSpecialization fSpec; + private final ICPPEvaluation fReturnExpression; + + public ConfigureFunctionSpecialization(ICPPFunction original, PDOMCPPFunctionSpecialization spec) { + fSpec = spec; + fReturnExpression = CPPFunction.getReturnExpression(original); + postProcesses.add(this); + } + + @Override + public void run() { + fSpec.initData(fReturnExpression); + } + } class ConfigureFunctionTemplate implements Runnable { private final PDOMCPPFunctionTemplate fTemplate; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodInstance.java index a54785dbb7b..e2cbeba4567 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodInstance.java @@ -30,7 +30,7 @@ class PDOMCPPMethodInstance extends PDOMCPPFunctionInstance implements ICPPMetho @SuppressWarnings("hiding") protected static final int RECORD_SIZE = PDOMCPPFunctionInstance.RECORD_SIZE + 0; - public PDOMCPPMethodInstance(PDOMLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding instantiated) + public PDOMCPPMethodInstance(PDOMCPPLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding instantiated) throws CoreException { super(linkage, parent, method, instantiated); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java index 397fdddfcaa..142b6ece483 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPMethodSpecialization.java @@ -51,7 +51,7 @@ class PDOMCPPMethodSpecialization extends PDOMCPPFunctionSpecialization */ private static final int CV_OFFSET = PDOMCPPAnnotation.MAX_EXTRA_OFFSET + 1; - public PDOMCPPMethodSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding specialized) throws CoreException { + public PDOMCPPMethodSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPMethod method, PDOMBinding specialized) throws CoreException { super(linkage, parent, method, specialized); Database db = getDB();