Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2017-03-05 03:14:35 -0500
committerNathan Ridge2017-04-08 02:15:37 -0400
commite0e7f9c1d7b039b2c2a156f5ee73717615c8a4a9 (patch)
treef09b6d26f3c58d207971be075511b714236789fd
parentbe635f520a581a5341544265cfc496e134b5c5d9 (diff)
downloadorg.eclipse.cdt-e0e7f9c1d7b039b2c2a156f5ee73717615c8a4a9.tar.gz
org.eclipse.cdt-e0e7f9c1d7b039b2c2a156f5ee73717615c8a4a9.tar.xz
org.eclipse.cdt-e0e7f9c1d7b039b2c2a156f5ee73717615c8a4a9.zip
Bug 512932 - Name lookup for friend class
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java14
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java8
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java21
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java9
-rw-r--r--lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java2
14 files changed, 80 insertions, 14 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 59becb789f..d3cd674623 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -10586,6 +10586,20 @@ public class AST2CPPTests extends AST2TestBase {
public void testFriendConstructorDestructor_400940() throws Exception {
parseAndCheckBindings();
}
+
+ // namespace Hugo {
+ // class C {
+ // friend class Waldo;
+ // };
+ // }
+ // using namespace Hugo;
+ // class Waldo {};
+ // void foo() {
+ // Waldo c; // error here
+ // }
+ public void testFriendClassLookup_512932() throws Exception {
+ parseAndCheckBindings();
+ }
// struct S {
// virtual void mFuncDecl() final;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java
index 458a148b18..5f7324e6cb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java
@@ -114,6 +114,7 @@ public interface IScope {
private boolean fResolve= true;
private boolean fPrefixLookup;
private boolean fIgnorePointOfDeclaration;
+ private boolean fArgumentDependent;
public ScopeLookupData(IASTName name, boolean resolve, boolean prefixLookup) {
if (name == null)
@@ -162,6 +163,11 @@ public interface IScope {
public final void setIgnorePointOfDeclaration(boolean ignorePointOfDeclaration) {
fIgnorePointOfDeclaration = ignorePointOfDeclaration;
}
+
+ /** @since 6.3 */
+ public final void setArgumentDependent(boolean argumentDependent) {
+ fArgumentDependent = argumentDependent;
+ }
public final void setLookupKey(char[] key) {
fLookupKey= key;
@@ -187,6 +193,11 @@ public interface IScope {
return fIgnorePointOfDeclaration;
}
+ /** @since 6.3 */
+ public final boolean isArgumentDependent() {
+ return fArgumentDependent;
+ }
+
public final IIndexFileSet getIncludedFiles() {
return fTu == null ? IIndexFileSet.EMPTY : fTu.getIndexFileSet();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java
index a59a0152ce..2895ce1c15 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTInternal.java
@@ -91,8 +91,12 @@ public class ASTInternal {
}
public static void addName(IScope scope, IASTName name) {
+ addName(scope, name, /* adlOnly = */ false);
+ }
+
+ public static void addName(IScope scope, IASTName name, boolean adlOnly) {
if (scope instanceof IASTInternalScope) {
- ((IASTInternalScope) scope).addName(name);
+ ((IASTInternalScope) scope).addName(name, adlOnly);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java
index e8ff4c19d5..b22e5d9211 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalScope.java
@@ -31,9 +31,13 @@ public interface IASTInternalScope extends IScope {
public void addBinding(IBinding binding);
/**
- * Adds an IASTName to be cached in this scope
+ * Adds an IASTName to be cached in this scope.
+ * @param adlOnly whether this declaration of this name only makes the name visible to
+ * argument-dependent lookup
+ *
+ * Implementation note: only CPPNamespaceScope cares about "adlOnly".
*/
- public void addName(IASTName name);
+ public void addName(IASTName name, boolean adlOnly);
/**
* Can be called during ambiguity resolution to populate a scope without considering
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
index 5c875bb8f4..a6e3c032c0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
@@ -192,7 +192,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
}
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java
index faa972f7b8..9635347ccd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java
@@ -194,7 +194,7 @@ public class CScope implements ICScope, IASTInternalScope {
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
final char[] nchars = name.toCharArray();
if (nchars.length == 0)
return;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
index 53e47990dc..e2f04b0514 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java
@@ -212,7 +212,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
// Don't add names from inactive code branches.
if (!name.isActive())
return;
@@ -251,7 +251,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return;
}
}
- super.addName(name);
+ super.addName(name, adlOnly);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java
index 5fba88908d..068dd2a782 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java
@@ -29,7 +29,7 @@ public class CPPClassSpecializationScope extends AbstractCPPClassSpecializationS
// This scope does not cache its own names
@Override
- public void addName(IASTName name) {}
+ public void addName(IASTName name, boolean adlOnly) {}
@Override
public IASTNode getPhysicalNode() { return null; }
@Override
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
index a82e28c6b3..9161272250 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
@@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IIndexName;
+import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScopeMapper.InlineNamespaceDirective;
@@ -59,6 +60,9 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
private ICPPNamespaceScope[] fEnclosingNamespaceSet;
private List<ICPPASTNamespaceDefinition> fInlineNamespaceDefinitions;
private ICPPInternalNamespaceScope[] fInlineNamespaces;
+
+ // The set of names declared in this scope that are currently only visible to argument-dependent lookup.
+ private CharArraySet fVisibleToAdlOnly = new CharArraySet(0);
public CPPNamespaceScope(IASTNode physicalNode) {
super(physicalNode);
@@ -154,10 +158,23 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
if (name instanceof ICPPASTQualifiedName && !canDenoteNamespaceMember((ICPPASTQualifiedName) name))
return;
- super.addName(name);
+ super.addName(name, adlOnly);
+ if (adlOnly) {
+ fVisibleToAdlOnly.put(name.getLookupKey());
+ } else {
+ fVisibleToAdlOnly.remove(name.getLookupKey());
+ }
+ }
+
+ @Override
+ protected boolean nameIsVisibleToLookup(ScopeLookupData lookup) {
+ if (lookup.isArgumentDependent()) {
+ return true;
+ }
+ return !fVisibleToAdlOnly.containsKey(lookup.getLookupKey());
}
public boolean canDenoteNamespaceMember(ICPPASTQualifiedName name) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
index 0152fb0b17..badcb044d2 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
@@ -90,7 +90,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
@Override
@SuppressWarnings({ "unchecked" })
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
// Don't add inactive names to the scope.
if (!name.isActive())
return;
@@ -224,11 +224,18 @@ abstract public class CPPScope implements ICPPASTInternalScope {
return ArrayUtil.trim(IBinding.class, result);
}
+
+ protected boolean nameIsVisibleToLookup(ScopeLookupData lookup) {
+ return true;
+ }
public IBinding[] getBindingsInAST(ScopeLookupData lookup) {
populateCache();
final char[] c = lookup.getLookupKey();
IBinding[] result = IBinding.EMPTY_BINDING_ARRAY;
+ if (!nameIsVisibleToLookup(lookup)) {
+ return result;
+ }
Object obj = null;
if (lookup.isPrefixLookup()) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java
index c9696f4f20..e308094f3d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java
@@ -178,7 +178,7 @@ public class CPPUnknownTypeScope implements ICPPInternalUnknownScope {
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
}
protected IBinding getOrCreateBinding(final char[] name, int idx) {
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 1a37a1e4e1..0cba0c4389 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
@@ -631,6 +631,7 @@ public class CPPSemantics {
// don't ascend into enclosing scopes.
boolean originalQualified = data.qualified;
data.qualified = true;
+ data.setArgumentDependent(true);
Set<ICPPFunction> friendFns = new HashSet<>(2);
Set<ICPPNamespaceScope> associated = getAssociatedScopes(data, friendFns);
for (ICPPNamespaceScope scope : associated) {
@@ -643,6 +644,7 @@ public class CPPSemantics {
new NameMatcherPredicate(data.getLookupKey())).toArray();
mergeResults(data, matchingFriendFns, false);
data.qualified = originalQualified;
+ data.setArgumentDependent(false);
}
private static class NameMatcherPredicate implements IUnaryPredicate<ICPPFunction> {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index 013da7a435..4b3672c057 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -550,7 +550,14 @@ public class CPPVisitor extends ASTQueries {
binding = new CPPClassType(name, binding);
}
// Name may live in a different scope, so make sure to add it to the owner scope as well.
- ASTInternal.addName(scope, elabType.getName());
+ // [namespace.memdef] p3:
+ // "If a friend declaration in a non-local class first declares a
+ // class, function, class template or function template the friend
+ // is a member of the innermost enclosing namespace. The friend
+ // declaration does not by itself make the name visible to
+ // unqualified lookup or qualified lookup."
+ boolean visibleToAdlOnly = isFriend;
+ ASTInternal.addName(scope, elabType.getName(), visibleToAdlOnly);
}
} catch (DOMException e) {
binding = e.getProblem();
diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java
index 33eb1b9f54..5c55059108 100644
--- a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java
+++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java
@@ -96,7 +96,7 @@ public class C99Scope implements IC99Scope, IASTInternalScope {
}
@Override
- public void addName(IASTName name) {
+ public void addName(IASTName name, boolean adlOnly) {
throw new UnsupportedOperationException();
}

Back to the top