From c3470476a050c262c51cf28011485ce7c57e4b38 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Fri, 1 Feb 2013 02:15:24 -0500 Subject: Bug 389009 - Enumerator with dependent value Change-Id: I4fc077870419bccd6dce15c33a0d455e8379d7e0 Reviewed-on: https://git.eclipse.org/r/10092 Reviewed-by: Sergey Prigogin IP-Clean: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/tests/ast2/AST2TemplateTests.java | 2 +- .../org/eclipse/cdt/core/dom/ast/IEnumeration.java | 3 +- .../dom/ast/cpp/ICPPEnumerationSpecialization.java | 27 ++++++ .../internal/core/dom/parser/c/CEnumeration.java | 34 +------ .../core/dom/parser/cpp/CPPEnumeration.java | 38 +------- .../parser/cpp/CPPEnumerationSpecialization.java | 105 +++++++++++++++++++++ .../parser/cpp/CPPEnumeratorSpecialization.java | 45 +++++++++ .../dom/parser/cpp/semantics/CPPEvaluation.java | 11 +++ .../dom/parser/cpp/semantics/CPPTemplates.java | 58 +++++++++++- .../core/dom/parser/cpp/semantics/EvalBinding.java | 62 +++--------- .../dom/parser/cpp/semantics/SemanticUtil.java | 39 ++++++++ .../index/composite/c/CompositeCEnumeration.java | 3 +- .../composite/cpp/CompositeCPPEnumeration.java | 3 +- .../cdt/internal/core/pdom/dom/PDOMASTAdapter.java | 4 +- .../cdt/internal/ui/typehierarchy/THGraph.java | 39 ++++---- .../dom/lrparser/c99/bindings/C99Enumeration.java | 34 +------ 16 files changed, 331 insertions(+), 176 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java 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 f6f66498610..9190046da02 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 @@ -7051,7 +7051,7 @@ public class AST2TemplateTests extends AST2TestBase { // void test() { // int x = C::id; // } - public void _testDependentEnumValue_389009() throws Exception { + public void testDependentEnumValue_389009() throws Exception { BindingAssertionHelper ah = getAssertionHelper(); IEnumerator binding = ah.assertNonProblem("C::id", "id"); IValue value = binding.getValue(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java index 7e976248eb9..47577e3a252 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumeration.java @@ -18,9 +18,8 @@ package org.eclipse.cdt.core.dom.ast; public interface IEnumeration extends IBinding, IType { /** * Returns an array of the IEnumerators declared in this enumeration - * @throws DOMException */ - IEnumerator[] getEnumerators() throws DOMException; + IEnumerator[] getEnumerators(); /** * @since 5.2 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java new file mode 100644 index 00000000000..684747193ad --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumerationSpecialization.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; + +/** + * @since 5.5 + */ +public interface ICPPEnumerationSpecialization extends ICPPEnumeration, ICPPSpecialization { + @Override + ICPPEnumeration getSpecializedBinding(); + + /** + * Return a specialized version of the given enumerator. The enumerator must be one + * of the enumerators of the enumeration being specialized. + */ + IEnumerator specializeEnumerator(IEnumerator enumerator); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java index e0fdf88dd99..f70277a545b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java @@ -8,6 +8,7 @@ * Contributors: * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -25,18 +26,17 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTEnumerationSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.Linkage; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** * Binding for enumerations in C. */ public class CEnumeration extends PlatformObject implements IEnumeration, ICInternalBinding { - private IASTName[] declarations = null; private IASTName definition = null; private Long fMinValue; @@ -204,20 +204,7 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte if (fMinValue != null) return fMinValue.longValue(); - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } + long minValue = SemanticUtil.computeMinValue(this); fMinValue= minValue; return minValue; } @@ -227,20 +214,7 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte if (fMaxValue != null) return fMaxValue.longValue(); - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } + long maxValue = SemanticUtil.computeMaxValue(this); fMaxValue= maxValue; return maxValue; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java index 1ea5e20d6de..e595d99b1a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -9,6 +9,7 @@ * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -29,7 +30,6 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; /** @@ -220,20 +221,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (fMinValue != null) return fMinValue.longValue(); - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } + long minValue = SemanticUtil.computeMinValue(this); fMinValue= minValue; return minValue; } @@ -243,20 +231,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (fMaxValue != null) return fMaxValue.longValue(); - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } + long maxValue = SemanticUtil.computeMaxValue(this); fMaxValue= maxValue; return maxValue; } @@ -278,10 +253,7 @@ public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, I if (definition == null) { ICPPEnumeration typeInIndex= getIndexBinding(); if (typeInIndex != null) { - try { - return typeInIndex.getEnumerators(); - } catch (DOMException e) { - } + return typeInIndex.getEnumerators(); } return EMPTY_ENUMERATORS; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java new file mode 100644 index 00000000000..8f0c041607d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerationSpecialization.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; + +/** + * Binding for a specialization of an enumeration. + */ +public class CPPEnumerationSpecialization extends CPPSpecialization implements ICPPEnumerationSpecialization { + private IEnumerator[] fEnumerators; + private final IType fFixedType; + + public CPPEnumerationSpecialization(ICPPEnumeration specialized, IBinding owner, + ICPPTemplateParameterMap argumentMap, IType fixedType) { + super(specialized, owner, argumentMap); + fFixedType = fixedType; + } + + public void setEnumerators(IEnumerator[] enumerators) { + fEnumerators = enumerators; + } + + @Override + public ICPPEnumeration getSpecializedBinding() { + return (ICPPEnumeration) super.getSpecializedBinding(); + } + + @Override + public IEnumerator[] getEnumerators() { + return fEnumerators; + } + + @Override + public long getMinValue() { + return SemanticUtil.computeMinValue(this); + } + + @Override + public long getMaxValue() { + return SemanticUtil.computeMaxValue(this); + } + + @Override + public boolean isSameType(IType type) { + if (type == this) + return true; + if (type instanceof ITypedef) + return type.isSameType(this); + if (!(type instanceof ICPPEnumerationSpecialization)) + return false; + ICPPEnumerationSpecialization otherEnumSpec = (ICPPEnumerationSpecialization) type; + return getSpecializedBinding().isSameType(otherEnumSpec.getSpecializedBinding()) + && ((IType) getOwner()).isSameType((IType) otherEnumSpec.getOwner()); + } + + @Override + public boolean isScoped() { + return getSpecializedBinding().isScoped(); + } + + @Override + public IType getFixedType() { + return fFixedType; + } + + @Override + public ICPPScope asScope() { + // TODO(nathanridge): Do we need a CPPEnumSpecializationScope? + return getSpecializedBinding().asScope(); + } + + @Override + public Object clone() { + throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$ + } + + @Override + public IEnumerator specializeEnumerator(IEnumerator enumerator) { + // The specialized enumerators are already computed, just need + // to look up the right one. + IEnumerator[] unspecializedEnumerators = getSpecializedBinding().getEnumerators(); + for (int i = 0; i < fEnumerators.length; ++i) { + if (enumerator.equals(unspecializedEnumerators[i])) + return fEnumerators[i]; + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java new file mode 100644 index 00000000000..b3c3ca4516e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeratorSpecialization.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2013 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 + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; + +/** + * Binding for a specialization of an enumerator. + */ +public class CPPEnumeratorSpecialization extends CPPSpecialization implements IEnumerator { + private final IValue fValue; + + public CPPEnumeratorSpecialization(IEnumerator specialized, ICPPEnumerationSpecialization owner, + ICPPTemplateParameterMap argumentMap, IValue value) { + super(specialized, owner, argumentMap); + fValue = value; + } + + @Override + public ICPPEnumerationSpecialization getOwner() { + return (ICPPEnumerationSpecialization) super.getOwner(); + } + + @Override + public IType getType() { + return getOwner(); + } + + @Override + public IValue getValue() { + return fValue; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 81a51e64dd1..c68c28a7f23 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -7,6 +7,7 @@ * * Contributors: * Sergey Prigogin (Google) - initial API and implementation + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -57,4 +58,14 @@ public abstract class CPPEvaluation implements ICPPEvaluation { } return args; } + + protected static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, + ICPPClassSpecialization within, int maxdepth, IASTNode point) { + try { + return CPPTemplates.instantiateBinding(binding, tpMap, packOffset, within, maxdepth, point); + } catch (DOMException e) { + CCorePlugin.log(e); + } + return binding; + } } \ No newline at end of file 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 9e4a6d0a356..0e5e3383e75 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 @@ -42,7 +42,6 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; @@ -76,6 +75,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; @@ -120,6 +121,8 @@ 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.CPPEnumerationSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeratorSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFieldSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionSpecialization; @@ -852,9 +855,29 @@ public class CPPTemplates { ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl; IType type= instantiateType(aliasTemplate.getType(), tpMap, -1, getSpecializationContext(owner), point); spec = new CPPAliasTemplateInstance(decl.getNameCharArray(), aliasTemplate, type); - } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { - // TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter. - spec = decl; + } else if (decl instanceof ICPPEnumeration) { + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPEnumeration enumeration = (ICPPEnumeration) decl; + IType fixedType = instantiateType(enumeration.getFixedType(), tpMap, -1, within, point); + CPPEnumerationSpecialization specializedEnumeration = + new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); + IEnumerator[] enumerators = enumeration.getEnumerators(); + IEnumerator[] specializedEnumerators = new IEnumerator[enumerators.length]; + for (int i = 0; i < enumerators.length; ++i) { + IEnumerator enumerator = enumerators[i]; + IValue specializedValue = + instantiateValue(enumerator.getValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + specializedEnumerators[i] = + new CPPEnumeratorSpecialization(enumerator, specializedEnumeration, tpMap, specializedValue); + } + specializedEnumeration.setEnumerators(specializedEnumerators); + spec = specializedEnumeration; + } else if (decl instanceof IEnumerator) { + IEnumerator enumerator = (IEnumerator) decl; + ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); + ICPPEnumerationSpecialization enumSpec = + (ICPPEnumerationSpecialization) owner.specializeMember(enumeration, point); + spec = enumSpec.specializeEnumerator(enumerator); } else if (decl instanceof ICPPUsingDeclaration) { IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); List result= new ArrayList(); @@ -1305,6 +1328,33 @@ public class CPPTemplates { } } + public static IBinding instantiateBinding(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset, + ICPPClassSpecialization within, int maxdepth, IASTNode point) throws DOMException { + if (binding instanceof IEnumerator) { + IEnumerator enumerator = (IEnumerator) binding; + IBinding owner = enumerator.getOwner(); + if (!(owner instanceof ICPPEnumerationSpecialization)) { + owner = instantiateBinding(owner, tpMap, packOffset, within, maxdepth, point); + } + if (owner instanceof ICPPEnumerationSpecialization) { + return ((ICPPEnumerationSpecialization) owner).specializeEnumerator(enumerator); + } + } else if (binding instanceof ICPPUnknownBinding) { + return resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset, within, point); + } else if (binding instanceof ICPPMethod || binding instanceof ICPPField || binding instanceof ICPPEnumeration) { + IBinding owner = binding.getOwner(); + if (owner instanceof ICPPClassTemplate) { + owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), + tpMap, packOffset, within, point); + } + if (owner instanceof ICPPClassSpecialization) { + // TODO(nathanridge): use specializeMember instead, then combine with ICPPEnumeration branch + return ((ICPPClassSpecialization) owner).specializeMember(binding, point); + } + } + return binding; + } + public static IType resolveTemplateTypeParameter(final ICPPTemplateParameter tpar, ICPPTemplateParameterMap tpMap, int packOffset, IASTNode point) { ICPPTemplateArgument arg= null; 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 a4419e5c668..d2eaaabe21c 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Wind River Systems, Inc. and others. + * Copyright (c) 2012, 2013 Wind River Systems, Inc. and others. * 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 @@ -25,10 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -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.core.dom.ast.cpp.ICPPTemplateArgument; @@ -325,55 +322,26 @@ public class EvalBinding extends CPPEvaluation { @Override public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { - IBinding binding = getBinding(); - if (binding instanceof IEnumerator) { - IEnumerator enumerator = (IEnumerator) binding; - IType originalType = enumerator.getType(); - IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point); - IValue originalValue = enumerator.getValue(); - IValue value = CPPTemplates.instantiateValue(originalValue, tpMap, packOffset, within, maxdepth, point); - // TODO(sprigogin): Not sure if following condition is correct. - if (type != originalType || value != originalValue) - return new EvalFixed(type, ValueCategory.PRVALUE, value); - } else if (binding instanceof ICPPTemplateNonTypeParameter) { - ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) binding); + IBinding origBinding = getBinding(); + if (origBinding instanceof ICPPTemplateNonTypeParameter) { + ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) origBinding); if (argument != null && argument.isNonTypeValue()) { return argument.getNonTypeEvaluation(); } // TODO(sprigogin): Do we need something similar for pack expansion? - } else if (binding instanceof ICPPUnknownBinding) { - binding = resolveUnknown((ICPPUnknownBinding) binding, tpMap, packOffset, within, point); - } else if (binding instanceof ICPPMethod) { - IBinding owner = binding.getOwner(); - if (owner instanceof ICPPClassTemplate) { - owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), - tpMap, packOffset, within, point); - } - if (owner instanceof ICPPClassSpecialization) { - binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, - binding, point); - } - } else if (binding instanceof ICPPField) { - IBinding owner = binding.getOwner(); - if (owner instanceof ICPPClassTemplate) { - owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), - tpMap, packOffset, within, point); - } - if (owner instanceof ICPPClassSpecialization) { - binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner, - binding, point); - } - } else if (binding instanceof ICPPParameter) { - ICPPParameter parameter = (ICPPParameter) binding; - IType originalType = parameter.getType(); - IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point); - if (originalType != type) { - return new EvalFixed(type, ValueCategory.LVALUE, Value.create(this)); + } else if (origBinding instanceof ICPPParameter) { + ICPPParameter parameter = (ICPPParameter) origBinding; + IType origType = parameter.getType(); + IType instantiatedType = CPPTemplates.instantiateType(origType, tpMap, packOffset, within, point); + if (origType != instantiatedType) { + return new EvalFixed(instantiatedType, ValueCategory.LVALUE, Value.create(this)); } + } else { + IBinding instantiatedBinding = instantiateBinding(origBinding, tpMap, packOffset, within, maxdepth, point); + if (instantiatedBinding != origBinding) + return new EvalBinding(instantiatedBinding, getFixedType()); } - if (binding == fBinding) - return this; - return new EvalBinding(binding, getFixedType()); + return this; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 5e86257e167..a5d91072c07 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -34,12 +34,15 @@ import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -669,4 +672,40 @@ public class SemanticUtil { } return false; } + + public static long computeMaxValue(IEnumeration enumeration) { + long maxValue = Long.MIN_VALUE; + IEnumerator[] enumerators = enumeration.getEnumerators(); + for (IEnumerator enumerator : enumerators) { + IValue value = enumerator.getValue(); + if (value != null) { + Long val = value.numericalValue(); + if (val != null) { + long v = val.longValue(); + if (v > maxValue) { + maxValue = v; + } + } + } + } + return maxValue; + } + + public static long computeMinValue(IEnumeration enumeration) { + long minValue = Long.MAX_VALUE; + IEnumerator[] enumerators = enumeration.getEnumerators(); + for (IEnumerator enumerator : enumerators) { + IValue value = enumerator.getValue(); + if (value != null) { + Long val = value.numericalValue(); + if (val != null) { + long v = val.longValue(); + if (v < minValue) { + minValue = v; + } + } + } + } + return minValue; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java index a08ab1bb058..6b6416b7c5b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumeration.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.c; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -25,7 +24,7 @@ class CompositeCEnumeration extends CompositeCBinding implements IEnumeration, I } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { IEnumerator[] result = ((IEnumeration)rbinding).getEnumerators(); for (int i= 0; i < result.length; i++) result[i] = (IEnumerator) cf.getCompositeBinding((IIndexFragmentBinding) result[i]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java index dbae723aa2f..21835141616 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java @@ -11,7 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -27,7 +26,7 @@ class CompositeCPPEnumeration extends CompositeCPPBinding implements ICPPEnumera } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { IEnumerator[] result = ((IEnumeration)rbinding).getEnumerators(); for (int i= 0; i < result.length; i++) result[i] = (IEnumerator) cf.getCompositeBinding((IIndexFragmentBinding) result[i]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java index d320edec18a..0ea282443f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -309,7 +309,7 @@ public class PDOMASTAdapter { } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { return fDelegate.getEnumerators(); } @@ -507,7 +507,7 @@ public class PDOMASTAdapter { } @Override - public IEnumerator[] getEnumerators() throws DOMException { + public IEnumerator[] getEnumerators() { return ((IEnumeration) fDelegate).getEnumerators(); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java index 5ab9c6dc2c2..814f1506258 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2013 Wind River Systems, Inc. and others. * 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 @@ -19,8 +19,6 @@ import java.util.List; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.cdt.core.dom.IName; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -39,7 +37,7 @@ import org.eclipse.cdt.internal.core.model.ext.ICElementHandle; import org.eclipse.cdt.internal.ui.viewsupport.IndexUI; class THGraph { - private static final ICElement[] NO_MEMBERS = new ICElement[0]; + private static final ICElement[] NO_MEMBERS = {}; private THGraphNode fInputNode= null; private HashSet fRootNodes= new HashSet(); private HashSet fLeaveNodes= new HashSet(); @@ -251,25 +249,22 @@ class THGraph { private void addMembers(IIndex index, THGraphNode graphNode, IBinding binding) throws CoreException { if (graphNode.getMembers(false) == null) { ArrayList memberList= new ArrayList(); - try { - if (binding instanceof ICPPClassType) { - ICPPClassType ct= (ICPPClassType) binding; - IBinding[] members= ct.getDeclaredFields(); - addMemberElements(index, members, memberList); - members= ct.getDeclaredMethods(); - addMemberElements(index, members, memberList); - } else if (binding instanceof ICompositeType) { - ICompositeType ct= (ICompositeType) binding; - IBinding[] members= ct.getFields(); - addMemberElements(index, members, memberList); - } else if (binding instanceof IEnumeration) { - IEnumeration ct= (IEnumeration) binding; - IBinding[] members= ct.getEnumerators(); - addMemberElements(index, members, memberList); - } - } catch (DOMException e) { - // Problem bindings should not be reported to the log. + if (binding instanceof ICPPClassType) { + ICPPClassType ct= (ICPPClassType) binding; + IBinding[] members= ct.getDeclaredFields(); + addMemberElements(index, members, memberList); + members= ct.getDeclaredMethods(); + addMemberElements(index, members, memberList); + } else if (binding instanceof ICompositeType) { + ICompositeType ct= (ICompositeType) binding; + IBinding[] members= ct.getFields(); + addMemberElements(index, members, memberList); + } else if (binding instanceof IEnumeration) { + IEnumeration ct= (IEnumeration) binding; + IBinding[] members= ct.getEnumerators(); + addMemberElements(index, members, memberList); } + if (memberList.isEmpty()) { graphNode.setMembers(NO_MEMBERS); } else { diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java index ee669909627..84d603e782c 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Enumeration.java @@ -21,9 +21,9 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.core.runtime.PlatformObject; @SuppressWarnings("restriction") @@ -114,38 +114,10 @@ public class C99Enumeration extends PlatformObject implements IC99Binding, IEnum } public long getMinValue() { - long minValue = Long.MAX_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v < minValue) { - minValue = v; - } - } - } - } - return minValue; + return SemanticUtil.computeMinValue(this); } public long getMaxValue() { - long maxValue = Long.MIN_VALUE; - IEnumerator[] enumerators = getEnumerators(); - for (IEnumerator enumerator : enumerators) { - IValue value = enumerator.getValue(); - if (value != null) { - Long val = value.numericalValue(); - if (val != null) { - long v = val.longValue(); - if (v > maxValue) { - maxValue = v; - } - } - } - } - return maxValue; + return SemanticUtil.computeMaxValue(this); } } -- cgit v1.2.3