1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-21 16:05:25 +02:00

Bug 509662 - Friend function declared in header included at non-global scope

This fix is a hacky workaround. A proper fix involves fixing bug 315964.

Change-Id: I733064fe3aa0d9416854954ef3e3a8250566dac1
This commit is contained in:
Nathan Ridge 2016-12-27 18:38:50 -05:00
parent 86ab2bdefc
commit fbbed5cf82
2 changed files with 46 additions and 2 deletions

View file

@ -164,6 +164,29 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
checkBindings(); checkBindings();
} }
// test.h
// friend int operator*(double, C) { return 0; }
// test.cpp *
// namespace N {
//
// struct unrelated {};
//
// struct B {
// friend int operator*(unrelated, unrelated) { return 0; }
// };
// }
//
// template <typename = int>
// struct C : public N::B {
// #include "test.h"
// };
// template <typename> struct Waldo;
// Waldo<decltype(0.5 * C<>{})> w;
public void testFriendFunctionInHeaderIncludedAtClassScope_509662() throws Exception {
checkBindings();
}
// test.h // test.h
// template <typename T> // template <typename T>
// struct atomic; // struct atomic;
@ -209,5 +232,4 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
// This code is invalid, so we don't checkBindings(). // This code is invalid, so we don't checkBindings().
// If the test gets this far (doesn't throw in setup() during indexing), it passes. // If the test gets this far (doesn't throw in setup() during indexing), it passes.
} }
} }

View file

@ -153,6 +153,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; 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.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
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.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
@ -3714,7 +3715,7 @@ public class CPPSemantics {
Object item = items[i]; Object item = items[i];
items[i]= null; items[i]= null;
if (item instanceof IIndexBinding) { if (item instanceof IIndexBinding) {
if (!fileSet.containsDeclaration((IIndexBinding) item)) { if (!indexBindingIsReachable(fileSet, (IIndexBinding) item)) {
continue; continue;
} }
} }
@ -3826,6 +3827,27 @@ public class CPPSemantics {
return null; return null;
} }
private static boolean indexBindingIsReachable(IIndexFileSet fileSet, IIndexBinding item) {
if (fileSet.containsDeclaration(item)) {
return true;
}
// Specializations of friend functions are sometimes created in the context
// of the file for which the AST is created, and which is thus not in the index
// file set. In some cases, an AST binding cannot be created for such
// specializations. To support these cases, consider the binding reachable if
// the friend function being specialized is reachable.
// This situation only arises in the presence of #includes that are not at
// global scope. Once bug 315964 is fixed, this workaround can be removed.
if (item instanceof ICPPFunctionSpecialization && !(item instanceof ICPPFunctionInstance)) {
IBinding specialized = ((ICPPFunctionSpecialization) item).getSpecializedBinding();
return !(specialized instanceof IIndexBinding)
|| fileSet.containsDeclaration((IIndexBinding) specialized);
}
return false;
}
private static IBinding createSurrogateCallFunction(IScope scope, IType returnType, IType rt, IType[] parameterTypes) { private static IBinding createSurrogateCallFunction(IScope scope, IType returnType, IType rt, IType[] parameterTypes) {
IType[] parms = new IType[parameterTypes.length + 1]; IType[] parms = new IType[parameterTypes.length + 1];
ICPPParameter[] theParms = new ICPPParameter[parms.length]; ICPPParameter[] theParms = new ICPPParameter[parms.length];