mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Bug 494216 - Instantiation of variable templates with dependent arguments
Change-Id: If9c27267d25ce8cccb89e7a5404bf5e3e6480dcb
This commit is contained in:
parent
e6ed5e4037
commit
c180a3e798
3 changed files with 70 additions and 5 deletions
|
@ -12,14 +12,18 @@
|
|||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPartialSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassInstance;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldTemplateSpecialization;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
@ -309,6 +313,34 @@ public class AST2VariableTemplateTests extends AST2TestBase {
|
|||
assertEquals(template, bInst.getSpecializedBinding());
|
||||
}
|
||||
|
||||
// template <typename T>
|
||||
// struct meta {
|
||||
// static const bool value = true;
|
||||
// };
|
||||
//
|
||||
// template <typename T>
|
||||
// constexpr bool var = meta<T>::value;
|
||||
//
|
||||
// template <bool> struct S {};
|
||||
//
|
||||
// template <typename T>
|
||||
// S<var<T>> foo();
|
||||
//
|
||||
// void bar() {
|
||||
// auto waldo = foo<int>();
|
||||
// }
|
||||
public void test_bug494216() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
|
||||
BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP);
|
||||
ICPPVariable waldo = ah.assertNonProblem("waldo");
|
||||
IType type = waldo.getType();
|
||||
assertInstance(type, CPPClassInstance.class);
|
||||
ICPPTemplateArgument[] args = ((CPPClassInstance) type).getTemplateArguments();
|
||||
assertEquals(1, args.length);
|
||||
assertValue(args[0].getNonTypeValue(), 1);
|
||||
}
|
||||
|
||||
private IASTTranslationUnit parseAndCheckBindings() throws Exception {
|
||||
return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import junit.framework.TestResult;
|
|||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
|
@ -358,9 +359,13 @@ public class BaseTestCase extends TestCase {
|
|||
return clazz.cast(o);
|
||||
}
|
||||
|
||||
protected static void assertValue(IValue value, long expectedValue) {
|
||||
assertNotNull(value);
|
||||
assertNotNull(value.numericalValue());
|
||||
assertEquals(expectedValue, value.numericalValue().longValue());
|
||||
}
|
||||
|
||||
protected static void assertVariableValue(IVariable var, long expectedValue) {
|
||||
assertNotNull(var.getInitialValue());
|
||||
assertNotNull(var.getInitialValue().numberValue());
|
||||
assertEquals(expectedValue, var.getInitialValue().numberValue().longValue());
|
||||
assertValue(var.getInitialValue(), expectedValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTypeSpecialization;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUnaryTypeTransformation;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
|
@ -254,7 +255,7 @@ public class CPPTemplates {
|
|||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point);
|
||||
|
||||
if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) {
|
||||
return deferredInstance(template, arguments);
|
||||
return deferredInstance(template, arguments, point);
|
||||
}
|
||||
|
||||
if (template instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
|
@ -500,7 +501,8 @@ public class CPPTemplates {
|
|||
}
|
||||
}
|
||||
|
||||
private static IBinding deferredInstance(ICPPPartiallySpecializable template, ICPPTemplateArgument[] arguments) throws DOMException {
|
||||
private static IBinding deferredInstance(ICPPPartiallySpecializable template,
|
||||
ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException {
|
||||
ICPPTemplateInstance instance= getInstance(template, arguments, false);
|
||||
if (instance != null)
|
||||
return instance;
|
||||
|
@ -509,6 +511,16 @@ public class CPPTemplates {
|
|||
instance = new CPPDeferredClassInstance((ICPPClassTemplate) template, arguments);
|
||||
addInstance(template, arguments, instance);
|
||||
}
|
||||
if (template instanceof ICPPVariableTemplate) {
|
||||
// TODO(nathanridge): Do we need a CPPDeferredVariableInstance?
|
||||
ICPPVariableTemplate variableTemplate = ((ICPPVariableTemplate) template);
|
||||
CPPTemplateParameterMap tpMap = createParameterMap(template, arguments, point);
|
||||
InstantiationContext context = new InstantiationContext(tpMap, point);
|
||||
IType type = instantiateType(variableTemplate.getType(), context);
|
||||
IValue value = instantiateValue(variableTemplate.getInitialValue(), context,
|
||||
Value.MAX_RECURSION_DEPTH);
|
||||
instance = new CPPVariableInstance(template, template.getOwner(), tpMap, arguments, type, value);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
@ -1712,6 +1724,22 @@ public class CPPTemplates {
|
|||
result.setParameters(specializeParameters(origInstance.getParameters(), result, context, maxDepth));
|
||||
return result;
|
||||
}
|
||||
} else if (binding instanceof ICPPVariableInstance) {
|
||||
// TODO(nathanridge):
|
||||
// Similar to the ICPPFunctionInstance case above, perhaps we should have an
|
||||
// ICPPDeferredVariableInstance.
|
||||
ICPPVariableInstance origInstance = (ICPPVariableInstance) binding;
|
||||
ICPPTemplateArgument[] origArgs = origInstance.getTemplateArguments();
|
||||
ICPPTemplateArgument[] newArgs = instantiateArguments(origArgs, context, false);
|
||||
if (origArgs != newArgs) {
|
||||
CPPTemplateParameterMap newMap = instantiateArgumentMap(
|
||||
origInstance.getTemplateParameterMap(), context);
|
||||
IType newType = instantiateType(origInstance.getType(), context);
|
||||
IValue newValue = instantiateValue(origInstance.getInitialValue(), context,
|
||||
Value.MAX_RECURSION_DEPTH);
|
||||
return new CPPVariableInstance(origInstance.getTemplateDefinition(), origInstance.getOwner(),
|
||||
newMap, newArgs, newType, newValue);
|
||||
}
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue