From 55b2de412418feaaaff5ca5b6dc2209ffd74c443 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Tue, 19 Aug 2014 19:27:24 -0700 Subject: [PATCH] Bug 442117 - Name resolution problem with namespace alias. --- .../tests/IndexCPPBindingResolutionTest.java | 14 +++- .../index/tests/IndexMultiFileTest.java | 48 +++++++++++- .../core/dom/parser/cpp/ClassTypeHelper.java | 4 +- .../parser/cpp/semantics/CPPSemantics.java | 10 ++- .../parser/cpp/semantics/SemanticUtil.java | 77 ++++++++++++------- .../core/pdom/dom/c/PDOMCEnumeration.java | 12 +-- .../pdom/dom/cpp/PDOMCPPClassTemplate.java | 4 +- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 4 +- .../core/pdom/dom/cpp/PDOMCPPEnumeration.java | 4 +- .../cpp/PDOMCPPEnumerationSpecialization.java | 4 +- 10 files changed, 132 insertions(+), 49 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 5b7e70cf050..6050161bb6b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -1705,7 +1705,19 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti // namespace alias = ns; // void alias::fun() { // } - public void testNamespaceAliasAsQualifier_356493() throws Exception { + public void testNamespaceAliasAsQualifier_356493a() throws Exception { + IFunction ref= getBindingFromASTName("fun", 0); + assertEquals("ns", ref.getOwner().getName()); + } + + // namespace ns { + // void fun(); + // } + // namespace alias = ns; + + // void alias::fun() { + // } + public void testNamespaceAliasAsQualifier_356493b() throws Exception { IFunction ref= getBindingFromASTName("fun", 0); assertEquals("ns", ref.getOwner().getName()); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java index 08d9dff32f1..70a1f6d537f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Google, Inc and others. + * Copyright (c) 2013, 2014 Google, Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,7 +13,7 @@ package org.eclipse.cdt.internal.index.tests; import junit.framework.TestSuite; /** - * Tests for header files included in multiple variants. + * Index tests involving multiple header and source files. * * The first line of each comment section preceding a test contains the name of the file * to put the contents of the section to. To request the AST of a file, put an asterisk after @@ -56,4 +56,48 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase { public void testAnonymousNamespace_416278() throws Exception { checkBindings(); } + + // a.h + // namespace ns1 { + // } + // + // namespace ns2 { + // namespace ns3 { + // namespace waldo = ns1; + // } + // } + + // a.cpp + // #include "a.h" + + // b.h + // namespace ns1 { + // } + // + // namespace ns2 { + // namespace waldo = ns1; + // } + + // b.cpp + // #include "b.h" + // + // namespace ns2 { + // namespace waldo = ::ns1; + // } + + // c.cpp + // namespace ns1 { + // class A {}; + // } + // + // namespace waldo = ns1; + // + // namespace ns2 { + // namespace ns3 { + // waldo::A a; + // } + // } + public void testNamespaceAlias_442117() throws Exception { + checkBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index b544ab03738..18160fab4d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2013 IBM Corporation and others. + * Copyright (c) 2004, 2014 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 @@ -154,7 +154,7 @@ public class ClassTypeHelper { for (IBinding friend : getFriends(classType, null)) { if (friend instanceof ICPPFunction && CharArrayUtils.equals(name, friend.getNameCharArray()) && - SemanticUtil.isSameOwner(binding.getOwner(), friend.getOwner()) && + SemanticUtil.haveSameOwner(binding, friend) && type.isSameType(((ICPPFunction) friend).getType())) { return true; } 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 8abc87c5ca2..9bb27812c7c 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2013 IBM Corporation and others. + * Copyright (c) 2004, 2014 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 @@ -2061,9 +2061,11 @@ public class CPPSemantics { } else { if (obj == null) { obj = temp; - } else if (obj.equals(temp)) { - // Ok, delegates are synonyms. - } else { + } else if (!obj.equals(temp)) { + if (obj instanceof ICPPNamespace && temp instanceof ICPPNamespace && + SemanticUtil.isSameNamespace((ICPPNamespace) obj, (ICPPNamespace) temp)) { + continue; + } int c = compareByRelevance(tu, obj, temp); if (c < 0) { obj= temp; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 1fdda243551..d8b9645d568 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -56,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; 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; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; @@ -163,12 +164,12 @@ public class SemanticUtil { * @throws DOMException */ public static ObjectSet inheritanceClosure(ICPPClassType root, IASTNode point) throws DOMException { - ObjectSet done= new ObjectSet(2); - ObjectSet current= new ObjectSet(2); + ObjectSet done= new ObjectSet<>(2); + ObjectSet current= new ObjectSet<>(2); current.put(root); for (int count = 0; count < CPPSemantics.MAX_INHERITANCE_DEPTH && !current.isEmpty(); count++) { - ObjectSet next= new ObjectSet(2); + ObjectSet next= new ObjectSet<>(2); for (int i = 0; i < current.size(); i++) { ICPPClassType clazz= current.keyAt(i); @@ -622,33 +623,57 @@ public class SemanticUtil { /** * Returns {@code true} if two bindings have the same owner. */ - public static boolean isSameOwner(IBinding owner1, IBinding owner2) { - // Ignore anonymous namespaces - while (owner1 instanceof ICPPNamespace && owner1.getNameCharArray().length == 0) - owner1= owner1.getOwner(); - // Ignore anonymous namespaces - while (owner2 instanceof ICPPNamespace && owner2.getNameCharArray().length == 0) - owner2= owner2.getOwner(); - - if (owner1 == null) - return owner2 == null; - if (owner2 == null) + public static boolean haveSameOwner(IBinding b1, IBinding b2) { + if (b1 == b2) + return true; + b1 = b1.getOwner(); + b2 = b2.getOwner(); + if (b1 == b2) + return true; + if (b1 instanceof IType) { + if (b2 instanceof IType) + return ((IType) b1).isSameType((IType) b2); return false; - - if (owner1 instanceof IType) { - if (owner2 instanceof IType) { - return ((IType) owner1).isSameType((IType) owner2); - } - } else if (owner1 instanceof ICPPNamespace) { - if (owner2 instanceof ICPPNamespace) { - if (!CharArrayUtils.equals(owner1.getNameCharArray(), owner2.getNameCharArray())) - return false; - return isSameOwner(owner1.getOwner(), owner2.getOwner()); - } } + if (b1 instanceof ICPPNamespace && b2 instanceof ICPPNamespace) + return isSameNamespace((ICPPNamespace) b1, (ICPPNamespace) b2); return false; } + /** + * Returns {@code true} if the two given bindings represent the same type or namespace. + */ + public static boolean isSameNamespace(ICPPNamespace ns1, ICPPNamespace ns2) { + IBinding b1 = ns1; + IBinding b2 = ns2; + + while (true) { + for (int i = 0; b1 instanceof ICPPNamespaceAlias && i < 20; i++) + b1= ((ICPPNamespaceAlias) b1).getBinding(); + // TODO(sprigogin): Anonymous namespaces should not be ignored here. + // Ignore anonymous namespaces. + while (b1 instanceof ICPPNamespace && b1.getNameCharArray().length == 0) + b1= b1.getOwner(); + for (int i = 0; b2 instanceof ICPPNamespaceAlias && i < 20; i++) + b2= ((ICPPNamespaceAlias) b2).getBinding(); + // Ignore anonymous namespaces. + while (b2 instanceof ICPPNamespace && b2.getNameCharArray().length == 0) + b2= b2.getOwner(); + + if (b1 == null) + return b2 == null; + if (b2 == null) + return false; + + if (!(b1 instanceof ICPPNamespace) || !(b2 instanceof ICPPNamespace)) + return false; + if (!CharArrayUtils.equals(b1.getNameCharArray(), b2.getNameCharArray())) + return false; + b1 = b1.getOwner(); + b2 = b2.getOwner(); + } + } + public static boolean isVoidType(IType ptype) { while (ptype instanceof ITypedef) { ptype= ((ITypedef) ptype).getType(); @@ -679,7 +704,7 @@ public class SemanticUtil { * no inheritance relation */ public static final int calculateInheritanceDepth(IType type, IType baseClass, IASTNode point) { - return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet(), type, baseClass, point); + return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<>(), type, baseClass, point); } private static final int calculateInheritanceDepth(int maxdepth, Set hashSet, IType type, IType baseClass, IASTNode point) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumeration.java index e8823998e44..460105ee04f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumeration.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 QNX Software Systems and others. + * Copyright (c) 2006, 2014 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Doug Schaefer (QNX) - Initial API and implementation - * Markus Schorn (Wind River Systems) + * Doug Schaefer (QNX) - Initial API and implementation + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.c; @@ -70,8 +70,8 @@ class PDOMCEnumeration extends PDOMBinding implements IEnumeration, IIndexType, 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); + db.putLong(record + OFFSET_MIN_VALUE, minValue); + db.putLong(record + OFFSET_MAX_VALUE, maxValue); fMinValue= minValue; fMaxValue= maxValue; } @@ -204,7 +204,7 @@ class PDOMCEnumeration extends PDOMBinding implements IEnumeration, IIndexType, if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) return false; - return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); + return SemanticUtil.haveSameOwner(this, etype); } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java index fefac6d29b0..7009a805f7e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 QNX Software Systems and others. + * Copyright (c) 2007, 2014 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 @@ -264,7 +264,7 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) return false; - return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner()); + return SemanticUtil.haveSameOwner(this, ctype); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index dd50f94fd06..5884c3b8372 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2013 QNX Software Systems and others. + * Copyright (c) 2005, 2014 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 @@ -290,7 +290,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) return false; - return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner()); + return SemanticUtil.haveSameOwner(this, ctype); } return false; } 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 dc00b59e45b..3f25a4828a1 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 QNX Software Systems and others. + * Copyright (c) 2006, 2014 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 @@ -144,7 +144,7 @@ class PDOMCPPEnumeration extends PDOMCPPBinding implements IPDOMCPPEnumType, IPD if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) return false; - return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); + return SemanticUtil.haveSameOwner(this, etype); } return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java index ffc814affd8..d8719ce0e48 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerationSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Google, Inc and others. + * Copyright (c) 2013, 2014 Google, Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -151,7 +151,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) return false; - return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); + return SemanticUtil.haveSameOwner(this, etype); } return false; }