[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] Bug48307 - friendship needs to be handled better
|
This patch addresses friend functions with changes to the the parser and
symbol table.
Core:
Added IDerivableContainerSymbol.lookupFunctionForFriendship.
Modified IASTFactory.createMethod to take an ITokenDuple for the
method name.
Added LookupType.FORFRIENDSHIP and use it in LookupElement.
Modified CompleteParseASTFactory.createMethod to handle friend
functions.
Tests:
Added CompleteParseASTTest::testBug48307_FriendFunction_1
Added CompleteParseASTTest::testBug48307_FriendFunction_2
Tested on Windows.
-Andrew
Index: parser/ChangeLog-parser
===================================================================
retrieving revision 1.14
diff -u -r1.14 ChangeLog-parser
--- parser/ChangeLog-parser 7 Jan 2004 02:00:17 -0000 1.14
+++ parser/ChangeLog-parser 8 Jan 2004 15:24:03 -0000
@@ -1,3 +1,10 @@
+2004-01-08 Andrew Niefer
+ Fixing 48307 - PST: Friendship needs to be handled better
+ Added IDerivableContainerSymbol.lookupFunctionForFriendship.
+ Modified IASTFactory.createMethod to take an ITokenDuple for the method name.
+ Added LookupType.FORFRIENDSHIP and use it in LookupElement.
+ Modified CompleteParseASTFactory.createMethod to handle friend functions.
+
2004-01-06 Andrew Niefer
For Content Assist, support lookup using LookupKind.THIS (lookup in the class of the this pointer )
Fix bug where forward declared method/functions appeared twice in the content assist lookup results.
Index: parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java
===================================================================
retrieving revision 1.44
diff -u -r1.44 IASTFactory.java
--- parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java 6 Jan 2004 15:26:41 -0000 1.44
+++ parser/org/eclipse/cdt/core/parser/ast/IASTFactory.java 8 Jan 2004 15:24:04 -0000
@@ -180,7 +180,7 @@
public IASTMethod createMethod(
IASTScope scope,
- String name,
+ ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
Index: parser/org/eclipse/cdt/internal/core/parser/DeclarationWrapper.java
===================================================================
retrieving revision 1.28
diff -u -r1.28 DeclarationWrapper.java
--- parser/org/eclipse/cdt/internal/core/parser/DeclarationWrapper.java 6 Jan 2004 15:26:41 -0000 1.28
+++ parser/org/eclipse/cdt/internal/core/parser/DeclarationWrapper.java 8 Jan 2004 15:24:07 -0000
@@ -463,7 +463,7 @@
return astFactory
.createMethod(
scope,
- nested ? declarator.getOwnedDeclarator().getName() : declarator.getName(),
+ nested ? declarator.getOwnedDeclarator().getNameDuple() : declarator.getNameDuple(),
createParameterList(declarator.getParameters()),
astFactory.createAbstractDeclaration(
constt,
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java
===================================================================
retrieving revision 1.62
diff -u -r1.62 CompleteParseASTFactory.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 6 Jan 2004 15:26:41 -0000 1.62
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java 8 Jan 2004 15:24:10 -0000
@@ -107,6 +107,7 @@
public static final LookupType QUALIFIED = new LookupType( 1 );
public static final LookupType UNQUALIFIED = new LookupType( 2 );
public static final LookupType FORDEFINITION = new LookupType( 3 );
+ public static final LookupType FORFRIENDSHIP = new LookupType( 4 );
private LookupType( int constant)
{
@@ -174,8 +175,11 @@
result = startingScope.qualifiedFunctionLookup(name, new LinkedList(parameters));
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.unqualifiedFunctionLookup( name, new LinkedList( parameters ) );
- else
+ else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMethodForDefinition( name, new LinkedList( parameters ) );
+ else if( lookupType == LookupType.FORFRIENDSHIP ){
+ result = ((IDerivableContainerSymbol)startingScope).lookupFunctionForFriendship( name, new LinkedList( parameters) );
+ }
}
else
result = null;
@@ -185,8 +189,10 @@
result = startingScope.qualifiedLookup(name, type);
else if( lookupType == LookupType.UNQUALIFIED )
result = startingScope.elaboratedLookup( type, name );
- else
+ else if( lookupType == LookupType.FORDEFINITION )
result = startingScope.lookupMemberForDefinition( name );
+ else if( lookupType == LookupType.FORFRIENDSHIP )
+ result = ((IDerivableContainerSymbol)startingScope).lookupForFriendship( name );
}
} catch (ParserSymbolTableException e) {
if( e.reason != ParserSymbolTableException.r_UnableToResolveFunction )
@@ -1622,7 +1628,7 @@
name.length() - 1 );
return createMethod(
methodParentScope,
- newName.toString(),
+ newName,
parameters,
returnType,
exception,
@@ -1876,7 +1882,7 @@
public IASTMethod createMethod(
IASTScope scope,
- String name,
+ ITokenDuple name,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
@@ -1902,7 +1908,7 @@
public IASTMethod createMethod(
IASTScope scope,
- String name,
+ ITokenDuple nameDuple,
List parameters,
IASTAbstractDeclaration returnType,
IASTExceptionSpecification exception,
@@ -1926,7 +1932,7 @@
boolean isDestructor = false;
IContainerSymbol ownerScope = scopeToSymbol( scope );
- IParameterizedSymbol symbol = pst.newParameterizedSymbol( name, TypeInfo.t_function );
+ IParameterizedSymbol symbol = pst.newParameterizedSymbol( nameDuple.toString(), TypeInfo.t_function );
setFunctionTypeInfoBits(isInline, isFriend, isStatic, symbol);
setMethodTypeInfoBits( symbol, isConst, isVolatile, isVirtual, isExplicit );
if(references == null)
@@ -1943,9 +1949,9 @@
if(parentName.indexOf(DOUBLE_COLON) != -1){
parentName = parentName.substring(parentName.lastIndexOf(DOUBLE_COLON) + DOUBLE_COLON.length());
}
- if( parentName.equals(name) ){
+ if( parentName.equals(nameDuple.toString()) ){
isConstructor = true;
- } else if(name.startsWith(TELTA) && parentName.equals(name.substring(1))){
+ } else if(nameDuple.getFirstToken().getType() == IToken.tCOMPL && parentName.equals(nameDuple.getLastToken().getImage())){
isDestructor = true;
}
}
@@ -1953,7 +1959,9 @@
symbol.setIsForwardDeclaration(!isFunctionDefinition);
boolean previouslyDeclared = false;
- if( isFunctionDefinition )
+ IParameterizedSymbol functionDeclaration = null;
+
+ if( isFunctionDefinition || isFriend )
{
List functionParameters = new LinkedList();
// the lookup requires a list of type infos
@@ -1964,15 +1972,34 @@
functionParameters.add(param.getSymbol().getTypeInfo());
}
- IParameterizedSymbol functionDeclaration = null;
-
List functionReferences = new ArrayList();
- functionDeclaration =
- (IParameterizedSymbol) lookupQualifiedName(ownerScope, name, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
-
- if( functionDeclaration != null )
+
+ if( isFriend )
+ {
+ functionDeclaration =
+ (IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple, isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, functionReferences, false, LookupType.FORFRIENDSHIP );
+ } else {
+ functionDeclaration =
+ (IParameterizedSymbol) lookupQualifiedName(ownerScope, nameDuple.toString(), isConstructor ? TypeInfo.t_constructor : TypeInfo.t_function, functionParameters, 0, functionReferences, false, LookupType.FORDEFINITION );
+ }
+
+ previouslyDeclared = ( functionDeclaration != null );
+
+ if( isFriend )
+ {
+ if( functionDeclaration != null )
+ {
+ symbol.setTypeSymbol( functionDeclaration );
+ // friend declaration, has no real visibility, set private
+ visibility = ASTAccessVisibility.PRIVATE;
+ } else
+ {
+ //for a friend function declaration, if there is no prior declaration, the program is illformed
+ throw new ASTSemanticException();
+ }
+
+ } else if( functionDeclaration != null )
{
- previouslyDeclared = true;
functionDeclaration.setTypeSymbol( symbol );
// set the definition visibility = declaration visibility
ASTMethodReference reference = (ASTMethodReference) functionReferences.iterator().next();
@@ -1982,7 +2009,10 @@
try
{
- if( !isConstructor )
+ if( isFriend )
+ {
+ ((IDerivableContainerSymbol)ownerScope).addFriend( functionDeclaration );
+ } else if( !isConstructor )
ownerScope.addSymbol( symbol );
else
{
Index: parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java
===================================================================
retrieving revision 1.44
diff -u -r1.44 QuickParseASTFactory.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java 6 Jan 2004 15:26:41 -0000 1.44
+++ parser/org/eclipse/cdt/internal/core/parser/ast/quick/QuickParseASTFactory.java 8 Jan 2004 15:24:11 -0000
@@ -193,9 +193,9 @@
/* (non-Javadoc)
* @see org.eclipse.cdt.core.parser.ast.IASTFactory#createMethod(org.eclipse.cdt.core.parser.ast.IASTScope, java.lang.String, java.util.List, org.eclipse.cdt.core.parser.ast.IASTAbstractDeclaration, org.eclipse.cdt.core.parser.ast.IASTExceptionSpecification, boolean, boolean, boolean, int, int, org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration, boolean, boolean, boolean, boolean, boolean, boolean, boolean, org.eclipse.cdt.core.parser.ast.ASTAccessVisibility)
*/
- public IASTMethod createMethod(IASTScope scope, String name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments )
+ public IASTMethod createMethod(IASTScope scope, ITokenDuple name, List parameters, IASTAbstractDeclaration returnType, IASTExceptionSpecification exception, boolean isInline, boolean isFriend, boolean isStatic, int startOffset, int nameOffset, int nameEndOffset, IASTTemplate ownerTemplate, boolean isConst, boolean isVolatile, boolean isVirtual, boolean isExplicit, boolean isPureVirtual, ASTAccessVisibility visibility, List constructorChain, boolean isFunctionDefinition, boolean hasFunctionTryBlock, boolean hasVariableArguments )
{
- return new ASTMethod(scope, name, nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, hasVariableArguments);
+ return new ASTMethod(scope, name.toString(), nameEndOffset, parameters, returnType, exception, isInline, isFriend, isStatic, startOffset, nameOffset, ownerTemplate, isConst, isVolatile, false, false, isVirtual, isExplicit, isPureVirtual, visibility, constructorChain, hasFunctionTryBlock, hasVariableArguments);
}
/* (non-Javadoc)
Index: parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java
===================================================================
retrieving revision 1.3
diff -u -r1.3 DerivableContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java 17 Dec 2003 20:51:39 -0000 1.3
+++ parser/org/eclipse/cdt/internal/core/parser/pst/DerivableContainerSymbol.java 8 Jan 2004 15:24:11 -0000
@@ -287,6 +287,25 @@
return ParserSymbolTable.resolveAmbiguities( data );
}
+ public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException{
+ LookupData data = new LookupData( name, TypeInfo.t_any, getTemplateInstance() );
+
+ data.parameters = parameters;
+
+ IContainerSymbol enclosing = getContainingSymbol();
+ if( enclosing != null && enclosing.isType( TypeInfo.t_namespace, TypeInfo.t_union ) ){
+ while( enclosing != null && ( enclosing.getType() != TypeInfo.t_namespace) )
+ {
+ enclosing = enclosing.getContainingSymbol();
+ }
+ }
+ data.stopAt = enclosing;
+
+ ParserSymbolTable.lookup( data, this );
+ return (IParameterizedSymbol) ParserSymbolTable.resolveAmbiguities( data );
+ }
+
+
public List getFriends(){
if( _friends == null ){
_friends = new LinkedList();
Index: parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java
===================================================================
retrieving revision 1.8
diff -u -r1.8 IDerivableContainerSymbol.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java 17 Dec 2003 20:51:39 -0000 1.8
+++ parser/org/eclipse/cdt/internal/core/parser/pst/IDerivableContainerSymbol.java 8 Jan 2004 15:24:11 -0000
@@ -40,6 +40,8 @@
public void addFriend( ISymbol friend ) throws ParserSymbolTableException;
public ISymbol lookupForFriendship( String name ) throws ParserSymbolTableException;
+ public IParameterizedSymbol lookupFunctionForFriendship( String name, List parameters ) throws ParserSymbolTableException;
+
public List getFriends();
public interface IParentSymbol{
Index: ChangeLog
===================================================================
retrieving revision 1.161
diff -u -r1.161 ChangeLog
--- ChangeLog 7 Jan 2004 02:00:22 -0000 1.161
+++ ChangeLog 8 Jan 2004 15:23:24 -0000
@@ -1,3 +1,7 @@
+2004-01-08 Andrew Niefer
+ Added CompleteParseASTTest::testBug48307_FriendFunction_1
+ Added CompleteParseASTTest::testBug48307_FriendFunction_2
+
2004-01-06 Andrew Niefer
Added ContextualParseTest::testCompletionLookup_LookupKindTHIS
Index: parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java
===================================================================
retrieving revision 1.45
diff -u -r1.45 CompleteParseASTTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 6 Jan 2004 15:26:48 -0000 1.45
+++ parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java 8 Jan 2004 15:23:27 -0000
@@ -32,6 +32,7 @@
import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTReference;
import org.eclipse.cdt.core.parser.ast.IASTScope;
@@ -41,6 +42,7 @@
import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTVariableReference;
+import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
import org.eclipse.cdt.internal.core.parser.ParserException;
@@ -1112,5 +1114,49 @@
Iterator i = parse(buffer.toString() ).getDeclarations();
while( i.hasNext() )
assertTrue( ((IASTFunction)i.next()).takesVarArgs() );
+ }
+
+ public void testBug48307_FriendFunction_1() throws Exception {
+ StringWriter writer = new StringWriter();
+ writer.write( "class A{ public : void foo(); }; " );
+ writer.write( "class B{ ");
+ writer.write( " private : int aPrivate;" );
+ writer.write( " friend void A::foo(); ");
+ writer.write( "};" );
+ writer.write( "void A::foo(){}" );
+
+ Iterator i = parse( writer.toString() ).getDeclarations();
+
+ IASTClassSpecifier classA = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
+ IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
+ IASTMethod method = (IASTMethod) i.next();
+
+ LookupResult result = method.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
+
+ assertEquals( result.getResultsSize(), 1 );
+ IASTField field = (IASTField) result.getNodes().next();
+ assertEquals( field.getName(), "aPrivate" );
+ }
+
+ public void testBug48307_FriendFunction_2() throws Exception {
+ StringWriter writer = new StringWriter();
+ writer.write( "void global();" );
+ writer.write( "class B{ ");
+ writer.write( " private : int aPrivate;" );
+ writer.write( " friend void global(); ");
+ writer.write( "};" );
+ writer.write( "void global(){}" );
+
+ Iterator i = parse( writer.toString() ).getDeclarations();
+
+ IASTFunction functionDecl = (IASTFunction) i.next();
+ IASTClassSpecifier classB = (IASTClassSpecifier)((IASTAbstractTypeSpecifierDeclaration)i.next()).getTypeSpecifier();
+ IASTFunction functionDef = (IASTFunction) i.next();
+
+ LookupResult result = functionDef.lookup( "a", new IASTNode.LookupKind[] { IASTNode.LookupKind.ALL }, classB );
+
+ assertEquals( result.getResultsSize(), 1 );
+ IASTField field = (IASTField) result.getNodes().next();
+ assertEquals( field.getName(), "aPrivate" );
}
}