Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMarkus Schorn2010-03-19 13:06:51 +0000
committerMarkus Schorn2010-03-19 13:06:51 +0000
commitb01672b1f37bdf0602f513c2f3d5fd85d0755ec3 (patch)
tree0df7a79e99e0fe7b32ea29b890a6618b67cb45dd /core
parent90f7d1a70295c7566d6306cd701bb2ea595e4bf5 (diff)
downloadorg.eclipse.cdt-b01672b1f37bdf0602f513c2f3d5fd85d0755ec3.tar.gz
org.eclipse.cdt-b01672b1f37bdf0602f513c2f3d5fd85d0755ec3.tar.xz
org.eclipse.cdt-b01672b1f37bdf0602f513c2f3d5fd85d0755ec3.zip
Bug 305975: Strongly typed enums, forward declarations for enum.
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java163
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java9
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java51
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/EScopeKind.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTEnumerationSpecifier.java66
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java44
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java32
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java121
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java20
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumScope.java34
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java194
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java65
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java112
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java30
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java74
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java53
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java52
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumeration.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java26
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java27
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java36
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java176
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumeration.java158
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java47
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java33
42 files changed, 1457 insertions, 339 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
index 07ac9f39c12..fb3ee4fbf29 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java
@@ -494,7 +494,7 @@ public class AST2BaseTest extends BaseTestCase {
public IProblemBinding assertProblem(String section, int len) {
if (len <= 0)
- len= section.length()-len;
+ len= section.length()+len;
IBinding binding= binding(section, len);
assertTrue("Non-ProblemBinding for name: " + section.substring(0, len),
binding instanceof IProblemBinding);
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 3fb6d5b0ae8..2cb8f63ff45 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -100,6 +100,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
@@ -119,6 +120,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@@ -8332,5 +8334,166 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals("int (* (int))(int)", ASTTypeUtil.getType(f.getType()));
}
+ // enum class EScoped1 {a1};
+ // enum class EScoped2 : short {a2};
+ // enum class EScoped3;
+ // enum EUnscoped1 {b1};
+ // enum EUnscoped2 : long {b2};
+ // enum EUnscoped3 : int;
+ public void testScopedEnums_305975a() throws Exception {
+ String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+
+ ICPPEnumeration e;
+ ICPPBinding ei;
+ e= bh.assertNonProblem("EScoped1", 0);
+ assertTrue(e.isScoped());
+ assertEquals("int", ASTTypeUtil.getType(e.getFixedType()));
+ assertDefinition(e);
+ ei= bh.assertNonProblem("a1", 0);
+ assertSame(e, ei.getOwner());
+ assertEquals(2, ei.getQualifiedName().length);
+
+ e= bh.assertNonProblem("EScoped2", 0);
+ assertTrue(e.isScoped());
+ assertEquals("short int", ASTTypeUtil.getType(e.getFixedType()));
+ assertDefinition(e);
+ ei= bh.assertNonProblem("a2", 0);
+ assertSame(e, ei.getOwner());
+ assertEquals(2, ei.getQualifiedName().length);
+
+ e= bh.assertNonProblem("EScoped3", 0);
+ assertTrue(e.isScoped());
+ assertEquals("int", ASTTypeUtil.getType(e.getFixedType()));
+ assertDeclaration(e);
+
+ e= bh.assertNonProblem("EUnscoped1", 0);
+ assertFalse(e.isScoped());
+ assertNull(e.getFixedType());
+ assertDefinition(e);
+ ei= bh.assertNonProblem("b1", 0);
+ assertSame(e, ei.getOwner());
+ assertEquals(1, ei.getQualifiedName().length);
+
+ e= bh.assertNonProblem("EUnscoped2", 0);
+ assertFalse(e.isScoped());
+ assertEquals("long int", ASTTypeUtil.getType(e.getFixedType()));
+ assertDefinition(e);
+ ei= bh.assertNonProblem("b2", 0);
+ assertSame(e, ei.getOwner());
+ assertEquals(1, ei.getQualifiedName().length);
+
+ e= bh.assertNonProblem("EUnscoped3", 0);
+ assertFalse(e.isScoped());
+ assertEquals("int", ASTTypeUtil.getType(e.getFixedType()));
+ assertDeclaration(e);
+ }
+
+ private void assertDefinition(ICPPBinding b) {
+ assertTrue(((IASTName)((ICPPInternalBinding) b).getDefinition()).isDefinition());
+ }
+
+ private void assertDeclaration(ICPPBinding b) {
+ assertTrue(((IASTName)((ICPPInternalBinding) b).getDeclarations()[0]).isDeclaration());
+ }
+
+ // enum class E { a, b };
+ // enum E x1 = E::a; // OK
+ // enum F { a, b };
+ // enum F y1 = a; // OK
+ // enum E1 : int; // OK: E1 is un-scoped, underlying type is int
+ // enum class F1; // OK: F1 is scoped, underlying type is int
+ public void testScopedEnums_305975b() throws Exception {
+ String code= getAboveComment();
+ parseAndCheckBindings(code);
+ }
+
+ // enum class E x2 = E::a; // illegal (elaborated type specifier)
+ // enum class F y2 = a; // illegal
+ // enum E; // illegal
+ public void testScopedEnums_305975c() throws Exception {
+ String code= getAboveComment();
+ IASTTranslationUnit tu= parse(code, ParserLanguage.CPP, true, false);
+ IASTDeclaration[] decls = tu.getDeclarations();
+ assertEquals(3, decls.length);
+ assertInstance(decls[0], IASTProblemDeclaration.class);
+ assertInstance(decls[1], IASTProblemDeclaration.class);
+ assertInstance(decls[2], IASTProblemDeclaration.class);
+ }
+
+ // enum class Col { red, yellow, green };
+ // void fint(int);
+ // void fbool(bool);
+ // void fCol(Col);
+ //
+ // void test() {
+ // fCol(Col::red);
+ // fint(Col::red); // error: no conversion to int
+ // fbool(Col::red); // error: no Col to bool conversion
+ // }
+ public void testScopedEnums_305975d() throws Exception {
+ String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+
+ bh.assertNonProblem("fCol(Col::red)", 4);
+ bh.assertProblem("fint(Col::red)", 4);
+ bh.assertProblem("fbool(Col::red)", 5);
+ }
+
+ // enum direction { left='l', right='r'};
+ // void g() {
+ // direction d; // OK
+ // d = left; // OK
+ // d = direction::right; // OK
+ // }
+ //
+ // enum class altitude { high=1, low=2 };
+ // void h() {
+ // altitude a; // OK
+ // a = altitude::low; // OK
+ // }
+ //
+ // struct X {
+ // enum xdir { xl=1, xr=2 };
+ // int f(int i) { return i==xl ? 0 : i==xr ? 1 : 2; }
+ // };
+ // void g(X* p) {
+ // int i;
+ // i = p->f(X::xr); // OK
+ // i = p->f(p->xl); // OK
+ // }
+ public void testScopedEnums_305975e() throws Exception {
+ String code= getAboveComment();
+ parseAndCheckBindings(code);
+ }
+
+ // enum class altitude { high=1, low=2 };
+ // struct X {
+ // enum xdir { xl=1, xr=2 };
+ // int f(int i) { return i==xl ? 0 : i==xr ? 1 : 2; }
+ // };
+ // void g(X* p) {
+ // altitude a= high; // error: high not in scope
+ // xdir d; // error: xdir not in scope
+ // xl; // error: not in scope
+ // }
+ public void testScopedEnums_305975f() throws Exception {
+ String code= getAboveComment();
+ BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
+
+ bh.assertProblem("high;", -1);
+ bh.assertProblem("xdir d", -2);
+ bh.assertProblem("xl;", -1);
+ }
+
+ // void f(int);
+ // enum class X {e1, e2= e1+2, e3};
+ // enum class Y {e1, e2= f(e1)+2, e3};
+ // enum A {e1, e2= e1+2, e3};
+ // enum B {e1, e2= f(e1)+2, e3};
+ public void testScopedEnums_305975g() throws Exception {
+ String code= getAboveComment();
+ parseAndCheckBindings(code);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java
index ef72bed2d4b..670ab8625dc 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2006, 2010 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
@@ -8,7 +8,6 @@
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
-
package org.eclipse.cdt.internal.index.tests;
import java.util.LinkedList;
@@ -217,13 +216,13 @@ public class IndexSearchTest extends IndexTestBase {
checkIsEnumerator(bindings[0]);
bindings= fIndex.findBindings(new Pattern[]{pEnumeration, pEnumerator}, true, INDEX_FILTER, NPM);
- assertEquals(0, bindings.length);
+ assertEquals(1, bindings.length);
bindings= fIndex.findBindings(new char[][]{sEnumeration, sEnumerator}, INDEX_FILTER, NPM);
- assertEquals(0, bindings.length);
+ assertEquals(1, bindings.length);
bindings= fIndex.findBindings(new Pattern[]{pEnumeration, pEnumerator}, false, INDEX_FILTER, NPM);
- assertEquals(0, bindings.length);
+ assertEquals(1, bindings.length);
bindings= fIndex.findBindings(pEnumeration, true, INDEX_FILTER, NPM);
assertEquals(1, bindings.length);
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
index f92cfd9f630..54cb32245e4 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2010 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
@@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
@@ -1215,4 +1216,52 @@ public class IndexUpdateTests extends IndexTestBase {
fIndex.releaseReadLock();
}
}
+
+ // enum E {e0};
+
+ // enum class E;
+
+ // enum E : short {e1};
+
+ // enum class E {e2};
+
+ // enum class E : short {e1};
+
+ // enum E : int;
+ public void testEnumCPP() throws Exception {
+ setupFile(6, true);
+ checkEnum(false, null, "e0");
+ updateFile();
+ checkEnum(true, "int", null);
+ updateFile();
+ checkEnum(false, "short int", "e1");
+ updateFile();
+ checkEnum(true, "int", "e2");
+ updateFile();
+ checkEnum(true, "short int", "e1");
+ updateFile();
+ checkEnum(false, "int", null);
+ }
+
+ private void checkEnum(boolean scoped, String fixedType, String enumItem) throws Exception {
+ fIndex.acquireReadLock();
+ try {
+ ICPPEnumeration enumType = (ICPPEnumeration) findBinding("E");
+ assertEquals(scoped, enumType.isScoped());
+ if (fixedType == null) {
+ assertNull(enumType.getFixedType());
+ } else {
+ assertEquals(fixedType, ASTTypeUtil.getType(enumType.getFixedType()));
+ }
+ final IEnumerator[] enumItems = enumType.getEnumerators();
+ if (enumItem == null) {
+ assertEquals(0, enumItems.length);
+ } else {
+ assertEquals(1, enumItems.length);
+ assertEquals(enumItem, enumItems[0].getName());
+ }
+ } finally {
+ fIndex.releaseReadLock();
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/EScopeKind.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/EScopeKind.java
index 74f9cb8d13f..c9bfea87709 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/EScopeKind.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/EScopeKind.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2010 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
@@ -20,6 +20,10 @@ public enum EScopeKind {
* function-prototype scope (parameters in function prototypes).
*/
eLocal,
+ /**
+ * @since 5.2
+ */
+ eEnumeration,
eNamespace,
/**
* For classes, structs or unions.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java
index 7c90bf4015e..90eb7683513 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -48,10 +48,11 @@ public interface IBinding extends IAdaptable {
* Returns the binding that owns this binding, or <code>null</code> if there is no owner.
* <p>
* The owner is determined as follows:
- * <br> {@link ICPPUsingDeclaration}: the owner depends on where the declaration is found, within a
+ * <br> {@link ICPPUsingDeclaration}: The owner depends on where the declaration is found, within a
* function or method, a class-type, a namespace or on global scope.
- * <br> {@link ICPPTemplateParameter}: the owner is the {@link ICPPTemplateDefinition}.
- * <br> for all other bindings the owner depends on where the binding can be defined (it could be
+ * <br> {@link ICPPTemplateParameter}: The owner is the {@link ICPPTemplateDefinition}.
+ * <br> {@link IEnumerator}: The owner is the {@link IEnumeration}, independent of whether they are scoped or not.
+ * <br> For all other bindings: The owner depends on where the binding can be defined (it could be
* declared else where).
* <p> Possible owners are:
* <br> {@link IFunction}: for parameters, local types, variables, enumerators, labels and using declarations;
@@ -60,7 +61,8 @@ public interface IBinding extends IAdaptable {
* <br> {@link ICompositeType}: for struct- and union-members, even if the composite type is anonymous;
* also for anonymous structs or unions found within another struct;
* <br> {@link ICPPNamespace}: for global types, functions, variables, enumerators, namespaces and using declarations;
- * <br> <code>null</code>: for types, functions, variables, enumerators, namespaces and using declarations;
+ * <br> {@link IEnumeration}: for enumerators.
+ * <br> <code>null</code>: for types, functions, variables, namespaces and using declarations;
* @since 5.1
*/
public IBinding getOwner() throws DOMException;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTEnumerationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTEnumerationSpecifier.java
new file mode 100644
index 00000000000..78678e5240f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTEnumerationSpecifier.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
+
+/**
+ * <code> enum struct : unsigned int {...}</code>
+ *
+ * @since 5.2
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICPPASTEnumerationSpecifier extends IASTEnumerationSpecifier, ICPPASTDeclSpecifier {
+
+ public static final ASTNodeProperty BASE_TYPE = new ASTNodeProperty(
+ "ICPPASTEnumerationSpecifier.BASE_TYPE [ICPPASTDeclSpecifier]"); //$NON-NLS-1$
+
+ public ICPPASTEnumerationSpecifier copy();
+
+ /**
+ * Not allowed on frozen ast.
+ */
+ public void setIsScoped(boolean isScoped);
+
+ /**
+ * An enum is scoped if it uses the enumeration head
+ * <code>enum class</code> or <code>enum struct</code>
+ */
+ public boolean isScoped();
+
+ /**
+ * Not allowed on frozen ast.
+ */
+ public void setIsOpaque(boolean isOpaque);
+
+ /**
+ * An opaque specifier does not have a body.
+ */
+ public boolean isOpaque();
+
+ /**
+ * Not allowed on frozen ast.
+ */
+ public void setBaseType(ICPPASTDeclSpecifier baseType);
+
+ /**
+ * Returns the base type for this enum or <code>null</code> if it was not specified.
+ */
+ public ICPPASTDeclSpecifier getBaseType();
+
+ /**
+ * Returns the scope containing the enumerators of this enumeration, or <code>null</code> if the specifier
+ * is opaque.
+ */
+ public ICPPScope getScope();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java
new file mode 100644
index 00000000000..7cd598500e0
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPEnumeration.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IEnumeration;
+import org.eclipse.cdt.core.dom.ast.IType;
+
+/**
+ * C++ specific version of enumerations.
+ *
+ * @since 5.2
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ICPPEnumeration extends IEnumeration, ICPPBinding {
+
+ /**
+ * Returns whether this enumeration is scoped.
+ * An enumeration can only be scoped in C++.
+ */
+ boolean isScoped();
+
+ /**
+ * Returns the underlying type of the enumeration if it is fixed, or <code>null</code> otherwise.
+ * The underlying type can only be fixed in C++.
+ */
+ IType getFixedType();
+
+ /**
+ * Returns the scope containing the enumerators.
+ * By the standard the scope is only defined for scoped enums, however it will be returned
+ * for any enum. In case the enum has no definition (just opaque declarations) an empty scope
+ * will be returned.
+ */
+ ICPPScope asScope();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
index a69eb686ad7..b29a6ce8219 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java
@@ -99,6 +99,11 @@ public interface ICPPNodeFactory extends INodeFactory {
public ICPPASTElaboratedTypeSpecifier newElaboratedTypeSpecifier(int kind, IASTName name);
+ /**
+ * @since 5.2
+ */
+ public ICPPASTEnumerationSpecifier newEnumerationSpecifier(boolean isScoped, IASTName name, ICPPASTDeclSpecifier baseType);
+
public ICPPASTExplicitTemplateInstantiation newExplicitTemplateInstantiation(IASTDeclaration declaration);
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 6a3767650c5..65ef81c1824 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -1451,8 +1451,13 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
final IASTEnumerationSpecifier result= nodeFactory.newEnumerationSpecifier(name);
- boolean needComma= false;
- int endOffset= consume().getEndOffset(); // IToken.tLBRACE
+ int endOffset= enumBody(result);
+ return setRange(result, offset, endOffset);
+ }
+
+ protected int enumBody(final IASTEnumerationSpecifier result) throws EndOfFileException, BacktrackException {
+ boolean needComma= false;
+ int endOffset= consume(IToken.tLBRACE).getEndOffset(); // IToken.tLBRACE
int problemOffset= endOffset;
try {
loop: while (true) {
@@ -1504,9 +1509,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTProblem problem= skipProblemEnumerator(problemOffset);
throwBacktrack(problem, result);
}
- setRange(result, offset, endOffset);
- return result;
- }
+ return endOffset;
+ }
protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException;
@@ -1556,7 +1560,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return result;
// support simple declarations without declarators
- final boolean acceptEmpty = acceptCompoundWithoutDtor && specifiesCompound(result.fDeclSpec1);
+ final boolean acceptEmpty = acceptCompoundWithoutDtor && isLegalWithoutDtor(result.fDeclSpec1);
if (acceptEmpty) {
switch(lt1) {
case 0:
@@ -1615,7 +1619,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return result.set(declspec2, dtor2, dtorMark2);
}
- protected boolean specifiesCompound(IASTDeclSpecifier declSpec) {
+ protected boolean isLegalWithoutDtor(IASTDeclSpecifier declSpec) {
if (declSpec instanceof IASTCompositeTypeSpecifier)
return true;
if (declSpec instanceof IASTElaboratedTypeSpecifier)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
index 47758ddc058..bd86e1eae97 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java
@@ -12,10 +12,11 @@ package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType;
+import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IType;
-import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
/**
* Arithmetic conversions as required to compute the type of unary or binary expressions.
@@ -46,7 +47,7 @@ public abstract class ArithmeticConversion {
* or 5.0.9 of C++ standard
*/
public final IType convertOperandTypes(int operator, IType op1, IType op2) {
- if (!isArithmeticOrEnum(op1) || !isArithmeticOrEnum(op2)) {
+ if (!isArithmeticOrUnscopedEnum(op1) || !isArithmeticOrUnscopedEnum(op2)) {
return null;
}
switch (operator) {
@@ -76,17 +77,24 @@ public abstract class ArithmeticConversion {
}
public final IType promoteType(IType type) {
- if (!isIntegralOrEnum(type))
+ if (!isIntegralOrUnscopedEnum(type))
return null;
return promote(type, getDomain(type));
}
- private boolean isArithmeticOrEnum(IType op1) {
- return op1 instanceof IBasicType || op1 instanceof IEnumeration;
+ private boolean isArithmeticOrUnscopedEnum(IType op1) {
+ if (op1 instanceof IBasicType)
+ return true;
+ if (op1 instanceof IEnumeration) {
+ if (op1 instanceof ICPPEnumeration && ((ICPPEnumeration) op1).isScoped())
+ return false;
+ return true;
+ }
+ return false;
}
- private boolean isIntegralOrEnum(IType op1) {
+ private boolean isIntegralOrUnscopedEnum(IType op1) {
if (op1 instanceof IEnumeration)
return true;
@@ -175,8 +183,16 @@ public abstract class ArithmeticConversion {
private IBasicType promote(IType type, Domain domain) {
if (type instanceof IEnumeration) {
- return createBasicType(Kind.eInt, domain.getModifier() | getEnumIntTypeModifiers((IEnumeration) type));
- } else if (type instanceof IBasicType) {
+ IType fixedType= null;
+ if (type instanceof ICPPEnumeration) {
+ fixedType= ((ICPPEnumeration) type).getFixedType();
+ }
+ if (fixedType == null)
+ return createBasicType(Kind.eInt, domain.getModifier() | getEnumIntTypeModifiers((IEnumeration) type));
+ type= fixedType;
+ }
+
+ if (type instanceof IBasicType) {
final IBasicType bt = (IBasicType) type;
final Kind kind = bt.getKind();
switch (kind) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java
index 31345c55536..0a986d15408 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/DeclarationOptions.java
@@ -27,13 +27,14 @@ public class DeclarationOptions {
final public static int ALLOW_PARAMETER_PACKS= 0x400;
final public static int REQUIRE_SIMPLE_NAME= 0x800;
final public static int ALLOW_FOLLOWED_BY_BRACE= 0x1000;
+ final public static int ALLOW_OPAQUE_ENUM= 0x2000;
public static final DeclarationOptions
- GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER),
+ GLOBAL= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_OPAQUE_ENUM),
FUNCTION_STYLE_ASM= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | NO_INITIALIZER | ALLOW_ABSTRACT),
C_MEMBER= new DeclarationOptions(ALLOW_BITFIELD | ALLOW_ABSTRACT),
CPP_MEMBER= new DeclarationOptions(ALLOW_EMPTY_SPECIFIER | ALLOW_BITFIELD | NO_CTOR_STYLE_INITIALIZER),
- LOCAL= new DeclarationOptions(0),
+ LOCAL= new DeclarationOptions(ALLOW_OPAQUE_ENUM),
PARAMETER= new DeclarationOptions(ALLOW_ABSTRACT | ALLOW_PARAMETER_PACKS | REQUIRE_SIMPLE_NAME | NO_BRACED_INITIALIZER | NO_CTOR_STYLE_INITIALIZER),
TYPEID= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER),
TYPEID_TRAILING_RETURN_TYPE= new DeclarationOptions(REQUIRE_ABSTRACT | NO_INITIALIZER | ALLOW_FOLLOWED_BY_BRACE),
@@ -55,6 +56,7 @@ public class DeclarationOptions {
final public boolean fAllowNested;
final public boolean fAllowParameterPacks;
final public boolean fRequireSimpleName;
+ final public boolean fAllowOpaqueEnum;
public DeclarationOptions(int options) {
fAllowEmptySpecifier= (options & ALLOW_EMPTY_SPECIFIER) != 0;
@@ -69,5 +71,6 @@ public class DeclarationOptions {
fAllowParameterPacks= (options & ALLOW_PARAMETER_PACKS) != 0;
fRequireSimpleName= (options & REQUIRE_SIMPLE_NAME) != 0;
fCanBeFollowedByBrace= fAllowBracedInitializer || (options & ALLOW_FOLLOWED_BY_BRACE) != 0;
+ fAllowOpaqueEnum= (options & ALLOW_OPAQUE_ENUM) != 0;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
index 3d747f9bed1..b22d16fffe8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -38,6 +38,8 @@ import org.eclipse.core.runtime.PlatformObject;
* Implementation of problem bindings
*/
public class ProblemBinding extends PlatformObject implements IProblemBinding, IASTInternalScope {
+ public static ProblemBinding NOT_INITIALIZED= new ProblemBinding(null, 0);
+
protected final int id;
protected char[] arg;
protected IASTNode node;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java
index feb7c24a701..7b19eeb589b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumerator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -14,15 +14,14 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
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.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTEnumerator;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@@ -76,18 +75,17 @@ public class CEnumerator extends PlatformObject implements IEnumerator {
* @see org.eclipse.cdt.core.dom.ast.IEnumerator#getType()
*/
public IType getType() {
- IASTEnumerator etor = (IASTEnumerator) enumeratorName.getParent();
- IASTEnumerationSpecifier enumSpec = (IASTEnumerationSpecifier) etor.getParent();
- IEnumeration enumeration = (IEnumeration) enumSpec.getName().resolveBinding();
- return enumeration;
+ return (IType) getOwner();
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
- public IBinding getOwner() throws DOMException {
- return CVisitor.findEnclosingFunction(enumeratorName);
+ public IBinding getOwner() {
+ IASTEnumerator etor = (IASTEnumerator) enumeratorName.getParent();
+ IASTEnumerationSpecifier enumSpec = (IASTEnumerationSpecifier) etor.getParent();
+ return enumSpec.getName().resolveBinding();
}
public IValue getValue() {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java
index f4fb42ccffd..37bfb093d72 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTEnumerationSpecifier.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -13,6 +13,9 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier;
@@ -20,22 +23,34 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTInternalEnumerationSpecifier
* AST node for c++ enumeration specifiers.
*/
public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
- implements IASTInternalEnumerationSpecifier {
+ implements IASTInternalEnumerationSpecifier, ICPPASTEnumerationSpecifier {
- private IASTName name;
- private boolean valuesComputed= false;
+ private boolean fIsScoped;
+ private boolean fIsOpaque;
+ private IASTName fName;
+ private ICPPASTDeclSpecifier fBaseType;
+
+ private IASTEnumerator[] fItems = null;
+ private int fItemPos=-1;
+
+ private boolean fValuesComputed= false;
+ private CPPEnumScope fScope;
-
public CPPASTEnumerationSpecifier() {
}
- public CPPASTEnumerationSpecifier(IASTName name) {
+ public CPPASTEnumerationSpecifier(boolean isScoped, IASTName name, ICPPASTDeclSpecifier baseType) {
+ fIsScoped= isScoped;
setName(name);
+ setBaseType(baseType);
}
public CPPASTEnumerationSpecifier copy() {
- CPPASTEnumerationSpecifier copy = new CPPASTEnumerationSpecifier(name == null ? null : name.copy());
- for(IASTEnumerator enumerator : getEnumerators())
+ CPPASTEnumerationSpecifier copy = new CPPASTEnumerationSpecifier(fIsScoped,
+ fName == null ? null : fName.copy(),
+ fBaseType == null ? null : fBaseType.copy());
+ copy.fIsOpaque= fIsOpaque;
+ for (IASTEnumerator enumerator : getEnumerators())
copy.addEnumerator(enumerator == null ? null : enumerator.copy());
copyBaseDeclSpec(copy);
return copy;
@@ -43,10 +58,10 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
public boolean startValueComputation() {
- if (valuesComputed)
+ if (fValuesComputed)
return false;
- valuesComputed= true;
+ fValuesComputed= true;
return true;
}
@@ -55,24 +70,21 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
if (enumerator != null) {
enumerator.setParent(this);
enumerator.setPropertyInParent(ENUMERATOR);
- enumerators = (IASTEnumerator[]) ArrayUtil.append( IASTEnumerator.class, enumerators, ++enumeratorsPos, enumerator );
+ fItems = (IASTEnumerator[]) ArrayUtil.append( IASTEnumerator.class, fItems, ++fItemPos, enumerator );
}
}
public IASTEnumerator[] getEnumerators() {
- if (enumerators == null)
+ if (fItems == null)
return IASTEnumerator.EMPTY_ENUMERATOR_ARRAY;
- enumerators = (IASTEnumerator[]) ArrayUtil.removeNullsAfter( IASTEnumerator.class, enumerators, enumeratorsPos );
- return enumerators;
+
+ fItems = (IASTEnumerator[]) ArrayUtil.removeNullsAfter(IASTEnumerator.class, fItems, fItemPos);
+ return fItems;
}
-
- private IASTEnumerator[] enumerators = null;
- private int enumeratorsPos=-1;
-
public void setName(IASTName name) {
assertNotFrozen();
- this.name = name;
+ fName = name;
if (name != null) {
name.setParent(this);
name.setPropertyInParent(ENUMERATION_NAME);
@@ -80,7 +92,7 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
}
public IASTName getName() {
- return name;
+ return fName;
}
@Override
@@ -95,28 +107,67 @@ public class CPPASTEnumerationSpecifier extends CPPASTBaseDeclSpecifier
break;
}
}
- if (name != null)
- if (!name.accept(action))
- return false;
- IASTEnumerator[] enums = getEnumerators();
- for (int i = 0; i < enums.length; i++)
- if (!enums[i].accept(action))
+ if (fName != null && !fName.accept(action))
+ return false;
+
+ if (fBaseType != null && !fBaseType.accept(action)) {
+ return false;
+ }
+
+ for (IASTEnumerator e : getEnumerators()) {
+ if (!e.accept(action))
return false;
-
- if( action.shouldVisitDeclSpecifiers ){
- switch( action.leave( this ) ){
- case ASTVisitor.PROCESS_ABORT : return false;
- case ASTVisitor.PROCESS_SKIP : return true;
- default : break;
- }
}
+
+ if (action.shouldVisitDeclSpecifiers && action.leave(this) == ASTVisitor.PROCESS_ABORT)
+ return false;
return true;
}
public int getRoleForName(IASTName n) {
- if (name == n)
- return r_definition;
+ if (fName == n)
+ return isOpaque() ? r_declaration : r_definition;
return r_unclear;
}
+
+ public void setIsScoped(boolean isScoped) {
+ assertNotFrozen();
+ fIsScoped= isScoped;
+ }
+
+ public boolean isScoped() {
+ return fIsScoped;
+ }
+
+ public void setBaseType(ICPPASTDeclSpecifier baseType) {
+ assertNotFrozen();
+ fBaseType= baseType;
+ if (baseType != null) {
+ baseType.setParent(this);
+ baseType.setPropertyInParent(BASE_TYPE);
+ }
+ }
+
+ public ICPPASTDeclSpecifier getBaseType() {
+ return fBaseType;
+ }
+
+ public void setIsOpaque(boolean isOpaque) {
+ assertNotFrozen();
+ fIsOpaque= isOpaque;
+ }
+
+ public boolean isOpaque() {
+ return fIsOpaque;
+ }
+
+ public ICPPScope getScope() {
+ if (isOpaque())
+ return null;
+ if (fScope == null) {
+ fScope= new CPPEnumScope(this);
+ }
+ return fScope;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
index 3eb92576c84..ebeaec8ea0c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2009 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -24,9 +24,11 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IASTCompletionContext {
@@ -92,7 +94,21 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, IAS
if (binding instanceof IVariable) {
return SemanticUtil.mapToAST(((IVariable) binding).getType(), this);
} else if (binding instanceof IEnumerator) {
- return ((IEnumerator) binding).getType();
+ IType type= ((IEnumerator) binding).getType();
+ if (type instanceof ICPPEnumeration) {
+ ICPPEnumeration enumType= (ICPPEnumeration) type;
+ if (enumType.asScope() == CPPVisitor.getContainingScope(this)) {
+ // C++0x: 7.2-5
+ IType fixedType= enumType.getFixedType();
+ if (fixedType != null)
+ return fixedType;
+ // This is a simplification, the actual type is determined
+ // - in an implementation dependent manner - by the value
+ // of the enumerator.
+ return CPPSemantics.INT_TYPE;
+ }
+ }
+ return type;
} else if (binding instanceof IProblemBinding) {
return (IType) binding;
} else if (binding instanceof IFunction) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
index 5b29f013e3d..ab54ddcfb9e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2010 IBM Corporation 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
@@ -34,6 +34,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
* Unqualified name, also base class for operator and conversion name.
*/
public class CPPASTName extends CPPASTNameBase implements IASTCompletionContext {
+ public static IASTName NOT_INITIALIZED= new CPPASTName(null);
+
private char[] name;
public CPPASTName(char[] name) {
this.name = name;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumScope.java
new file mode 100644
index 00000000000..db69723d23a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumScope.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.IName;
+import org.eclipse.cdt.core.dom.ast.EScopeKind;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
+
+/**
+ * Implementation of namespace scopes, including global scope.
+ */
+public class CPPEnumScope extends CPPScope {
+ public CPPEnumScope(ICPPASTEnumerationSpecifier specifier) {
+ super(specifier);
+ }
+
+ public EScopeKind getKind() {
+ return EScopeKind.eNamespace;
+ }
+
+ @Override
+ public IName getScopeName() {
+ ICPPASTEnumerationSpecifier node = (ICPPASTEnumerationSpecifier) getPhysicalNode();
+ return node.getName();
+ }
+}
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 2eab4fe1c15..123b68ff3c4 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
@@ -14,18 +14,32 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.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.CPPASTVisitor;
+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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
+import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
+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.core.runtime.PlatformObject;
@@ -33,22 +47,87 @@ import org.eclipse.core.runtime.PlatformObject;
/**
* Enumerations in C++
*/
-public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPPInternalBinding {
- private IASTName enumName;
+public class CPPEnumeration extends PlatformObject implements ICPPEnumeration, ICPPInternalBinding {
+ private static final IASTName NOT_INITIALIZED = CPPASTName.NOT_INITIALIZED;
+ private static final IEnumerator[] EMPTY_ENUMERATORS = {};
+
+ private final boolean fIsScoped;
+ private final IType fFixedType;
+ private IASTName fDefinition= NOT_INITIALIZED;
+ private IASTName[] fDeclarations= IASTName.EMPTY_NAME_ARRAY;
private Long fMaxValue;
private Long fMinValue;
- public CPPEnumeration(IASTName name) {
- this.enumName = name;
- name.setBinding(this);
+ private ICPPEnumeration fIndexBinding= null;
+ private boolean fSearchedIndex= false;
+
+ public CPPEnumeration(ICPPASTEnumerationSpecifier spec, IType fixedType) {
+ final IASTName name = spec.getName();
+ fIsScoped= spec.isScoped();
+ fFixedType= fixedType;
+ if (spec.isOpaque()) {
+ addDeclaration(name);
+ } else {
+ addDefinition(name);
+ }
+ name.setBinding(this);
}
public IASTNode[] getDeclarations() {
- return null;
+ fDeclarations= ArrayUtil.trim(fDeclarations);
+ return fDeclarations;
}
- public IASTNode getDefinition() {
- return enumName;
+ private class FindDefinitionAction extends CPPASTVisitor {
+ private char[] nameArray = CPPEnumeration.this.getNameCharArray();
+ public IASTName result = null;
+
+ {
+ shouldVisitNames = true;
+ shouldVisitDeclarations = true;
+ shouldVisitDeclSpecifiers = true;
+ shouldVisitDeclarators = true;
+ }
+
+ @Override
+ public int visit(IASTName name) {
+ if (name instanceof ICPPASTTemplateId || name instanceof ICPPASTQualifiedName)
+ return PROCESS_SKIP;
+ char[] c = name.getLookupKey();
+ if (name.getParent() instanceof ICPPASTEnumerationSpecifier && CharArrayUtils.equals(c, nameArray)) {
+ IBinding binding = name.resolveBinding();
+ if (binding == CPPEnumeration.this) {
+ result= name;
+ return PROCESS_ABORT;
+ }
+ }
+ return PROCESS_CONTINUE;
+ }
+
+ @Override
+ public int visit(IASTDeclaration declaration) {
+ if (declaration instanceof IASTSimpleDeclaration)
+ return PROCESS_CONTINUE;
+ return PROCESS_SKIP;
+ }
+ @Override
+ public int visit(IASTDeclSpecifier declSpec) {
+ return (declSpec instanceof ICPPASTEnumerationSpecifier) ? PROCESS_CONTINUE : PROCESS_SKIP;
+ }
+ @Override
+ public int visit(IASTDeclarator declarator) {
+ return PROCESS_SKIP;
+ }
+ }
+
+ public IASTName getDefinition() {
+ if (fDefinition == NOT_INITIALIZED) {
+ FindDefinitionAction action = new FindDefinitionAction();
+ IASTNode node = CPPVisitor.getContainingBlockItem(getADeclaration()).getParent();
+ node.accept(action);
+ fDefinition = action.result;
+ }
+ return fDefinition;
}
public String getName() {
@@ -56,37 +135,22 @@ public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPP
}
public char[] getNameCharArray() {
- return enumName.getSimpleID();
+ return getADeclaration().getSimpleID();
}
- public IScope getScope() {
- return CPPVisitor.getContainingScope(enumName);
- }
+ private IASTName getADeclaration() {
+ if (fDefinition != null && fDefinition != NOT_INITIALIZED)
+ return fDefinition;
+ return fDeclarations[0];
+ }
- public IASTNode getPhysicalNode() {
- return enumName;
+ public IScope getScope() {
+ return CPPVisitor.getContainingScope(getADeclaration());
}
-
+
@Override
public Object clone() {
- IType t = null;
- try {
- t = (IType) super.clone();
- } catch (CloneNotSupportedException e) {
- //not going to happen
- }
- return t;
- }
-
- public IEnumerator[] getEnumerators() {
- IASTEnumerationSpecifier.IASTEnumerator[] enums =
- ((IASTEnumerationSpecifier) enumName.getParent()).getEnumerators();
- IEnumerator[] bindings = new IEnumerator[enums.length];
-
- for (int i = 0; i < enums.length; i++) {
- bindings[i] = (IEnumerator) enums[i].getName().resolveBinding();
- }
- return bindings;
+ throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$
}
public String[] getQualifiedName() {
@@ -108,9 +172,17 @@ public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPP
}
public void addDefinition(IASTNode node) {
+ assert fDefinition == null || fDefinition == NOT_INITIALIZED;
+ fDefinition= (IASTName) node;
}
public void addDeclaration(IASTNode node) {
+ assert node instanceof IASTName;
+ if (fDeclarations == null) {
+ fDeclarations= new IASTName[] {(IASTName) node};
+ } else {
+ fDeclarations= ArrayUtil.append(fDeclarations, (IASTName) node);
+ }
}
public boolean isSameType(IType type) {
@@ -126,7 +198,7 @@ public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPP
}
public IBinding getOwner() throws DOMException {
- return CPPVisitor.findDeclarationOwner(enumName, true);
+ return CPPVisitor.findDeclarationOwner(getADeclaration(), true);
}
@Override
@@ -177,4 +249,56 @@ public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPP
fMaxValue= maxValue;
return maxValue;
}
+
+ public boolean isScoped() {
+ return fIsScoped;
+ }
+
+ public IType getFixedType() {
+ return fFixedType;
+ }
+
+ public IEnumerator[] getEnumerators() {
+ final IASTName definition = getDefinition();
+ if (definition == null) {
+ ICPPEnumeration typeInIndex= getIndexBinding();
+ if (typeInIndex != null) {
+ try {
+ return typeInIndex.getEnumerators();
+ } catch (DOMException e) {
+ }
+ }
+ return EMPTY_ENUMERATORS;
+ }
+
+ IASTEnumerator[] enums = ((IASTEnumerationSpecifier) definition.getParent()).getEnumerators();
+ IEnumerator[] bindings = new IEnumerator[enums.length];
+ for (int i = 0; i < enums.length; i++) {
+ bindings[i] = (IEnumerator) enums[i].getName().resolveBinding();
+ }
+ return bindings;
+ }
+
+ private ICPPEnumeration getIndexBinding() {
+ if (!fSearchedIndex) {
+ final IASTTranslationUnit translationUnit = getADeclaration().getTranslationUnit();
+ IIndex index= translationUnit.getIndex();
+ if (index != null) {
+ fIndexBinding= (ICPPEnumeration) index.adaptBinding(this);
+ }
+ }
+ return fIndexBinding;
+ }
+
+ public ICPPScope asScope() {
+ IASTName def = getDefinition();
+ if (def == null) {
+ ICPPEnumeration indexBinding= getIndexBinding();
+ if (indexBinding != null) {
+ return indexBinding.asScope();
+ }
+ def= getADeclaration();
+ }
+ return ((ICPPASTEnumerationSpecifier) def.getParent()).getScope();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
index 85c5e4d0b7d..4661f2afa41 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java
@@ -24,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
@@ -47,13 +47,13 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
@@ -61,6 +61,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator;
@@ -103,7 +104,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
@@ -237,8 +237,13 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return new CPPASTElaboratedTypeSpecifier(kind, name);
}
- public IASTEnumerationSpecifier newEnumerationSpecifier(IASTName name) {
- return new CPPASTEnumerationSpecifier(name);
+ public ICPPASTEnumerationSpecifier newEnumerationSpecifier(boolean isScoped, IASTName name,
+ ICPPASTDeclSpecifier baseType) {
+ return new CPPASTEnumerationSpecifier(isScoped, name, baseType);
+ }
+
+ public ICPPASTEnumerationSpecifier newEnumerationSpecifier(IASTName name) {
+ return new CPPASTEnumerationSpecifier(false, name, null);
}
public IASTEnumerator newEnumerator(IASTName name, IASTExpression value) {
@@ -261,7 +266,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public ICPPASTExpressionList newExpressionList() {
return new CPPASTExpressionList();
}
-
+
public IASTExpressionStatement newExpressionStatement(IASTExpression expression) {
return new CPPASTExpressionStatement(expression);
}
@@ -269,15 +274,15 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public ICPPASTFieldDeclarator newFieldDeclarator(IASTName name, IASTExpression bitFieldSize) {
return new CPPASTFieldDeclarator(name, bitFieldSize);
}
-
+
public ICPPASTFieldReference newFieldReference(IASTName name, IASTExpression owner) {
return new CPPASTFieldReference(name, owner);
}
-
+
public ICPPASTForStatement newForStatement() {
return new CPPASTForStatement();
}
-
+
public ICPPASTForStatement newForStatement(IASTStatement init, IASTDeclaration condition,
IASTExpression iterationExpression, IASTStatement body) {
return new CPPASTForStatement(init, condition, iterationExpression, body);
@@ -287,14 +292,14 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
IASTExpression iterationExpr, IASTStatement body) {
return new CPPASTForStatement(init, condition, iterationExpr, body);
}
-
+
@Deprecated
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
CPPASTFunctionCallExpression result = new CPPASTFunctionCallExpression(idExpr, null);
result.setParameterExpression(argList);
return result;
}
-
+
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTInitializerClause[] arguments) {
return new CPPASTFunctionCallExpression(idExpr, arguments);
}
@@ -316,7 +321,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement) {
return new CPPASTCompoundStatementExpression(compoundStatement);
}
-
+
public IASTGotoStatement newGotoStatement(IASTName name) {
return new CPPASTGotoStatement(name);
}
@@ -324,7 +329,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IASTIdExpression newIdExpression(IASTName name) {
return new CPPASTIdExpression(name);
}
-
+
public ICPPASTIfStatement newIfStatement() {
return new CPPASTIfStatement();
}
@@ -349,19 +354,19 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IASTLabelStatement newLabelStatement(IASTName name, IASTStatement nestedStatement) {
return new CPPASTLabelStatement(name, nestedStatement);
}
-
+
public ICPPASTLinkageSpecification newLinkageSpecification(String literal) {
return new CPPASTLinkageSpecification(literal);
}
-
+
public ICPPASTLiteralExpression newLiteralExpression(int kind, String rep) {
return new CPPASTLiteralExpression(kind, rep.toCharArray());
}
-
+
public IASTName newName() {
return new CPPASTName();
}
-
+
public IASTName newName(char[] name) {
return new CPPASTName(name);
}
@@ -409,11 +414,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IGPPASTPointer newPointerGPP() {
return new GPPASTPointer();
}
-
+
public ICPPASTPointerToMember newPointerToMember(IASTName name) {
return new CPPASTPointerToMember(name);
}
-
+
public IGPPASTPointerToMember newPointerToMemberGPP(IASTName name) {
return new GPPASTPointerToMember(name);
}
@@ -457,11 +462,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IASTReturnStatement newReturnStatement(IASTInitializerClause retValue) {
return new CPPASTReturnStatement(retValue);
}
-
+
public IASTSimpleDeclaration newSimpleDeclaration(IASTDeclSpecifier declSpecifier) {
return new CPPASTSimpleDeclaration(declSpecifier);
}
-
+
public ICPPASTSimpleDeclSpecifier newSimpleDeclSpecifier() {
return new CPPASTSimpleDeclSpecifier();
}
@@ -470,6 +475,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier newSimpleDeclSpecifierGPP() {
return new GPPASTSimpleDeclSpecifier();
}
+
+ public ICPPASTSimpleTypeConstructorExpression newSimpleTypeConstructorExpression(
+ ICPPASTDeclSpecifier declSpec, IASTInitializer initializer) {
+ return new CPPASTSimpleTypeConstructorExpression(declSpec, initializer);
+ }
@Deprecated
public ICPPASTSimpleTypeConstructorExpression newSimpleTypeConstructorExpression(int type, IASTExpression expression) {
@@ -478,11 +488,6 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
result.setInitialValue(expression);
return result;
}
-
- public ICPPASTSimpleTypeConstructorExpression newSimpleTypeConstructorExpression(
- ICPPASTDeclSpecifier declSpec, IASTInitializer initializer) {
- return new CPPASTSimpleTypeConstructorExpression(declSpec, initializer);
- }
public ICPPASTSimpleTypeTemplateParameter newSimpleTypeTemplateParameter(int type, IASTName name, IASTTypeId typeId) {
return new CPPASTSimpleTypeTemplateParameter(type, name, typeId);
@@ -508,11 +513,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public ICPPASTTemplateDeclaration newTemplateDeclaration(IASTDeclaration declaration) {
return new CPPASTTemplateDeclaration(declaration);
}
-
+
public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue) {
return new CPPASTTemplatedTypeTemplateParameter(name, defaultValue);
}
-
+
public ICPPASTTemplateId newTemplateId(IASTName templateName) {
return new CPPASTTemplateId(templateName);
}
@@ -554,12 +559,12 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
public IASTTypeIdInitializerExpression newTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) {
return new CPPASTTypeIdInitializerExpression(typeId, initializer);
}
-
+
@Deprecated
public org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression newTypenameExpression(IASTName qualifiedName, IASTExpression expr, boolean isTemplate) {
return new CPPASTTypenameExpression(qualifiedName, expr);
}
-
+
public ICPPASTUnaryExpression newUnaryExpression(int operator, IASTExpression operand) {
return new CPPASTUnaryExpression(operator, operand);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index 88f5df13c79..da044f9075c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -72,6 +72,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
@@ -1874,8 +1875,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return null;
}
+ @Override
+ protected boolean isLegalWithoutDtor(IASTDeclSpecifier declSpec) {
+ if (declSpec instanceof IASTElaboratedTypeSpecifier) {
+ return ((IASTElaboratedTypeSpecifier) declSpec).getKind() != IASTElaboratedTypeSpecifier.k_enum;
+ }
+ return super.isLegalWithoutDtor(declSpec);
+ }
- /**
+ /**
* Parses a declaration with the given options.
*/
protected IASTDeclaration simpleDeclaration(DeclarationOptions declOption) throws BacktrackException, EndOfFileException {
@@ -1905,7 +1913,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
dtor= addInitializer(lie, declOption);
} catch (BacktrackException e) {
IASTNode node= e.getNodeBeforeProblem();
- if (node instanceof IASTDeclSpecifier && specifiesCompound((IASTDeclSpecifier) node)) {
+ if (node instanceof IASTDeclSpecifier && isLegalWithoutDtor((IASTDeclSpecifier) node)) {
IASTSimpleDeclaration d= nodeFactory.newSimpleDeclaration((IASTDeclSpecifier) node);
setRange(d, node);
throwBacktrack(e.getProblem(), d);
@@ -1956,7 +1964,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
default:
if (declOption != DeclarationOptions.LOCAL) {
insertSemi= true;
- if (specifiesCompound(declSpec) && markBeforDtor != null && !isOnSameLine(calculateEndOffset(declSpec), markBeforDtor.getOffset())) {
+ if (isLegalWithoutDtor(declSpec) && markBeforDtor != null && !isOnSameLine(calculateEndOffset(declSpec), markBeforDtor.getOffset())) {
backup(markBeforDtor);
declarators= IASTDeclarator.EMPTY_DECLARATOR_ARRAY;
endOffset= calculateEndOffset(declSpec);
@@ -2147,15 +2155,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
*/
@Override
protected Decl declSpecifierSeq(final DeclarationOptions option) throws BacktrackException, EndOfFileException {
- return declSpecifierSeq(option.fAllowEmptySpecifier, false);
+ return declSpecifierSeq(option, false);
}
private ICPPASTDeclSpecifier simpleTypeSpecifier() throws BacktrackException, EndOfFileException {
- Decl d= declSpecifierSeq(false, true);
+ Decl d= declSpecifierSeq(null, true);
return (ICPPASTDeclSpecifier) d.fDeclSpec1;
}
-
- private Decl declSpecifierSeq(final boolean allowEmpty, final boolean single) throws BacktrackException, EndOfFileException {
+
+ private ICPPASTDeclSpecifier simpleTypeSpecifierSequence() throws BacktrackException, EndOfFileException {
+ Decl d= declSpecifierSeq(null, false);
+ return (ICPPASTDeclSpecifier) d.fDeclSpec1;
+ }
+
+ private Decl declSpecifierSeq(final DeclarationOptions option, final boolean single) throws BacktrackException, EndOfFileException {
int storageClass = IASTDeclSpecifier.sc_unspecified;
int simpleType = IASTSimpleDeclSpecifier.t_unspecified;
int options= 0;
@@ -2350,7 +2363,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (encounteredRawType || encounteredTypename)
break declSpecifiers;
- if (allowEmpty && LT(1) != IToken.tCOMPLETION) {
+ if (option != null && option.fAllowEmptySpecifier && LT(1) != IToken.tCOMPLETION) {
if ((options & FORBID_IN_EMPTY_DECLSPEC) == 0 && storageClass == IASTDeclSpecifier.sc_unspecified) {
altResult= buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
returnToken= mark();
@@ -2382,15 +2395,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (encounteredTypename || encounteredRawType)
break declSpecifiers;
try {
- result= (ICPPASTDeclSpecifier) enumSpecifier();
+ result= enumDeclaration(option != null && option.fAllowOpaqueEnum);
} catch (BacktrackException bt) {
if (bt.getNodeBeforeProblem() instanceof ICPPASTDeclSpecifier) {
result= (ICPPASTDeclSpecifier) bt.getNodeBeforeProblem();
problem= bt.getProblem();
break declSpecifiers;
- } else {
- result= elaboratedTypeSpecifier();
- }
+ }
+ throw bt;
}
endOffset= calculateEndOffset(result);
encounteredTypename= true;
@@ -2450,7 +2462,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
// check for empty specification
- if (!encounteredRawType && !encounteredTypename && LT(1) != IToken.tEOC && !allowEmpty) {
+ if (!encounteredRawType && !encounteredTypename && LT(1) != IToken.tEOC
+ && (option == null || !option.fAllowEmptySpecifier)) {
throwBacktrack(LA(1));
}
@@ -2526,6 +2539,65 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
declSpec.setRestrict((options & RESTRICT) != 0);
}
+ private ICPPASTDeclSpecifier enumDeclaration(boolean allowOpaque) throws BacktrackException, EndOfFileException {
+ IToken mark= mark();
+ final int offset= consume(IToken.t_enum).getOffset();
+ int endOffset= 0;
+ boolean isScoped= false;
+ IASTName name= null;
+ ICPPASTDeclSpecifier baseType= null;
+
+ try {
+ int lt1= LT(1);
+ if (lt1 == IToken.t_class || lt1 == IToken.t_struct) {
+ isScoped= true;
+ consume();
+ }
+ // if __attribute__ or __declspec occurs after struct/union/class and before the identifier
+ __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
+
+ if (isScoped || LT(1) == IToken.tIDENTIFIER) {
+ name= identifier();
+ endOffset= calculateEndOffset(name);
+ }
+
+ if (LT(1) == IToken.tCOLON) {
+ consume();
+ baseType= simpleTypeSpecifierSequence();
+ endOffset= calculateEndOffset(baseType);
+ }
+ } catch (BacktrackException e) {
+ backup(mark);
+ return elaboratedTypeSpecifier();
+ }
+
+ final int lt1= LT(1);
+ final boolean isDef= lt1 == IToken.tLBRACE || (lt1 == IToken.tEOC && baseType != null);
+ final boolean isOpaque= !isDef && allowOpaque && lt1 == IToken.tSEMI;
+ if (!isDef && !isOpaque) {
+ backup(mark);
+ return elaboratedTypeSpecifier();
+ }
+ mark= null;
+
+ if (isOpaque && !isScoped && baseType == null)
+ throwBacktrack(LA(1));
+
+ if (name == null) {
+ if (isOpaque)
+ throwBacktrack(LA(1));
+ name= nodeFactory.newName();
+ }
+
+ final ICPPASTEnumerationSpecifier result= nodeFactory.newEnumerationSpecifier(isScoped, name, baseType);
+ result.setIsOpaque(isOpaque);
+ if (lt1 == IToken.tLBRACE) {
+ endOffset= enumBody(result);
+ }
+ assert endOffset != 0;
+ return setRange(result, offset, endOffset);
+ }
+
/**
* Parse an elaborated type specifier.
*
@@ -2534,10 +2606,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
*/
protected ICPPASTElaboratedTypeSpecifier elaboratedTypeSpecifier() throws BacktrackException, EndOfFileException {
// this is an elaborated class specifier
- IToken t = consume();
+ final int lt1= LT(1);
int eck = 0;
- switch (t.getType()) {
+ switch (lt1) {
case IToken.t_class:
eck = ICPPASTElaboratedTypeSpecifier.k_class;
break;
@@ -2551,18 +2623,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
eck = IASTElaboratedTypeSpecifier.k_enum;
break;
default:
- backup(t);
- throwBacktrack(t.getOffset(), t.getLength());
+ throwBacktrack(LA(1));
}
+
+ final int offset= consume().getOffset();
// if __attribute__ or __declspec occurs after struct/union/class and before the identifier
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
IASTName name = qualifiedName(CastExprCtx.eNotBExpr);
-
- ICPPASTElaboratedTypeSpecifier elaboratedTypeSpec = nodeFactory.newElaboratedTypeSpecifier(eck, name);
- ((ASTNode) elaboratedTypeSpec).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset());
- return elaboratedTypeSpec;
+ return setRange(nodeFactory.newElaboratedTypeSpecifier(eck, name), offset, calculateEndOffset(name));
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index da4c58662f1..f1ef7980e68 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -40,7 +40,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
-import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
@@ -89,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@@ -209,6 +209,7 @@ public class CPPSemantics {
public static final char[] OPERATOR_ = new char[] {'o','p','e','r','a','t','o','r',' '};
private static final char[] CALL_FUNCTION = "call-function".toCharArray(); //$NON-NLS-1$
public static final IType VOID_TYPE = new CPPBasicType(Kind.eVoid, 0);
+ public static final IType INT_TYPE = new CPPBasicType(Kind.eInt, 0);
// Set to true for debugging.
public static boolean traceBindingResolution = false;
@@ -814,7 +815,6 @@ public class CPPSemantics {
* @param start either a scope or a name.
*/
static protected void lookup(LookupData data, IScope start) throws DOMException {
- final IIndexFileSet fileSet= getIndexFileSet(data);
if (data.astName == null)
return;
@@ -850,6 +850,7 @@ public class CPPSemantics {
}
}
+ final IIndexFileSet fileSet= getIndexFileSet(data);
while (nextScope != null || nextTmplScope != null) {
// when the non-template scope is no longer contained within the first template scope,
// we use the template scope for the next iteration.
@@ -1208,6 +1209,12 @@ public class CPPSemantics {
} else {
nodes= new IASTNode[] {initDeclaration};
}
+ } else if (parent instanceof ICPPASTEnumerationSpecifier) {
+ // The enumeration scope contains the enumeration items
+ for (IASTEnumerator enumerator : ((ICPPASTEnumerationSpecifier) parent).getEnumerators()) {
+ ASTInternal.addName(scope, enumerator.getName());
+ }
+ return;
}
int idx = -1;
@@ -1390,18 +1397,15 @@ public class CPPSemantics {
populateCache(scope, decl);
}
}
- } else if (declSpec instanceof IASTEnumerationSpecifier) {
- IASTEnumerationSpecifier enumeration = (IASTEnumerationSpecifier) declSpec;
+ } else if (declSpec instanceof ICPPASTEnumerationSpecifier) {
+ ICPPASTEnumerationSpecifier enumeration = (ICPPASTEnumerationSpecifier) declSpec;
specName = enumeration.getName();
- // Check enumerators too
- IASTEnumerator[] list = enumeration.getEnumerators();
- IASTName tempName;
- for (IASTEnumerator enumerator : list) {
- if (enumerator == null)
- break;
- tempName = enumerator.getName();
- ASTInternal.addName(scope, tempName);
+ // Add unscoped enumerators to the enclosing scope
+ if (!enumeration.isScoped()) {
+ for (IASTEnumerator enumerator : enumeration.getEnumerators()) {
+ ASTInternal.addName(scope, enumerator.getName());
+ }
}
}
if (specName != null) {
@@ -1422,6 +1426,7 @@ public class CPPSemantics {
dtor.accept(visitor);
}
break;
+ case eEnumeration:
case eClassType:
case eTemplateDeclaration:
break;
@@ -1462,6 +1467,7 @@ public class CPPSemantics {
break;
case eClassType:
case eTemplateDeclaration:
+ case eEnumeration:
break;
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index a6d490161f5..0823ef86f3a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -88,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@@ -120,6 +121,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
@@ -254,8 +256,8 @@ public class CPPVisitor extends ASTQueries {
return createBinding((ICPPASTElaboratedTypeSpecifier) parent);
} else if (parent instanceof IASTDeclaration) {
return createBinding((IASTDeclaration) parent);
- } else if (parent instanceof IASTEnumerationSpecifier) {
- return createBinding((IASTEnumerationSpecifier) parent);
+ } else if (parent instanceof ICPPASTEnumerationSpecifier) {
+ return createBinding((ICPPASTEnumerationSpecifier) parent);
} else if (parent instanceof IASTEnumerator) {
return createBinding((IASTEnumerator) parent);
} else if (parent instanceof IASTGotoStatement) {
@@ -322,23 +324,48 @@ public class CPPVisitor extends ASTQueries {
return enumtor;
}
- private static IBinding createBinding(IASTEnumerationSpecifier specifier) {
+ private static IBinding createBinding(ICPPASTEnumerationSpecifier specifier) {
ICPPScope scope = (ICPPScope) getContainingScope(specifier);
- IBinding enumeration;
try {
final IASTName name = specifier.getName();
- enumeration = scope.getBinding(name, false);
- if (enumeration == null || !(enumeration instanceof IEnumeration)) {
- enumeration = new CPPEnumeration(name);
- }
+ IType fixedType= createEnumBaseType(specifier);
+ IBinding binding = scope.getBinding(name, false);
+ if (binding instanceof CPPEnumeration) {
+ CPPEnumeration e= (CPPEnumeration) binding;
+ if (e.isScoped() == specifier.isScoped()) {
+ IType ft2= e.getFixedType();
+ if (fixedType == ft2 || (fixedType != null && fixedType.isSameType(ft2))) {
+ if (specifier.isOpaque()) {
+ e.addDeclaration(specifier);
+ } else if (e.getDefinition() == null) {
+ e.addDefinition(specifier);
+ } else {
+ return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION);
+ }
+ return e;
+ }
+ }
+ return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
+ }
+ return new CPPEnumeration(specifier, fixedType);
} catch (DOMException e) {
- enumeration = e.getProblem();
+ return e.getProblem();
}
-
- return enumeration;
}
- private static IBinding createBinding(final ICPPASTElaboratedTypeSpecifier elabType) {
+ private static IType createEnumBaseType(ICPPASTEnumerationSpecifier specifier) {
+ ICPPASTDeclSpecifier declspec = specifier.getBaseType();
+ if (declspec != null) {
+ IType type= createType(declspec);
+ return SemanticUtil.getNestedType(type, ALLCVQ);
+ }
+ if (specifier.isScoped()) {
+ return CPPSemantics.INT_TYPE;
+ }
+ return null;
+ }
+
+ private static IBinding createBinding(final ICPPASTElaboratedTypeSpecifier elabType) {
final IASTNode parent = elabType.getParent();
IBinding binding = null;
boolean mustBeSimple = true;
@@ -940,6 +967,18 @@ public class CPPVisitor extends ASTQueries {
}
return getContainingScope(n);
+ } else if (node instanceof IASTEnumerator) {
+ node= node.getParent();
+ if (node instanceof ICPPASTEnumerationSpecifier) {
+ ICPPASTEnumerationSpecifier enumSpec= (ICPPASTEnumerationSpecifier) node;
+ IBinding binding = enumSpec.getName().resolveBinding();
+ if (binding instanceof ICPPEnumeration) {
+ ICPPEnumeration enumType = (ICPPEnumeration) binding;
+ if (enumType.isScoped()) {
+ return enumType.asScope();
+ }
+ }
+ }
}
node = node.getParent();
}
@@ -1017,6 +1056,8 @@ public class CPPVisitor extends ASTQueries {
scope= ((ICPPClassType) binding).getCompositeScope();
} else if (binding instanceof ICPPNamespace) {
scope= ((ICPPNamespace) binding).getNamespaceScope();
+ } else if (binding instanceof ICPPEnumeration) {
+ scope= ((ICPPEnumeration) binding).asScope();
} else if (binding instanceof ICPPUnknownBinding) {
scope= ((ICPPUnknownBinding) binding).asScope();
} else if (binding instanceof IProblemBinding) {
@@ -2144,6 +2185,9 @@ public class CPPVisitor extends ASTQueries {
String[] ns = null;
try {
for (IBinding owner= binding.getOwner(); owner != null; owner= owner.getOwner()) {
+ if (owner instanceof ICPPEnumeration && !((ICPPEnumeration) owner).isScoped()) {
+ continue;
+ }
String n= owner.getName();
if (n == null)
break;
@@ -2306,6 +2350,8 @@ public class CPPVisitor extends ASTQueries {
isNonSimpleElabDecl= false;
}
}
+ } else if (node instanceof IASTEnumerator) {
+ break;
}
node= node.getParent();
}
@@ -2348,6 +2394,10 @@ public class CPPVisitor extends ASTQueries {
name= ((ICPPASTNamespaceDefinition) node).getName();
break;
}
+ if (node instanceof ICPPASTEnumerationSpecifier) {
+ name= ((ICPPASTEnumerationSpecifier) node).getName();
+ break;
+ }
}
if (name == null)
return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
index 7ea27c4cd8d..4909609fd68 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java
@@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
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.IFunctionType;
@@ -34,11 +35,11 @@ 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.IValue;
-import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
@@ -903,7 +904,32 @@ public class Conversions {
if (trg instanceof IBasicType) {
IBasicType basicTgt = (IBasicType) trg;
final Kind tKind = basicTgt.getKind();
-
+
+ if (src instanceof ICPPEnumeration) {
+ final ICPPEnumeration enumType = (ICPPEnumeration) src;
+ if (enumType.isScoped()) {
+ return false;
+ }
+ IType fixedType= enumType.getFixedType();
+ if (fixedType == null) {
+ if (tKind == Kind.eInt || tKind == Kind.eUnspecified) {
+ if (trg instanceof ICPPBasicType) {
+ int qualifiers = ArithmeticConversion.getEnumIntTypeModifiers((IEnumeration) src);
+ int targetModifiers = ((ICPPBasicType) trg).getModifiers();
+ if (qualifiers == (targetModifiers & (IBasicType.IS_LONG | IBasicType.IS_LONG_LONG | IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED))) {
+ canPromote = true;
+ }
+ } else {
+ canPromote = true;
+ }
+ }
+ } else {
+ if (fixedType.isSameType(trg))
+ canPromote= true;
+ // Allow to further promote the fixed type
+ src= fixedType;
+ }
+ }
if (src instanceof IBasicType) {
final IBasicType basicSrc = (IBasicType) src;
Kind sKind = basicSrc.getKind();
@@ -926,19 +952,7 @@ public class Conversions {
} else if (tKind == Kind.eDouble && sKind == Kind.eFloat) {
canPromote= true;
}
- } else if (src instanceof IEnumeration) {
- if (tKind == Kind.eInt || tKind == Kind.eUnspecified) {
- if (trg instanceof ICPPBasicType) {
- int qualifiers = ArithmeticConversion.getEnumIntTypeModifiers((IEnumeration) src);
- int targetModifiers = ((ICPPBasicType) trg).getModifiers();
- if (qualifiers == (targetModifiers & (IBasicType.IS_LONG | IBasicType.IS_LONG_LONG | IBasicType.IS_SHORT | IBasicType.IS_UNSIGNED))) {
- canPromote = true;
- }
- } else {
- canPromote = true;
- }
- }
- }
+ }
}
if (canPromote) {
cost.setRank(Rank.PROMOTION);
@@ -963,9 +977,14 @@ public class Conversions {
// 4.7 integral conversion
// 4.8 floating point conversion
// 4.9 floating-integral conversion
- if (s instanceof IBasicType || s instanceof IEnumeration) {
+ if (s instanceof IBasicType) {
// 4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
- // An rvalue of an enumeration type can be converted to an rvalue of an integer type.
+ cost.setRank(Rank.CONVERSION);
+ cost.setCouldNarrow();
+ return true;
+ }
+ if (s instanceof ICPPEnumeration && !((ICPPEnumeration) s).isScoped()) {
+ // 4.7 An rvalue of an enumeration type can be converted to an rvalue of an integer type.
cost.setRank(Rank.CONVERSION);
cost.setCouldNarrow();
return true;
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 92a942f84fa..abeb51c1236 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2009 Symbian Software Systems and others.
+ * Copyright (c) 2007, 2010 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
@@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
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.IPointerType;
import org.eclipse.cdt.core.dom.ast.IQualifierType;
@@ -30,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
@@ -344,8 +344,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
result = ns.length == 0 ? null : new CompositeCPPNamespace(this, ns);
} else if (binding instanceof ICPPUsingDeclaration) {
result = new CompositeCPPUsingDeclaration(this, (ICPPUsingDeclaration) binding);
- } else if (binding instanceof IEnumeration) {
- IEnumeration def = (IEnumeration) findOneBinding(binding);
+ } else if (binding instanceof ICPPEnumeration) {
+ ICPPEnumeration def = (ICPPEnumeration) findOneBinding(binding);
result = def == null ? null : new CompositeCPPEnumeration(this, def);
} else if (binding instanceof ICPPFunction) {
result = new CompositeCPPFunction(this, (ICPPFunction) binding);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java
new file mode 100644
index 00000000000..3413928e38a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.index.composite.cpp;
+
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.EScopeKind;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexFileSet;
+import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
+import org.eclipse.cdt.internal.core.index.composite.CompositeScope;
+import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
+
+class CompositeCPPEnumScope extends CompositeScope implements ICPPScope {
+ public CompositeCPPEnumScope(ICompositesFactory cf, IIndexFragmentBinding rbinding) {
+ super(cf, rbinding);
+ }
+
+ public EScopeKind getKind() {
+ return EScopeKind.eEnumeration;
+ }
+
+ public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
+ IBinding binding = ((ICPPEnumeration)rbinding).asScope().getBinding(name, resolve, fileSet);
+ return processUncertainBinding(binding);
+ }
+
+ public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException {
+ IBinding[] bindings = ((ICPPEnumeration)rbinding).asScope().getBindings(name, resolve, prefixLookup, fileSet);
+ return processUncertainBindings(bindings);
+ }
+
+ public IBinding[] find(String name) throws DOMException {
+ IBinding[] preresult = ((ICPPEnumeration)rbinding).asScope().find(name);
+ return processUncertainBindings(preresult);
+ }
+
+ public IIndexBinding getScopeBinding() {
+ return cf.getCompositeBinding(rbinding);
+ }
+}
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 091b88c98df..75a7cbace78 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
@@ -15,12 +15,14 @@ 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;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
-class CompositeCPPEnumeration extends CompositeCPPBinding implements IEnumeration, IIndexType {
- public CompositeCPPEnumeration(ICompositesFactory cf, IEnumeration rbinding) {
+class CompositeCPPEnumeration extends CompositeCPPBinding implements ICPPEnumeration, IIndexType {
+ public CompositeCPPEnumeration(ICompositesFactory cf, ICPPEnumeration rbinding) {
super(cf, rbinding);
}
@@ -49,4 +51,16 @@ class CompositeCPPEnumeration extends CompositeCPPBinding implements IEnumeratio
public long getMaxValue() {
return ((IEnumeration)rbinding).getMaxValue();
}
+
+ public boolean isScoped() {
+ return ((ICPPEnumeration)rbinding).isScoped();
+ }
+
+ public IType getFixedType() {
+ return ((ICPPEnumeration)rbinding).getFixedType();
+ }
+
+ public ICPPScope asScope() {
+ return new CompositeCPPEnumScope(cf, rbinding);
+ }
}
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 8c6049ef55e..88036473e75 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 QNX Software Systems and others.
+ * Copyright (c) 2005, 2010 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
@@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IIndexBinding;
@@ -181,9 +182,9 @@ public class PDOM extends PlatformObject implements IPDOM {
* 81.0 - change to c++ function types, bug 264479
* 82.0 - offsets for using directives, bug 270806
* #83.0# - unconditionally store name in PDOMInclude, bug 272815 - <<CDT 6.0>>
- * 84.0 - storing free record pointers as (ptr>>3) and allocated pointers as (ptr-2)>>3 RECPTR_DENSE_VERSION
+ * #84.0# - storing free record pointers as (ptr>>3), bug 279620 - <<CDT 6.0.1>>
*
- * CDT 6.1 development (versions not supported on the 6.0.x branch)
+ * CDT 7.0 development (versions not supported on the 6.0.x branch)
* 90.0 - support for array sizes, bug 269926
* 91.0 - storing unknown bindings other than unknown class types, bug 284686.
* 92.0 - simplification of basic types, bug 231859.
@@ -192,10 +193,11 @@ public class PDOM extends PlatformObject implements IPDOM {
* 95.0 - parameter packs, bug 294730.
* 96.0 - storing pack expansions in the template parameter map, bug 294730.
* 97.0 - storing file contents hash in PDOMFile, bug 302083.
+ * 98.0 - strongly typed enums, bug 305975.
*/
- private static final int MIN_SUPPORTED_VERSION= version(97, 0);
- private static final int MAX_SUPPORTED_VERSION= version(97, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(97, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(98, 0);
+ private static final int MAX_SUPPORTED_VERSION= version(98, Short.MAX_VALUE);
+ private static final int DEFAULT_VERSION = version(98, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
@@ -532,6 +534,11 @@ public class PDOM extends PlatformObject implements IPDOM {
// check if we have a partial match
if (nnode.mayHaveChildren()) {
+ // Avoid visiting unscoped enumerator items twice
+ if (pattern.length == 1 && nnode instanceof ICPPEnumeration
+ && !((ICPPEnumeration) nnode).isScoped()) {
+ return false;
+ }
boolean visitNextLevel= false;
BitSet updatedMatchesUpToLevel= new BitSet();
if (!isFullyQualified) {
@@ -1065,6 +1072,8 @@ public class PDOM extends PlatformObject implements IPDOM {
try {
linkage.accept(visitor);
if (!filescope) {
+ // Avoid adding unscoped enumerator items twice
+ visitor.setSkipGlobalEnumerators(true);
linkage.getNestedBindingsIndex().accept(visitor);
}
} catch (OperationCanceledException e) {
@@ -1104,8 +1113,11 @@ public class PDOM extends PlatformObject implements IPDOM {
if (!isCaseSensitive)
linkage.accept(visitor);
- if (!filescope)
+ if (!filescope) {
+ // Avoid adding unscoped enumerator items twice
+ visitor.setSkipGlobalEnumerators(true);
linkage.getNestedBindingsIndex().accept(visitor);
+ }
PDOMBinding[] bindings = visitor.getBindings();
for (PDOMBinding binding : bindings) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java
index 650ef027b79..5aa74e415d6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 QNX Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -15,6 +15,8 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IEnumerator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.core.runtime.CoreException;
@@ -24,6 +26,7 @@ import org.eclipse.core.runtime.CoreException;
*/
public final class BindingCollector extends NamedNodeCollector {
private IndexFilter filter;
+ private boolean fSkipGlobalEnumerators;
/**
* Collects all bindings with given name.
@@ -44,6 +47,15 @@ public final class BindingCollector extends NamedNodeCollector {
@Override
public boolean addNode(PDOMNamedNode tBinding) throws CoreException {
if (tBinding instanceof PDOMBinding) {
+ if (fSkipGlobalEnumerators && tBinding instanceof IEnumerator) {
+ PDOMNode parent = tBinding.getParentNode();
+ if (parent instanceof ICPPEnumeration) {
+ final ICPPEnumeration enumType = (ICPPEnumeration) parent;
+ if (parent.getParentNode() == null && !enumType.isScoped()) {
+ return true;
+ }
+ }
+ }
if (filter == null || filter.acceptBinding((IBinding) tBinding)) {
return super.addNode(tBinding);
}
@@ -55,4 +67,8 @@ public final class BindingCollector extends NamedNodeCollector {
List<PDOMNamedNode> bindings= getNodeList();
return bindings.toArray(new PDOMBinding[bindings.size()]);
}
+
+ public void setSkipGlobalEnumerators(boolean b) {
+ fSkipGlobalEnumerators= b;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java
index 13beb3f0813..a9f7d5b52ab 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/FindBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Symbian Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -94,8 +94,8 @@ public class FindBinding {
protected boolean matches(PDOMBinding nnode) throws CoreException {
if (nnode.hasName(fName)) {
int constant = nnode.getNodeType();
- for (int i=0; i<fConstants.length; i++) {
- if (constant == fConstants[i]) {
+ for (int c : fConstants) {
+ if (constant == c) {
return true;
}
}
@@ -164,6 +164,7 @@ public class FindBinding {
public static PDOMBinding findBinding(IPDOMNode node, final PDOMLinkage linkage, final char[] name, final int[] constants,
long localToFileRec) throws CoreException {
+ // mstodo faster searches
final DefaultFindBindingVisitor visitor = new DefaultFindBindingVisitor(linkage, name, constants, localToFileRec);
try {
node.accept(visitor);
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 4f58960228b..f40e2d12b04 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
@@ -34,8 +34,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.IToken;
@@ -406,7 +408,7 @@ public class PDOMASTAdapter {
}
}
- private static class AnonymousCPPEnumeration extends AnonymousCPPBinding implements IEnumeration {
+ private static class AnonymousCPPEnumeration extends AnonymousCPPBinding implements ICPPEnumeration {
public AnonymousCPPEnumeration(char[] name, IEnumeration delegate) {
super(name, (ICPPBinding) delegate);
}
@@ -426,6 +428,18 @@ public class PDOMASTAdapter {
public long getMaxValue() {
return ((IEnumeration)fDelegate).getMaxValue();
}
+
+ public boolean isScoped() {
+ return ((ICPPEnumeration)fDelegate).isScoped();
+ }
+
+ public IType getFixedType() {
+ return ((ICPPEnumeration)fDelegate).getFixedType();
+ }
+
+ public ICPPScope asScope() {
+ return ((ICPPEnumeration)fDelegate).asScope();
+ }
}
private static class AnonymousClassType extends AnonymousCPPBinding implements ICPPClassType {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
index ac99f9808ba..3fb28f271c5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 QNX Software Systems and others.
+ * Copyright (c) 2005, 2010 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
@@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
@@ -209,14 +210,22 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding
// The parent node in the binding hierarchy is the scope.
try {
IBinding parent= getParentBinding();
- if (parent instanceof ICPPClassType) {
- return (IIndexScope) ((ICPPClassType) parent).getCompositeScope();
- } else if (parent instanceof ICPPUnknownBinding) {
- return (IIndexScope) ((ICPPUnknownBinding) parent).asScope();
- }
-
- if (parent instanceof IIndexScope) {
- return (IIndexScope) parent;
+ while (parent != null) {
+ if (parent instanceof ICPPClassType) {
+ return (IIndexScope) ((ICPPClassType) parent).getCompositeScope();
+ } else if (parent instanceof ICPPUnknownBinding) {
+ return (IIndexScope) ((ICPPUnknownBinding) parent).asScope();
+ } else if (parent instanceof ICPPEnumeration) {
+ final ICPPEnumeration enumeration = (ICPPEnumeration) parent;
+ if (enumeration.isScoped()) {
+ return (IIndexScope) enumeration.asScope();
+ }
+ parent= ((PDOMNamedNode) parent).getParentBinding();
+ } else if (parent instanceof IIndexScope) {
+ return (IIndexScope) parent;
+ } else {
+ return null;
+ }
}
} catch (DOMException e) {
} catch (CoreException ce) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
index e4881124af9..2155ca7eec3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 QNX Software Systems and others.
+ * Copyright (c) 2005, 2010 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
@@ -306,7 +306,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage
* @throws CoreException
* @since 4.0.1
*/
- public void afterAddBinding(PDOMBinding pdomBinding) throws CoreException {
+ protected final void insertIntoNestedBindingsIndex(PDOMBinding pdomBinding) throws CoreException {
if (pdomBinding.getParentNodeRec() != record) {
getNestedBindingsIndex().insert(pdomBinding.getRecord());
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java
index 4810f34bbb2..92acdcf2456 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMNamedNode.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 QNX Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -11,7 +11,6 @@
* Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-
package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.Arrays;
@@ -128,7 +127,7 @@ public abstract class PDOMNamedNode extends PDOMNode {
return null;
}
- public final IIndexFragmentBinding getOwner() {
+ public IIndexFragmentBinding getOwner() {
try {
return getParentBinding();
} catch (CoreException e) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java
index 68a33392c04..554979910eb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 QNX Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.index.IIndexCBindingConstants;
+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;
@@ -86,6 +87,10 @@ class PDOMCEnumerator extends PDOMBinding implements IEnumerator {
}
public IType getType() throws DOMException {
+ return getEnumeration();
+ }
+
+ private PDOMCEnumeration getEnumeration() {
try {
return new PDOMCEnumeration(getLinkage(), getDB().getRecPtr(record + ENUMERATION));
} catch (CoreException e) {
@@ -93,6 +98,11 @@ class PDOMCEnumerator extends PDOMBinding implements IEnumerator {
return null;
}
}
+
+ @Override
+ public IIndexFragmentBinding getOwner() {
+ return getEnumeration();
+ }
public IValue getValue() {
try {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
index 0a8904445c6..95f59a9c5da 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 QNX Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -141,7 +141,7 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
if (pdomBinding != null) {
pdomBinding.setLocalToFileRec(localToFile);
parent.addChild(pdomBinding);
- afterAddBinding(pdomBinding);
+ insertIntoNestedBindingsIndex(pdomBinding);
}
return pdomBinding;
}
@@ -215,6 +215,10 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants {
}
IBinding owner= binding.getOwner();
+ // For plain c the enumeration type is not the parent of the enumeration item.
+ if (owner instanceof IEnumeration) {
+ owner= owner.getOwner();
+ }
if (owner == null) {
return this;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java
index d21c232c538..621cdd74531 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/CPPFindBinding.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 Symbian Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -104,6 +104,7 @@ public class CPPFindBinding extends FindBinding {
public static PDOMBinding findBinding(PDOMNode node, PDOMLinkage linkage, char[] name, int constant,
int sigHash, long localToFileRec) throws CoreException {
+ // mstodo faster searches
CPPFindBindingVisitor visitor= new CPPFindBindingVisitor(linkage, name, constant, sigHash,
localToFileRec);
try {
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
new file mode 100644
index 00000000000..2395d9b6e85
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPEnumType.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom.dom.cpp;
+
+import org.eclipse.cdt.core.dom.ast.IEnumerator;
+import org.eclipse.cdt.core.dom.ast.IScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
+import org.eclipse.cdt.core.index.IIndexName;
+import org.eclipse.cdt.core.parser.util.CharArrayMap;
+import org.eclipse.cdt.internal.core.index.IIndexType;
+import org.eclipse.cdt.internal.core.pdom.dom.IPDOMBinding;
+
+/**
+ * Interface that allows to implement a class-scope.
+ */
+public interface IPDOMCPPEnumType extends ICPPEnumeration, IPDOMBinding, IIndexType {
+ /**
+ * Return the scope name, for use in {@link IScope#getScopeName()}
+ */
+ IIndexName getScopeName();
+
+ IEnumerator[] getEnumerators();
+
+ /**
+ * Called by the scope to access the enumerators.
+ */
+ void loadEnumerators(CharArrayMap<PDOMCPPEnumerator> map);
+}
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
new file mode 100644
index 00000000000..83b1a99e351
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.pdom.dom.cpp;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.dom.IPDOMVisitor;
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.EScopeKind;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IEnumerator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
+import org.eclipse.cdt.core.index.IIndexBinding;
+import org.eclipse.cdt.core.index.IIndexFileSet;
+import org.eclipse.cdt.core.index.IIndexName;
+import org.eclipse.cdt.core.index.IndexFilter;
+import org.eclipse.cdt.core.parser.util.CharArrayMap;
+import org.eclipse.cdt.core.parser.util.CharArrayUtils;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
+import org.eclipse.cdt.internal.core.index.IIndexScope;
+import org.eclipse.cdt.internal.core.pdom.PDOM;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * Represents the enum scope for an enum stored in the index.
+ */
+class PDOMCPPEnumScope implements ICPPScope, IIndexScope {
+ private IPDOMCPPEnumType fBinding;
+
+ public PDOMCPPEnumScope(IPDOMCPPEnumType binding) {
+ fBinding= binding;
+ }
+
+ public EScopeKind getKind() {
+ return EScopeKind.eEnumeration;
+ }
+
+ public IBinding getBinding(IASTName name, boolean resolve) throws DOMException {
+ return getBinding(name, resolve, null);
+ }
+
+ public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) throws DOMException {
+ return getBindings(name, resolve, prefixLookup, null);
+ }
+
+ public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
+ try {
+ CharArrayMap<PDOMCPPEnumerator> map= getBindingMap(fBinding);
+ return map.get(name.toCharArray());
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ return null;
+ }
+ }
+
+ public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException {
+ try {
+ CharArrayMap<PDOMCPPEnumerator> map= getBindingMap(fBinding);
+ if (prefixLookup) {
+ final List<IBinding> result= new ArrayList<IBinding>();
+ final char[] nc= name.toCharArray();
+ for (char[] key : map.keys()) {
+ if (CharArrayUtils.equals(key, 0, nc.length, nc, true)) {
+ result.add(map.get(key));
+ }
+ }
+ return result.toArray(new IBinding[result.size()]);
+ }
+ IBinding b= map.get(name.toCharArray());
+ if (b != null) {
+ return new IBinding[] {b};
+ }
+ } catch (Exception e) {
+ CCorePlugin.log(e);
+ }
+ return IBinding.EMPTY_BINDING_ARRAY;
+ }
+
+ public IBinding[] find(String name) throws DOMException {
+ return CPPSemantics.findBindings(this, name, false);
+ }
+
+ public IIndexBinding getScopeBinding() {
+ return fBinding;
+ }
+
+ public IIndexScope getParent() {
+ return fBinding.getScope();
+ }
+
+ public IIndexName getScopeName() {
+ return fBinding.getScopeName();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof PDOMCPPEnumScope)
+ return fBinding.equals(((PDOMCPPEnumScope) obj).fBinding);
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return fBinding.hashCode();
+ }
+
+ private static CharArrayMap<PDOMCPPEnumerator> 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();
+
+ if (map == null) {
+ // there is no cache, build it:
+ map= new CharArrayMap<PDOMCPPEnumerator>();
+ enumeration.loadEnumerators(map);
+ pdom.putCachedResult(key, new SoftReference<CharArrayMap<?>>(map));
+ }
+ return map;
+ }
+
+ public static void updateCache(PDOMCPPEnumeration enumType, PDOMCPPEnumerator 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();
+ if (map != null) {
+ map.put(enumType.getNameCharArray(), enumItem);
+ }
+ }
+
+ public static IEnumerator[] getEnumerators(PDOMCPPEnumeration enumType) {
+ try {
+ CharArrayMap<PDOMCPPEnumerator> map = getBindingMap(enumType);
+ List<IEnumerator> result= new ArrayList<IEnumerator>();
+ for (IEnumerator value : map.values()) {
+ if (IndexFilter.ALL_DECLARED.acceptBinding(value)) {
+ result.add(value);
+ }
+ }
+ Collections.reverse(result);
+ return result.toArray(new IEnumerator[result.size()]);
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ return new IEnumerator[0];
+ }
+
+ public static void acceptViaCache(PDOMCPPEnumeration enumType, IPDOMVisitor visitor) {
+ try {
+ CharArrayMap<PDOMCPPEnumerator> map = getBindingMap(enumType);
+ for (PDOMCPPEnumerator enumItem : map.values()) {
+ visitor.visit(enumItem);
+ visitor.leave(enumItem);
+ }
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
+ }
+}
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 ddf18e6c844..c4c707c0cdc 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
@@ -12,9 +12,9 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
-import java.util.ArrayList;
-
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.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
@@ -22,36 +22,45 @@ 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.ICPPScope;
+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.index.IIndexType;
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.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException;
/**
* Enumerations in the index.
*/
-class PDOMCPPEnumeration extends PDOMCPPBinding implements IEnumeration, IIndexType {
+class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPDOMMemberOwner {
- private static final int FIRST_ENUMERATOR = PDOMBinding.RECORD_SIZE;
- private static final int OFFSET_MIN_VALUE= FIRST_ENUMERATOR + Database.PTR_SIZE;
+ private static final int OFFSET_ENUMERATOR_LIST = PDOMBinding.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_MAX_VALUE + 8;
+ protected static final int RECORD_SIZE = OFFSET_FLAGS + 1;
private Long fMinValue;
private Long fMaxValue;
+ private IType fFixedType= ProblemBinding.NOT_INITIALIZED;
+ private PDOMCPPEnumScope fScope;
- public PDOMCPPEnumeration(PDOMLinkage linkage, PDOMNode parent, IEnumeration enumeration)
+ public PDOMCPPEnumeration(PDOMLinkage linkage, PDOMNode parent, ICPPEnumeration enumeration)
throws CoreException {
super(linkage, parent, enumeration.getNameCharArray());
- storeValueBounds(enumeration);
+ storeProperties(enumeration);
}
public PDOMCPPEnumeration(PDOMLinkage linkage, long record) {
@@ -60,17 +69,25 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IEnumeration, IIndexT
@Override
public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException {
- storeValueBounds((IEnumeration) newBinding);
+ storeProperties((ICPPEnumeration) newBinding);
}
- private void storeValueBounds(IEnumeration enumeration) throws CoreException {
+ private void storeProperties(ICPPEnumeration enumeration) throws CoreException {
final Database db= getDB();
- 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;
+ 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
@@ -83,43 +100,29 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IEnumeration, IIndexT
return IIndexCPPBindingConstants.CPPENUMERATION;
}
- public IEnumerator[] getEnumerators() throws DOMException {
- try {
- ArrayList<PDOMCPPEnumerator> enums = new ArrayList<PDOMCPPEnumerator>();
- for (PDOMCPPEnumerator enumerator = getFirstEnumerator();
- enumerator != null;
- enumerator = enumerator.getNextEnumerator()) {
- enums.add(enumerator);
- }
-
- IEnumerator[] enumerators = enums.toArray(new IEnumerator[enums.size()]);
-
- // Reverse the list since they are last in first out
- int n = enumerators.length;
- for (int i = 0; i < n / 2; ++i) {
- IEnumerator tmp = enumerators[i];
- enumerators[i] = enumerators[n - 1 - i];
- enumerators[n - 1 - i] = tmp;
- }
-
- return enumerators;
- } catch (CoreException e) {
- CCorePlugin.log(e);
- return new IEnumerator[0];
- }
+ public IEnumerator[] getEnumerators() {
+ return PDOMCPPEnumScope.getEnumerators(this);
+ }
+
+ @Override
+ public void accept(IPDOMVisitor visitor) throws CoreException {
+ PDOMCPPEnumScope.acceptViaCache(this, visitor);
}
- private PDOMCPPEnumerator getFirstEnumerator() throws CoreException {
- long value = getDB().getRecPtr(record + FIRST_ENUMERATOR);
- return value != 0 ? new PDOMCPPEnumerator(getLinkage(), value) : null;
+ @Override
+ public void addChild(PDOMNode node) throws CoreException {
+ if (node instanceof PDOMCPPEnumerator) {
+ PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST);
+ list.addMember(node);
+ PDOMCPPEnumScope.updateCache(this, (PDOMCPPEnumerator) node);
+ }
}
-
- public void addEnumerator(PDOMCPPEnumerator enumerator) throws CoreException {
- PDOMCPPEnumerator first = getFirstEnumerator();
- enumerator.setNextEnumerator(first);
- getDB().putRecPtr(record + FIRST_ENUMERATOR, enumerator.getRecord());
+
+ @Override
+ public boolean mayHaveChildren() {
+ return true;
}
-
+
public boolean isSameType(IType type) {
if (type instanceof ITypedef) {
return type.isSameType(this);
@@ -176,8 +179,57 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IEnumeration, IIndexT
return maxValue;
}
- @Override
+ @Override
public Object clone() {
- throw new PDOMNotImplementedError();
+ throw new IllegalArgumentException("Enums must not be cloned"); //$NON-NLS-1$
+ }
+
+ public boolean isScoped() {
+ try {
+ return getDB().getByte(record + OFFSET_FLAGS) != 0;
+ } catch (CoreException e) {
+ return false;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ public ICPPScope asScope() {
+ if (fScope == null) {
+ fScope= new PDOMCPPEnumScope(this);
+ }
+ return fScope;
+ }
+
+ public void loadEnumerators(final CharArrayMap<PDOMCPPEnumerator> map) {
+ try {
+ PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + OFFSET_ENUMERATOR_LIST);
+ list.accept(new IPDOMVisitor() {
+ public boolean visit(IPDOMNode node) throws CoreException {
+ if (node instanceof PDOMCPPEnumerator) {
+ final PDOMCPPEnumerator item = (PDOMCPPEnumerator) node;
+ map.put(item.getNameCharArray(), item);
+ }
+ return true;
+ }
+ public void leave(IPDOMNode node) {}
+ });
+ } catch (CoreException e) {
+ CCorePlugin.log(e);
+ }
}
}
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 2c4faec0a1a..8640fc9828d 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,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2009 QNX Software Systems and others.
+ * Copyright (c) 2006, 2010 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
@@ -9,7 +9,6 @@
* Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
@@ -20,8 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
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.pdom.db.Database;
-import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
+import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
@@ -30,22 +28,15 @@ import org.eclipse.core.runtime.CoreException;
* Binding for a c++ enumerator in the index.
*/
class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator {
-
- private static final int ENUMERATION = PDOMBinding.RECORD_SIZE + 0;
- private static final int NEXT_ENUMERATOR = PDOMBinding.RECORD_SIZE + 4;
- private static final int VALUE= PDOMBinding.RECORD_SIZE + 8;
+ private static final int VALUE= PDOMCPPBinding.RECORD_SIZE;
@SuppressWarnings("hiding")
- protected static final int RECORD_SIZE = PDOMBinding.RECORD_SIZE + 12;
+ protected static final int RECORD_SIZE = VALUE + 4;
- public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, IEnumerator enumerator, PDOMCPPEnumeration enumeration)
+ public PDOMCPPEnumerator(PDOMLinkage linkage, PDOMNode parent, IEnumerator enumerator)
throws CoreException {
super(linkage, parent, enumerator.getNameCharArray());
-
- final Database db = getDB();
- db.putRecPtr(record + ENUMERATION, enumeration.getRecord());
- storeValue(db, enumerator);
- enumeration.addEnumerator(this);
+ storeValue(enumerator);
}
public PDOMCPPEnumerator(PDOMLinkage linkage, long record) {
@@ -62,37 +53,25 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator {
return IIndexCPPBindingConstants.CPPENUMERATOR;
}
- private void storeValue(final Database db, IEnumerator enumerator) throws CoreException {
+ private void storeValue(IEnumerator enumerator) throws CoreException {
IValue value= enumerator.getValue();
if (value != null) {
Long val= value.numericalValue();
- db.putInt(record + VALUE, val == null ? -1 : val.intValue());
+ getDB().putInt(record + VALUE, val == null ? -1 : val.intValue());
}
}
@Override
public void update(PDOMLinkage linkage, IBinding newBinding) throws CoreException {
if (newBinding instanceof IEnumerator)
- storeValue(getDB(), (IEnumerator) newBinding);
+ storeValue((IEnumerator) newBinding);
}
- public PDOMCPPEnumerator getNextEnumerator() throws CoreException {
- long value = getDB().getRecPtr(record + NEXT_ENUMERATOR);
- return value != 0 ? new PDOMCPPEnumerator(getLinkage(), value) : null;
- }
-
- public void setNextEnumerator(PDOMCPPEnumerator enumerator) throws CoreException {
- long value = enumerator != null ? enumerator.getRecord() : 0;
- getDB().putRecPtr(record + NEXT_ENUMERATOR, value);
- }
-
public IType getType() throws DOMException {
- try {
- return new PDOMCPPEnumeration(getLinkage(), getDB().getRecPtr(record + ENUMERATION));
- } catch (CoreException e) {
- CCorePlugin.log(e);
- return null;
- }
+ IIndexFragmentBinding owner = getOwner();
+ if (owner instanceof IType)
+ return (IType) owner;
+ return null;
}
public IValue getValue() {
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 15795a7516f..e752c99f450 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, 2009 QNX Software Systems and others.
+ * Copyright (c) 2005, 2010 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
@@ -31,6 +31,7 @@ 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.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@@ -43,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
@@ -62,7 +64,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
-import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
@@ -299,6 +300,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (fromName.isDefinition()) {
return true;
}
+ // Update opaque enums.
+ if (pdomBinding instanceof ICPPEnumeration && fromName.isDeclaration()) {
+ return true;
+ }
return !getPDOM().hasLastingDefinition(pdomBinding);
}
return false;
@@ -306,6 +311,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMBinding createBinding(PDOMNode parent, IBinding binding, long fileLocalRec) throws CoreException, DOMException {
PDOMBinding pdomBinding= null;
+ PDOMNode parent2= null;
// template parameters are created directly by their owners.
if (binding instanceof ICPPTemplateParameter)
@@ -361,15 +367,15 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
pdomBinding = new PDOMCPPNamespace(this, parent, (ICPPNamespace) binding);
} else if (binding instanceof ICPPUsingDeclaration) {
pdomBinding = new PDOMCPPUsingDeclaration(this, parent, (ICPPUsingDeclaration) binding);
- } else if (binding instanceof IEnumeration) {
- pdomBinding = new PDOMCPPEnumeration(this, parent, (IEnumeration) binding);
+ } else if (binding instanceof ICPPEnumeration) {
+ pdomBinding = new PDOMCPPEnumeration(this, parent, (ICPPEnumeration) binding);
} else if (binding instanceof IEnumerator) {
- final IEnumerator etor = (IEnumerator) binding;
- IType enumeration= etor.getType();
- if (enumeration instanceof IEnumeration) {
- PDOMBinding pdomEnumeration = adaptBinding((IEnumeration) enumeration);
- if (pdomEnumeration instanceof PDOMCPPEnumeration) {
- pdomBinding = new PDOMCPPEnumerator(this, parent, etor, (PDOMCPPEnumeration)pdomEnumeration);
+ assert parent instanceof ICPPEnumeration;
+ pdomBinding = new PDOMCPPEnumerator(this, parent, (IEnumerator) binding);
+ if (parent instanceof ICPPEnumeration && !((ICPPEnumeration) parent).isScoped()) {
+ parent2= parent.getParentNode();
+ if (parent2 == null) {
+ parent2= this;
}
}
} else if (binding instanceof ITypedef) {
@@ -379,7 +385,12 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (pdomBinding != null) {
pdomBinding.setLocalToFileRec(fileLocalRec);
parent.addChild(pdomBinding);
- afterAddBinding(pdomBinding);
+ if (parent2 != null) {
+ parent2.addChild(pdomBinding);
+ }
+ if (parent2 != this) {
+ insertIntoNestedBindingsIndex(pdomBinding);
+ }
}
return pdomBinding;

Back to the top