diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java index 08dabb7ad36..4b4b130acd0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/BindingCollector.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.pdom.dom.cpp.IPDOMCPPClassType; import org.eclipse.core.runtime.CoreException; /** @@ -70,6 +71,13 @@ public final class BindingCollector extends NamedNodeCollector { } } } + if (tBinding instanceof IPDOMCPPClassType) { + // Skip bindings that are visible to ADL only. + // TODO(nathanridge): Check if we're doing ADL, and accept it in that case. + if (((IPDOMCPPClassType) tBinding).isVisibleToAdlOnly()) { + return true; + } + } if (filter == null || filter.acceptBinding((IBinding) tBinding)) { return super.addNode(tBinding); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPClassType.java index 996e4d62572..9efb5691307 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/IPDOMCPPClassType.java @@ -40,4 +40,11 @@ public interface IPDOMCPPClassType extends ICPPClassType, IPDOMBinding, IIndexTy * @param visibility The visibility of the member. */ void addMember(PDOMNode member, int visibility) throws CoreException; + + /** + * Returns true if this class type is visible to ADL only. + * A class type is visible to ADL only if it's only declaration so far + * is a friend declaration inside another class. + */ + default boolean isVisibleToAdlOnly() { return false; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java index 2789171a391..56886cbda20 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java @@ -60,9 +60,10 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType private volatile ICPPTemplateParameter[] params; // Cached template parameters. - public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template) + public PDOMCPPClassTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplate template, + boolean visibleToAdlOnly) throws CoreException, DOMException { - super(linkage, parent, template); + super(linkage, parent, template, visibleToAdlOnly); final Database db = getDB(); ICPPTemplateParameter[] origParams= template.getTemplateParameters(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java index 4c7d96a7052..27084e9ee4d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java @@ -49,7 +49,7 @@ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate public PDOMCPPClassTemplatePartialSpecialization(PDOMCPPLinkage linkage, PDOMNode parent, ICPPClassTemplatePartialSpecialization partial, PDOMCPPClassTemplate primary) throws CoreException, DOMException { - super(linkage, parent, partial); + super(linkage, parent, partial, false); getDB().putRecPtr(record + PRIMARY, primary.getRecord()); primary.addPartial(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 1cb07ac3874..a8f4cad182d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -56,17 +56,20 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO private static final int KEY = FIRSTFRIEND + 4; // byte private static final int ANONYMOUS = KEY + 1; // byte private static final int FINAL = ANONYMOUS + 1; // byte + private static final int VISIBLE_TO_ADL_ONLY = FINAL + 1; // byte @SuppressWarnings("hiding") - protected static final int RECORD_SIZE = FINAL + 1; + protected static final int RECORD_SIZE = VISIBLE_TO_ADL_ONLY + 1; private PDOMCPPClassScope fScope; // No need for volatile, all fields of PDOMCPPClassScope are final. - public PDOMCPPClassType(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType) throws CoreException { + public PDOMCPPClassType(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, + boolean visibleToAdlOnly) throws CoreException { super(linkage, parent, classType.getNameCharArray()); setKind(classType); setAnonymous(classType); setFinal(classType); + setVisibleToAdlOnly(visibleToAdlOnly); // Linked list is initialized by storage being zero'd by malloc. } @@ -106,6 +109,10 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO private void setFinal(ICPPClassType ct) throws CoreException { getDB().putByte(record + FINAL, (byte) (ct.isFinal() ? 1 : 0)); } + + private void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException { + getDB().putByte(record + VISIBLE_TO_ADL_ONLY, (byte) (visibleToAdlOnly ? 1 : 0)); + } @Override public boolean mayHaveChildren() { @@ -268,6 +275,16 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO return false; } } + + @Override + public boolean isVisibleToAdlOnly() { + try { + return getDB().getByte(record + VISIBLE_TO_ADL_ONLY) != 0; + } catch (CoreException e) { + CCorePlugin.log(e); + return false; + } + } @Override public boolean isSameType(IType type) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index a79dd854fcd..6612330bf08 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -796,13 +796,12 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { // name is not found by name lookup until a matching declaration is provided in the innermost // enclosing nonclass scope. // See http://bugs.eclipse.org/508338 - if (!(binding instanceof ICPPInternalBinding) - || ASTInternal.hasNonFriendDeclaration((ICPPInternalBinding) binding)) { - if (binding instanceof ICPPClassTemplate) { - pdomBinding= new PDOMCPPClassTemplate(this, parent, (ICPPClassTemplate) binding); - } else { - pdomBinding= new PDOMCPPClassType(this, parent, (ICPPClassType) binding); - } + boolean visibleToAdlOnly = (binding instanceof ICPPInternalBinding) + && !ASTInternal.hasNonFriendDeclaration((ICPPInternalBinding) binding); + if (binding instanceof ICPPClassTemplate) { + pdomBinding= new PDOMCPPClassTemplate(this, parent, (ICPPClassTemplate) binding, visibleToAdlOnly); + } else { + pdomBinding= new PDOMCPPClassType(this, parent, (ICPPClassType) binding, visibleToAdlOnly); } } else if (binding instanceof ICPPVariableTemplate) { pdomBinding = new PDOMCPPVariableTemplate(this, parent, (ICPPVariableTemplate) binding); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 2ceb03dddd6..ebe55719a8f 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -220,7 +220,7 @@ public class CompletionTests extends CompletionTestBase { } //class _friend_class { C3* x; void m() {x->m/*cursor*/ - public void DISABLED_Bug_515417_testTypes_FriendClass() throws Exception { + public void testTypes_FriendClass() throws Exception { final String[] expected= { "m123(void)", "m12(void)", "m13(void)", "m23(void)", "m1protected(void)", "m2protected(void)", "m2private(void)"