Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2016-12-27 23:38:50 +0000
committerNathan Ridge2017-01-11 01:55:18 +0000
commitfbbed5cf82b69c285714cbeae26d2fd4155f88d4 (patch)
tree89ba8cda279fe73a364baef201750db0415cd805 /core
parent86ab2bdefcccb1ecbaf9bbc2ae060e07dfa4c2b9 (diff)
downloadorg.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')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexMultiFileTest.java24
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java24
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];

Back to the top