mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-15 04:55:22 +02:00
Bug 484959 - Instantiate return expression of constexpr function
template Change-Id: I3abec0f3bac58db77aacd61bd985c94c2185e3a8 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
ad2940f594
commit
1e598214ea
7 changed files with 68 additions and 8 deletions
|
@ -8752,6 +8752,24 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
public void testConstexprFunctionCallWithNonConstexprArguments_429891() throws Exception {
|
public void testConstexprFunctionCallWithNonConstexprArguments_429891() throws Exception {
|
||||||
parseAndCheckBindings();
|
parseAndCheckBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename>
|
||||||
|
// struct S;
|
||||||
|
//
|
||||||
|
// template <>
|
||||||
|
// struct S<int> {
|
||||||
|
// static const int value = 42;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// return S<T>::value;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// constexpr int waldo = foo<int>();
|
||||||
|
public void testInstantiationOfReturnExpression_484959() throws Exception {
|
||||||
|
getAssertionHelper().assertVariableValue("waldo", 42);
|
||||||
|
}
|
||||||
|
|
||||||
// template <typename> class A {};
|
// template <typename> class A {};
|
||||||
// template <int> class B {};
|
// template <int> class B {};
|
||||||
|
|
|
@ -776,9 +776,7 @@ public class AST2TestBase extends BaseTestCase {
|
||||||
|
|
||||||
public void assertVariableValue(String variableName, long expectedValue) {
|
public void assertVariableValue(String variableName, long expectedValue) {
|
||||||
IVariable var = assertNonProblem(variableName);
|
IVariable var = assertNonProblem(variableName);
|
||||||
assertNotNull(var.getInitialValue());
|
BaseTestCase.assertVariableValue(var, expectedValue);
|
||||||
assertNotNull(var.getInitialValue().numericalValue());
|
|
||||||
assertEquals(expectedValue, var.getInitialValue().numericalValue().longValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T, U extends T> U assertType(T obj, Class... cs) {
|
public <T, U extends T> U assertType(T obj, Class... cs) {
|
||||||
|
|
|
@ -2644,6 +2644,25 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
public void testSpecializationOfConstexprFunction_420995() throws Exception {
|
public void testSpecializationOfConstexprFunction_420995() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename>
|
||||||
|
// struct S;
|
||||||
|
//
|
||||||
|
// template <>
|
||||||
|
// struct S<int> {
|
||||||
|
// static const int value = 42;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// constexpr int foo() {
|
||||||
|
// return S<T>::value;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// constexpr int waldo = foo<int>();
|
||||||
|
public void testInstantiationOfReturnExpression_484959() throws Exception {
|
||||||
|
ICPPVariable waldo = getBindingFromASTName("waldo", 5);
|
||||||
|
assertVariableValue(waldo, 42);
|
||||||
|
}
|
||||||
|
|
||||||
// template <class TYPE>
|
// template <class TYPE>
|
||||||
// class waldo {
|
// class waldo {
|
||||||
|
|
|
@ -32,6 +32,7 @@ import junit.framework.TestResult;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.index.IIndex;
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
||||||
|
@ -349,4 +350,10 @@ public class BaseTestCase extends TestCase {
|
||||||
}
|
}
|
||||||
return clazz.cast(o);
|
return clazz.cast(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void assertVariableValue(IVariable var, long expectedValue) {
|
||||||
|
assertNotNull(var.getInitialValue());
|
||||||
|
assertNotNull(var.getInitialValue().numericalValue());
|
||||||
|
assertEquals(expectedValue, var.getInitialValue().numericalValue().longValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
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.ASTQueries;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.Value;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -330,7 +332,18 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
|
||||||
}
|
}
|
||||||
IBinding f = getSpecializedBinding();
|
IBinding f = getSpecializedBinding();
|
||||||
if (f instanceof ICPPComputableFunction) {
|
if (f instanceof ICPPComputableFunction) {
|
||||||
return ((ICPPComputableFunction) f).getReturnExpression();
|
ICPPEvaluation eval = ((ICPPComputableFunction) f).getReturnExpression();
|
||||||
|
if (eval != null) {
|
||||||
|
// TODO: Should we instead do this when the CPPFunctionSpecialization is created?
|
||||||
|
// It would mean getting a more accurate point of instantiation, but it would also
|
||||||
|
// mean doing the instantiation when we might never need it.
|
||||||
|
IASTNode point = f instanceof ICPPInternalFunction
|
||||||
|
? ((ICPPInternalFunction) f).getDefinition()
|
||||||
|
: null;
|
||||||
|
eval = eval.instantiate(getTemplateParameterMap(), -1,
|
||||||
|
CPPTemplates.getSpecializationContext(getOwner()), Value.MAX_RECURSION_DEPTH, point);
|
||||||
|
}
|
||||||
|
return eval;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,6 @@ public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument {
|
||||||
IValue value = evaluation.getValue(point);
|
IValue value = evaluation.getValue(point);
|
||||||
if (value == Value.ERROR) {
|
if (value == Value.ERROR) {
|
||||||
fEvaluation = EvalFixed.INCOMPLETE;
|
fEvaluation = EvalFixed.INCOMPLETE;
|
||||||
} else if (value.getEvaluation() instanceof EvalFixed) {
|
|
||||||
// Avoid nesting EvalFixed's as nesting causes the signature to be different.
|
|
||||||
fEvaluation = value.getEvaluation();
|
|
||||||
} else {
|
} else {
|
||||||
fEvaluation= new EvalFixed(evaluation.getType(point),
|
fEvaluation= new EvalFixed(evaluation.getType(point),
|
||||||
evaluation.getValueCategory(point), value);
|
evaluation.getValueCategory(point), value);
|
||||||
|
|
|
@ -45,6 +45,14 @@ public class EvalFixed extends CPPEvaluation {
|
||||||
private boolean fCheckedIsValueDependent;
|
private boolean fCheckedIsValueDependent;
|
||||||
|
|
||||||
public EvalFixed(IType type, ValueCategory cat, IValue value) {
|
public EvalFixed(IType type, ValueCategory cat, IValue value) {
|
||||||
|
// Avoid nesting EvalFixed's as nesting causes the signature to be different.
|
||||||
|
if (value.getEvaluation() instanceof EvalFixed) {
|
||||||
|
EvalFixed inner = (EvalFixed) value.getEvaluation();
|
||||||
|
type = inner.fType;
|
||||||
|
cat = inner.fValueCategory;
|
||||||
|
value = inner.fValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (type instanceof CPPBasicType) {
|
if (type instanceof CPPBasicType) {
|
||||||
Long num = value.numericalValue();
|
Long num = value.numericalValue();
|
||||||
if (num != null) {
|
if (num != null) {
|
||||||
|
@ -57,7 +65,7 @@ public class EvalFixed extends CPPEvaluation {
|
||||||
fValueCategory= cat;
|
fValueCategory= cat;
|
||||||
fValue= value;
|
fValue= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IType getType() {
|
public IType getType() {
|
||||||
return fType;
|
return fType;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue