mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
C++ bindings
- Field references before their declaration in inline class members - references in parameter declarations for member functions defined outside their scope - constructor references
This commit is contained in:
parent
c5183b1756
commit
eea3244085
5 changed files with 286 additions and 108 deletions
|
@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
|||
import org.eclipse.cdt.core.dom.ast.ILabel;
|
||||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
|
@ -1393,7 +1394,19 @@ public class CompleteParser2Tests extends TestCase {
|
|||
buffer.append( "void f ( int s ) { \n" ); //$NON-NLS-1$
|
||||
buffer.append( " struct s sInstance; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "}\n"); //$NON-NLS-1$
|
||||
parse( buffer.toString() );
|
||||
IASTTranslationUnit tu = parse( buffer.toString() );
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 5 );
|
||||
ICPPClassType s = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
IParameter s2 = (IParameter) col.getName(2).resolveBinding();
|
||||
IVariable instance = (IVariable) col.getName(4).resolveBinding();
|
||||
|
||||
assertInstances( col, s, 2 );
|
||||
assertInstances( col, s2, 1 );
|
||||
assertSame( instance.getType(), s );
|
||||
}
|
||||
|
||||
public void testQualifiedLookup() throws Exception{
|
||||
|
@ -1405,7 +1418,22 @@ public class CompleteParser2Tests extends TestCase {
|
|||
buffer.append( " class A { }; \n" ); //$NON-NLS-1$
|
||||
buffer.append( "}" ); //$NON-NLS-1$
|
||||
buffer.append( "void main() { N::A * a = new N::A(); a->f(); } "); //$NON-NLS-1$
|
||||
parse( buffer.toString() );
|
||||
IASTTranslationUnit tu = parse( buffer.toString() );
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 13 );
|
||||
ICPPNamespace N = (ICPPNamespace) col.getName(0).resolveBinding();
|
||||
IFunction f = (IFunction) col.getName(1).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(2).resolveBinding();
|
||||
|
||||
ICPPConstructor ctor = A.getConstructors()[0];
|
||||
|
||||
assertInstances( col, N, 3 );
|
||||
assertInstances( col, f, 2 );
|
||||
assertInstances( col, A, 3 );
|
||||
assertInstances( col, ctor, 2 );
|
||||
}
|
||||
|
||||
public void testBug43110() throws Exception
|
||||
|
@ -1414,7 +1442,18 @@ public class CompleteParser2Tests extends TestCase {
|
|||
buffer.append("void x( int y, ... );\n"); //$NON-NLS-1$
|
||||
buffer.append("void y( int x... );\n"); //$NON-NLS-1$
|
||||
buffer.append("void z(...);"); //$NON-NLS-1$
|
||||
parse(buffer.toString() );
|
||||
IASTTranslationUnit tu = parse( buffer.toString() );
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 5 );
|
||||
IFunction x = (IFunction) col.getName(0).resolveBinding();
|
||||
IFunction y = (IFunction) col.getName(2).resolveBinding();
|
||||
IFunction z = (IFunction) col.getName(4).resolveBinding();
|
||||
assertNotNull(x);
|
||||
assertNotNull(y);
|
||||
assertNotNull(z);
|
||||
}
|
||||
|
||||
public void testBug43110_XRef() throws Exception
|
||||
|
@ -1423,17 +1462,50 @@ public class CompleteParser2Tests extends TestCase {
|
|||
buffer.append( "void foo( ... ) {}\n" ); //$NON-NLS-1$
|
||||
buffer.append( "void main( ){ foo( 1 ); }\n" ); //$NON-NLS-1$
|
||||
|
||||
parse( buffer.toString() );
|
||||
IASTTranslationUnit tu = parse( buffer.toString() );
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 3 );
|
||||
IFunction foo = (IFunction) col.getName(0).resolveBinding();
|
||||
assertInstances( col, foo, 2 );
|
||||
}
|
||||
|
||||
public void testErrorHandling_1() throws Exception
|
||||
{
|
||||
parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ); //$NON-NLS-1$
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 9 );
|
||||
IProblemBinding p = (IProblemBinding) col.getName(0).resolveBinding();
|
||||
IVariable anA = (IVariable) col.getName(1).resolveBinding();
|
||||
assertNotNull( col.getName(2).resolveBinding() );
|
||||
IProblemBinding p2 = (IProblemBinding) col.getName(3).resolveBinding();
|
||||
ICPPClassType A = (ICPPClassType) col.getName(4).resolveBinding();
|
||||
|
||||
assertInstances( col, anA, 2 );
|
||||
assertInstances( col, A, 2 );
|
||||
|
||||
assertNotNull( p );
|
||||
assertNotNull( p2 );
|
||||
|
||||
assertSame( anA.getType(), p );
|
||||
}
|
||||
|
||||
public void testBug44340() throws Exception {
|
||||
// inline function with reference to variables declared after them
|
||||
parse ("class A{ int getX() {return x[1];} int x[10];};", false ); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse ("class A{ int getX() {return x[1];} int x[10];};"); //$NON-NLS-1$
|
||||
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 4 );
|
||||
|
||||
ICPPField x = (ICPPField) col.getName(2).resolveBinding();
|
||||
assertInstances( col, x, 2 );
|
||||
}
|
||||
|
||||
public void testBug47628() throws Exception
|
||||
|
@ -1451,7 +1523,17 @@ public class CompleteParser2Tests extends TestCase {
|
|||
Writer writer = new StringWriter();
|
||||
writer.write( "void f( char [] ); \n" ); //$NON-NLS-1$
|
||||
writer.write( "void f( char * ){} \n" ); //$NON-NLS-1$
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 4 );
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IParameter p1 = (IParameter)col.getName(1).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IParameter p2 = (IParameter)col.getName(3).resolveBinding();
|
||||
assertSame( f1, f2 );
|
||||
assertSame( p1, p2 );
|
||||
}
|
||||
|
||||
public void testBug45697() throws Exception
|
||||
|
@ -1460,7 +1542,18 @@ public class CompleteParser2Tests extends TestCase {
|
|||
writer.write( " int f( bool ); \n"); //$NON-NLS-1$
|
||||
writer.write( " int f( char ){ } "); //$NON-NLS-1$
|
||||
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 4 );
|
||||
IFunction f1 = (IFunction) col.getName(0).resolveBinding();
|
||||
IParameter p1 = (IParameter)col.getName(1).resolveBinding();
|
||||
IFunction f2 = (IFunction) col.getName(2).resolveBinding();
|
||||
IParameter p2 = (IParameter)col.getName(3).resolveBinding();
|
||||
|
||||
assertNotSame( f1, f2 );
|
||||
assertNotSame( p1, p2 );
|
||||
}
|
||||
|
||||
public void testBug54639() throws Exception
|
||||
|
@ -1468,7 +1561,20 @@ public class CompleteParser2Tests extends TestCase {
|
|||
Writer writer = new StringWriter();
|
||||
writer.write( "typedef enum _A { } A, *pA; " ); //$NON-NLS-1$
|
||||
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 3 );
|
||||
|
||||
IEnumeration _A = (IEnumeration) col.getName(0).resolveBinding();
|
||||
ITypedef A = (ITypedef) col.getName(1).resolveBinding();
|
||||
ITypedef pA = (ITypedef)col.getName(2).resolveBinding();
|
||||
|
||||
assertNotNull( _A );
|
||||
assertSame( A.getType(), _A );
|
||||
assertTrue( pA.getType() instanceof IPointerType );
|
||||
assertSame( ((IPointerType)pA.getType()).getType(), _A );
|
||||
}
|
||||
|
||||
public void testBug55163() throws Exception
|
||||
|
@ -1480,13 +1586,34 @@ public class CompleteParser2Tests extends TestCase {
|
|||
writer.write( " for( i = n - 1, di = (double)( i + i ); i > 0; i-- ){ } \n"); //$NON-NLS-1$
|
||||
writer.write( "}\n"); //$NON-NLS-1$
|
||||
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 11 );
|
||||
IVariable i = (IVariable)col.getName(1).resolveBinding();
|
||||
IVariable n = (IVariable)col.getName(2).resolveBinding();
|
||||
IVariable di = (IVariable)col.getName(3).resolveBinding();
|
||||
|
||||
assertInstances( col, i, 6 );
|
||||
assertInstances( col, n, 2 );
|
||||
assertInstances( col, di, 2 );
|
||||
}
|
||||
public void testBug55673() throws Exception{
|
||||
Writer writer = new StringWriter();
|
||||
writer.write( "struct Example { int i; int ( * pfi ) ( int ); }; "); //$NON-NLS-1$
|
||||
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 5 );
|
||||
ICPPField pfi = (ICPPField)col.getName(3).resolveBinding();
|
||||
|
||||
assertNotNull( pfi );
|
||||
assertTrue( pfi.getType() instanceof IPointerType );
|
||||
assertTrue( ((IPointerType)pfi.getType()).getType() instanceof IFunctionType );
|
||||
}
|
||||
|
||||
public void testBug54531() throws Exception
|
||||
|
@ -1496,7 +1623,15 @@ public class CompleteParser2Tests extends TestCase {
|
|||
|
||||
public void testBug56516() throws Exception
|
||||
{
|
||||
parse( "typedef struct blah sb;"); //$NON-NLS-1$
|
||||
IASTTranslationUnit tu = parse( "typedef struct blah sb;"); //$NON-NLS-1$
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 2 );
|
||||
|
||||
IProblemBinding blah = (IProblemBinding) col.getName(0).resolveBinding();
|
||||
ITypedef sb = (ITypedef) col.getName(1).resolveBinding();
|
||||
assertSame( sb.getType(), blah );
|
||||
}
|
||||
|
||||
public void testBug53786() throws Exception
|
||||
|
@ -1530,7 +1665,18 @@ public class CompleteParser2Tests extends TestCase {
|
|||
writer.write( " void f( T ); " ); //$NON-NLS-1$
|
||||
writer.write( "}; " ); //$NON-NLS-1$
|
||||
writer.write( "void X::f( T ) { } " ); //$NON-NLS-1$
|
||||
parse( writer.toString() );
|
||||
IASTTranslationUnit tu = parse( writer.toString() );
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
CPPVisitor.visitTranslationUnit( tu, col );
|
||||
|
||||
assertEquals( col.size(), 10 );
|
||||
ICPPClassType X = (ICPPClassType) col.getName(0).resolveBinding();
|
||||
ITypedef T = (ITypedef) col.getName(1).resolveBinding();
|
||||
ICPPMethod f = (ICPPMethod) col.getName(2).resolveBinding();
|
||||
|
||||
assertInstances( col, X, 2 );
|
||||
assertInstances( col, T, 3 );
|
||||
assertInstances( col, f, 3 );
|
||||
}
|
||||
|
||||
public void testBug57800() throws Exception
|
||||
|
|
|
@ -19,13 +19,14 @@ import java.text.MessageFormat;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
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.internal.core.dom.parser.cpp.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.parser.ParserMessages;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
*/
|
||||
public class ProblemBinding implements IProblemBinding {
|
||||
public class ProblemBinding implements IProblemBinding, IType {
|
||||
private final int id;
|
||||
private final char [] arg;
|
||||
|
||||
|
@ -111,4 +112,8 @@ public class ProblemBinding implements IProblemBinding {
|
|||
return null;
|
||||
}
|
||||
|
||||
public Object clone(){
|
||||
//don't clone problems
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
|
|||
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.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
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;
|
||||
|
@ -170,7 +171,11 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
|||
|
||||
private boolean isConstructorReference( IASTName name ){
|
||||
IASTNode node = name.getParent();
|
||||
|
||||
if( node instanceof ICPPASTQualifiedName ){
|
||||
IASTName [] ns = ((ICPPASTQualifiedName)node).getNames();
|
||||
if( ns[ ns.length - 1 ] == name )
|
||||
node = node.getParent();
|
||||
}
|
||||
if( node instanceof IASTDeclSpecifier ){
|
||||
IASTNode parent = node.getParent();
|
||||
if( parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression )
|
||||
|
|
|
@ -98,25 +98,71 @@ public class CPPSemantics {
|
|||
|
||||
static protected class LookupData
|
||||
{
|
||||
private IASTName astName;
|
||||
public char[] name;
|
||||
public ObjectMap usingDirectives = ObjectMap.EMPTY_MAP;
|
||||
public ObjectSet visited = ObjectSet.EMPTY_SET; //used to ensure we don't visit things more than once
|
||||
public ObjectSet inheritanceChain; //used to detect circular inheritance
|
||||
|
||||
public boolean qualified = false;
|
||||
public boolean ignoreUsingDirectives = false;
|
||||
public boolean usingDirectivesOnly = false;
|
||||
public boolean forDefinition = false;
|
||||
public boolean typesOnly = false;
|
||||
public List foundItems = null;
|
||||
public Object [] functionParameters;
|
||||
public boolean forUserDefinedConversion;
|
||||
public boolean forUsingDeclaration;
|
||||
public ProblemBinding problem;
|
||||
public boolean considerConstructors;
|
||||
|
||||
public LookupData( char[] n ){
|
||||
name = n;
|
||||
public LookupData( IASTName n ){
|
||||
astName = n;
|
||||
this.name = n.toCharArray();
|
||||
}
|
||||
public LookupData( char [] n ){
|
||||
astName = null;
|
||||
this.name = n;
|
||||
}
|
||||
public boolean typesOnly(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode parent = astName.getParent();
|
||||
return ( parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTElaboratedTypeSpecifier);
|
||||
}
|
||||
public boolean forUsingDeclaration(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode p1 = astName.getParent();
|
||||
IASTNode p2 = p1.getParent();
|
||||
return ( ( p1 instanceof ICPPASTUsingDeclaration ) ||
|
||||
( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTUsingDeclaration ) );
|
||||
}
|
||||
public boolean forDefinition(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode p1 = astName.getParent();
|
||||
IASTNode p2 = p1.getParent();
|
||||
|
||||
return ( ( p1 instanceof ICPPASTQualifiedName && p2 instanceof IASTDeclarator ) ||
|
||||
( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) );
|
||||
}
|
||||
public boolean considerConstructors(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode p1 = astName.getParent();
|
||||
IASTNode p2 = p1.getParent();
|
||||
|
||||
if( p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId )
|
||||
return p2.getParent() instanceof ICPPASTNewExpression;
|
||||
else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTFunctionDeclarator ){
|
||||
IASTName[] names = ((ICPPASTQualifiedName)p1).getNames();
|
||||
if( names.length >= 2 && names[ names.length - 1 ] == astName )
|
||||
return CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) p2 );
|
||||
} else if( p1 instanceof ICPPASTQualifiedName && p2 instanceof ICPPASTNamedTypeSpecifier ){
|
||||
IASTNode p3 = p2.getParent();
|
||||
return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public boolean qualified(){
|
||||
if( astName == null ) return false;
|
||||
IASTNode p1 = astName.getParent();
|
||||
if( p1 instanceof ICPPASTQualifiedName ){
|
||||
return ((ICPPASTQualifiedName)p1).getNames()[0] != astName;
|
||||
}
|
||||
return p1 instanceof ICPPASTFieldReference;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,33 +317,28 @@ public class CPPSemantics {
|
|||
IBinding binding = resolveAmbiguities( data, name );
|
||||
|
||||
//4: post processing
|
||||
if( data.considerConstructors && binding instanceof ICPPClassType ){
|
||||
if( binding instanceof ICPPClassType && data.considerConstructors() ){
|
||||
ICPPClassType cls = (ICPPClassType) binding;
|
||||
//force resolution of constructor bindings
|
||||
cls.getConstructors();
|
||||
//then use the class scope to resolve which one.
|
||||
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding( name );
|
||||
}
|
||||
if( binding != null && data.forDefinition && !( binding instanceof IProblemBinding ) ){
|
||||
if( binding != null && data.forDefinition() && !( binding instanceof IProblemBinding ) ){
|
||||
addDefinition( binding, name );
|
||||
}
|
||||
if( binding == null )
|
||||
binding = new ProblemBinding(IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray() );
|
||||
return binding;
|
||||
}
|
||||
|
||||
static private CPPSemantics.LookupData createLookupData( IASTName name ){
|
||||
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name.toCharArray() );
|
||||
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
|
||||
IASTNode parent = name.getParent();
|
||||
if( parent instanceof ICPPASTQualifiedName ){
|
||||
IASTName[] names = ((ICPPASTQualifiedName)parent).getNames();
|
||||
data.qualified = names[0] != name;
|
||||
parent = parent.getParent();
|
||||
if( parent instanceof IASTDeclarator ){
|
||||
data.forDefinition = true;
|
||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
if( names.length >= 2 && names[ names.length - 1 ] == name )
|
||||
data.considerConstructors = CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) parent );
|
||||
}
|
||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
} else if( parent instanceof IASTIdExpression ){
|
||||
parent = parent.getParent();
|
||||
if( parent instanceof IASTFunctionCallExpression ){
|
||||
|
@ -309,19 +350,9 @@ public class CPPSemantics {
|
|||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
} else if( parent instanceof ICPPASTUsingDeclaration ){
|
||||
data.forUsingDeclaration = true;
|
||||
}
|
||||
} else if( parent instanceof IASTDeclarator ){
|
||||
if( parent.getParent() instanceof IASTSimpleDeclaration )
|
||||
data.forDefinition = true;
|
||||
if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
}
|
||||
} else if ( parent instanceof ICPPASTBaseSpecifier ||
|
||||
parent instanceof ICPPASTElaboratedTypeSpecifier)
|
||||
{
|
||||
data.typesOnly = true;
|
||||
} else if( parent instanceof ICPPASTFunctionDeclarator ){
|
||||
data.functionParameters = ((ICPPASTFunctionDeclarator)parent).getParameters();
|
||||
} else if( parent instanceof IASTIdExpression ){
|
||||
parent = parent.getParent();
|
||||
if( parent instanceof IASTFunctionCallExpression ){
|
||||
|
@ -333,31 +364,20 @@ public class CPPSemantics {
|
|||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
} else if( parent instanceof ICPPASTFieldReference ){
|
||||
data.qualified = true;
|
||||
|
||||
if( parent.getParent() instanceof IASTFunctionCallExpression ){
|
||||
IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression();
|
||||
if( exp instanceof IASTExpressionList )
|
||||
data.functionParameters = ((IASTExpressionList) exp ).getExpressions();
|
||||
else if( exp != null )
|
||||
data.functionParameters = new IASTExpression [] { exp };
|
||||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
}
|
||||
} else if( parent instanceof ICPPASTUsingDeclaration ){
|
||||
data.forUsingDeclaration = true;
|
||||
} else if( parent instanceof ICPPASTNamedTypeSpecifier ){
|
||||
if( parent.getParent() instanceof IASTTypeId ){
|
||||
IASTTypeId typeId = (IASTTypeId) parent.getParent();
|
||||
if( typeId.getAbstractDeclarator() instanceof IASTFunctionDeclarator ){
|
||||
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) typeId.getAbstractDeclarator();
|
||||
data.functionParameters = fdtor.getParameters();
|
||||
}
|
||||
if( typeId.getParent() instanceof ICPPASTNewExpression ){
|
||||
data.considerConstructors = true;
|
||||
}
|
||||
}
|
||||
} else if( parent instanceof ICPPASTFieldReference && parent.getParent() instanceof IASTFunctionCallExpression ){
|
||||
IASTExpression exp = ((IASTFunctionCallExpression)parent.getParent()).getParameterExpression();
|
||||
if( exp instanceof IASTExpressionList )
|
||||
data.functionParameters = ((IASTExpressionList) exp ).getExpressions();
|
||||
else if( exp != null )
|
||||
data.functionParameters = new IASTExpression [] { exp };
|
||||
else
|
||||
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
|
||||
} else if( parent instanceof ICPPASTNamedTypeSpecifier && parent.getParent() instanceof IASTTypeId ){
|
||||
IASTTypeId typeId = (IASTTypeId) parent.getParent();
|
||||
if( typeId.getAbstractDeclarator() instanceof IASTFunctionDeclarator ){
|
||||
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) typeId.getAbstractDeclarator();
|
||||
data.functionParameters = fdtor.getParameters();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -365,13 +385,7 @@ public class CPPSemantics {
|
|||
static private ICPPScope getLookupScope( IASTName name ){
|
||||
IASTNode parent = name.getParent();
|
||||
|
||||
if( parent instanceof IASTDeclSpecifier ){
|
||||
IASTNode node = parent.getParent();
|
||||
if( node instanceof IASTParameterDeclaration ){
|
||||
IASTNode n = CPPVisitor.getContainingBlockItem( parent );
|
||||
return (ICPPScope) CPPVisitor.getContainingScope( n );
|
||||
}
|
||||
} else if( parent instanceof ICPPASTBaseSpecifier ) {
|
||||
if( parent instanceof ICPPASTBaseSpecifier ) {
|
||||
IASTNode n = CPPVisitor.getContainingBlockItem( parent );
|
||||
return (ICPPScope) CPPVisitor.getContainingScope( n );
|
||||
} else if( parent instanceof ICPPASTConstructorChainInitializer ){
|
||||
|
@ -419,7 +433,7 @@ public class CPPSemantics {
|
|||
transitives.clear();
|
||||
transitives = lookupInNominated( data, scope, transitives );
|
||||
|
||||
if( !data.qualified || data.foundItems == null ){
|
||||
if( !data.qualified() || data.foundItems == null ){
|
||||
processDirectives( data, scope, transitives );
|
||||
}
|
||||
}
|
||||
|
@ -437,7 +451,7 @@ public class CPPSemantics {
|
|||
return;
|
||||
|
||||
//if still not found, loop and check our containing scope
|
||||
if( data.qualified && !data.usingDirectives.isEmpty() )
|
||||
if( data.qualified() && !data.usingDirectives.isEmpty() )
|
||||
data.usingDirectivesOnly = true;
|
||||
|
||||
if( blockItem != null )
|
||||
|
@ -623,6 +637,10 @@ public class CPPSemantics {
|
|||
namespaceIdx = -1;
|
||||
}
|
||||
|
||||
if( scope instanceof ICPPClassScope ){
|
||||
blockItem = null;
|
||||
}
|
||||
|
||||
int idx = -1;
|
||||
IASTNode item = ( nodes != null ? (nodes.length > 0 ? nodes[++idx] : null ) : parent );
|
||||
|
||||
|
@ -695,7 +713,7 @@ public class CPPSemantics {
|
|||
|
||||
//only consider the transitive using directives if we are an unqualified
|
||||
//lookup, or we didn't find the name in decl
|
||||
if( usings != null && usings.size() > 0 && (!data.qualified || found == null ) ){
|
||||
if( usings != null && usings.size() > 0 && (!data.qualified() || found == null ) ){
|
||||
if( transitives == null )
|
||||
transitives = new ArrayList(2);
|
||||
transitives.addAll( usings );
|
||||
|
@ -719,11 +737,11 @@ public class CPPSemantics {
|
|||
|
||||
if( declaration instanceof IASTSimpleDeclaration ){
|
||||
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
||||
if( !data.typesOnly ) {
|
||||
if( !data.typesOnly() ) {
|
||||
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
|
||||
for( int i = 0; i < declarators.length; i++ ){
|
||||
IASTDeclarator declarator = declarators[i];
|
||||
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
if( data.considerConstructors() || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
IASTName declaratorName = declarator.getName();
|
||||
if( CharArrayUtils.equals( declaratorName.toCharArray(), data.name ) ){
|
||||
return declaratorName;
|
||||
|
@ -750,7 +768,7 @@ public class CPPSemantics {
|
|||
if( CharArrayUtils.equals( eName.toCharArray(), data.name ) ){
|
||||
return eName;
|
||||
}
|
||||
if( !data.typesOnly ) {
|
||||
if( !data.typesOnly() ) {
|
||||
//check enumerators too
|
||||
IASTEnumerator [] list = enumeration.getEnumerators();
|
||||
for( int i = 0; i < list.length; i++ ) {
|
||||
|
@ -775,7 +793,7 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
}
|
||||
if( data.typesOnly )
|
||||
if( data.typesOnly() )
|
||||
return null;
|
||||
|
||||
if( declaration instanceof IASTFunctionDefinition ){
|
||||
|
@ -784,7 +802,7 @@ public class CPPSemantics {
|
|||
|
||||
//check the function itself
|
||||
IASTName declName = declarator.getName();
|
||||
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
if( data.considerConstructors() || !CPPVisitor.isConstructor( scope, declarator ) ){
|
||||
if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){
|
||||
return declName;
|
||||
}
|
||||
|
@ -897,7 +915,7 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
if( type != null ) {
|
||||
if( data.typesOnly || (obj == null && fns == null) )
|
||||
if( data.typesOnly() || (obj == null && fns == null) )
|
||||
return type;
|
||||
IScope typeScope = type.getScope();
|
||||
if( obj != null && obj.getScope() != typeScope ){
|
||||
|
@ -960,7 +978,7 @@ public class CPPSemantics {
|
|||
//if there are m arguments in the list, all candidate functions having m parameters
|
||||
//are viable
|
||||
if( num == numParameters ){
|
||||
if( data.forDefinition && !functionHasParameters( fName, (IASTParameterDeclaration[]) data.functionParameters ) ){
|
||||
if( data.forDefinition() && !functionHasParameters( fName, (IASTParameterDeclaration[]) data.functionParameters ) ){
|
||||
functions.remove( i-- );
|
||||
size--;
|
||||
}
|
||||
|
@ -1024,7 +1042,7 @@ public class CPPSemantics {
|
|||
return null;
|
||||
}
|
||||
static private IBinding resolveFunction( CPPSemantics.LookupData data, List fns ){
|
||||
if( data.forUsingDeclaration ){
|
||||
if( data.forUsingDeclaration() ){
|
||||
if( fns.size() == 1 )
|
||||
return (IBinding) fns.get( 0 );
|
||||
return new CPPCompositeBinding( fns );
|
||||
|
@ -1140,7 +1158,7 @@ public class CPPSemantics {
|
|||
//In order for this function to be better than the previous best, it must
|
||||
//have at least one parameter match that is better that the corresponding
|
||||
//match for the other function, and none that are worse.
|
||||
for( int j = 0; j < numSourceParams; j++ ){
|
||||
for( int j = 0; j < numSourceParams || j == 0; j++ ){
|
||||
if( currFnCost[ j ].rank < 0 ){
|
||||
hasWorse = true;
|
||||
hasBetter = false;
|
||||
|
|
|
@ -73,6 +73,7 @@ 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.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
|
@ -127,17 +128,22 @@ public class CPPVisitor {
|
|||
*/
|
||||
public static IBinding createBinding(IASTName name) {
|
||||
IASTNode parent = name.getParent();
|
||||
IBinding binding = null;
|
||||
if( parent instanceof IASTNamedTypeSpecifier ||
|
||||
parent instanceof ICPPASTQualifiedName ||
|
||||
parent instanceof ICPPASTBaseSpecifier ||
|
||||
parent instanceof ICPPASTConstructorChainInitializer )
|
||||
{
|
||||
IBinding binding = CPPSemantics.resolveBinding( name );
|
||||
if( binding == null && parent instanceof ICPPASTQualifiedName ){
|
||||
binding = createBinding( (IASTName) parent );
|
||||
binding = CPPSemantics.resolveBinding( name );
|
||||
if( binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName ){
|
||||
if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND ){
|
||||
parent = parent.getParent();
|
||||
}
|
||||
} else {
|
||||
return binding;
|
||||
}
|
||||
return binding;
|
||||
} else if( parent instanceof IASTIdExpression ){
|
||||
}
|
||||
if( parent instanceof IASTIdExpression ){
|
||||
return resolveBinding( parent );
|
||||
} else if( parent instanceof ICPPASTFieldReference ){
|
||||
return resolveBinding( parent );
|
||||
|
@ -497,20 +503,14 @@ public class CPPVisitor {
|
|||
* @return
|
||||
*/
|
||||
public static IScope getContainingScope(IASTParameterDeclaration parameterDeclaration) {
|
||||
IASTNode parent = parameterDeclaration.getParent();
|
||||
if( parent instanceof IASTStandardFunctionDeclarator ){
|
||||
IASTStandardFunctionDeclarator functionDeclarator = (IASTStandardFunctionDeclarator) parent;
|
||||
if( functionDeclarator.getNestedDeclarator() != null ){
|
||||
return getContainingScope( functionDeclarator );
|
||||
}
|
||||
IASTName fnName = functionDeclarator.getName();
|
||||
IBinding binding = fnName.resolveBinding();
|
||||
if( binding instanceof IFunction )
|
||||
return ((IFunction)binding).getFunctionScope();
|
||||
return binding.getScope();
|
||||
}
|
||||
|
||||
return null;
|
||||
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parameterDeclaration.getParent();
|
||||
IASTName name = dtor.getName();
|
||||
if( name instanceof ICPPASTQualifiedName ) {
|
||||
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
|
||||
if( ns.length > 0 )
|
||||
return getContainingScope( ns [ ns.length - 1 ] );
|
||||
}
|
||||
return getContainingScope( dtor );
|
||||
}
|
||||
|
||||
public static IASTNode getContainingBlockItem( IASTNode node ){
|
||||
|
@ -1285,6 +1285,10 @@ public class CPPVisitor {
|
|||
IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding();
|
||||
if( binding instanceof IType )
|
||||
type = (IType) binding;
|
||||
} else if( declSpec instanceof IASTEnumerationSpecifier ){
|
||||
IBinding binding = ((IASTEnumerationSpecifier)declSpec).getName().resolveBinding();
|
||||
if( binding instanceof IType )
|
||||
type = (IType) binding;
|
||||
} else if( declSpec instanceof ICPPASTSimpleDeclSpecifier ){
|
||||
ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec;
|
||||
int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) &
|
||||
|
|
Loading…
Add table
Reference in a new issue