1
0
Fork 0
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:
Andrew Niefer 2005-06-23 17:36:30 +00:00
parent cf09e84a32
commit cbd0d0ef66
2 changed files with 73 additions and 1 deletions

View file

@ -4822,4 +4822,28 @@ public class AST2CPPTests extends AST2BaseTest {
IFunction free = (IFunction) col.getName(0).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() );
}
}

View file

@ -382,6 +382,42 @@ public class CPPSemantics {
}
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
@ -871,6 +907,15 @@ public class CPPSemantics {
else
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 ){
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;
}
if( !data.usingDirectivesOnly && scope instanceof ICPPClassScope ){
mergeResults( data, lookupInParents( data, scope ), true );