diff options
author | Nathan Ridge | 2016-12-27 23:38:50 +0000 |
---|---|---|
committer | Nathan Ridge | 2017-01-11 01:55:18 +0000 |
commit | fbbed5cf82b69c285714cbeae26d2fd4155f88d4 (patch) | |
tree | 89ba8cda279fe73a364baef201750db0415cd805 /core | |
parent | 86ab2bdefcccb1ecbaf9bbc2ae060e07dfa4c2b9 (diff) | |
download | org.eclipse.cdt-fbbed5cf82b69c285714cbeae26d2fd4155f88d4.tar.gz org.eclipse.cdt-fbbed5cf82b69c285714cbeae26d2fd4155f88d4.tar.xz org.eclipse.cdt-fbbed5cf82b69c285714cbeae26d2fd4155f88d4.zip |
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
Diffstat (limited to 'core')
2 files changed, 46 insertions, 2 deletions
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 dbf8ad5df66..23d52d1aaff 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 @@ -165,6 +165,29 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase { } // 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 // template <typename T> // struct atomic; // @@ -209,5 +232,4 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase { // This code is invalid, so we don't checkBindings(). // If the test gets this far (doesn't throw in setup() during indexing), it passes. } - } 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 d75ed6a77c4..14c71b4773c 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 @@ -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.ICPPFunction; 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.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; @@ -3714,7 +3715,7 @@ public class CPPSemantics { Object item = items[i]; items[i]= null; if (item instanceof IIndexBinding) { - if (!fileSet.containsDeclaration((IIndexBinding) item)) { + if (!indexBindingIsReachable(fileSet, (IIndexBinding) item)) { continue; } } @@ -3826,6 +3827,27 @@ public class CPPSemantics { 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) { IType[] parms = new IType[parameterTypes.length + 1]; ICPPParameter[] theParms = new ICPPParameter[parms.length]; |