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:
parent
86ab2bdefc
commit
fbbed5cf82
2 changed files with 46 additions and 2 deletions
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Add table
Reference in a new issue