diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java index cbf0efbd67e..e0ac69c486c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2VariableTemplateTests.java @@ -340,6 +340,27 @@ public class AST2VariableTemplateTests extends AST2TestBase { assertEquals(1, args.length); assertValue(args[0].getNonTypeValue(), 1); } + + // template + // constexpr bool type_in_pack{type_in_pack}; + // + // template + // constexpr bool type_in_pack{true}; + // + // template + // constexpr bool type_in_pack{false}; + // + // constexpr bool waldo1 = type_in_pack; + // constexpr bool waldo2 = type_in_pack; + 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 { return parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java index 702d0ce21b2..a27522ab04c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java @@ -43,7 +43,8 @@ public interface ITypeMarshalBuffer { TYPE_TRANSFORMATION = 0x0F, UNKNOWN_MEMBER_TYPE = 0x10, 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. final static byte diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredVariableInstance.java new file mode 100644 index 00000000000..d69e89429bd --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredVariableInstance.java @@ -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); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPDeferredVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPDeferredVariableInstance.java new file mode 100644 index 00000000000..3c9144a70c4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPDeferredVariableInstance.java @@ -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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 3bf437daac2..dd69a67f381 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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.CPPDeferredClassInstance; 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.CPPFieldInstance; 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.ICPPComputableFunction; 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.ICPPExecution; 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); } @@ -517,14 +519,8 @@ public class CPPTemplates { 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, - IntegralValue.MAX_RECURSION_DEPTH); - instance = new CPPVariableInstance(template, template.getOwner(), tpMap, arguments, type, value); + instance = new CPPDeferredVariableInstance((ICPPVariableTemplate) template, arguments); + addInstance(template, arguments, instance); } return instance; } @@ -2960,6 +2956,9 @@ public class CPPTemplates { if (unknown instanceof ICPPDeferredClassInstance) { return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, context); } + if (unknown instanceof ICPPDeferredVariableInstance) { + return resolveDeferredVariableInstance((ICPPDeferredVariableInstance) unknown, context); + } if (unknown instanceof ICPPUnknownMember) { return resolveUnknownMember((ICPPUnknownMember) unknown, context); } @@ -3060,6 +3059,32 @@ public class CPPTemplates { } 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) { final ICPPTemplateArgument[] m1= i1.getTemplateArguments(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java index dc392d10cbb..8f2b9546a4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -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.cpp.CPPParameter; 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.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; @@ -231,12 +232,12 @@ public class EvalBinding extends CPPDependentEvaluation { if (fBinding instanceof ICPPTemplateNonTypeParameter) { return true; } - if (fBinding instanceof IVariable) { - return IntegralValue.isDependentValue(((IVariable) fBinding).getInitialValue()); - } if (fBinding instanceof ICPPUnknownBinding) { return true; } + if (fBinding instanceof IVariable) { + return IntegralValue.isDependentValue(((IVariable) fBinding).getInitialValue()); + } if (fBinding instanceof IFunction) { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index e8a16f24ee6..f76d3471ef0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -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.cpp.CPPDeferredFunction; 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.ICPPInternalEnumerator; 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); } 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; final IASTName lastName = name.getLastName(); if (lastName instanceof ICPPASTTemplateId) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java index b8a8c45a22b..cc005df8d14 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexCPPBindingConstants.java @@ -72,4 +72,5 @@ public interface IIndexCPPBindingConstants { int CPP_FIELD_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 58; int CPP_VARIABLE_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 59; int CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 60; + int CPP_DEFERRED_VARIABLE_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 61; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 0d20dab3130..16b3ac21b51 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -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.ICPPClassSpecializationScope; 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.ICPPInternalEnumerator; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -557,6 +558,15 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { ICPPClassTemplate t= (ICPPClassTemplate) getCompositeType(t0); ICPPTemplateArgument[] args = TemplateInstanceUtil.convert(this, args0); 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 { if (binding instanceof ICPPClassType) { return new CompositeCPPClassInstance(this, (ICPPClassType) findOneBinding(binding)); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredVariableInstance.java new file mode 100644 index 00000000000..74d3fec0124 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPDeferredVariableInstance.java @@ -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(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredVariableInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredVariableInstance.java new file mode 100644 index 00000000000..84c35fb63d0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPDeferredVariableInstance.java @@ -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; + } +} 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 1d35959666f..2f30bed6356 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 @@ -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.CPPDeferredClassInstance; 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.CPPFunctionType; 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); case ITypeMarshalBuffer.DEFERRED_FUNCTION: return CPPDeferredFunction.unmarshal(firstBytes, buffer); + case ITypeMarshalBuffer.DEFERRED_VARIABLE_INSTANCE: + return CPPDeferredVariableInstance.unmarshal(getPDOM(), firstBytes, buffer); case ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE: IType type= TypeOfDependentExpression.unmarshal(firstBytes, buffer); if (type instanceof IBinding)