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:
parent
8c18009c05
commit
0f10569314
21 changed files with 779 additions and 196 deletions
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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$
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -70,5 +70,10 @@ public interface ICPPClassType extends ICompositeType {
|
|||
* @return List of ICPPMethod
|
||||
*/
|
||||
public List getDeclaredMethods();
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public ICPPConstructor[] getConstructors();
|
||||
|
||||
}
|
||||
|
|
|
@ -18,4 +18,9 @@ package org.eclipse.cdt.core.dom.ast.cpp;
|
|||
*/
|
||||
public interface ICPPConstructor extends ICPPMethod {
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
boolean isExplicit();
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Add table
Reference in a new issue