1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-06 15:55:47 +02:00

Bug 442117 - Name resolution problem with namespace alias.

This commit is contained in:
Sergey Prigogin 2014-08-19 19:27:24 -07:00
parent eaf6b52cba
commit 7ed07030b2
10 changed files with 132 additions and 49 deletions

View file

@ -1705,7 +1705,19 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
// namespace alias = ns; // namespace alias = ns;
// void alias::fun() { // 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); IFunction ref= getBindingFromASTName("fun", 0);
assertEquals("ns", ref.getOwner().getName()); assertEquals("ns", ref.getOwner().getName());
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -13,7 +13,7 @@ package org.eclipse.cdt.internal.index.tests;
import junit.framework.TestSuite; 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 * 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 * 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 { public void testAnonymousNamespace_416278() throws Exception {
checkBindings(); 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();
}
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -154,7 +154,7 @@ public class ClassTypeHelper {
for (IBinding friend : getFriends(classType, null)) { for (IBinding friend : getFriends(classType, null)) {
if (friend instanceof ICPPFunction && if (friend instanceof ICPPFunction &&
CharArrayUtils.equals(name, friend.getNameCharArray()) && CharArrayUtils.equals(name, friend.getNameCharArray()) &&
SemanticUtil.isSameOwner(binding.getOwner(), friend.getOwner()) && SemanticUtil.haveSameOwner(binding, friend) &&
type.isSameType(((ICPPFunction) friend).getType())) { type.isSameType(((ICPPFunction) friend).getType())) {
return true; return true;
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -2061,9 +2061,11 @@ public class CPPSemantics {
} else { } else {
if (obj == null) { if (obj == null) {
obj = temp; obj = temp;
} else if (obj.equals(temp)) { } else if (!obj.equals(temp)) {
// Ok, delegates are synonyms. if (obj instanceof ICPPNamespace && temp instanceof ICPPNamespace &&
} else { SemanticUtil.isSameNamespace((ICPPNamespace) obj, (ICPPNamespace) temp)) {
continue;
}
int c = compareByRelevance(tu, obj, temp); int c = compareByRelevance(tu, obj, temp);
if (c < 0) { if (c < 0) {
obj= temp; obj= temp;

View file

@ -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.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.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.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
@ -163,12 +164,12 @@ public class SemanticUtil {
* @throws DOMException * @throws DOMException
*/ */
public static ObjectSet<ICPPClassType> inheritanceClosure(ICPPClassType root, IASTNode point) throws DOMException { public static ObjectSet<ICPPClassType> inheritanceClosure(ICPPClassType root, IASTNode point) throws DOMException {
ObjectSet<ICPPClassType> done= new ObjectSet<ICPPClassType>(2); ObjectSet<ICPPClassType> done= new ObjectSet<>(2);
ObjectSet<ICPPClassType> current= new ObjectSet<ICPPClassType>(2); ObjectSet<ICPPClassType> current= new ObjectSet<>(2);
current.put(root); current.put(root);
for (int count = 0; count < CPPSemantics.MAX_INHERITANCE_DEPTH && !current.isEmpty(); count++) { for (int count = 0; count < CPPSemantics.MAX_INHERITANCE_DEPTH && !current.isEmpty(); count++) {
ObjectSet<ICPPClassType> next= new ObjectSet<ICPPClassType>(2); ObjectSet<ICPPClassType> next= new ObjectSet<>(2);
for (int i = 0; i < current.size(); i++) { for (int i = 0; i < current.size(); i++) {
ICPPClassType clazz= current.keyAt(i); ICPPClassType clazz= current.keyAt(i);
@ -622,33 +623,57 @@ public class SemanticUtil {
/** /**
* Returns {@code true} if two bindings have the same owner. * Returns {@code true} if two bindings have the same owner.
*/ */
public static boolean isSameOwner(IBinding owner1, IBinding owner2) { public static boolean haveSameOwner(IBinding b1, IBinding b2) {
// Ignore anonymous namespaces if (b1 == b2)
while (owner1 instanceof ICPPNamespace && owner1.getNameCharArray().length == 0) return true;
owner1= owner1.getOwner(); b1 = b1.getOwner();
// Ignore anonymous namespaces b2 = b2.getOwner();
while (owner2 instanceof ICPPNamespace && owner2.getNameCharArray().length == 0) if (b1 == b2)
owner2= owner2.getOwner(); return true;
if (b1 instanceof IType) {
if (owner1 == null) if (b2 instanceof IType)
return owner2 == null; return ((IType) b1).isSameType((IType) b2);
if (owner2 == null)
return false; 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; 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) { public static boolean isVoidType(IType ptype) {
while (ptype instanceof ITypedef) { while (ptype instanceof ITypedef) {
ptype= ((ITypedef) ptype).getType(); ptype= ((ITypedef) ptype).getType();
@ -679,7 +704,7 @@ public class SemanticUtil {
* no inheritance relation * no inheritance relation
*/ */
public static final int calculateInheritanceDepth(IType type, IType baseClass, IASTNode point) { public static final int calculateInheritanceDepth(IType type, IType baseClass, IASTNode point) {
return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>(), type, baseClass, point); return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<>(), type, baseClass, point);
} }
private static final int calculateInheritanceDepth(int maxdepth, Set<Object> hashSet, IType type, IType baseClass, IASTNode point) { private static final int calculateInheritanceDepth(int maxdepth, Set<Object> hashSet, IType type, IType baseClass, IASTNode point) {

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Doug Schaefer (QNX) - Initial API and implementation * Doug Schaefer (QNX) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.c; 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 Database db= getDB();
final long minValue = enumeration.getMinValue(); final long minValue = enumeration.getMinValue();
final long maxValue = enumeration.getMaxValue(); final long maxValue = enumeration.getMaxValue();
db.putLong(record+ OFFSET_MIN_VALUE, minValue); db.putLong(record + OFFSET_MIN_VALUE, minValue);
db.putLong(record+ OFFSET_MAX_VALUE, maxValue); db.putLong(record + OFFSET_MAX_VALUE, maxValue);
fMinValue= minValue; fMinValue= minValue;
fMaxValue= maxValue; fMaxValue= maxValue;
} }
@ -204,7 +204,7 @@ class PDOMCEnumeration extends PDOMBinding implements IEnumeration, IIndexType,
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false; return false;
return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); return SemanticUtil.haveSameOwner(this, etype);
} }
return false; return false;
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -264,7 +264,7 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false; return false;
return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner()); return SemanticUtil.haveSameOwner(this, ctype);
} }
@Override @Override

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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())) if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false; return false;
return SemanticUtil.isSameOwner(getOwner(), ctype.getOwner()); return SemanticUtil.haveSameOwner(this, ctype);
} }
return false; return false;
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * 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())) if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false; return false;
return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); return SemanticUtil.haveSameOwner(this, etype);
} }
return false; return false;
} }

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -151,7 +151,7 @@ class PDOMCPPEnumerationSpecialization extends PDOMCPPSpecialization
if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray())) if (nchars == null || !CharArrayUtils.equals(nchars, getNameCharArray()))
return false; return false;
return SemanticUtil.isSameOwner(getOwner(), etype.getOwner()); return SemanticUtil.haveSameOwner(this, etype);
} }
return false; return false;
} }