1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-05 08:05:24 +02:00

Bug 530430 - Proper handling of class initially declared as a friend

When a subsequent regular (non-friend) declaration of such a class
is indexed, the index binding needs to be marked as being fully
visible to name lookup.

Change-Id: I1a625f93eda1af257a9af50b5c4f115fc9bf6526
This commit is contained in:
Nathan Ridge 2018-01-31 01:03:09 -05:00
parent 1566253cb8
commit 5fe2be43e7
6 changed files with 61 additions and 3 deletions

View file

@ -362,4 +362,24 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
public void testAliasTemplateReferencingSameName_518937() throws Exception { public void testAliasTemplateReferencingSameName_518937() throws Exception {
checkBindings(); checkBindings();
} }
//h1.h
// class A {
// friend class B1;
// };
//s1.cpp
// #include "h1.h"
//h2.h
// class B1 {};
// class B2 {};
//s2.cpp *
// #include "h2.h"
// B1 b1;
// B2 b2;
public void testClassFirstDeclaredAsFriend_530430() throws Exception {
checkBindings();
}
} }

View file

@ -56,7 +56,7 @@ public interface IName {
public boolean isReference(); public boolean isReference();
/** /**
* Is this name being used in the AST as a reference rather than a declaration? * Is this name being used in the AST as a definition rather than a declaration?
* @return boolean * @return boolean
*/ */
public boolean isDefinition(); public boolean isDefinition();

View file

@ -46,5 +46,11 @@ public interface IPDOMCPPClassType extends ICPPClassType, IPDOMBinding, IIndexTy
* A class type is visible to ADL only if it's only declaration so far * A class type is visible to ADL only if it's only declaration so far
* is a friend declaration inside another class. * is a friend declaration inside another class.
*/ */
default boolean isVisibleToAdlOnly() { return false; } boolean isVisibleToAdlOnly();
/**
* Set whether this class type is visible to ADL only.
* See isVisibleToAdlOnly().
*/
void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException;
} }

View file

@ -558,4 +558,15 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization
return v_private; // Fallback visibility return v_private; // Fallback visibility
} }
} }
// Class specializations do not need to be marked "visible to ADL only"
// independent of their specialized class types, so they do not need
// to implement these methods.
@Override
public boolean isVisibleToAdlOnly() {
return false;
}
@Override
public void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException {
}
} }

View file

@ -110,7 +110,8 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
getDB().putByte(record + FINAL, (byte) (ct.isFinal() ? 1 : 0)); getDB().putByte(record + FINAL, (byte) (ct.isFinal() ? 1 : 0));
} }
private void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException { @Override
public void setVisibleToAdlOnly(boolean visibleToAdlOnly) throws CoreException {
getDB().putByte(record + VISIBLE_TO_ADL_ONLY, (byte) (visibleToAdlOnly ? 1 : 0)); getDB().putByte(record + VISIBLE_TO_ADL_ONLY, (byte) (visibleToAdlOnly ? 1 : 0));
} }

View file

@ -635,6 +635,26 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
addImplicitMethods(pdomBinding, (ICPPClassType) binding); addImplicitMethods(pdomBinding, (ICPPClassType) binding);
} }
} }
// If we have a non-friend declaration of a class type, mark the class type
// as being fully visible (not just visible to ADL only). This is important
// in case the first declaration of the class type was a friend declaration,
// in which case it was initially marked as visible to ADL only.
if (pdomBinding instanceof IPDOMCPPClassType && (name.isDeclaration() || name.isDefinition())) {
boolean declaresFriend = false;
IASTNode parent = name.getParent();
if (parent instanceof ICPPASTQualifiedName) {
parent = parent.getParent();
}
if (parent instanceof ICPPASTElaboratedTypeSpecifier) {
if (((ICPPASTElaboratedTypeSpecifier) parent).isFriend()) {
declaresFriend = true;
}
}
if (!declaresFriend) {
((IPDOMCPPClassType) pdomBinding).setVisibleToAdlOnly(false);
}
}
// Some of the nodes created during addImplicitMethods() can // Some of the nodes created during addImplicitMethods() can
// also schedule post-processes, so we need to run through // also schedule post-processes, so we need to run through