mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
C++ friend declarations
This commit is contained in:
parent
5155c977ec
commit
0b8b62e408
7 changed files with 323 additions and 10 deletions
|
@ -1248,7 +1248,8 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
|
||||
ICPPClassType Node = (ICPPClassType) col.getName(1).resolveBinding();
|
||||
ICPPClassType Data = (ICPPClassType) col.getName(3).resolveBinding();
|
||||
|
||||
assertSame( Data.getScope(), tu.getScope() );
|
||||
|
||||
assertInstances(col, Node, 3);
|
||||
assertInstances(col, Data, 2);
|
||||
}
|
||||
|
@ -1702,5 +1703,97 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertInstances( col, A, 5 );
|
||||
assertInstances( col, pm, 2 );
|
||||
}
|
||||
|
||||
public void testFriend_1() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class A { \n"); //$NON-NLS-1$
|
||||
buffer.append(" friend void set(); \n"); //$NON-NLS-1$
|
||||
buffer.append(" friend class B; \n"); //$NON-NLS-1$
|
||||
buffer.append("}; \n"); //$NON-NLS-1$
|
||||
buffer.append("void set(); \n"); //$NON-NLS-1$
|
||||
buffer.append("class B{}; \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
IFunction set = (IFunction) col.getName(1).resolveBinding();
|
||||
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
|
||||
assertInstances( col, set, 2 );
|
||||
assertInstances( col, B, 2 );
|
||||
|
||||
IBinding [] friends = A.getFriends();
|
||||
assertEquals( 2, friends.length );
|
||||
assertSame( friends[0], set );
|
||||
assertSame( friends[1], B );
|
||||
}
|
||||
|
||||
public void testBug59149() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class A { friend class B; friend class B; }; \n"); //$NON-NLS-1$
|
||||
buffer.append("class B{}; \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
|
||||
assertInstances( col, B, 3 );
|
||||
|
||||
IBinding [] friends = A.getFriends();
|
||||
assertEquals( friends.length, 1 );
|
||||
assertSame( friends[0], B );
|
||||
}
|
||||
public void testBug59302() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "class A { \n"); //$NON-NLS-1$
|
||||
buffer.append( " public: class N {}; \n"); //$NON-NLS-1$
|
||||
buffer.append( "}; \n"); //$NON-NLS-1$
|
||||
buffer.append( "class B { \n"); //$NON-NLS-1$
|
||||
buffer.append( " friend class A::N; \n"); //$NON-NLS-1$
|
||||
buffer.append( "}; \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
ICPPClassType N = (ICPPClassType) col.getName(5).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
ICPPClassType B = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
assertInstances( col, N, 3 );
|
||||
|
||||
IBinding [] friends = B.getFriends();
|
||||
assertEquals( friends.length, 1 );
|
||||
assertSame( friends[0], N );
|
||||
|
||||
assertEquals( A.getFriends().length, 0 );
|
||||
assertEquals( N.getFriends().length, 0 );
|
||||
}
|
||||
|
||||
public void testBug75482() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "class A { \n"); //$NON-NLS-1$
|
||||
buffer.append( " friend class B *helper(); \n"); //$NON-NLS-1$
|
||||
buffer.append( "}; \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse(buffer.toString(), ParserLanguage.CPP);
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit(tu, col);
|
||||
|
||||
IFunction helper = (IFunction) col.getName(2).resolveBinding();
|
||||
assertSame( helper.getScope(), tu.getScope() );
|
||||
|
||||
ICPPClassType B = (ICPPClassType) col.getName(1).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
assertSame( B.getScope(), A.getScope() );
|
||||
|
||||
IBinding [] friends = A.getFriends();
|
||||
assertEquals( friends.length, 1 );
|
||||
assertSame( friends[0], helper );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
|||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||
import org.eclipse.cdt.core.dom.ast.IField;
|
||||
|
||||
|
@ -78,4 +79,5 @@ public interface ICPPClassType extends ICompositeType {
|
|||
*/
|
||||
public ICPPConstructor[] getConstructors() throws DOMException;
|
||||
|
||||
public IBinding [] getFriends() throws DOMException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Created on Feb 16, 2005
|
||||
*/
|
||||
package org.eclipse.cdt.core.parser.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public class ArrayUtil {
|
||||
public static final int DEFAULT_LENGTH = 2;
|
||||
/**
|
||||
* Adds obj to array in the first null slot.
|
||||
* If array is null, a new array is created and obj is added to the new array.
|
||||
* If the array is full, a new array of larger size is created, the contents
|
||||
* of array are copied over and obj is added to the new array.
|
||||
*
|
||||
* The type of any new arrays will be array of c, where c is given.
|
||||
* es: c = IBinding.class results in an IBinding[]
|
||||
* @param Class c
|
||||
* @param Object [] array
|
||||
* @param Object obj
|
||||
* @return
|
||||
*/
|
||||
static public Object [] append( Class c, Object[] array, Object obj ){
|
||||
if( array == null || array.length == 0){
|
||||
array = (Object[]) Array.newInstance( c, DEFAULT_LENGTH );
|
||||
array[0] = obj;
|
||||
return array;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for( ; i < array.length; i++ ){
|
||||
if( array[i] == null ){
|
||||
array[i] = obj;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
Object [] temp = (Object[]) Array.newInstance( c, array.length * 2 );
|
||||
System.arraycopy( array, 0, temp, 0, array.length );
|
||||
temp[array.length] = obj;
|
||||
array = temp;
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the given array and returns a new array with no null entries.
|
||||
* if array == null, a new array of length 0 is returned
|
||||
* if forceNew == true, a new array will always be created.
|
||||
* if forceNew == false, a new array will only be created if the original array
|
||||
* contained null entries.
|
||||
*
|
||||
* @param Class c: the type of the new array
|
||||
* @param Object [] array, the array to be trimmed
|
||||
* @param forceNew
|
||||
* @return
|
||||
*/
|
||||
static public Object [] trim( Class c, Object [] array, boolean forceNew ){
|
||||
if( array == null )
|
||||
return (Object[]) Array.newInstance( c, 0 );
|
||||
|
||||
int i = 0;
|
||||
for( ; i < array.length; i++ ){
|
||||
if( array[i] == null ) break;
|
||||
}
|
||||
if( forceNew || i < array.length ){
|
||||
Object [] temp = (Object[]) Array.newInstance( c, i );
|
||||
System.arraycopy( array, 0, temp, 0, i );
|
||||
array = temp;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class1
|
||||
* @param fields
|
||||
* @return
|
||||
*/
|
||||
public static Object[] trim( Class c, Object[] array ) {
|
||||
return trim( c, array, false );
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
@ -32,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
|
@ -39,8 +41,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
|
@ -88,6 +94,9 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
public List find(String name) throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
public IBinding[] getFriends() throws DOMException {
|
||||
throw new DOMException( this );
|
||||
}
|
||||
}
|
||||
|
||||
private ICPPASTCompositeTypeSpecifier definition;
|
||||
|
@ -185,7 +194,7 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
|
||||
IASTDeclaration[] members = definition.getMembers();
|
||||
int size = members.length;
|
||||
IField[] fields = new IField[ size ];
|
||||
IField[] fields = null;
|
||||
if( size > 0 ){
|
||||
|
||||
for( int i = 0; i < size; i++ ){
|
||||
|
@ -196,13 +205,13 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
IASTDeclarator declarator = declarators[i];
|
||||
IBinding binding = declarator.getName().resolveBinding();
|
||||
if( binding != null && binding instanceof IField )
|
||||
fields[i] = (IField) binding;
|
||||
fields = (IField[]) ArrayUtil.append( IField.class, fields, binding );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return fields;
|
||||
return (IField[]) ArrayUtil.trim( IField.class, fields );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -236,7 +245,22 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
|
||||
name = ns[ ns.length - 1 ];
|
||||
}
|
||||
return CPPVisitor.getContainingScope( name );
|
||||
IScope scope = CPPVisitor.getContainingScope( name );
|
||||
if( definition == null && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){
|
||||
IASTNode node = declarations[0].getParent();
|
||||
if( node instanceof IASTFunctionDefinition || node instanceof IASTParameterDeclaration ||
|
||||
( node instanceof IASTSimpleDeclaration &&
|
||||
( ((IASTSimpleDeclaration) node).getDeclarators().length > 0 || declarations[0].isFriend() ) ) )
|
||||
{
|
||||
while( scope instanceof ICPPClassScope || scope instanceof ICPPFunctionScope ){
|
||||
try {
|
||||
scope = (ICPPScope) scope.getParent();
|
||||
} catch (DOMException e1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -371,4 +395,43 @@ public class CPPClassType implements ICPPClassType, ICPPBinding {
|
|||
|
||||
return ((CPPClassScope)scope).getConstructors();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends()
|
||||
*/
|
||||
public IBinding[] getFriends() {
|
||||
if( definition == null ){
|
||||
checkForDefinition();
|
||||
if( definition == null ){
|
||||
return new IBinding [] { new ProblemBinding( IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) };
|
||||
}
|
||||
}
|
||||
ObjectSet resultSet = new ObjectSet(2);
|
||||
IASTDeclaration [] members = definition.getMembers();
|
||||
for( int i = 0; i < members.length; i++ ){
|
||||
if( members[i] instanceof IASTSimpleDeclaration ){
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)members[i]).getDeclSpecifier();
|
||||
if( declSpec.isFriend() ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
|
||||
if( declSpec instanceof ICPPASTElaboratedTypeSpecifier && dtors.length == 0 ){
|
||||
resultSet.put( ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding() );
|
||||
} else {
|
||||
for( int j = 0; j < dtors.length; j++ ){
|
||||
if( dtors[j] == null ) break;
|
||||
resultSet.put( dtors[j].getName().resolveBinding() );
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if( members[i] instanceof IASTFunctionDefinition ){
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)members[i]).getDeclSpecifier();
|
||||
if( declSpec.isFriend() ){
|
||||
IASTDeclarator dtor = ((IASTFunctionDefinition)members[i]).getDeclarator();
|
||||
resultSet.put( dtor.getName().resolveBinding() );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return (IBinding[]) ArrayUtil.trim( IBinding.class, resultSet.keyArray(), true );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,13 +18,16 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||
|
||||
/**
|
||||
|
@ -152,7 +155,25 @@ public class CPPFunction implements IFunction, ICPPBinding {
|
|||
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
|
||||
*/
|
||||
public IScope getScope() {
|
||||
return CPPVisitor.getContainingScope( definition != null ? definition : declarations[0] );
|
||||
ICPPASTDeclSpecifier declSpec = null;
|
||||
if( definition != null ){
|
||||
IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent();
|
||||
declSpec = (ICPPASTDeclSpecifier) def.getDeclSpecifier();
|
||||
} else {
|
||||
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) declarations[0].getParent();
|
||||
declSpec = (ICPPASTDeclSpecifier) decl.getDeclSpecifier();
|
||||
}
|
||||
|
||||
IScope scope = CPPVisitor.getContainingScope( definition != null ? definition : declarations[0] );
|
||||
if( declSpec.isFriend() && scope instanceof ICPPClassScope ){
|
||||
try {
|
||||
while( scope instanceof ICPPClassScope ){
|
||||
scope = scope.getParent();
|
||||
}
|
||||
} catch ( DOMException e ) {
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
|
@ -28,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
|
@ -55,6 +57,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
|
|||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
|
@ -192,6 +195,22 @@ public class CPPSemantics {
|
|||
p1 = p1.getParent();
|
||||
return ( p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME );
|
||||
}
|
||||
public boolean checkWholeClassScope() {
|
||||
if( astName == null ) return false;
|
||||
ASTNodeProperty prop = astName.getPropertyInParent();
|
||||
if( prop == IASTIdExpression.ID_NAME ||
|
||||
prop == IASTFieldReference.FIELD_NAME ||
|
||||
prop == ICASTFieldDesignator.FIELD_NAME ||
|
||||
prop == ICPPASTUsingDirective.QUALIFIED_NAME ||
|
||||
prop == ICPPASTUsingDeclaration.NAME ||
|
||||
prop == IASTFunctionCallExpression.FUNCTION_NAME ||
|
||||
prop == ICPPASTUsingDeclaration.NAME ||
|
||||
prop == IASTNamedTypeSpecifier.NAME )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static protected class Cost
|
||||
|
@ -805,11 +824,11 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
int idx = -1;
|
||||
boolean classScope = ( scope instanceof ICPPClassScope );
|
||||
boolean checkWholeClassScope = ( scope instanceof ICPPClassScope ) && data.checkWholeClassScope();
|
||||
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
|
||||
|
||||
while( item != null ) {
|
||||
if( !classScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() )
|
||||
if( !checkWholeClassScope && blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() )
|
||||
break;
|
||||
|
||||
if( item != blockItem || data.includeBlockItem( item ) ){
|
||||
|
@ -829,7 +848,7 @@ public class CPPSemantics {
|
|||
}
|
||||
}
|
||||
}
|
||||
if( item == blockItem && !classScope )
|
||||
if( item == blockItem && !checkWholeClassScope )
|
||||
break;
|
||||
if( idx > -1 && ++idx < nodes.length ){
|
||||
item = nodes[idx];
|
||||
|
|
|
@ -93,6 +93,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
|
@ -255,10 +256,14 @@ public class CPPVisitor {
|
|||
IASTNode parent = elabType.getParent();
|
||||
IBinding binding = null;
|
||||
boolean mustBeSimple = true;
|
||||
boolean isFriend = false;
|
||||
if( parent instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators();
|
||||
if( dtors.length > 0 ){
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)parent).getDeclSpecifier();
|
||||
isFriend = declSpec.isFriend() && dtors.length == 0;
|
||||
if( dtors.length > 0 || isFriend ){
|
||||
binding = CPPSemantics.resolveBinding( elabType.getName() );
|
||||
mustBeSimple = !isFriend;
|
||||
} else {
|
||||
mustBeSimple = false;
|
||||
}
|
||||
|
@ -292,6 +297,13 @@ public class CPPVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
if( scope instanceof ICPPClassScope && isFriend ){
|
||||
try {
|
||||
while( scope instanceof ICPPClassScope )
|
||||
scope = (ICPPScope) scope.getParent();
|
||||
} catch ( DOMException e1 ) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
binding = scope.getBinding( elabType.getName() );
|
||||
if( binding == null ){
|
||||
|
@ -369,6 +381,15 @@ public class CPPVisitor {
|
|||
}
|
||||
|
||||
ICPPScope scope = (ICPPScope) getContainingScope( parent );
|
||||
if( parent instanceof IASTSimpleDeclaration && scope instanceof ICPPClassScope ){
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)parent).getDeclSpecifier();
|
||||
if( declSpec.isFriend() ){
|
||||
try {
|
||||
scope = (ICPPScope) scope.getParent();
|
||||
} catch ( DOMException e1 ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
IBinding binding;
|
||||
try {
|
||||
binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null;
|
||||
|
|
Loading…
Add table
Reference in a new issue