mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 513429 - Defer instantiation of variable templates with dependent arguments
Change-Id: Ic5875b19b384ae2726fe000fe5ab2b8cf5dd45a7
This commit is contained in:
parent
d35f9e1a60
commit
9742e45559
12 changed files with 367 additions and 14 deletions
|
@ -340,6 +340,27 @@ public class AST2VariableTemplateTests extends AST2TestBase {
|
||||||
assertEquals(1, args.length);
|
assertEquals(1, args.length);
|
||||||
assertValue(args[0].getNonTypeValue(), 1);
|
assertValue(args[0].getNonTypeValue(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<typename T, typename = class _, typename... P>
|
||||||
|
// constexpr bool type_in_pack{type_in_pack<T, P...>};
|
||||||
|
//
|
||||||
|
// template<typename T, typename... P>
|
||||||
|
// constexpr bool type_in_pack<T, T, P...>{true};
|
||||||
|
//
|
||||||
|
// template<typename T>
|
||||||
|
// constexpr bool type_in_pack<T>{false};
|
||||||
|
//
|
||||||
|
// constexpr bool waldo1 = type_in_pack<int, int, char>;
|
||||||
|
// constexpr bool waldo2 = type_in_pack<int, float, char>;
|
||||||
|
public void testStackOverflow_513429() throws Exception {
|
||||||
|
parseAndCheckBindings();
|
||||||
|
|
||||||
|
BindingAssertionHelper ah = getAssertionHelper(ParserLanguage.CPP);
|
||||||
|
ICPPVariable waldo1 = ah.assertNonProblem("waldo1");
|
||||||
|
assertVariableValue(waldo1, 1);
|
||||||
|
ICPPVariable waldo2 = ah.assertNonProblem("waldo2");
|
||||||
|
assertVariableValue(waldo2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private IASTTranslationUnit parseAndCheckBindings() throws Exception {
|
private IASTTranslationUnit parseAndCheckBindings() throws Exception {
|
||||||
return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
|
||||||
|
|
|
@ -43,7 +43,8 @@ public interface ITypeMarshalBuffer {
|
||||||
TYPE_TRANSFORMATION = 0x0F,
|
TYPE_TRANSFORMATION = 0x0F,
|
||||||
UNKNOWN_MEMBER_TYPE = 0x10,
|
UNKNOWN_MEMBER_TYPE = 0x10,
|
||||||
INITIALIZER_LIST_TYPE = 0x11,
|
INITIALIZER_LIST_TYPE = 0x11,
|
||||||
DEFERRED_FUNCTION = 0x12;
|
DEFERRED_FUNCTION = 0x12,
|
||||||
|
DEFERRED_VARIABLE_INSTANCE = 0x13;
|
||||||
// Can add more types up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
|
// Can add more types up to 0x1C, after that it will collide with TypeMarshalBuffer.UNSTORABLE_TYPE.
|
||||||
|
|
||||||
final static byte
|
final static byte
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPDeferredVariableInstance;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AST implementation of ICPPDeferredVariableInstance.
|
||||||
|
*/
|
||||||
|
public class CPPDeferredVariableInstance extends CPPUnknownBinding implements ICPPDeferredVariableInstance,
|
||||||
|
ISerializableType {
|
||||||
|
private final ICPPVariableTemplate fTemplate;
|
||||||
|
private final ICPPTemplateArgument[] fArguments;
|
||||||
|
|
||||||
|
public CPPDeferredVariableInstance(ICPPVariableTemplate template, ICPPTemplateArgument[] arguments) {
|
||||||
|
super(template.getNameCharArray());
|
||||||
|
fTemplate = template;
|
||||||
|
fArguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinding getOwner() {
|
||||||
|
return fTemplate.getOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPVariableTemplate getSpecializedBinding() {
|
||||||
|
return fTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPTemplateParameterMap getTemplateParameterMap() {
|
||||||
|
ICPPTemplateParameter[] params = fTemplate.getTemplateParameters();
|
||||||
|
int size = Math.min(fArguments.length, params.length);
|
||||||
|
CPPTemplateParameterMap map = new CPPTemplateParameterMap(size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
map.put(params[i], fArguments[i]);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IType getType() {
|
||||||
|
// The type cannot vary in partial specializations, so it's safe to use the primary template's type.
|
||||||
|
InstantiationContext context = new InstantiationContext(getTemplateParameterMap(), null);
|
||||||
|
return CPPTemplates.instantiateType(fTemplate.getType(), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IValue getInitialValue() {
|
||||||
|
// Partial specializations can have different initial values, so we can't compute the initial value
|
||||||
|
// until we have concrete template arguments and can select a partial specialization or the
|
||||||
|
// primary template.
|
||||||
|
return IntegralValue.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStatic() {
|
||||||
|
return fTemplate.isStatic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExtern() {
|
||||||
|
return fTemplate.isExtern();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAuto() {
|
||||||
|
return fTemplate.isAuto();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRegister() {
|
||||||
|
return fTemplate.isRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMutable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isConstexpr() {
|
||||||
|
return fTemplate.isConstexpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExternC() {
|
||||||
|
return fTemplate.isExternC();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPVariableTemplate getTemplateDefinition() {
|
||||||
|
return fTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICPPTemplateArgument[] getTemplateArguments() {
|
||||||
|
return fArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExplicitSpecialization() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
short firstBytes = ITypeMarshalBuffer.DEFERRED_VARIABLE_INSTANCE;
|
||||||
|
buffer.putShort(firstBytes);
|
||||||
|
buffer.marshalBinding(fTemplate);
|
||||||
|
buffer.putInt(fArguments.length);
|
||||||
|
for (ICPPTemplateArgument arg : fArguments) {
|
||||||
|
buffer.marshalTemplateArgument(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ICPPDeferredVariableInstance unmarshal(IIndexFragment fragment, short firstBytes,
|
||||||
|
ITypeMarshalBuffer buffer) throws CoreException {
|
||||||
|
IBinding template= buffer.unmarshalBinding();
|
||||||
|
int argcount= buffer.getInt();
|
||||||
|
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
|
||||||
|
for (int i = 0; i < argcount; i++) {
|
||||||
|
args[i]= buffer.unmarshalTemplateArgument();
|
||||||
|
}
|
||||||
|
return new PDOMCPPDeferredVariableInstance(fragment, (ICPPVariableTemplate) template, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableInstance;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an instantiation of a variable template that cannot be performed because of dependent arguments.
|
||||||
|
*/
|
||||||
|
public interface ICPPDeferredVariableInstance extends ICPPUnknownBinding, ICPPVariableInstance {
|
||||||
|
@Override
|
||||||
|
ICPPVariableTemplate getTemplateDefinition();
|
||||||
|
}
|
|
@ -146,6 +146,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorSpecialization
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplateSpecialization;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerationSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerationSpecialization;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldSpecialization;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldSpecialization;
|
||||||
|
@ -184,6 +185,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariableTemplatePartialSp
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
|
||||||
|
@ -240,9 +242,9 @@ public class CPPTemplates {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a class template with the given arguments. May return {@code null}.
|
* Instantiates a class or variable template with the given arguments. May return {@code null}.
|
||||||
*/
|
*/
|
||||||
public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, IASTNode point) {
|
public static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, IASTNode point) {
|
||||||
return instantiate(template, args, false, false, point);
|
return instantiate(template, args, false, false, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,14 +519,8 @@ public class CPPTemplates {
|
||||||
addInstance(template, arguments, instance);
|
addInstance(template, arguments, instance);
|
||||||
}
|
}
|
||||||
if (template instanceof ICPPVariableTemplate) {
|
if (template instanceof ICPPVariableTemplate) {
|
||||||
// TODO(nathanridge): Do we need a CPPDeferredVariableInstance?
|
instance = new CPPDeferredVariableInstance((ICPPVariableTemplate) template, arguments);
|
||||||
ICPPVariableTemplate variableTemplate = ((ICPPVariableTemplate) template);
|
addInstance(template, arguments, instance);
|
||||||
CPPTemplateParameterMap tpMap = createParameterMap(template, arguments, point);
|
|
||||||
InstantiationContext context = new InstantiationContext(tpMap, point);
|
|
||||||
IType type = instantiateType(variableTemplate.getType(), context);
|
|
||||||
IValue value = instantiateValue(variableTemplate.getInitialValue(), context,
|
|
||||||
IntegralValue.MAX_RECURSION_DEPTH);
|
|
||||||
instance = new CPPVariableInstance(template, template.getOwner(), tpMap, arguments, type, value);
|
|
||||||
}
|
}
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
@ -2960,6 +2956,9 @@ public class CPPTemplates {
|
||||||
if (unknown instanceof ICPPDeferredClassInstance) {
|
if (unknown instanceof ICPPDeferredClassInstance) {
|
||||||
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context);
|
return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context);
|
||||||
}
|
}
|
||||||
|
if (unknown instanceof ICPPDeferredVariableInstance) {
|
||||||
|
return resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context);
|
||||||
|
}
|
||||||
if (unknown instanceof ICPPUnknownMember) {
|
if (unknown instanceof ICPPUnknownMember) {
|
||||||
return resolveUnknownMember((ICPPUnknownMember) unknown, context);
|
return resolveUnknownMember((ICPPUnknownMember) unknown, context);
|
||||||
}
|
}
|
||||||
|
@ -3060,6 +3059,32 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
return dci;
|
return dci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IBinding resolveDeferredVariableInstance(ICPPDeferredVariableInstance dvi,
|
||||||
|
InstantiationContext context) {
|
||||||
|
ICPPVariableTemplate variableTemplate = dvi.getTemplateDefinition();
|
||||||
|
ICPPTemplateArgument[] arguments = dvi.getTemplateArguments();
|
||||||
|
ICPPTemplateArgument[] newArgs;
|
||||||
|
try {
|
||||||
|
newArgs = instantiateArguments(arguments, context, true);
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return e.getProblem();
|
||||||
|
}
|
||||||
|
if (newArgs == null) {
|
||||||
|
return createProblem(variableTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS,
|
||||||
|
context.getPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlike class templates, variable templates cannot be passed as template template arguments,
|
||||||
|
// so there is no need to instantiate the template itself.
|
||||||
|
|
||||||
|
if (arguments != newArgs) {
|
||||||
|
IBinding inst = instantiate(variableTemplate, newArgs, context.getPoint());
|
||||||
|
if (inst != null)
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
return dvi;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean haveSameArguments(ICPPTemplateInstance i1, ICPPTemplateInstance i2) {
|
public static boolean haveSameArguments(ICPPTemplateInstance i1, ICPPTemplateInstance i2) {
|
||||||
final ICPPTemplateArgument[] m1= i1.getTemplateArguments();
|
final ICPPTemplateArgument[] m1= i1.getTemplateArguments();
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
|
||||||
|
@ -231,12 +232,12 @@ public class EvalBinding extends CPPDependentEvaluation {
|
||||||
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
|
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (fBinding instanceof IVariable) {
|
|
||||||
return IntegralValue.isDependentValue(((IVariable) fBinding).getInitialValue());
|
|
||||||
}
|
|
||||||
if (fBinding instanceof ICPPUnknownBinding) {
|
if (fBinding instanceof ICPPUnknownBinding) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (fBinding instanceof IVariable) {
|
||||||
|
return IntegralValue.isDependentValue(((IVariable) fBinding).getInitialValue());
|
||||||
|
}
|
||||||
if (fBinding instanceof IFunction) {
|
if (fBinding instanceof IFunction) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
|
@ -222,6 +223,11 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
return new EvalFunctionSet((CPPFunctionSet) binding, qualified, isAddressOf(expr), null, expr);
|
return new EvalFunctionSet((CPPFunctionSet) binding, qualified, isAddressOf(expr), null, expr);
|
||||||
}
|
}
|
||||||
if (binding instanceof ICPPUnknownBinding) {
|
if (binding instanceof ICPPUnknownBinding) {
|
||||||
|
// If the id-expression names a variable template, there is no need to defer name lookup.
|
||||||
|
if (binding instanceof ICPPDeferredVariableInstance) {
|
||||||
|
return new EvalBinding(binding, null, expr);
|
||||||
|
}
|
||||||
|
|
||||||
ICPPTemplateArgument[] templateArgs = null;
|
ICPPTemplateArgument[] templateArgs = null;
|
||||||
final IASTName lastName = name.getLastName();
|
final IASTName lastName = name.getLastName();
|
||||||
if (lastName instanceof ICPPASTTemplateId) {
|
if (lastName instanceof ICPPASTTemplateId) {
|
||||||
|
|
|
@ -72,4 +72,5 @@ public interface IIndexCPPBindingConstants {
|
||||||
int CPP_FIELD_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 58;
|
int CPP_FIELD_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 58;
|
||||||
int CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 59;
|
int CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 59;
|
||||||
int CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 60;
|
int CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 60;
|
||||||
|
int CPP_DEFERRED_VARIABLE_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 61;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnaryTypeTransformation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMember;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalEnumerator;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||||
|
@ -557,6 +558,15 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
||||||
ICPPClassTemplate t= (ICPPClassTemplate) getCompositeType(t0);
|
ICPPClassTemplate t= (ICPPClassTemplate) getCompositeType(t0);
|
||||||
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
|
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
|
||||||
return new CompositeCPPDeferredClassInstance(t, args);
|
return new CompositeCPPDeferredClassInstance(t, args);
|
||||||
|
} else if (binding instanceof ICPPDeferredVariableInstance) {
|
||||||
|
ICPPDeferredVariableInstance def= (ICPPDeferredVariableInstance) binding;
|
||||||
|
ICPPVariableTemplate t0= def.getTemplateDefinition();
|
||||||
|
ICPPTemplateArgument[] args0= def.getTemplateArguments();
|
||||||
|
|
||||||
|
ICPPVariableTemplate t=
|
||||||
|
(ICPPVariableTemplate) getCompositeBinding((IIndexFragmentBinding) t0);
|
||||||
|
ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0);
|
||||||
|
return new CompositeCPPDeferredVariableInstance(t, args);
|
||||||
} else {
|
} else {
|
||||||
if (binding instanceof ICPPClassType) {
|
if (binding instanceof ICPPClassType) {
|
||||||
return new CompositeCPPClassInstance(this, (ICPPClassType) findOneBinding(binding));
|
return new CompositeCPPClassInstance(this, (ICPPClassType) findOneBinding(binding));
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.index.composite.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredVariableInstance;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
public class CompositeCPPDeferredVariableInstance extends CPPDeferredVariableInstance
|
||||||
|
implements IIndexBinding {
|
||||||
|
public CompositeCPPDeferredVariableInstance(ICPPVariableTemplate template,
|
||||||
|
ICPPTemplateArgument[] arguments) {
|
||||||
|
super(template, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileLocal() throws CoreException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexFile getLocalToFile() throws CoreException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexBinding getOwner() {
|
||||||
|
return (IIndexBinding) super.getOwner();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariableTemplate;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFile;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredVariableInstance;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexFragment;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
|
||||||
|
import org.eclipse.cdt.internal.core.index.IIndexScope;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDOM implementation of ICPPDeferredVariableInstance.
|
||||||
|
*/
|
||||||
|
public class PDOMCPPDeferredVariableInstance extends CPPDeferredVariableInstance
|
||||||
|
implements IIndexFragmentBinding {
|
||||||
|
private final IIndexFragment fFragment;
|
||||||
|
|
||||||
|
public PDOMCPPDeferredVariableInstance(IIndexFragment fragment, ICPPVariableTemplate template,
|
||||||
|
ICPPTemplateArgument[] arguments) {
|
||||||
|
super(template, arguments);
|
||||||
|
fFragment = fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFileLocal() throws CoreException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexFile getLocalToFile() throws CoreException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexFragment getFragment() {
|
||||||
|
return fFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasDefinition() throws CoreException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasDeclaration() throws CoreException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBindingConstant() {
|
||||||
|
return IIndexCPPBindingConstants.CPP_DEFERRED_VARIABLE_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexScope getScope() {
|
||||||
|
try {
|
||||||
|
return (IIndexScope) super.getScope();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IIndexFragmentBinding getOwner() {
|
||||||
|
return (IIndexFragmentBinding) super.getOwner();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBindingID() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,6 +95,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredVariableInstance;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod;
|
||||||
|
@ -1559,6 +1560,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
return CPPDeferredClassInstance.unmarshal(getPDOM(), firstBytes, buffer);
|
return CPPDeferredClassInstance.unmarshal(getPDOM(), firstBytes, buffer);
|
||||||
case ITypeMarshalBuffer.DEFERRED_FUNCTION:
|
case ITypeMarshalBuffer.DEFERRED_FUNCTION:
|
||||||
return CPPDeferredFunction.unmarshal(firstBytes, buffer);
|
return CPPDeferredFunction.unmarshal(firstBytes, buffer);
|
||||||
|
case ITypeMarshalBuffer.DEFERRED_VARIABLE_INSTANCE:
|
||||||
|
return CPPDeferredVariableInstance.unmarshal(getPDOM(), firstBytes, buffer);
|
||||||
case ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE:
|
case ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE:
|
||||||
IType type= TypeOfDependentExpression.unmarshal(firstBytes, buffer);
|
IType type= TypeOfDependentExpression.unmarshal(firstBytes, buffer);
|
||||||
if (type instanceof IBinding)
|
if (type instanceof IBinding)
|
||||||
|
|
Loading…
Add table
Reference in a new issue