1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bindings in the new Parser:

- Class Scopes
- Implicit member functions
This commit is contained in:
Andrew Niefer 2005-01-21 21:07:42 +00:00
parent 8c18009c05
commit 0f10569314
21 changed files with 779 additions and 196 deletions

View file

@ -35,15 +35,18 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
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;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor;
@ -899,5 +902,54 @@ public class AST2CPPTests extends AST2BaseTest {
assertInstances( collector, x2, 1 );
}
public void testImplicitConstructors() throws Exception{
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { }; " ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTCompositeTypeSpecifier compSpec = (IASTCompositeTypeSpecifier) decl.getDeclSpecifier();
ICPPClassType A = (ICPPClassType) compSpec.getName().resolveBinding();
ICPPConstructor [] ctors = A.getConstructors();
assertNotNull( ctors );
assertEquals( ctors.length, 2 );
assertEquals( ctors[0].getParameters().length, 0 );
assertEquals( ctors[1].getParameters().length, 1 );
IType t = ctors[1].getParameters()[0].getType();
assertTrue( t instanceof ICPPReferenceType );
assertTrue( ((ICPPReferenceType) t).getType() instanceof IQualifierType );
IQualifierType qt = (IQualifierType) ((ICPPReferenceType) t).getType();
assertTrue( qt.isConst() );
assertSame( qt.getType(), A );
}
public void testConstructors() throws Exception{
StringBuffer buffer = new StringBuffer();
buffer.append( "class A { A(); A( const A & ); }; " ); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0];
IASTCompositeTypeSpecifier compSpec = (IASTCompositeTypeSpecifier) decl.getDeclSpecifier();
ICPPClassType A = (ICPPClassType) compSpec.getName().resolveBinding();
ICPPConstructor [] ctors = A.getConstructors();
assertNotNull( ctors );
assertEquals( ctors.length, 2 );
assertEquals( ctors[0].getParameters().length, 0 );
assertEquals( ctors[1].getParameters().length, 1 );
IType t = ctors[1].getParameters()[0].getType();
assertTrue( t instanceof ICPPReferenceType );
assertTrue( ((ICPPReferenceType) t).getType() instanceof IQualifierType );
IQualifierType qt = (IQualifierType) ((ICPPReferenceType) t).getType();
assertTrue( qt.isConst() );
assertSame( qt.getType(), A );
}
}

View file

@ -531,8 +531,8 @@ public class AST2KnRTests extends AST2BaseTest {
assertEquals( x4.resolveBinding(), x5.resolveBinding() );
// test CFunction.getParameters size
List f1_parms = f_fun1.getParameters();
assertEquals( f1_parms.size(), 1 );
IParameter[] f1_parms = f_fun1.getParameters();
assertEquals( f1_parms.length, 1 );
// test tu.getDeclarations(IBinding)
IASTName[] decls = tu.getDeclarations(x2.resolveBinding());
@ -600,10 +600,10 @@ public class AST2KnRTests extends AST2BaseTest {
IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0];
ICASTKnRFunctionDeclarator f_decltor = (ICASTKnRFunctionDeclarator)f.getDeclarator();
IFunction f_fun = (IFunction)f_decltor.getName().resolveBinding();
List f_parms = f_fun.getParameters();
assertEquals( f_parms.size(), 2 );
assertEquals( ((CKnRParameter)f_parms.get(0)).getName(), "a" ); //$NON-NLS-1$
assertEquals( ((CKnRParameter)f_parms.get(1)).getName(), "b" ); //$NON-NLS-1$
IParameter [] f_parms = f_fun.getParameters();
assertEquals( f_parms.length, 2 );
assertEquals( ((CKnRParameter)f_parms[0]).getName(), "a" ); //$NON-NLS-1$
assertEquals( ((CKnRParameter)f_parms[1]).getName(), "b" ); //$NON-NLS-1$
}

View file

