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:
parent
1566253cb8
commit
5fe2be43e7
6 changed files with 61 additions and 3 deletions
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -636,6 +636,26 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
// them again.
|
// them again.
|
||||||
|
|
Loading…
Add table
Reference in a new issue