diff options
author | Sergey Prigogin | 2013-02-01 22:39:26 +0000 |
---|---|---|
committer | Sergey Prigogin | 2013-02-05 18:18:20 +0000 |
commit | d3160c878f2fca56769930f7fbf7ab1df40ff951 (patch) | |
tree | 7a3a6a3ade5cad15992e0478b61feb63ae3bc508 | |
parent | c3470476a050c262c51cf28011485ce7c57e4b38 (diff) | |
download | org.eclipse.cdt-d3160c878f2fca56769930f7fbf7ab1df40ff951.tar.gz org.eclipse.cdt-d3160c878f2fca56769930f7fbf7ab1df40ff951.tar.xz org.eclipse.cdt-d3160c878f2fca56769930f7fbf7ab1df40ff951.zip |
Bug 389009 - Enumerator with dependent value. Index support.
Change-Id: Ic54e20e2b4c04241d9a86c1f363b190091a28d0e
Reviewed-on: https://git.eclipse.org/r/10125
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
11 files changed, 438 insertions, 37 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 2c1033ffc30..54d2e340f7a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -23,12 +23,14 @@ import org.eclipse.cdt.core.dom.ast.IASTName; 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.IEnumerator; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; 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.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -2063,6 +2065,27 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa checkBindings(); } + // template <typename T> + // struct B { + // enum { value = 1 }; + // }; + // + // template <typename T> + // struct C { + // enum { id = B<T>::value }; + // }; + + // void test() { + // int x = C<bool>::id; + // } + public void testDependentEnumValue_389009() throws Exception { + IEnumerator binding = getBindingFromASTName("id;", 2, IEnumerator.class); + IValue value = binding.getValue(); + Long num = value.numericalValue(); + assertNotNull(num); + assertEquals(1, num.longValue()); + } + // template<typename U> // struct A { // typedef U type1; 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 7aab87f9d8d..a56f3d3318f 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 Symbian Software Systems and others. + * Copyright (c) 2007, 2013 Symbian Software Systems 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 @@ -9,6 +9,7 @@ * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Thomas Corbat (IFS) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.index; @@ -62,4 +63,6 @@ public interface IIndexCPPBindingConstants { int CPP_USING_DECLARATION_SPECIALIZATION= IIndexBindingConstants.LAST_CONSTANT + 49; int CPP_UNKNOWN_METHOD = IIndexBindingConstants.LAST_CONSTANT + 50; int CPP_TEMPLATE_ALIAS = IIndexBindingConstants.LAST_CONSTANT + 51; + int CPP_ENUMERATION_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 52; + int CPP_ENUMERATOR_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 53; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index c042cd8cf51..03c11be0d0c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -229,10 +229,11 @@ public class PDOM extends PlatformObject implements IPDOM { * 137.0 - Fixed serialization of very large types and template arguments, bug 392278. * 138.0 - Constexpr functions, bug 395238. * 139.0 - More efficient and robust storage of types and template arguments, bug 395243. + * 140.0 - Enumerators with dependent values, bug 389009. */ - private static final int MIN_SUPPORTED_VERSION= version(139, 0); - private static final int MAX_SUPPORTED_VERSION= version(139, Short.MAX_VALUE); - private static final int DEFAULT_VERSION = version(139, 0); + private static final int MIN_SUPPORTED_VERSION= version(140, 0); + private static final int MAX_SUPPORTED_VERSION= version(140, Short.MAX_VALUE); + private static final int DEFAULT_VERSION = version(140, 0); private static int version(int major, int minor) { return (major << 16) + minor; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java index 19b7e2b5c5a..807886f84a1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2010, 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -23,7 +24,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; */ public interface IPDOMCPPEnumType extends ICPPEnumeration, IPDOMBinding, IIndexType { /** - * Return the scope name, for use in {@link IScope#getScopeName()} + * Returns the scope name, for use in {@link IScope#getScopeName()} */ IIndexName getScopeName(); @@ -33,5 +34,5 @@ public interface IPDOMCPPEnumType extends ICPPEnumeration, IPDOMBinding, IIndexT /** * Called by the scope to access the enumerators. */ - void loadEnumerators(CharArrayMap<PDOMCPPEnumerator> map); + void loadEnumerators(CharArrayMap<IPDOMCPPEnumerator> map); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java new file mode 100644 index 00000000000..ff2f767d2e1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumerator.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding; + +/** + * Interface for a c++ enumerator stored in the index. + */ +public interface IPDOMCPPEnumerator extends IEnumerator, IPDOMBinding { +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java index 25f34538a52..f892e243acd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java @@ -65,7 +65,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { @Override public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { try { - CharArrayMap<PDOMCPPEnumerator> map= getBindingMap(fBinding); + CharArrayMap<IPDOMCPPEnumerator> map= getBindingMap(fBinding); return map.get(name.toCharArray()); } catch (CoreException e) { CCorePlugin.log(e); @@ -81,7 +81,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { @Override public IBinding[] getBindings(ScopeLookupData lookup) { try { - CharArrayMap<PDOMCPPEnumerator> map= getBindingMap(fBinding); + CharArrayMap<IPDOMCPPEnumerator> map= getBindingMap(fBinding); if (lookup.isPrefixLookup()) { final List<IBinding> result= new ArrayList<IBinding>(); final char[] nc= lookup.getLookupKey(); @@ -135,36 +135,36 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { return fBinding.hashCode(); } - private static CharArrayMap<PDOMCPPEnumerator> getBindingMap(IPDOMCPPEnumType enumeration) throws CoreException { + private static CharArrayMap<IPDOMCPPEnumerator> getBindingMap(IPDOMCPPEnumType enumeration) throws CoreException { final Long key= enumeration.getRecord() + PDOMCPPLinkage.CACHE_MEMBERS; final PDOM pdom = enumeration.getPDOM(); @SuppressWarnings("unchecked") - Reference<CharArrayMap<PDOMCPPEnumerator>> cached= (Reference<CharArrayMap<PDOMCPPEnumerator>>) pdom.getCachedResult(key); - CharArrayMap<PDOMCPPEnumerator> map= cached == null ? null : cached.get(); + Reference<CharArrayMap<IPDOMCPPEnumerator>> cached= (Reference<CharArrayMap<IPDOMCPPEnumerator>>) pdom.getCachedResult(key); + CharArrayMap<IPDOMCPPEnumerator> map= cached == null ? null : cached.get(); if (map == null) { // there is no cache, build it: - map= new CharArrayMap<PDOMCPPEnumerator>(); + map= new CharArrayMap<IPDOMCPPEnumerator>(); enumeration.loadEnumerators(map); pdom.putCachedResult(key, new SoftReference<CharArrayMap<?>>(map)); } return map; } - public static void updateCache(PDOMCPPEnumeration enumType, PDOMCPPEnumerator enumItem) { + public static void updateCache(IPDOMCPPEnumType enumType, IPDOMCPPEnumerator enumItem) { final Long key= enumType.getRecord() + PDOMCPPLinkage.CACHE_MEMBERS; final PDOM pdom = enumType.getPDOM(); @SuppressWarnings("unchecked") - Reference<CharArrayMap<PDOMCPPEnumerator>> cached= (Reference<CharArrayMap<PDOMCPPEnumerator>>) pdom.getCachedResult(key); - CharArrayMap<PDOMCPPEnumerator> map= cached == null ? null : cached.get(); + Reference<CharArrayMap<IPDOMCPPEnumerator>> cached= (Reference<CharArrayMap<IPDOMCPPEnumerator>>) pdom.getCachedResult(key); + CharArrayMap<IPDOMCPPEnumerator> map= cached == null ? null : cached.get(); if (map != null) { map.put(enumType.getNameCharArray(), enumItem); } } - public static IEnumerator[] getEnumerators(PDOMCPPEnumeration enumType) { + public static IEnumerator[] getEnumerators(IPDOMCPPEnumType enumType) { try { - CharArrayMap<PDOMCPPEnumerator> map = getBindingMap(enumType); + CharArrayMap<IPDOMCPPEnumerator> map = getBindingMap(enumType); List<IEnumerator> result= new ArrayList<IEnumerator>(); for (IEnumerator value : map.values()) { if (IndexFilter.ALL_DECLARED.acceptBinding(value)) { @@ -179,10 +179,10 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { return new IEnumerator[0]; } - public static void acceptViaCache(PDOMCPPEnumeration enumType, IPDOMVisitor visitor) { + public static void acceptViaCache(IPDOMCPPEnumType enumType, IPDOMVisitor visitor) { try { - CharArrayMap<PDOMCPPEnumerator> map = getBindingMap(enumType); - for (PDOMCPPEnumerator enumItem : map.values()) { + CharArrayMap<IPDOMCPPEnumerator> map = getBindingMap(enumType); + for (IPDOMCPPEnumerator enumItem : map.values()) { visitor.visit(enumItem); visitor.leave(enumItem); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java index 33cc375ef8f..1c8c7b53f6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java @@ -114,7 +114,7 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD if (node instanceof PDOMCPPEnumerator) { PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); list.addMember(node); - PDOMCPPEnumScope.updateCache(this, (PDOMCPPEnumerator) node); + PDOMCPPEnumScope.updateCache(this, (IPDOMCPPEnumerator) node); } } @@ -218,14 +218,14 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD } @Override - public void loadEnumerators(final CharArrayMap<PDOMCPPEnumerator> map) { + public void loadEnumerators(final CharArrayMap<IPDOMCPPEnumerator> map) { try { PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); list.accept(new IPDOMVisitor() { @Override public boolean visit(IPDOMNode node) throws CoreException { - if (node instanceof PDOMCPPEnumerator) { - final PDOMCPPEnumerator item = (PDOMCPPEnumerator) node; + if (node instanceof IPDOMCPPEnumerator) { + final IPDOMCPPEnumerator item = (IPDOMCPPEnumerator) node; map.put(item.getNameCharArray(), item); } return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java new file mode 100644 index 00000000000..e4e9d451bc0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +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.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.ICPPSpecialization; +import org.eclipse.cdt.core.parser.util.CharArrayMap; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.db.PDOMNodeLinkedList; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * Enumeration specialization in the index. + */ +class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization + implements IPDOMCPPEnumType, IPDOMMemberOwner, ICPPEnumerationSpecialization { + private static final int OFFSET_ENUMERATOR_LIST = PDOMCPPSpecialization.RECORD_SIZE; + private static final int OFFSET_MIN_VALUE= OFFSET_ENUMERATOR_LIST + Database.PTR_SIZE; + private static final int OFFSET_MAX_VALUE= OFFSET_MIN_VALUE + 8; + private static final int OFFSET_FIXED_TYPE = OFFSET_MAX_VALUE + 8; + private static final int OFFSET_FLAGS = OFFSET_FIXED_TYPE + Database.TYPE_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = OFFSET_FLAGS + 1; + + private Long fMinValue; // No need for volatile, all fields of Long are final. + private Long fMaxValue; // No need for volatile, all fields of Long are final. + private volatile IType fFixedType= ProblemBinding.NOT_INITIALIZED; + private PDOMCPPEnumScope fScope; // No need for volatile, all fields of PDOMCPPEnumScope are final. + + public PDOMCPPEnumerationSpecialization(PDOMLinkage linkage, PDOMNode parent, + ICPPEnumeration enumeration, PDOMBinding specialized) throws CoreException { + super(linkage, parent, (ICPPSpecialization) enumeration, specialized); + storeProperties(enumeration); + } + + public PDOMCPPEnumerationSpecialization(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + public ICPPEnumeration getSpecializedBinding() { + return (ICPPEnumeration) super.getSpecializedBinding(); + } + + @Override + public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { + storeProperties((ICPPEnumeration) newBinding); + } + + private void storeProperties(ICPPEnumeration enumeration) throws CoreException { + final Database db= getDB(); + db.putByte(record + OFFSET_FLAGS, enumeration.isScoped() ? (byte) 1 : (byte) 0); + + getLinkage().storeType(record + OFFSET_FIXED_TYPE, enumeration.getFixedType()); + + if (enumeration instanceof ICPPInternalBinding) { + if (((ICPPInternalBinding) enumeration).getDefinition() != null) { + final long minValue = enumeration.getMinValue(); + final long maxValue = enumeration.getMaxValue(); + db.putLong(record + OFFSET_MIN_VALUE, minValue); + db.putLong(record + OFFSET_MAX_VALUE, maxValue); + fMinValue= minValue; + fMaxValue= maxValue; + } + } + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_ENUMERATION_SPECIALIZATION; + } + + @Override + public IEnumerator[] getEnumerators() { + return PDOMCPPEnumScope.getEnumerators(this); + } + + @Override + public void accept(IPDOMVisitor visitor) throws CoreException { + PDOMCPPEnumScope.acceptViaCache(this, visitor); + } + + @Override + public void addChild(PDOMNode node) throws CoreException { + if (node instanceof IPDOMCPPEnumerator) { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); + list.addMember(node); + PDOMCPPEnumScope.updateCache(this, (IPDOMCPPEnumerator) node); + } + } + + @Override + public boolean mayHaveChildren() { + return true; + } + + @Override + public boolean isSameType(IType type) { + if (type instanceof ITypedef) { + return type.isSameType(this); + } + + if (type instanceof PDOMNode) { + PDOMNode node= (PDOMNode) type; + if (node.getPDOM() == getPDOM()) { + return node.getRecord() == getRecord(); + } + } + + if (type instanceof IEnumeration) { + IEnumeration etype= (IEnumeration) type; + char[] nchars = etype.getNameCharArray(); + if (nchars.length == 0) { + nchars= ASTTypeUtil.createNameForAnonymous(etype); + } + if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) + return false; + + return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); + } + return false; + } + + @Override + public long getMinValue() { + if (fMinValue != null) { + return fMinValue.longValue(); + } + long minValue= 0; + try { + minValue= getDB().getLong(record + OFFSET_MIN_VALUE); + } catch (CoreException e) { + } + fMinValue= minValue; + return minValue; + } + + @Override + public long getMaxValue() { + if (fMaxValue != null) { + return fMaxValue.longValue(); + } + long maxValue= 0; + try { + maxValue= getDB().getLong(record + OFFSET_MAX_VALUE); + } catch (CoreException e) { + } + fMaxValue= maxValue; + return maxValue; + } + + @Override + public Object clone() { + throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$ + } + + @Override + public boolean isScoped() { + try { + return getDB().getByte(record + OFFSET_FLAGS) != 0; + } catch (CoreException e) { + return false; + } + } + + @Override + public IType getFixedType() { + if (fFixedType == ProblemBinding.NOT_INITIALIZED) { + fFixedType= loadFixedType(); + } + return fFixedType; + } + + private IType loadFixedType() { + try { + return getLinkage().loadType(record + OFFSET_FIXED_TYPE); + } catch (CoreException e) { + CCorePlugin.log(e); + return null; + } + } + + @Override + public ICPPScope asScope() { + if (fScope == null) { + fScope= new PDOMCPPEnumScope(this); + } + return fScope; + } + + @Override + public void loadEnumerators(final CharArrayMap<IPDOMCPPEnumerator> map) { + try { + PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST); + list.accept(new IPDOMVisitor() { + @Override + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof IPDOMCPPEnumerator) { + final IPDOMCPPEnumerator item = (IPDOMCPPEnumerator) node; + map.put(item.getNameCharArray(), item); + } + return true; + } + @Override + public void leave(IPDOMNode node) {} + }); + } catch (CoreException e) { + CCorePlugin.log(e); + } + } + + @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 < unspecializedEnumerators.length; ++i) { + if (enumerator.equals(unspecializedEnumerators[i])) { + IEnumerator[] enumerators = getEnumerators(); + return i < enumerators.length ? enumerators[i] : enumerator; + } + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java index b449b88b6ab..3e28624a9cd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java @@ -1,13 +1,14 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 QNX Software Systems and others. + * Copyright (c) 2006, 2013 QNX Software Systems 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Doug Schaefer (QNX) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Doug Schaefer (QNX) - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -19,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.core.runtime.CoreException; @@ -26,11 +28,11 @@ import org.eclipse.core.runtime.CoreException; /** * Binding for a c++ enumerator in the index. */ -class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { +class PDOMCPPEnumerator extends PDOMCPPBinding implements IPDOMCPPEnumerator { private static final int VALUE= PDOMCPPBinding.RECORD_SIZE; @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = VALUE + 4; + protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, IEnumerator enumerator) throws CoreException { @@ -55,11 +57,10 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { private void storeValue(IEnumerator enumerator) throws CoreException { IValue value= enumerator.getValue(); if (value != null) { - Long val= value.numericalValue(); - getDB().putInt(record + VALUE, val == null ? -1 : val.intValue()); + getLinkage().storeValue(record + VALUE, value); } } - + @Override public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { if (newBinding instanceof IEnumerator) @@ -77,8 +78,7 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { @Override public IValue getValue() { try { - int val= getDB().getInt(record + VALUE); - return Value.create(val); + return getLinkage().loadValue(record + VALUE); } catch (CoreException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java new file mode 100644 index 00000000000..2044ee6b535 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeratorSpecialization.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2013 Google, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom.dom.cpp; + +import org.eclipse.cdt.core.CCorePlugin; +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.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; +import org.eclipse.core.runtime.CoreException; + +/** + * Binding for a specialization of an enumerator in the index. + */ +class PDOMCPPEnumeratorSpecialization extends PDOMCPPSpecialization implements IPDOMCPPEnumerator { + private static final int VALUE= PDOMCPPSpecialization.RECORD_SIZE; + + @SuppressWarnings("hiding") + protected static final int RECORD_SIZE = VALUE + Database.VALUE_SIZE; + + public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, PDOMNode parent, + IEnumerator enumerator, PDOMBinding specialized) throws CoreException { + super(linkage, parent, (ICPPSpecialization) enumerator, specialized); + storeValue(enumerator); + } + + public PDOMCPPEnumeratorSpecialization(PDOMLinkage linkage, long record) { + super(linkage, record); + } + + @Override + protected int getRecordSize() { + return RECORD_SIZE; + } + + @Override + public int getNodeType() { + return IIndexCPPBindingConstants.CPP_ENUMERATOR_SPECIALIZATION; + } + + private void storeValue(IEnumerator enumerator) throws CoreException { + IValue value= enumerator.getValue(); + if (value != null) { + getLinkage().storeValue(record + VALUE, value); + } + } + + @Override + public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException { + if (newBinding instanceof IEnumerator) + storeValue((IEnumerator) newBinding); + } + + @Override + public IType getType() { + IIndexFragmentBinding owner = getOwner(); + if (owner instanceof IType) + return (IType) owner; + return null; + } + + @Override + public IValue getValue() { + try { + return getLinkage().loadValue(record + VALUE); + } catch (CoreException e) { + CCorePlugin.log(e); + } + return Value.UNKNOWN; + } +} 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 80eeb687946..b21ab32e014 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2012 QNX Software Systems and others. + * Copyright (c) 2005, 2013 QNX Software Systems 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 @@ -534,6 +534,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { result= new PDOMCPPTypedefSpecialization(this, parent, (ITypedef) special, orig); } else if (special instanceof ICPPUsingDeclaration) { result= new PDOMCPPUsingDeclarationSpecialization(this, parent, (ICPPUsingDeclaration) special, orig); + } else if (special instanceof ICPPEnumeration) { + result= new PDOMCPPEnumerationSpecialization(this, parent, (ICPPEnumeration) special, orig); + } else if (special instanceof IEnumerator) { + result= new PDOMCPPEnumeratorSpecialization(this, parent, (IEnumerator) special, orig); } return result; @@ -893,6 +897,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { return new PDOMCPPUsingDeclarationSpecialization(this, record); case CPP_TEMPLATE_ALIAS: return new PDOMCPPAliasTemplate(this, record); + case CPP_ENUMERATION_SPECIALIZATION: + return new PDOMCPPEnumeratorSpecialization(this, record); + case CPP_ENUMERATOR_SPECIALIZATION: + return new PDOMCPPEnumeratorSpecialization(this, record); } assert false : "nodeid= " + nodeType; //$NON-NLS-1$ return null; |