@ -10,8 +10,6 @@
**********************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
@ -786,10 +784,10 @@ public class AST2Tests extends AST2BaseTest {
assertEquals( "a", param_a.getName() ); //$NON-NLS-1$
assertEquals( "b", param_b.getName() ); //$NON-NLS-1$
List params = function.getParameters();
assertEquals( 2, params.size() );
assertSame( params.get(0), param_a );
assertSame( params.get(1), param_b );
IParameter[] params = function.getParameters();
assertEquals( 2, params.length );
assertSame( params[0], param_a );
assertSame( params[1], param_b );
// test tu.getDeclarations(IBinding)
IASTName[] decls = tu.getDeclarations(fName.resolveBinding());

View file

@ -404,8 +404,8 @@ public class CompleteParser2Tests extends TestCase {
IFunction foo = (IFunction) col.getName(0).resolveBinding();
IParameter p = (IParameter) col.getName(1).resolveBinding();
assertEquals( foo.getParameters().size(), 1 );
assertSame( foo.getParameters().get(0), p );
assertEquals( foo.getParameters().length, 1 );
assertSame( foo.getParameters()[0], p );
assertSame( p.getScope(), foo.getFunctionScope() );
}

View file

@ -10,7 +10,6 @@
**********************************************************************/
package org.eclipse.cdt.core.dom.ast;
import java.util.List;
/**
* This represents a function in the program. A function is also a scope
@ -25,7 +24,7 @@ public interface IFunction extends IBinding {
*
* @return List of IParameter
*/
public List getParameters();
public IParameter [] getParameters();
/**
* Get the function scope

View file

@ -17,5 +17,5 @@ package org.eclipse.cdt.core.dom.ast;
* @author Doug Schaefer
*/
public interface IParameter extends IVariable {
public static final IParameter [] EMPTY_PARAMETER_ARRAY = new IParameter[0];
}

View file

@ -70,5 +70,10 @@ public interface ICPPClassType extends ICompositeType {
* @return List of ICPPMethod
*/
public List getDeclaredMethods();
/**
* @return
*/
public ICPPConstructor[] getConstructors();
}

View file

@ -18,4 +18,9 @@ package org.eclipse.cdt.core.dom.ast.cpp;
*/
public interface ICPPConstructor extends ICPPMethod {
/**
* @return
*/
boolean isExplicit();
}

View file

@ -19,15 +19,13 @@ 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.internal.core.dom.parser.cpp.CPPSemantics;
import org.eclipse.cdt.internal.core.parser.ParserMessages;
/**
* @author aniefer
*/
public class ProblemBinding implements IProblemBinding {
private final static String EMPTY_NAME = ""; //$NON-NLS-1$
private final static char[] EMPTY_NAME_ARRAY = new char[0];
private final int id;
private final char [] arg;
@ -89,14 +87,14 @@ public class ProblemBinding implements IProblemBinding {
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return EMPTY_NAME;
return CPPSemantics.EMPTY_NAME;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return EMPTY_NAME_ARRAY;
return CPPSemantics.EMPTY_NAME_ARRAY;
}
/* (non-Javadoc)

View file

@ -10,9 +10,6 @@
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
@ -24,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
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.IType;
import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
@ -84,24 +82,24 @@ public class CFunction implements IFunction {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters()
*/
public List getParameters() {
List result = null;
public IParameter[] getParameters() {
IParameter [] result = null;
IASTFunctionDeclarator dtor = ( definition != null ) ? definition : declarators[0];
if (dtor instanceof IASTStandardFunctionDeclarator) {
IASTParameterDeclaration[] params = ((IASTStandardFunctionDeclarator)dtor).getParameters();
int size = params.length;
result = new ArrayList( size );
result = new IParameter[ size ];
if( size > 0 ){
for( int i = 0; i < size; i++ ){
IASTParameterDeclaration p = params[i];
result.add( p.getDeclarator().getName().resolveBinding() );
result[i] = (IParameter) p.getDeclarator().getName().resolveBinding();
}
}
} else if (dtor instanceof ICASTKnRFunctionDeclarator) {
IASTDeclaration[] params = ((ICASTKnRFunctionDeclarator)dtor).getParameterDeclarations();
IASTName[] names = ((ICASTKnRFunctionDeclarator)dtor).getParameterNames();
result = new ArrayList( names.length );
result = new IParameter[ names.length ];
if( names.length > 0 ){
// ensures that the List of parameters is created in the same order as the K&R C parameter names
for( int i=0; i<names.length; i++ ) {
@ -110,10 +108,9 @@ public class CFunction implements IFunction {
IASTDeclarator[] decltors = ((IASTSimpleDeclaration)params[j]).getDeclarators();
for (int k=0; k<decltors.length; k++) {
if ( CharArrayUtils.equals(names[i].toCharArray(), decltors[k].getName().toCharArray()) ) {
result.add( decltors[k].getName().resolveBinding() );
result[i] = (IParameter) decltors[k].getName().resolveBinding();
}
}
}
} }
}
}
}

View file

@ -69,6 +69,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
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.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
@ -683,9 +684,9 @@ public class CVisitor {
int index = -1;
for( index = 0; index < ps.length; index++ )
if( ps[index] == param ) break;
List params = function.getParameters();
if( index >= 0 && index < params.size() ){
return (IBinding) params.get( index );
IParameter [] params = function.getParameters();
if( index >= 0 && index < params.length ){
return params[ index ];
}
}
}
@ -1651,9 +1652,9 @@ public class CVisitor {
outerLoop: for( index = 0; index < ps.length; index++ )
for (int j=0; j<parmDeclarations.length; j++)
if( ps[index] == parmDeclarations[j] ) break outerLoop;
List params = function.getParameters();
if( index >= 0 && index < params.size() ){
return (IBinding) params.get( index );
IParameter[] params = function.getParameters();
if( index >= 0 && index < params.length ){
return params[ index ];
}
}
}

View file

@ -13,38 +13,151 @@
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
/**
* @author aniefer
*/
public class CPPClassScope extends CPPScope implements ICPPClassScope {
public CPPClassScope( IASTNode physicalNode ) {
private CharArrayObjectMap bindings = CharArrayObjectMap.EMPTY_MAP;
private ICPPConstructor [] constructors = null;
public CPPClassScope( ICPPASTCompositeTypeSpecifier physicalNode ) {
super( physicalNode );
createImplicitMembers();
}
// 12.1 The default constructor, copy constructor, copy assignment operator, and destructor are
//special member functions. The implementation will implicitly declare these member functions
//for a class type when the program does not declare them.
private void createImplicitMembers(){
//create bindings for the implicit members, if the user declared them then those declarations
//will resolve to these bindings.
ICPPASTCompositeTypeSpecifier compTypeSpec = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
//default constructor: A()
addBinding( new CPPImplicitConstructor( this, IParameter.EMPTY_PARAMETER_ARRAY ) );
ICPPClassType clsType = (ICPPClassType) compTypeSpec.getName().resolveBinding();
//copy constructor: A( const A & )
IType pType = new CPPReferenceType( new CPPQualifierType( clsType, true, false ) );
IParameter [] ps = new IParameter [] { new CPPParameter( pType ) };
addBinding( new CPPImplicitConstructor( this, ps ) );
//copy assignment operator: A& operator = ( const A & )
IType refType = new CPPReferenceType( clsType );
addBinding( new CPPImplicitMethod( this, "operator =".toCharArray(), refType, ps ) ); //$NON-NLS-1$
//destructor: ~A()
char [] dtorName = CharArrayUtils.concat( "~".toCharArray(), compTypeSpec.getName().toCharArray() ); //$NON-NLS-1$
addBinding( new CPPImplicitMethod( this, dtorName, new CPPBasicType( IBasicType.t_unspecified, 0 ), IParameter.EMPTY_PARAMETER_ARRAY ) );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/
public void addBinding(IBinding binding) {
// TODO Auto-generated method stub
if( binding instanceof ICPPConstructor ){
addConstructor( (ICPPConstructor) binding );
return;
}
if( bindings == CharArrayObjectMap.EMPTY_MAP )
bindings = new CharArrayObjectMap(1);
char [] c = binding.getNameCharArray();
Object o = bindings.get( c );
if( o != null ){
if( o instanceof List ){
((List)o).add( binding );
} else {
List list = new ArrayList(2);
list.add( o );
list.add( binding );
bindings.put( c, list );
}
} else {
bindings.put( c, binding );
}
}
private void addConstructor( ICPPConstructor constructor ){
if( constructors == null )
constructors = new ICPPConstructor[ 2 ];
int i = 0;
for( ; i < constructors.length; i++ ){
if( constructors[i] == null ){
constructors[i] = constructor;
return;
}
}
ICPPConstructor [] temp = new ICPPConstructor[ constructors.length * 2 ];
System.arraycopy( constructors, 0, temp, 0, constructors.length );
temp[ constructors.length ] = constructor;
constructors = temp;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
*/
public IBinding getBinding( IASTName name ) {
// TODO Auto-generated method stub
return null;
char [] c = name.toCharArray();
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
if( CharArrayUtils.equals( c, compType.getName().toCharArray() ) ){
if( isConstructorReference( name ) ){
if( constructors == null )
return null;
return CPPSemantics.resolveAmbiguities( name, Arrays.asList( constructors ) );
}
//9.2 ... The class-name is also inserted into the scope of the class itself
return compType.getName().resolveBinding();
}
Object obj = bindings.get( c );
if( obj != null ){
if( obj instanceof List ){
obj = CPPSemantics.resolveAmbiguities( name, (List) obj );
}
}
return (IBinding) obj;
}
protected ICPPConstructor [] getConstructors(){
if( constructors == null ){
constructors = new ICPPConstructor[0];
return constructors;
}
int i = 0;
for( ; i < constructors.length; i++ )
if( constructors[i] == null )
break;
if( i < constructors.length ){
ICPPConstructor[] temp = new ICPPConstructor[ i ];
System.arraycopy( constructors, 0, temp, 0, i );
constructors = temp;
}
return constructors;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/
@ -52,5 +165,14 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
// TODO Auto-generated method stub
return null;
}
private boolean isConstructorReference( IASTName name ){
IASTNode node = name.getParent();
if( node instanceof IASTDeclSpecifier )
return false;
return true;
}
}

View file

@ -16,24 +16,30 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
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.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
/**
* @author aniefer
@ -49,19 +55,73 @@ public class CPPClassType implements ICPPClassType {
declarations = new ICPPASTElaboratedTypeSpecifier[] { (ICPPASTElaboratedTypeSpecifier) declSpec };
}
private ICPPASTCompositeTypeSpecifier checkForDefinition( IASTElaboratedTypeSpecifier declSpec ){
//TODO
return null;
private class FindDefinitionAction extends CPPVisitor.CPPBaseVisitorAction {
private char [] nameArray = CPPClassType.this.getNameCharArray();
public ICPPASTCompositeTypeSpecifier result = null;
{
processNames = true;
processDeclarations = true;
processDeclSpecifiers = true;
processDeclarators = true;
processNamespaces = true;
}
public int processName( IASTName name ){
if( name.getParent() instanceof ICPPASTCompositeTypeSpecifier &&
CharArrayUtils.equals( name.toCharArray(), nameArray ) )
{
IBinding binding = name.resolveBinding();
if( binding == CPPClassType.this ){
result = (ICPPASTCompositeTypeSpecifier) name.getParent();
return PROCESS_ABORT;
}
}
return PROCESS_CONTINUE;
}
public int processDeclaration( IASTDeclaration declaration ){
return (declaration instanceof IASTSimpleDeclaration ) ? PROCESS_CONTINUE : PROCESS_SKIP;
}
public int processDeclSpecifier( IASTDeclSpecifier declSpec ){
return (declSpec instanceof ICPPASTCompositeTypeSpecifier ) ? PROCESS_CONTINUE : PROCESS_SKIP;
}
public int processDeclarators( IASTDeclarator declarator ) { return PROCESS_SKIP; }
}
private void checkForDefinition(){
FindDefinitionAction action = new FindDefinitionAction();
IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent();
if( node instanceof ICPPASTNamespaceDefinition ){
CPPVisitor.visitNamespaceDefinition( (ICPPASTNamespaceDefinition) node, action );
definition = action.result;
} else if( node instanceof IASTCompoundStatement ){
//a local class, nowhere else to look if we don't find it here...
CPPVisitor.visitStatement( (IASTStatement) node, action );
definition = action.result;
return;
}
if( definition == null ){
IASTTranslationUnit tu = null;
while( !(node instanceof IASTTranslationUnit) ) {
node = node.getParent();
}
tu = (IASTTranslationUnit) node;
CPPVisitor.visitTranslationUnit( tu, action );
definition = action.result;
}
return;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields()
*/
public List getFields() {
if( definition == null ){
ICPPASTCompositeTypeSpecifier temp = checkForDefinition( declarations[0] );
if( temp == null )
checkForDefinition();
if( definition == null )
return null; //TODO IProblem
definition = temp;
}
IASTDeclaration[] members = definition.getMembers();
@ -226,7 +286,30 @@ public class CPPClassType implements ICPPClassType {
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
*/
public ICPPConstructor[] getConstructors() {
// TODO Auto-generated method stub
return null;
if( definition == null ){
checkForDefinition();
if( definition == null ){
return null; //TODO problem
}
}
ICPPClassScope scope = (ICPPClassScope) getCompositeScope();
IASTDeclaration [] members = definition.getMembers();
for( int i = 0; i < members.length; i++ ){
if( members[i] instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)members[i]).getDeclarators();
for( int j = 0; j < dtors.length; j++ ){
if( dtors[j] == null ) break;
if( CPPVisitor.isConstructor( scope, dtors[j] ) )
dtors[j].getName().resolveBinding();
}
} else if( members[i] instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)members[i]).getDeclarator();
if( CPPVisitor.isConstructor( scope, dtor ) )
dtor.getName().resolveBinding();
}
}
return ((CPPClassScope)scope).getConstructors();
}
}

View file

@ -28,4 +28,12 @@ public class CPPConstructor extends CPPMethod implements ICPPConstructor {
super( declarator );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
*/
public boolean isExplicit() {
// TODO Auto-generated method stub
return false;
}
}

View file

@ -13,9 +13,6 @@
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -24,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
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.ICPPASTFunctionDeclarator;
@ -33,14 +31,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
public class CPPFunction implements IFunction {
protected ICPPASTFunctionDeclarator [] declarations;
protected ICPPASTFunctionDeclarator definition;
private IFunctionType type = null;
protected IFunctionType type = null;
public CPPFunction( ICPPASTFunctionDeclarator declarator ){
IASTNode parent = declarator.getParent();
if( parent instanceof IASTFunctionDefinition )
definition = declarator;
else
declarations = new ICPPASTFunctionDeclarator [] { declarator };
if( declarator != null ) {
IASTNode parent = declarator.getParent();
if( parent instanceof IASTFunctionDefinition )
definition = declarator;
else
declarations = new ICPPASTFunctionDeclarator [] { declarator };
}
}
public void addDefinition( ICPPASTFunctionDeclarator dtor ){
@ -56,6 +56,7 @@ public class CPPFunction implements IFunction {
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = dtor;
updateParameterBindings( dtor );
return;
}
}
@ -68,15 +69,15 @@ public class CPPFunction implements IFunction {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters()
*/
public List getParameters() {
public IParameter [] getParameters() {
IASTStandardFunctionDeclarator dtor = ( definition != null ) ? definition : declarations[0];
IASTParameterDeclaration[] params = dtor.getParameters();
int size = params.length;
List result = new ArrayList( size );
IParameter [] result = new IParameter[ size ];
if( size > 0 ){
for( int i = 0; i < size; i++ ){
IASTParameterDeclaration p = params[i];
result.add( p.getDeclarator().getName().resolveBinding() );
result[i] = (IParameter) p.getDeclarator().getName().resolveBinding();
}
}
return result;
@ -118,7 +119,11 @@ public class CPPFunction implements IFunction {
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return ( definition != null ) ? definition : declarations[0];
if( definition != null )
return definition;
else if( declarations != null && declarations.length > 0 )
return declarations[0];
return null;
}
/* (non-Javadoc)
@ -145,14 +150,14 @@ public class CPPFunction implements IFunction {
}
//create a new binding and set it for the corresponding parameter in all known defns and decls
binding = new CPPParameter( param.getDeclarator() );
binding = new CPPParameter( name );
IASTParameterDeclaration temp = null;
if( definition != null ){
temp = definition.getParameters()[i];
((CPPASTName)temp.getDeclarator().getName()).setBinding( binding );
}
if( declarations != null ){
for( int j = 0; j < declarations.length; j++ ){
for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){
temp = declarations[j].getParameters()[i];
((CPPASTName)temp.getDeclarator().getName()).setBinding( binding );
}
@ -160,15 +165,17 @@ public class CPPFunction implements IFunction {
return binding;
}
private void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){
protected void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){
ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) getPhysicalNode();
IASTParameterDeclaration [] ops = orig.getParameters();
IASTParameterDeclaration [] nps = fdtor.getParameters();
IBinding temp = null;
CPPParameter temp = null;
for( int i = 0; i < nps.length; i++ ){
temp = ((CPPASTName)ops[i].getDeclarator().getName()).getBinding();
temp = (CPPParameter) ((CPPASTName)ops[i].getDeclarator().getName()).getBinding();
if( temp != null ){
((CPPASTName)nps[i].getDeclarator().getName()).setBinding( temp );
CPPASTName name = (CPPASTName) nps[i].getDeclarator().getName();
name.setBinding( temp );
temp.addDeclaration( name );
}
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* 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 Jan 19, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
/**
* @author aniefer
*/
public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
/**
* @param name
* @param params
*/
public CPPImplicitConstructor( ICPPClassScope scope, IParameter[] params ) {
super( scope, CPPSemantics.EMPTY_NAME_ARRAY, new CPPBasicType( IBasicType.t_unspecified, 0 ), params );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit()
*/
public boolean isExplicit() {
return false;
}
}

View file

@ -0,0 +1,125 @@
/*******************************************************************************
* 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 Jan 19, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
/**
* @author aniefer
*/
public class CPPImplicitMethod extends CPPMethod {
private char [] implicitName = null;
private IParameter [] parameters = null;
private IType returnType = null;
private ICPPClassScope scope = null;
public CPPImplicitMethod( ICPPClassScope scope, char[] name, IType returnType, IParameter[] params ) {
super( null );
this.implicitName = name;
this.parameters = params;
this.returnType = returnType;
}
/**
* @param cs
* @param ps
*/
public IParameter [] getParameters() {
return parameters;
}
public IFunctionType getType() {
if( type == null ) {
type = CPPVisitor.createImplicitFunctionType( returnType, parameters );
}
return type;
}
public String getName() {
return String.valueOf( implicitName );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return implicitName;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/
public IScope getScope() {
return scope;
}
public IBinding resolveParameter( IASTParameterDeclaration param ){
IASTName name = param.getDeclarator().getName();
IParameter binding = (IParameter) ((CPPASTName)name).getBinding();
if( binding != null )
return binding;
//get the index in the parameter list
ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent();
IASTParameterDeclaration [] ps = fdtor.getParameters();
int i = 0;
for( ; i < ps.length; i++ ){
if( param == ps[i] )
break;
}
//set the binding for the corresponding parameter in all known defns and decls
binding = parameters[i];
IASTParameterDeclaration temp = null;
if( definition != null ){
temp = definition.getParameters()[i];
CPPASTName n = (CPPASTName) temp.getDeclarator().getName();
n.setBinding( binding );
((CPPParameter)binding).addDeclaration( n );
}
if( declarations != null ){
for( int j = 0; j < declarations.length; j++ ){
temp = declarations[j].getParameters()[i];
CPPASTName n = (CPPASTName) temp.getDeclarator().getName();
n.setBinding( binding );
((CPPParameter)binding).addDeclaration( n );
}
}
return binding;
}
protected void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){
if( parameters != null ){
IASTParameterDeclaration [] nps = fdtor.getParameters();
if( nps.length != parameters.length )
return;
for( int i = 0; i < nps.length; i++ ){
CPPASTName name = (CPPASTName) nps[i].getDeclarator().getName();
name.setBinding( parameters[i] );
((CPPParameter)parameters[i]).addDeclaration( name );
}
}
}
}

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -24,22 +25,49 @@ import org.eclipse.cdt.core.dom.ast.IType;
*/
public class CPPParameter implements IParameter {
private IType type = null;
private IASTDeclarator declarator = null;
public CPPParameter( IASTDeclarator declarator ){
this.declarator = declarator;
private IASTName [] declarations = null;
public CPPParameter( IASTName name ){
this.declarations = new IASTName [] { name };
}
public CPPParameter( IType type ){
this.type = type;
}
public void addDeclaration( IASTName name ){
if( declarations == null ){
declarations = new IASTName [] { name };
return;
}
for( int i = 0; i < declarations.length; i++ ){
if( declarations[i] == null ){
declarations[i] = name;
return;
}
}
IASTName [] tmp = new IASTName[ declarations.length * 2 ];
System.arraycopy( declarations, 0, tmp, 0, declarations.length );
tmp[ declarations.length ] = name;
declarations = tmp;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/
public String getName() {
return declarator.getName().toString();
if( declarations != null )
return declarations[0].toString();
return CPPSemantics.EMPTY_NAME;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
public char[] getNameCharArray() {
return declarator.getName().toCharArray();
if( declarations != null )
return declarations[0].toCharArray();
return CPPSemantics.EMPTY_NAME_ARRAY;
}
/* (non-Javadoc)
@ -54,15 +82,18 @@ public class CPPParameter implements IParameter {
* @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode()
*/
public IASTNode getPhysicalNode() {
return declarator;
if( declarations != null )
return declarations[0];
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
*/
public IType getType() {
if( type == null )
type = CPPVisitor.createType( declarator );
if( type == null && declarations != null ){
type = CPPVisitor.createType( (IASTDeclarator) declarations[0].getParent() );
}
return type;
}

View file

@ -43,8 +43,11 @@ public class CPPReferenceType implements ICPPReferenceType, ITypeContainer {
}
public boolean equals(Object obj) {
if( type == null )
return (obj == null);
if( obj instanceof ICPPReferenceType ){
return ((ICPPReferenceType) obj).getType().equals( type );
return type.equals( ((ICPPReferenceType) obj).getType() );
}
return false;
}

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -65,6 +66,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
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.ICPPCompositeBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
@ -84,6 +87,8 @@ import org.eclipse.cdt.internal.core.parser.pst.ITypeInfo;
public class CPPSemantics {
public static final char[] EMPTY_NAME_ARRAY = new char[0];
public static final String EMPTY_NAME = ""; //$NON-NLS-1$
public static final char[] OPERATOR_ = new char[] {'o','p','e','r','a','t','o','r',' '}; //$NON-NLS-1$
public static final IType VOID_TYPE = new CPPBasicType( IBasicType.t_void, 0 );
static protected class LookupData
@ -103,6 +108,7 @@ public class CPPSemantics {
public boolean forUserDefinedConversion;
public boolean forUsingDeclaration;
public ProblemBinding problem;
public boolean considerConstructors;
public LookupData( char[] n ){
name = n;
@ -268,12 +274,15 @@ public class CPPSemantics {
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name.toCharArray() );
IASTNode parent = name.getParent();
if( parent instanceof ICPPASTQualifiedName ){
data.qualified = ((ICPPASTQualifiedName)parent).getNames()[0] != name;
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 );
}
} else if( parent instanceof IASTIdExpression ){
parent = parent.getParent();
@ -292,6 +301,9 @@ public class CPPSemantics {
} 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)
{
@ -594,7 +606,7 @@ public class CPPSemantics {
if( usingDirectives != null )
usingDirectives.add( item );
} else {
possible = collectResult( data, item, (item == parent) );
possible = collectResult( data, scope, item, (item == parent) );
if( possible != null ){
if( found == null )
found = new ArrayList(2);
@ -657,7 +669,7 @@ public class CPPSemantics {
return transitives;
}
static private IASTName collectResult( CPPSemantics.LookupData data, IASTNode node, boolean checkAux ){
static private IASTName collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ){
IASTDeclaration declaration = null;
if( node instanceof IASTDeclaration )
declaration = (IASTDeclaration) node;
@ -675,9 +687,11 @@ public class CPPSemantics {
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i];
IASTName declaratorName = declarator.getName();
if( CharArrayUtils.equals( declaratorName.toCharArray(), data.name ) ){
return declaratorName;
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
IASTName declaratorName = declarator.getName();
if( CharArrayUtils.equals( declaratorName.toCharArray(), data.name ) ){
return declaratorName;
}
}
}
}
@ -734,12 +748,14 @@ public class CPPSemantics {
//check the function itself
IASTName declName = declarator.getName();
if( declName instanceof ICPPASTQualifiedName ){
IASTName [] names = ((ICPPASTQualifiedName)declName).getNames();
declName = names[ names.length - 1 ];
}
if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){
return declName;
if( data.considerConstructors || !CPPVisitor.isConstructor( scope, declarator ) ){
if( declName instanceof ICPPASTQualifiedName ){
IASTName [] names = ((ICPPASTQualifiedName)declName).getNames();
declName = names[ names.length - 1 ];
}
if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){
return declName;
}
}
if( checkAux ) {
//check the parameters
@ -796,9 +812,16 @@ public class CPPSemantics {
List fns = null;
for( int i = 0; i < data.foundItems.size(); i++ ){
IASTName n = (IASTName) data.foundItems.get( i );
Object o = data.foundItems.get( i );
if( o instanceof IASTName )
temp = ((IASTName) o).resolveBinding();
else if( o instanceof IBinding )
temp = (IBinding) o;
else
continue;
//IASTName n = (IASTName)
temp = n.resolveBinding();
//temp = n.resolveBinding();
if( temp instanceof ICPPCompositeBinding ){
IBinding [] bindings = ((ICPPCompositeBinding) temp).getBindings();
for( int j = 0; j < bindings.length; j++ )
@ -845,8 +868,8 @@ public class CPPSemantics {
return obj;
}
static private boolean functionHasParameters( ICPPASTFunctionDeclarator function, IASTParameterDeclaration [] params ){
IFunctionType ftype = (IFunctionType) CPPVisitor.createType( function );
static private boolean functionHasParameters( IFunction function, IASTParameterDeclaration [] params ){
IFunctionType ftype = function.getType();
if( params.length == 0 ){
return ftype.getParameterTypes().length == 0;
}
@ -871,17 +894,27 @@ public class CPPSemantics {
for( int i = 0; i < size; i++ ){
fName = (IFunction) functions.get(i);
function = (ICPPASTFunctionDeclarator) fName.getPhysicalNode();
num = function.getParameters().length;
if( function == null ){
//implicit member function, for now, not supporting default values or var args
num = fName.getParameters().length;
} else {
num = function.getParameters().length;
}
//if there are m arguments in the list, all candidate functions having m parameters
//are viable
if( num == numParameters ){
if( data.forDefinition && !functionHasParameters( function, (IASTParameterDeclaration[]) data.functionParameters ) ){
if( data.forDefinition && !functionHasParameters( fName, (IASTParameterDeclaration[]) data.functionParameters ) ){
functions.remove( i-- );
size--;
}
continue;
}
} else if( function == null ){
functions.remove( i-- );
size--;
continue;
}
//check for void
else if( numParameters == 0 && num == 1 ){
IASTParameterDeclaration param = function.getParameters()[0];
@ -965,6 +998,8 @@ public class CPPSemantics {
Object [] sourceParameters = null; //the parameters the function is being called with
IASTParameterDeclaration [] targetParameters = null; //the current function's parameters
IParameter [] targetBindings = null;
int targetLength = 0;
int numFns = fns.size();
int numSourceParams = ( data.functionParameters != null ) ? data.functionParameters.length : 0;
@ -981,9 +1016,16 @@ public class CPPSemantics {
}
ICPPASTFunctionDeclarator currDtor = (ICPPASTFunctionDeclarator) currFn.getPhysicalNode();
targetParameters = currDtor.getParameters();
targetParameters = ( currDtor != null ) ? currDtor.getParameters() : null;
int numTargetParams = ( targetParameters.length == 0 ) ? 1 : targetParameters.length;
if( targetParameters == null ){
targetBindings = currFn.getParameters();
targetLength = targetBindings.length;
} else {
targetLength = targetParameters.length;
}
int numTargetParams = ( targetLength == 0 ) ? 1 : targetLength;
if( currFnCost == null ){
currFnCost = new Cost [ (numSourceParams == 0) ? 1 : numSourceParams ];
}
@ -995,11 +1037,13 @@ public class CPPSemantics {
source = getSourceParameterType( sourceParameters, j );
if( j < numTargetParams ){
if( targetParameters.length == 0 && j == 0 ){
if( targetLength == 0 && j == 0 ){
target = VOID_TYPE;
} else if( targetParameters != null ) {
IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding();
target = param.getType();
} else {
IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding();
target = param.getType();
target = targetBindings[j].getType();
}
} else
varArgs = true;
@ -1124,80 +1168,70 @@ public class CPPSemantics {
static private Cost checkUserDefinedConversionSequence( IType source, IType target ) {
Cost cost = null;
// Cost constructorCost = null;
// Cost conversionCost = null;
Cost constructorCost = null;
Cost conversionCost = null;
// IType s = getUltimateType( source );
// IType t = getUltimateType( target );
// //ISymbol sourceDecl = null;
// IASTName constructor = null;
// IASTName conversion = null;
//
// //constructors
// if( t instanceof ICPPClassType ){
// LookupData data = new LookupData( EMPTY_NAME_ARRAY );
// data.forUserDefinedConversion = true;
// data.functionParameters = new Object [] { source };
//
// if( !container.getConstructors().isEmpty() ){
// ArrayList constructors = new ArrayList( container.getConstructors() );
// constructor = resolveFunction( data, constructors );
// }
// if( constructor != null && constructor.getTypeInfo().checkBit( ITypeInfo.isExplicit ) ){
// constructor = null;
// }
// }
IType s = getUltimateType( source );
IType t = getUltimateType( target );
ICPPConstructor constructor = null;
ICPPMethod conversion = null;
//constructors
if( t instanceof ICPPClassType ){
LookupData data = new LookupData( EMPTY_NAME_ARRAY );
data.forUserDefinedConversion = true;
data.functionParameters = new Object [] { source };
ICPPConstructor [] constructors = ((ICPPClassType)t).getConstructors();
if( constructors.length > 0 ){
constructor = (ICPPConstructor) resolveFunction( data, Arrays.asList( constructors ) );
}
if( constructor != null && constructor.isExplicit() ){
constructor = null;
}
}
//conversion operators
// if( source.getType() == ITypeInfo.t_type ){
// source = getFlatTypeInfo( source, provider );
// sourceDecl = ( source != null ) ? source.getTypeSymbol() : null;
//
// if( sourceDecl != null && (sourceDecl instanceof IContainerSymbol) ){
// char[] name = target.toCharArray();
//
// if( !CharArrayUtils.equals( name, EMPTY_NAME_ARRAY) ){
//
// LookupData data = new LookupData( CharArrayUtils.concat( OPERATOR_, name )){ //$NON-NLS-1$
// public List getParameters() { return Collections.EMPTY_LIST; }
// public TypeFilter getFilter() { return FUNCTION_FILTER; }
// };
// data.forUserDefinedConversion = true;
// data.foundItems = lookupInContained( data, (IContainerSymbol) sourceDecl );
// conversion = (data.foundItems != null ) ? (IParameterizedSymbol)resolveAmbiguities( data ) : null;
// }
// }
// }
//
// if( constructor != null ){
// IType info = provider.getTypeInfo( ITypeInfo.t_type );
// info.setTypeSymbol( constructor.getContainingSymbol() );
// constructorCost = checkStandardConversionSequence( info, target );
// }
// if( conversion != null ){
// IType info = provider.getTypeInfo( target.getType() );
// info.setTypeSymbol( target.getTypeSymbol() );
// conversionCost = checkStandardConversionSequence( info, target );
// }
if( s instanceof ICPPClassType ){
char[] name = null;//TODO target.toCharArray();
if( !CharArrayUtils.equals( name, EMPTY_NAME_ARRAY) ){
LookupData data = new LookupData( CharArrayUtils.concat( OPERATOR_, name ));
data.functionParameters = IASTExpression.EMPTY_EXPRESSION_ARRAY;
data.forUserDefinedConversion = true;
ICPPScope scope = (ICPPScope) ((ICPPClassType) s).getCompositeScope();
data.foundItems = lookupInScope( data, scope, null, null );
conversion = (ICPPMethod) ( (data.foundItems != null ) ? resolveFunction( data, data.foundItems ) : null );
}
}
// //if both are valid, then the conversion is ambiguous
// if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK &&
// conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK )
// {
// cost = constructorCost;
// cost.userDefined = Cost.AMBIGUOUS_USERDEFINED_CONVERSION;
// cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
// } else {
// if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK ){
// cost = constructorCost;
// cost.userDefined = constructor.hashCode();
// cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
// } else if( conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK ){
// cost = conversionCost;
// cost.userDefined = conversion.hashCode();
// cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
// }
// }
if( constructor != null ){
constructorCost = checkStandardConversionSequence( t, target );
}
if( conversion != null ){
conversionCost = checkStandardConversionSequence( conversion.getType().getReturnType(), target );
}
//if both are valid, then the conversion is ambiguous
if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK &&
conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK )
{
cost = constructorCost;
cost.userDefined = Cost.AMBIGUOUS_USERDEFINED_CONVERSION;
cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
} else {
if( constructorCost != null && constructorCost.rank != Cost.NO_MATCH_RANK ){
cost = constructorCost;
cost.userDefined = constructor.hashCode();
cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
} else if( conversionCost != null && conversionCost.rank != Cost.NO_MATCH_RANK ){
cost = conversionCost;
cost.userDefined = conversion.hashCode();
cost.rank = Cost.USERDEFINED_CONVERSION_RANK;
}
}
return cost;
}

View file

@ -15,8 +15,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
@ -74,8 +72,11 @@ import org.eclipse.cdt.core.dom.ast.IBasicType;
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.IQualifierType;
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.IVariable;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
@ -113,6 +114,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
/**
* @author aniefer
@ -293,18 +296,9 @@ public class CPPVisitor {
}
}
if( scope instanceof ICPPClassScope ){
char [] name = declarator.getName().toCharArray();
IASTDeclSpecifier decl = null;
if( parent instanceof IASTSimpleDeclaration )
decl = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
else if( parent instanceof IASTFunctionDefinition )
decl = ((IASTFunctionDefinition)parent).getDeclSpecifier();
if( decl != null && decl instanceof IASTSimpleDeclSpecifier &&
((IASTSimpleDeclSpecifier) decl).getType() == 0 &&
name.length > 0 && name[0] != '~' )
{
if( isConstructor( scope, declarator) )
binding = new CPPConstructor( (ICPPASTFunctionDeclarator) declarator );
} else
else
binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator );
} else {
binding = new CPPFunction( (ICPPASTFunctionDeclarator) declarator );
@ -330,6 +324,40 @@ public class CPPVisitor {
return binding;
}
public static boolean isConstructor( IScope containingScope, IASTDeclarator declarator ){
if( containingScope == null || !(containingScope instanceof ICPPClassScope) )
return false;
ICPPASTCompositeTypeSpecifier clsTypeSpec = (ICPPASTCompositeTypeSpecifier) ((ICPPClassScope)containingScope).getPhysicalNode();
return isConstructor( clsTypeSpec.getName(), declarator );
}
public static boolean isConstructor( IASTName parentName, IASTDeclarator declarator ){
if( declarator == null || !(declarator instanceof IASTFunctionDeclarator) )
return false;
IASTName name = declarator.getName();
if( name instanceof ICPPASTQualifiedName ){
IASTName [] names = ((ICPPASTQualifiedName)name).getNames();
name = names[ names.length - 1 ];
}
if( !CharArrayUtils.equals( name.toCharArray(), parentName.toCharArray() ) )
return false;
IASTDeclSpecifier declSpec = null;
IASTNode parent = declarator.getParent();
if( parent instanceof IASTSimpleDeclaration ){
declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
} else if( parent instanceof IASTFunctionDefinition ){
declSpec = ((IASTFunctionDefinition)parent).getDeclSpecifier();
}
if( declSpec != null && declSpec instanceof IASTSimpleDeclSpecifier ){
return ( ((IASTSimpleDeclSpecifier)declSpec).getType() == IASTSimpleDeclSpecifier.t_unspecified );
}
return false;
}
public static IScope getContainingScope( IASTNode node ){
if( node == null )
return null;
@ -1063,9 +1091,59 @@ public class CPPVisitor {
return true;
}
/**
* Generate a function type for an implicit function.
* NOTE: This does not currectly handle parameters with typedef types.
* @param returnType
* @param parameters
* @return
*/
public static IFunctionType createImplicitFunctionType( IType returnType, IParameter [] parameters ){
IType [] pTypes = new IType[ parameters.length ];
IType pt = null;
ArrayList temp = new ArrayList();
for( int i = 0; i < parameters.length; i++ ){
pt = parameters[i].getType();
temp.add( pt.clone() );
while( pt instanceof ITypeContainer){
pt = ((ITypeContainer)pt).getType();
if( pt instanceof ITypeContainer && !(pt instanceof ITypedef) ){
IType t = (IType) pt.clone();
((ITypeContainer) temp.get( temp.size() - 1 )).setType( t );
temp.add( t );
} else {
temp.add( pt );
break;
}
}
int lastIdx = temp.size() - 1;
if( lastIdx > 0 && temp.get( lastIdx - 1 ) instanceof IQualifierType ){
temp.remove( --lastIdx );
if( lastIdx > 0 ){
ITypeContainer cont = (ITypeContainer) temp.get( lastIdx - 1 );
cont.setType( (IType) temp.get( lastIdx ) );
}
}
IType lastType = (IType) temp.get( lastIdx );
if( lastType instanceof IArrayType ){
lastType = new CPPPointerType( ((IArrayType) lastType).getType() );
} else if( lastType instanceof IFunctionType ){
lastType = new CPPPointerType( lastType );
}
pTypes[i] = (IType) temp.get( 0 );
}
return new CPPFunctionType( returnType, pTypes );
}
private static IType createType( IType returnType, ICPPASTFunctionDeclarator fnDtor ){
List pTypes = Collections.EMPTY_LIST;
IASTParameterDeclaration [] params = fnDtor.getParameters();
IType [] pTypes = new IType [ params.length ];
IType pt = null;
for( int i = 0; i < params.length; i++ ){
@ -1089,16 +1167,12 @@ public class CPPVisitor {
pt = new CPPPointerType( pt );
}
if( pTypes == Collections.EMPTY_LIST ){
pTypes = new ArrayList();
}
pTypes.add( pt );
pTypes[i] = pt;
}
returnType = getPointerTypes( returnType, fnDtor );
IType [] array = new IType [ pTypes.size() ];
IType type = new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) );
IType type = new CPPFunctionType( returnType, pTypes );
IASTDeclarator nested = fnDtor.getNestedDeclarator();
if( nested != null ) {
return createType( type, nested );