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, BC, 2 );
|
||||||
assertInstances( collector, f ,1 );
|
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);
|
lastTokenOfExpression = consume(IToken.tSEMI);
|
||||||
expressionStatement = createExpressionStatement();
|
expressionStatement = createExpressionStatement();
|
||||||
expressionStatement.setExpression( expression );
|
expressionStatement.setExpression( expression );
|
||||||
|
((ASTNode)expressionStatement).setOffset(mark.getOffset());
|
||||||
expression.setParent( expressionStatement );
|
expression.setParent( expressionStatement );
|
||||||
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
|
expression.setPropertyInParent( IASTExpressionStatement.EXPFRESSION );
|
||||||
} catch (BacktrackException b) {
|
} catch (BacktrackException b) {
|
||||||
|
@ -1358,6 +1359,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
IASTDeclaration d = declaration();
|
IASTDeclaration d = declaration();
|
||||||
ds = createDeclarationStatement();
|
ds = createDeclarationStatement();
|
||||||
ds.setDeclaration(d);
|
ds.setDeclaration(d);
|
||||||
|
((ASTNode)ds).setOffset(mark.getOffset());
|
||||||
d.setParent( ds );
|
d.setParent( ds );
|
||||||
d.setPropertyInParent( IASTDeclarationStatement.DECLARATION );
|
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.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
|
import org.eclipse.cdt.internal.core.parser.pst.ISymbol;
|
||||||
import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo;
|
import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo;
|
||||||
|
import org.eclipse.cdt.internal.core.parser2.ASTNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author aniefer
|
* @author aniefer
|
||||||
|
@ -127,6 +128,16 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding createBinding( ICPPASTElaboratedTypeSpecifier elabType ){
|
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 );
|
ICPPScope scope = (ICPPScope) getContainingScope( elabType );
|
||||||
CPPClassType binding = (CPPClassType) scope.getBinding( 0, elabType.getName().toCharArray() );
|
CPPClassType binding = (CPPClassType) scope.getBinding( 0, elabType.getName().toCharArray() );
|
||||||
if( binding == null ){
|
if( binding == null ){
|
||||||
|
@ -308,13 +319,12 @@ public class CPPVisitor {
|
||||||
if( p instanceof IASTDeclarationStatement )
|
if( p instanceof IASTDeclarationStatement )
|
||||||
return p;
|
return p;
|
||||||
return parent;
|
return parent;
|
||||||
}
|
} else if( parent instanceof IASTExpression ){
|
||||||
//if parent is something that can contain a declaration
|
IASTNode p = parent.getParent();
|
||||||
else if ( parent instanceof IASTCompoundStatement ||
|
if( p instanceof IASTStatement )
|
||||||
parent instanceof IASTTranslationUnit ||
|
return parent;
|
||||||
parent instanceof IASTForStatement )
|
} else if ( parent instanceof IASTStatement || parent instanceof IASTTranslationUnit ) {
|
||||||
{
|
return parent;
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return getContainingBlockItem( parent );
|
return getContainingBlockItem( parent );
|
||||||
|
@ -338,7 +348,7 @@ public class CPPVisitor {
|
||||||
public boolean ignoreUsingDirectives = false;
|
public boolean ignoreUsingDirectives = false;
|
||||||
public boolean usingDirectivesOnly = false;
|
public boolean usingDirectivesOnly = false;
|
||||||
public boolean forDefinition = false;
|
public boolean forDefinition = false;
|
||||||
|
public boolean typesOnly = false;
|
||||||
public List foundItems = null;
|
public List foundItems = null;
|
||||||
|
|
||||||
public LookupData( char[] n ){
|
public LookupData( char[] n ){
|
||||||
|
@ -354,11 +364,10 @@ public class CPPVisitor {
|
||||||
lookup( data, name );
|
lookup( data, name );
|
||||||
|
|
||||||
//3: resolve ambiguities
|
//3: resolve ambiguities
|
||||||
//TODO
|
IASTName found = resolveAmbiguities( data, name );
|
||||||
if( data.foundItems != null && data.foundItems.size() == 1 ){
|
if( found != null ) {
|
||||||
IASTName found = (IASTName) data.foundItems.get(0);
|
|
||||||
IBinding binding = found.resolveBinding();
|
IBinding binding = found.resolveBinding();
|
||||||
if( data.forDefinition ){
|
if( binding != null && data.forDefinition ){
|
||||||
addDefinition( binding, name );
|
addDefinition( binding, name );
|
||||||
}
|
}
|
||||||
return binding;
|
return binding;
|
||||||
|
@ -386,23 +395,71 @@ public class CPPVisitor {
|
||||||
}
|
}
|
||||||
} else if( parent instanceof IASTDeclarator ){
|
} else if( parent instanceof IASTDeclarator ){
|
||||||
data.forDefinition = true;
|
data.forDefinition = true;
|
||||||
} else if ( parent instanceof ICPPASTBaseSpecifier ) {
|
} else if ( parent instanceof ICPPASTBaseSpecifier ||
|
||||||
//filter out non-type names
|
parent instanceof ICPPASTElaboratedTypeSpecifier)
|
||||||
|
{
|
||||||
|
data.typesOnly = true;
|
||||||
}
|
}
|
||||||
return data;
|
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 )
|
if( declaration instanceof IASTDeclarationStatement )
|
||||||
declaration = ((IASTDeclarationStatement)declaration).getDeclaration();
|
declaration = ((IASTDeclarationStatement)node).getDeclaration();
|
||||||
else if( declaration instanceof IASTForStatement )
|
else if( declaration instanceof IASTForStatement )
|
||||||
declaration = ((IASTForStatement)declaration).getInitDeclaration();
|
declaration = ((IASTForStatement)node).getInitDeclaration();
|
||||||
|
|
||||||
if( declaration == null )
|
if( declaration == null )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if( declaration instanceof IASTSimpleDeclaration ){
|
if( declaration instanceof IASTSimpleDeclaration ){
|
||||||
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
||||||
|
if( !data.typesOnly ) {
|
||||||
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
|
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
|
||||||
for( int i = 0; i < declarators.length; i++ ){
|
for( int i = 0; i < declarators.length; i++ ){
|
||||||
IASTDeclarator declarator = declarators[i];
|
IASTDeclarator declarator = declarators[i];
|
||||||
|
@ -411,6 +468,7 @@ public class CPPVisitor {
|
||||||
return declaratorName;
|
return declaratorName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//decl spec
|
//decl spec
|
||||||
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
|
||||||
|
@ -430,6 +488,7 @@ public class CPPVisitor {
|
||||||
if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){
|
if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){
|
||||||
return eName;
|
return eName;
|
||||||
}
|
}
|
||||||
|
if( !data.typesOnly ) {
|
||||||
//check enumerators too
|
//check enumerators too
|
||||||
IASTEnumerator [] list = enumeration.getEnumerators();
|
IASTEnumerator [] list = enumeration.getEnumerators();
|
||||||
for( int i = 0; i < list.length; i++ ) {
|
for( int i = 0; i < list.length; i++ ) {
|
||||||
|
@ -440,9 +499,13 @@ public class CPPVisitor {
|
||||||
return eName;
|
return eName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if( declaration instanceof IASTFunctionDefinition ){
|
}
|
||||||
|
}
|
||||||
|
if( data.typesOnly )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if( declaration instanceof IASTFunctionDefinition ){
|
||||||
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
||||||
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
|
IASTFunctionDeclarator declarator = functionDef.getDeclarator();
|
||||||
|
|
||||||
|
@ -472,6 +535,7 @@ public class CPPVisitor {
|
||||||
if( CharArrayUtils.equals( namespaceName.toCharArray(), data.name ) )
|
if( CharArrayUtils.equals( namespaceName.toCharArray(), data.name ) )
|
||||||
return namespaceName;
|
return namespaceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
static private void lookup( LookupData data, IASTName name ){
|
static private void lookup( LookupData data, IASTName name ){
|
||||||
|
@ -480,6 +544,9 @@ public class CPPVisitor {
|
||||||
ICPPScope scope = (ICPPScope) getContainingScope( node );
|
ICPPScope scope = (ICPPScope) getContainingScope( node );
|
||||||
while( scope != null ){
|
while( scope != null ){
|
||||||
IASTNode blockItem = getContainingBlockItem( node );
|
IASTNode blockItem = getContainingBlockItem( node );
|
||||||
|
if( scope.getPhysicalNode() != blockItem.getParent() )
|
||||||
|
blockItem = node;
|
||||||
|
|
||||||
List directives = null;
|
List directives = null;
|
||||||
if( !data.usingDirectivesOnly ){
|
if( !data.usingDirectivesOnly ){
|
||||||
directives = new ArrayList(2);
|
directives = new ArrayList(2);
|
||||||
|
@ -523,7 +590,7 @@ public class CPPVisitor {
|
||||||
data.usingDirectivesOnly = true;
|
data.usingDirectivesOnly = true;
|
||||||
|
|
||||||
if( blockItem != null )
|
if( blockItem != null )
|
||||||
node = blockItem.getParent();
|
node = blockItem;
|
||||||
scope = (ICPPScope) scope.getParent();
|
scope = (ICPPScope) scope.getParent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,7 +764,7 @@ public class CPPVisitor {
|
||||||
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
|
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
|
||||||
|
|
||||||
while( item != null ) {
|
while( item != null ) {
|
||||||
if( item == null || item == blockItem )
|
if( item == null || item == blockItem || ( blockItem != null && ((ASTNode)item).getOffset() > ((ASTNode) blockItem).getOffset() ))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( item instanceof ICPPASTUsingDirective && !data.ignoreUsingDirectives ) {
|
if( item instanceof ICPPASTUsingDirective && !data.ignoreUsingDirectives ) {
|
||||||
|
|
|
@ -2398,6 +2398,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
subName = createTemplateID( segments[i] );
|
subName = createTemplateID( segments[i] );
|
||||||
subName.setParent( result );
|
subName.setParent( result );
|
||||||
subName.setPropertyInParent( ICPPASTQualifiedName.SEGMENT_NAME );
|
subName.setPropertyInParent( ICPPASTQualifiedName.SEGMENT_NAME );
|
||||||
|
((ASTNode)subName).setOffset( segments[i].getStartOffset() );
|
||||||
result.addName( subName );
|
result.addName( subName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue