1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 419301 - Remove stray friend functions from lookup results

Change-Id: I69f79de6f38226aeceb0dfecb22ae43193c8c696
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/19890
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-12-17 03:55:04 -05:00 committed by Sergey Prigogin
parent 2136875477
commit a7e2467ba5
5 changed files with 107 additions and 22 deletions

View file

@ -8216,4 +8216,21 @@ public class AST2TemplateTests extends AST2TestBase {
BindingAssertionHelper helper = getAssertionHelper();
helper.assertNonProblem("waldo<T>", ICPPDeferredFunction.class);
}
// template <typename>
// struct C {
// friend bool operator==(C, C);
// friend bool operator!=(C, C);
// };
//
// template <typename U>
// void waldo(U, U);
//
// void test() {
// C<int> x;
// waldo(x, x);
// }
public void testStrayFriends_419301() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation and others.
* Copyright (c) 2004, 2013 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
@ -11,6 +11,7 @@
* Andrew Ferguson (Symbian)
* Mike Kucera (IBM)
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
@ -741,4 +742,29 @@ public abstract class ArrayUtil {
array[idx] = val;
return array;
}
/**
* Filter the elements of an array down to just the ones
* that match the given predicate.
* @since 5.6
*/
public static <T> T[] filter(T[] array, IUnaryPredicate<T> predicate) {
T[] result = array;
int resultIndex = 0;
for (int i = 0; i < array.length; ++i) {
if (predicate.apply(array[i])) {
if (result != array) {
result[resultIndex] = array[i];
}
++resultIndex;
} else {
if (result == array) {
// There will be at most array.length - 1 filtered elements.
result = Arrays.copyOf(array, array.length - 1);
Arrays.fill(result, i, result.length, null);
}
}
}
return resultIndex == result.length ? result : Arrays.copyOf(result, resultIndex);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2012 IBM Corporation and others.
* Copyright (c) 2006, 2013 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
@ -8,6 +8,7 @@
* Contributors:
* Mike Kucera (IBM Corporation) - initial API and implementation
* Sergey Prigogin (Google)
* Nathan Ridge
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
@ -151,4 +152,19 @@ public final class CollectionUtils {
}
return result;
}
/**
* Filter the elements of a collection down to just the ones
* that match the given predicate.
* @since 5.6
*/
public static <T> Collection<T> filter(Collection<T> collection, IUnaryPredicate<T> predicate) {
if (collection.isEmpty())
return collection;
Collection<T> result = new ArrayList<T>();
for (T t : collection)
if (predicate.apply(t))
result.add(t);
return result;
}
}

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2013 Nathan Ridge.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nathan Ridge - initial API
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
/**
* A generic unary predicate interface.
* Useful for operations that use unary predicates, like filtering an array.
* @since 5.6
*/
public interface IUnaryPredicate<T> {
boolean apply(T argument);
}

View file

@ -180,7 +180,9 @@ import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.CollectionUtils;
import org.eclipse.cdt.core.parser.util.DebugUtil;
import org.eclipse.cdt.core.parser.util.IUnaryPredicate;
import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
@ -597,10 +599,26 @@ public class CPPSemantics {
lookup(data, scope);
}
}
mergeResults(data, friendFns.toArray(), false);
Object[] matchingFriendFns = CollectionUtils.filter(
friendFns,
new NameMatcherPredicate(data.getLookupKey())).toArray();
mergeResults(data, matchingFriendFns, false);
data.qualified = originalQualified;
}
private static class NameMatcherPredicate implements IUnaryPredicate<ICPPFunction> {
private char[] fKey;
public NameMatcherPredicate(char[] key) {
fKey = key;
}
@Override
public boolean apply(ICPPFunction argument) {
return Arrays.equals(argument.getNameCharArray(), fKey);
}
}
static IBinding checkDeclSpecifier(IBinding binding, IASTName name, IASTNode decl) {
// Check for empty declaration specifiers.
if (!isCtorOrConversionOperator(binding)) {
@ -1262,29 +1280,17 @@ public class CPPSemantics {
}
if (data.ignoreRecursionResolvingBindings()) {
bindings = filterOutRecursionResovingBindings(bindings);
bindings = ArrayUtil.filter(bindings, new RecursionResolvingBindingFilter());
}
return expandUsingDeclarationsAndRemoveObjects(bindings, data);
}
private static IBinding[] filterOutRecursionResovingBindings(IBinding[] bindings) {
IBinding[] result = bindings;
int resultIndex = 0;
for (int i = 0; i < bindings.length; ++i) {
if (bindings[i] instanceof IRecursionResolvingBinding) {
if (result == bindings) {
result = new IBinding[bindings.length - 1];
System.arraycopy(bindings, 0, result, 0, i);
private static class RecursionResolvingBindingFilter implements IUnaryPredicate<IBinding> {
@Override
public boolean apply(IBinding argument) {
return !(argument instanceof IRecursionResolvingBinding);
}
} else {
if (result != bindings) {
result[resultIndex] = bindings[i];
}
++resultIndex;
}
}
return ArrayUtil.trim(result);
}
private static IBinding[] expandUsingDeclarationsAndRemoveObjects(final IBinding[] bindings,