mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
- Add basic ambiguity resolution
- start using offsets to aid in traversing different scopes. - set some offsets on some physical nodes as I notice them
This commit is contained in:
parent
7bef09d931
commit
494a85849b
4 changed files with 158 additions and 36 deletions
|
@ -341,4 +341,56 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
assertInstances( collector, BC, 2 );
|
||||
assertInstances( collector, f ,1 );
|
||||
}
|
||||
|
||||
public void testNameHiding() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "int A; \n"); //$NON-NLS-1$
|
||||
buffer.append( "class A {}; \n"); //$NON-NLS-1$
|
||||
buffer.append( "void f() { \n"); //$NON-NLS-1$
|
||||
buffer.append( " A++; \n"); //$NON-NLS-1$
|
||||
buffer.append( " class A a; \n"); //$NON-NLS-1$
|
||||
buffer.append( "} \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
|
||||
CPPNameCollector collector = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, collector );
|
||||
|
||||
assertEquals( collector.size(), 6 );
|
||||
IVariable vA = (IVariable) collector.getName( 0 ).resolveBinding();
|
||||
ICompositeType cA = (ICompositeType) collector.getName( 1 ).resolveBinding();
|
||||
IVariable a = (IVariable) collector.getName( 5 ).resolveBinding();
|
||||
|
||||
assertSame( a.getType(), cA );
|
||||
assertInstances( collector, vA, 2 );
|
||||
assertInstances( collector, cA, 2 );
|
||||
}
|
||||
|
||||
public void testBlockTraversal() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append( "class A { void f(); }; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "class B; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "void A::f() { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " B b; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "} \n" ); //$NON-NLS-1$
|
||||
buffer.append( "int B; \n" ); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
|
||||
CPPNameCollector collector = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, collector );
|
||||
|
||||
assertEquals( collector.size(), 9 );
|
||||
ICompositeType A = (ICompositeType) collector.getName( 0 ).resolveBinding();
|
||||
ICPPMethod f = (ICPPMethod) collector.getName( 1 ).resolveBinding();
|
||||
ICompositeType B = (ICompositeType) collector.getName( 2 ).resolveBinding();
|
||||
|
||||
IVariable b = (IVariable) collector.getName( 7 ).resolveBinding();
|
||||
IVariable B2 = (IVariable) collector.getName( 8 ).resolveBinding();
|
||||
assertSame( b.getType(), B );
|
||||
assertInstances( collector, A, 2 );
|
||||
assertInstances( collector, f, 3 );
|
||||
assertInstances( collector, B, 2 );
|
||||
assertInstances( collector, b, 1 );
|
||||
assertInstances( collector, B2, 1 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1344,6 +1344,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
lastTokenOfExpression = consume(IToken.tSEMI);
|
||||
expressionStatement = createExpressionStatement();
|
||||
expressionStatement.setExpression( expression );
|
||||
((ASTNode)expressionStatement).setOffset(mark.getOffset());
|
||||
expression.setParent( expressionStatement );
|
||||
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
|
||||
} catch (BacktrackException b) {
|
||||
|
@ -1358,6 +1359,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
IASTDeclaration d = declaration();
|
||||
ds = createDeclarationStatement();
|
||||
ds.setDeclaration(d);
|
||||
((ASTNode)ds).setOffset(mark.getOffset());
|
||||
d.setParent( ds );
|
||||
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
|
|||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
|
||||
import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo;
|
||||
import org.eclipse.cdt.internal.core.parser2.ASTNode;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -127,6 +128,16 @@ public class CPPVisitor {
|
|||
}
|
||||
|
||||
private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){
|
||||
IASTNode parent = elabType.getParent();
|
||||
if( parent instanceof IASTSimpleDeclaration ){
|
||||
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators();
|
||||
if( dtors.length > 0 ){
|
||||
IBinding binding = resolveBinding( elabType.getName() );
|
||||
if( binding != null )
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
|
||||
ICPPScope scope = (ICPPScope) getContainingScope( elabType );
|
||||
CPPClassType binding = (CPPClassType) scope.getBinding( 0, elabType.getName().toCharArray() );
|
||||
if( binding == null ){
|
||||
|
@ -308,13 +319,12 @@ public class CPPVisitor {
|
|||
if( p instanceof IASTDeclarationStatement )
|
||||
return p;
|
||||
return parent;
|
||||
}
|
||||
//if parent is something that can contain a declaration
|
||||
else if ( parent instanceof IASTCompoundStatement ||
|
||||
parent instanceof IASTTranslationUnit ||
|
||||
parent instanceof IASTForStatement )
|
||||
{
|
||||
return node;
|
||||
} else if( parent instanceof IASTExpression ){
|
||||
IASTNode p = parent.getParent();
|
||||
if( p instanceof IASTStatement )
|
||||
return parent;
|
||||
} else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
return getContainingBlockItem( parent );
|
||||
|
@ -338,7 +348,7 @@ public class CPPVisitor {
|
|||
public boolean ignoreUsingDirectives = false;
|
||||
public boolean usingDirectivesOnly = false;
|
||||
public boolean forDefinition = false;
|
||||
|
||||
public boolean typesOnly = false;
|
||||
public List foundItems = null;
|
||||
|
||||
public LookupData( char[] n ){
|
||||
|
@ -354,11 +364,10 @@ public class CPPVisitor {
|
|||
lookup( data, name );
|
||||
|
||||
//3: resolve ambiguities
|
||||
//TODO
|
||||
if( data.foundItems != null && data.foundItems.size() == 1 ){
|
||||
IASTName found = (IASTName) data.foundItems.get(0);
|
||||
IASTName found = resolveAmbiguities( data, name );
|
||||
if( found != null ) {
|
||||
IBinding binding = found.resolveBinding();
|
||||
if( data.forDefinition ){
|
||||
if( binding != null && data.forDefinition ){
|
||||
addDefinition( binding, name );
|
||||
}
|
||||
return binding;
|
||||
|
@ -386,23 +395,71 @@ public class CPPVisitor {
|
|||
}
|
||||
} else if( parent instanceof IASTDeclarator ){
|
||||
data.forDefinition = true;
|
||||
} else if ( parent instanceof ICPPASTBaseSpecifier ) {
|
||||
//filter out non-type names
|
||||
} else if ( parent instanceof ICPPASTBaseSpecifier ||
|
||||
parent instanceof ICPPASTElaboratedTypeSpecifier)
|
||||
{
|
||||
data.typesOnly = true;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static private IASTName collectResult( LookupData data, IASTNode declaration, boolean checkAux ){
|
||||
static private IASTName resolveAmbiguities( LookupData data, IASTName name ) {
|
||||
if( data.foundItems == null || data.foundItems.size() == 0 )
|
||||
return null;
|
||||
|
||||
if( data.foundItems.size() == 1 ){
|
||||
return (IASTName) data.foundItems.get(0);
|
||||
}
|
||||
|
||||
IASTName type = null;
|
||||
IASTName obj = null;
|
||||
for( int i = 0; i < data.foundItems.size(); i++ ){
|
||||
IASTName n = (IASTName) data.foundItems.get( i );
|
||||
IASTNode parent = n.getParent();
|
||||
if( parent instanceof IASTDeclarator ){
|
||||
if( obj == null ){
|
||||
obj = n;
|
||||
} else {
|
||||
//TODO
|
||||
}
|
||||
} else if( parent instanceof ICPPASTElaboratedTypeSpecifier ||
|
||||
parent instanceof IASTEnumerationSpecifier ||
|
||||
parent instanceof ICPPASTCompositeTypeSpecifier )
|
||||
{
|
||||
if( type == null ){
|
||||
type = n;
|
||||
} else {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( type != null ) {
|
||||
if( obj != null ){
|
||||
if( obj.resolveBinding().getScope() != type.resolveBinding().getScope() ){
|
||||
return null; //ambiguous
|
||||
}
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
static private IASTName collectResult( LookupData data, IASTNode node, boolean checkAux ){
|
||||
IASTDeclaration declaration = null;
|
||||
if( node instanceof IASTDeclaration )
|
||||
declaration = (IASTDeclaration) node;
|
||||
if( declaration instanceof IASTDeclarationStatement )
|
||||
declaration = ((IASTDeclarationStatement)declaration).getDeclaration();
|
||||
declaration = ((IASTDeclarationStatement)node).getDeclaration();
|
||||
else if( declaration instanceof IASTForStatement )
|
||||
declaration = ((IASTForStatement)declaration).getInitDeclaration();
|
||||
declaration = ((IASTForStatement)node).getInitDeclaration();
|
||||
|
||||
if( declaration == null )
|
||||
return null;
|
||||
|
||||
if( declaration instanceof IASTSimpleDeclaration ){
|
||||
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
||||
if( !data.typesOnly ) {
|
||||
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
|
||||
for( int i = 0; i < declarators.length; i++ ){
|
||||
IASTDeclarator declarator = declarators[i];
|
||||
|
@ -411,6 +468,7 @@ public class CPPVisitor {
|
|||
return declaratorName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//decl spec
|
||||
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
||||
|
@ -430,6 +488,7 @@ public class CPPVisitor {
|
|||
if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){
|
||||
return eName;
|
||||
}
|
||||
if( !data.typesOnly ) {
|
||||
//check enumerators too
|
||||
IASTEnumerator [] list = enumeration.getEnumerators();
|
||||
for( int i = 0; i < list.length; i++ ) {
|
||||
|
@ -440,9 +499,13 @@ public class CPPVisitor {
|
|||
return eName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else if( declaration instanceof IASTFunctionDefinition ){
|
||||
}
|
||||
}
|
||||
if( data.typesOnly )
|
||||
return null;
|
||||
|
||||
if( declaration instanceof IASTFunctionDefinition ){
|
||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
||||
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
|
||||
|
||||
|
@ -472,6 +535,7 @@ public class CPPVisitor {
|
|||
if( CharArrayUtils.equals( namespaceName.toCharArray(), data.name ) )
|
||||
return namespaceName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
static private void lookup( LookupData data, IASTName name ){
|
||||
|
@ -480,6 +544,9 @@ public class CPPVisitor {
|
|||
ICPPScope scope = (ICPPScope) getContainingScope( node );
|
||||
while( scope != null ){
|
||||
IASTNode blockItem = getContainingBlockItem( node );
|
||||
if( scope.getPhysicalNode() != blockItem.getParent() )
|
||||
blockItem = node;
|
||||
|
||||
List directives = null;
|
||||
if( !data.usingDirectivesOnly ){
|
||||
directives = new ArrayList(2);
|
||||
|
@ -523,7 +590,7 @@ public class CPPVisitor {
|
|||
data.usingDirectivesOnly = true;
|
||||
|
||||
if( blockItem != null )
|
||||
node = blockItem.getParent();
|
||||
node = blockItem;
|
||||
scope = (ICPPScope) scope.getParent();
|
||||
}
|
||||
}
|
||||
|
@ -697,7 +764,7 @@ public class CPPVisitor {
|
|||
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
|
||||
|
||||
while( item != null ) {
|
||||
if( item == null || item == blockItem )
|
||||
if( item == null || item == blockItem || ( blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() ))
|
||||
break;
|
||||
|
||||
if( item instanceof ICPPASTUsingDirective && !data.ignoreUsingDirectives ) {
|
||||
|
|
|
@ -2398,6 +2398,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
subName = createTemplateID( segments[i] );
|
||||
subName.setParent( result );
|
||||
subName.setPropertyInParent( ICPPASTQualifiedName.SEGMENT_NAME );
|
||||
((ASTNode)subName).setOffset( segments[i].getStartOffset() );
|
||||
result.addName( subName );
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue