mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
fix bug 86688 - friend declaration in local class
This commit is contained in:
parent
cf09e84a32
commit
cbd0d0ef66
2 changed files with 73 additions and 1 deletions
|
@ -4822,4 +4822,28 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
IFunction free = (IFunction) col.getName(0).resolveBinding();
|
IFunction free = (IFunction) col.getName(0).resolveBinding();
|
||||||
assertSame( free, col.getName(4).resolveBinding() );
|
assertSame( free, col.getName(4).resolveBinding() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug86688() throws Exception {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
buffer.append("class X; \n");
|
||||||
|
buffer.append("void f() { \n");
|
||||||
|
buffer.append(" class A { \n");
|
||||||
|
buffer.append(" friend class X; \n");
|
||||||
|
buffer.append(" }; \n");
|
||||||
|
buffer.append("} \n");
|
||||||
|
buffer.append("namespace B { \n");
|
||||||
|
buffer.append(" class A { \n");
|
||||||
|
buffer.append(" friend class X; \n");
|
||||||
|
buffer.append(" }; \n");
|
||||||
|
buffer.append("} \n");
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP, true, true );
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept( col );
|
||||||
|
|
||||||
|
ICPPClassType X = (ICPPClassType) col.getName(0).resolveBinding();
|
||||||
|
assertNotSame( X, col.getName(3).resolveBinding() );
|
||||||
|
assertTrue( col.getName(3).resolveBinding() instanceof ICPPClassType );
|
||||||
|
assertSame( X, col.getName(6).resolveBinding() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -382,6 +382,42 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
return implied;
|
return implied;
|
||||||
}
|
}
|
||||||
|
public boolean forFriendship() {
|
||||||
|
if( astName == null )
|
||||||
|
return false;
|
||||||
|
IASTNode node = astName.getParent();
|
||||||
|
while( node instanceof IASTName )
|
||||||
|
node = node.getParent();
|
||||||
|
|
||||||
|
IASTDeclaration decl = null;
|
||||||
|
IASTDeclarator dtor = null;
|
||||||
|
if( node instanceof ICPPASTDeclSpecifier && node.getParent() instanceof IASTDeclaration ){
|
||||||
|
decl = (IASTDeclaration) node.getParent();
|
||||||
|
} else if( node instanceof IASTDeclarator ) {
|
||||||
|
dtor = (IASTDeclarator) node;
|
||||||
|
while( dtor.getParent() instanceof IASTDeclarator )
|
||||||
|
dtor = (IASTDeclarator) dtor.getParent();
|
||||||
|
if( !(dtor.getParent() instanceof IASTDeclaration) )
|
||||||
|
return false;
|
||||||
|
decl = (IASTDeclaration) dtor.getParent();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if( decl instanceof IASTSimpleDeclaration ){
|
||||||
|
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) decl;
|
||||||
|
if( ! ((ICPPASTDeclSpecifier)simple.getDeclSpecifier()).isFriend() )
|
||||||
|
return false;
|
||||||
|
if( dtor != null )
|
||||||
|
return true;
|
||||||
|
return simple.getDeclarators().length == 0;
|
||||||
|
} else if( decl instanceof IASTFunctionDefinition ){
|
||||||
|
IASTFunctionDefinition fnDef = (IASTFunctionDefinition) decl;
|
||||||
|
if( ! ((ICPPASTDeclSpecifier)fnDef.getDeclSpecifier()).isFriend() )
|
||||||
|
return false;
|
||||||
|
return ( dtor != null );
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static protected class Cost
|
static protected class Cost
|
||||||
|
@ -871,6 +907,15 @@ public class CPPSemantics {
|
||||||
else
|
else
|
||||||
scope = getLookupScope( (IASTName) start );
|
scope = getLookupScope( (IASTName) start );
|
||||||
|
|
||||||
|
boolean friendInLocalClass = false;
|
||||||
|
if( scope instanceof ICPPClassScope && data.forFriendship() ){
|
||||||
|
try {
|
||||||
|
ICPPClassType cls = ((ICPPClassScope)scope).getClassType();
|
||||||
|
friendInLocalClass = !cls.isGloballyQualified();
|
||||||
|
} catch ( DOMException e ){
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while( scope != null ){
|
while( scope != null ){
|
||||||
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
|
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
|
||||||
|
|
||||||
|
@ -926,8 +971,11 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !data.prefixLookup && (data.problem != null || data.hasResults()) )
|
if( (!data.prefixLookup && (data.problem != null || data.hasResults())) ||
|
||||||
|
( friendInLocalClass && !(scope instanceof ICPPClassScope) ) )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !data.usingDirectivesOnly && scope instanceof ICPPClassScope ){
|
if( !data.usingDirectivesOnly && scope instanceof ICPPClassScope ){
|
||||||
mergeResults( data, lookupInParents( data, scope ), true );
|
mergeResults( data, lookupInParents( data, scope ), true );
|
||||||
|
|
Loading…
Add table
Reference in a new issue