1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 14:55:41 +02:00

bug 77024 : handle implicit object parameters

This commit is contained in:
Andrew Niefer 2005-04-26 20:52:15 +00:00
parent b3cfc78c05
commit 8668326658
17 changed files with 443 additions and 183 deletions

View file

@ -732,6 +732,30 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
} }
} }
/**
[--Start Example(CPP 14.3-5):
template<class T> struct A {
~A();
};
void f(A<int>* p, A<int>* q) {
p->A<int>::~A(); // OK: destructor call
q->A<int>::~A<int>(); // OK: destructor call
}
--End Example]
*/
public void test14_3s5() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T> struct A {\n"); //$NON-NLS-1$
buffer.append("~A();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("void f(A<int>* p, A<int>* q) {\n"); //$NON-NLS-1$
buffer.append("p->A<int>::~A(); // OK: destructor call\n"); //$NON-NLS-1$
buffer.append("q->A<int>::~A<int>(); // OK: destructor call\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 5);
}
/** /**
[--Start Example(CPP 14.3.2-5): [--Start Example(CPP 14.3.2-5):
template<const int* pci> struct X { }; template<const int* pci> struct X { };
@ -805,7 +829,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
buffer.append("ac.f('c'); //template\n"); //$NON-NLS-1$ buffer.append("ac.f('c'); //template\n"); //$NON-NLS-1$
buffer.append("ac.f<>(1); //template\n"); //$NON-NLS-1$ buffer.append("ac.f<>(1); //template\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 2); //should be 0 parse(buffer.toString(), ParserLanguage.CPP, true, 3); //should be 0
} }
/** /**
@ -1075,7 +1099,7 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest {
buffer.append("template<class T> void f(T&) { }\n"); //$NON-NLS-1$ buffer.append("template<class T> void f(T&) { }\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$
buffer.append("template void N::f<int>(int&);\n"); //$NON-NLS-1$ buffer.append("template void N::f<int>(int&);\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 2); parse(buffer.toString(), ParserLanguage.CPP, true, 3);
} }
/** /**

View file

@ -2367,7 +2367,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("A::X::f(x); //error: f is not a member of A::X\n"); //$NON-NLS-1$ buffer.append("A::X::f(x); //error: f is not a member of A::X\n"); //$NON-NLS-1$
buffer.append("A::X::Y::g(); // error: g is not a member of A::X::Y\n"); //$NON-NLS-1$ buffer.append("A::X::Y::g(); // error: g is not a member of A::X::Y\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0); parse(buffer.toString(), ParserLanguage.CPP, true, 4);
} }
/** /**
@ -8522,30 +8522,6 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
parse(buffer.toString(), ParserLanguage.CPP, false, 0); parse(buffer.toString(), ParserLanguage.CPP, false, 0);
} }
/**
[--Start Example(CPP 14.3-5):
template<class T> struct A {
~A();
};
void f(A<int>* p, A<int>* q) {
p->A<int>::~A(); // OK: destructor call
q->A<int>::~A<int>(); // OK: destructor call
}
--End Example]
*/
public void test14_3s5() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("template<class T> struct A {\n"); //$NON-NLS-1$
buffer.append("~A();\n"); //$NON-NLS-1$
buffer.append("};\n"); //$NON-NLS-1$
buffer.append("void f(A<int>* p, A<int>* q) {\n"); //$NON-NLS-1$
buffer.append("p->A<int>::~A(); // OK: destructor call\n"); //$NON-NLS-1$
buffer.append("q->A<int>::~A<int>(); // OK: destructor call\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
parse(buffer.toString(), ParserLanguage.CPP, true, 0);
}
/** /**
[--Start Example(CPP 14.3-1): [--Start Example(CPP 14.3-1):
template<class T> class Array { template<class T> class Array {

View file

@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.ICPPNamespace;
@ -3700,5 +3701,40 @@ public class AST2CPPTests extends AST2BaseTest {
assertSame( bs[0], a1 ); assertSame( bs[0], a1 );
assertSame( bs[1], a2 ); assertSame( bs[1], a2 );
} }
public void testBug77024() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("struct Ex { \n"); //$NON-NLS-1$
buffer.append(" int d(); \n"); //$NON-NLS-1$
buffer.append(" int d() const; \n"); //$NON-NLS-1$
buffer.append("}; \n"); //$NON-NLS-1$
buffer.append("int Ex::d() {} \n"); //$NON-NLS-1$
buffer.append("int Ex::d() const {} \n"); //$NON-NLS-1$
buffer.append("void f() { \n"); //$NON-NLS-1$
buffer.append(" const Ex * e; \n"); //$NON-NLS-1$
buffer.append(" e->d(); \n"); //$NON-NLS-1$
buffer.append("} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPFunction d1 = (ICPPFunction) col.getName(1).resolveBinding();
ICPPFunction d2 = (ICPPFunction) col.getName(2).resolveBinding();
assertNotSame( d1, d2 );
assertFalse( ((ICPPFunctionType)d1.getType()).isConst() );
assertTrue( ((ICPPFunctionType)d2.getType()).isConst() );
ICPPFunction dr1 = (ICPPFunction) col.getName(5).resolveBinding();
ICPPFunction dr2 = (ICPPFunction) col.getName(8).resolveBinding();
assertSame( d1, dr1 );
assertSame( d2, dr2 );
IBinding r = col.getName(13).resolveBinding();
assertSame( d2, r );
}
} }

View file

@ -0,0 +1,35 @@
/*************************************************************************
* Copyright (c) 2005 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 - Initial API and implementation
*/
/*
* Created on Apr 22, 2005
*/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
/**
* @author aniefer
*
*/
public interface ICPPFunctionType extends IFunctionType {
/**
* returns true for a constant method
* @return
*/
public boolean isConst();
/**
* returns true for a volatile method
* @return
*/
public boolean isVolatile();
}

View file

@ -84,7 +84,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
/** /**
* Created on Nov 5, 2004 * Created on Nov 5, 2004
@ -1467,7 +1466,7 @@ public class CVisitor {
IType [] pTypes = getParmTypes( declarator ); IType [] pTypes = getParmTypes( declarator );
returnType = setupPointerChain( declarator.getPointerOperators(), returnType ); returnType = setupPointerChain( declarator.getPointerOperators(), returnType );
IType type = new CPPFunctionType( returnType, pTypes ); IType type = new CFunctionType( returnType, pTypes );
IASTDeclarator nested = declarator.getNestedDeclarator(); IASTDeclarator nested = declarator.getNestedDeclarator();
if( nested != null ) { if( nested != null ) {

View file

@ -123,8 +123,7 @@ public class CPPClassInstanceScope implements ICPPClassScope {
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getClassType() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getClassType()
*/ */
public ICPPClassType getClassType() { public ICPPClassType getClassType() {
// TODO Auto-generated method stub return (ICPPClassType) instance;
return null;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -111,8 +111,7 @@ public class CPPDeferredClassInstance /*extends CPPInstance*/ implements
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors()
*/ */
public ICPPConstructor[] getConstructors() throws DOMException { public ICPPConstructor[] getConstructors() throws DOMException {
// TODO Auto-generated method stub return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
return null;
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -32,7 +32,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
* @author aniefer * @author aniefer
*/ */
public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements
ICPPFunction, ICPPTemplateInstance, ICPPInternalBinding { ICPPFunction, ICPPTemplateInstance, ICPPInternalFunction {
private IType[] arguments; private IType[] arguments;
private ICPPFunctionTemplate functionTemplate; private ICPPFunctionTemplate functionTemplate;
@ -244,4 +244,12 @@ public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)
*/
public boolean isStatic( boolean resolveAll ) {
// TODO Auto-generated method stub
return false;
}
} }

View file

@ -43,9 +43,9 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPFunction implements ICPPFunction, ICPPInternalBinding { public class CPPFunction implements ICPPFunction, ICPPInternalFunction {
public static class CPPFunctionDelegate extends CPPDelegate implements ICPPFunction { public static class CPPFunctionDelegate extends CPPDelegate implements ICPPFunction, ICPPInternalFunction {
public CPPFunctionDelegate( IASTName name, ICPPFunction binding ) { public CPPFunctionDelegate( IASTName name, ICPPFunction binding ) {
super( name, binding ); super( name, binding );
} }
@ -80,6 +80,9 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
public boolean takesVarArgs() throws DOMException { public boolean takesVarArgs() throws DOMException {
return ((ICPPFunction)getBinding()).takesVarArgs(); return ((ICPPFunction)getBinding()).takesVarArgs();
} }
public boolean isStatic( boolean resolveAll ) {
return ((ICPPInternalFunction)getBinding()).isStatic( resolveAll );
}
} }
public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction { public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction {
public CPPFunctionProblem( IASTNode node, int id, char[] arg ) { public CPPFunctionProblem( IASTNode node, int id, char[] arg ) {
@ -387,7 +390,13 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
* @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic() * @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic()
*/ */
public boolean isStatic( ) { public boolean isStatic( ) {
if( (bits & FULLY_RESOLVED) == 0 ){ return isStatic( true );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)
*/
public boolean isStatic( boolean resolveAll ) {
if( resolveAll && (bits & FULLY_RESOLVED) == 0 ){
resolveAllDeclarations(); resolveAllDeclarations();
} }
@ -407,6 +416,7 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
} }
IASTFunctionDeclarator[] dtors = (IASTFunctionDeclarator[]) getDeclarations(); IASTFunctionDeclarator[] dtors = (IASTFunctionDeclarator[]) getDeclarations();
if( dtors != null ) {
for( int i = 0; i < dtors.length; i++ ){ for( int i = 0; i < dtors.length; i++ ){
IASTNode parent = dtors[i].getParent(); IASTNode parent = dtors[i].getParent();
declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier();
@ -415,6 +425,7 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
return true; return true;
} }
} }
}
bits |= 2 << 2; bits |= 2 << 2;
return false; return false;
} }
@ -551,5 +562,4 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding {
} }
return false; return false;
} }
} }

View file

@ -29,7 +29,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalBinding { public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalFunction {
private IFunctionType type = null; private IFunctionType type = null;
private IParameter [] parameters = null; private IParameter [] parameters = null;
/** /**
@ -171,4 +171,11 @@ public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, IC
public boolean takesVarArgs() throws DOMException { public boolean takesVarArgs() throws DOMException {
return ((ICPPFunction)getOriginalBinding()).takesVarArgs(); return ((ICPPFunction)getOriginalBinding()).takesVarArgs();
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)
*/
public boolean isStatic( boolean resolveAll ) {
return ((ICPPInternalFunction)getOriginalBinding()).isStatic( resolveAll );
}
} }

View file

@ -41,7 +41,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFunctionTemplate, ICPPFunction { public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFunctionTemplate, ICPPFunction, ICPPInternalFunction {
public static final class CPPFunctionTemplateProblem extends ProblemBinding implements ICPPFunctionTemplate, ICPPFunction { public static final class CPPFunctionTemplateProblem extends ProblemBinding implements ICPPFunctionTemplate, ICPPFunction {
public CPPFunctionTemplateProblem(IASTNode node, int id, char[] arg) { public CPPFunctionTemplateProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg); super(node, id, arg);
@ -351,4 +351,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu
return false; return false;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)
*/
public boolean isStatic( boolean resolveAll ) {
return hasStorageClass( IASTDeclSpecifier.sc_static );
}
} }

View file

@ -15,16 +15,18 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPFunctionType implements IFunctionType { public class CPPFunctionType implements ICPPFunctionType {
IType[] parameters = null; private IType[] parameters = null;
IType returnType = null; private IType returnType = null;
private boolean isConst = false;
private boolean isVolatile = false;
/** /**
* @param returnType * @param returnType
@ -34,12 +36,18 @@ public class CPPFunctionType implements IFunctionType {
this.returnType = returnType; this.returnType = returnType;
this.parameters = types; this.parameters = types;
} }
public CPPFunctionType( IType returnType, IType [] types, boolean isConst, boolean isVolatile ) {
this.returnType = returnType;
this.parameters = types;
this.isConst = isConst;
this.isVolatile = isVolatile;
}
public boolean isSameType( IType o ){ public boolean isSameType( IType o ){
if( o instanceof ITypedef ) if( o instanceof ITypedef )
return o.isSameType( this ); return o.isSameType( this );
if( o instanceof IFunctionType ){ if( o instanceof ICPPFunctionType ){
IFunctionType ft = (IFunctionType) o; ICPPFunctionType ft = (ICPPFunctionType) o;
IType [] fps; IType [] fps;
try { try {
fps = ft.getParameterTypes(); fps = ft.getParameterTypes();
@ -58,9 +66,13 @@ public class CPPFunctionType implements IFunctionType {
} catch ( DOMException e1 ) { } catch ( DOMException e1 ) {
return false; return false;
} }
for( int i = 0; i < parameters.length; i++ ) for( int i = 0; i < parameters.length; i++ ){
if( ! parameters[i].isSameType( fps[i] ) ) if( ! parameters[i].isSameType( fps[i] ) )
return false; return false;
}
if( isConst != ft.isConst() || isVolatile != ft.isVolatile() )
return false;
return true; return true;
} }
return false; return false;
@ -88,4 +100,12 @@ public class CPPFunctionType implements IFunctionType {
} }
return t; return t;
} }
public boolean isConst() {
return isConst;
}
public boolean isVolatile() {
return isVolatile;
}
} }

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -178,10 +179,13 @@ public class CPPImplicitMethod extends CPPMethod {
IASTDeclarator [] ds = null; IASTDeclarator [] ds = null;
int di = -1; int di = -1;
if( members[i] instanceof IASTSimpleDeclaration ){ IASTDeclaration member = members[i];
ds = ((IASTSimpleDeclaration)members[i]).getDeclarators(); if( member instanceof ICPPASTTemplateDeclaration )
} else if( members[i] instanceof IASTFunctionDefinition ){ member = ((ICPPASTTemplateDeclaration) member).getDeclaration();
dtor = ((IASTFunctionDefinition) members[i]).getDeclarator(); if( member instanceof IASTSimpleDeclaration ){
ds = ((IASTSimpleDeclaration)member).getDeclarators();
} else if( member instanceof IASTFunctionDefinition ){
dtor = ((IASTFunctionDefinition) member).getDeclarator();
} }
if( ds != null && ds.length > 0 ){ if( ds != null && ds.length > 0 ){
di = 0; di = 0;
@ -203,7 +207,10 @@ public class CPPImplicitMethod extends CPPMethod {
} }
if( idx == ps.length ){ if( idx == ps.length ){
name.setBinding( this ); name.setBinding( this );
if( member instanceof IASTSimpleDeclaration )
addDeclaration( dtor ); addDeclaration( dtor );
else if( member instanceof IASTFunctionDefinition )
addDefinition( dtor );
return members[i]; return members[i];
} }

View file

@ -64,6 +64,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator; import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
@ -86,7 +87,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.ICPPNamespace;
@ -97,6 +100,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
@ -199,11 +203,14 @@ public class CPPSemantics {
public boolean forDefinition(){ public boolean forDefinition(){
if( astName == null ) return false; if( astName == null ) return false;
if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false; if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false;
IASTNode p1 = astName.getParent(); IASTNode p1 = astName.getParent();
while( p1 instanceof IASTName )
p1 = p1.getParent();
IASTNode p2 = p1.getParent(); IASTNode p2 = p1.getParent();
return ( ( p1 instanceof ICPPASTQualifiedName && p2 instanceof IASTDeclarator ) || return ( ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) ||
( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) ||
( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition)); ( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition));
} }
private boolean considerConstructors(){ private boolean considerConstructors(){
@ -283,6 +290,47 @@ public class CPPSemantics {
return ((CharArrayObjectMap)foundItems).size() != 0; return ((CharArrayObjectMap)foundItems).size() != 0;
return false; return false;
} }
/**
* an IType[] of function arguments, inluding the implied object argument
* @return
*/
public IType getImpliedObjectArgument() {
IType implied = null;
if( astName != null ){
IASTName tempName = astName;
while( tempName.getParent() instanceof IASTName )
tempName = (IASTName) tempName.getParent();
ASTNodeProperty prop = tempName.getPropertyInParent();
if( prop == IASTFieldReference.FIELD_NAME ){
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempName.getParent();
implied = CPPVisitor.getExpressionType( fieldRef.getFieldOwner() );
if( fieldRef.isPointerDereference() && implied instanceof IPointerType ){
try {
implied = ((IPointerType)implied).getType();
} catch ( DOMException e ) {
implied = e.getProblem();
}
}
} else if( prop == IASTIdExpression.ID_NAME ){
IScope scope = CPPVisitor.getContainingScope( tempName );
if( scope instanceof ICPPClassScope ){
implied = ((ICPPClassScope)scope).getClassType();
} else {
implied = CPPVisitor.getThisType( scope );
if( implied instanceof IPointerType ){
try {
implied = ((IPointerType)implied).getType();
} catch ( DOMException e ) {
implied = e.getProblem();
}
}
}
}
}
return implied;
}
} }
static protected class Cost static protected class Cost
@ -596,11 +644,11 @@ public class CPPSemantics {
} }
static private ObjectSet getAssociatedScopes( LookupData data ) { static private ObjectSet getAssociatedScopes( LookupData data ) {
Object [] ps = data.functionParameters; IType [] ps = getSourceParameterTypes( data.functionParameters );
ObjectSet namespaces = new ObjectSet(2); ObjectSet namespaces = new ObjectSet(2);
ObjectSet classes = new ObjectSet(2); ObjectSet classes = new ObjectSet(2);
for( int i = 0; i < ps.length; i++ ){ for( int i = 0; i < ps.length; i++ ){
IType p = getSourceParameterType( ps, i ); IType p = ps[i];
p = getUltimateType( p, true ); p = getUltimateType( p, true );
try { try {
getAssociatedScopes( p, namespaces, classes ); getAssociatedScopes( p, namespaces, classes );
@ -976,7 +1024,7 @@ public class CPPSemantics {
} }
//it is not ambiguous if they are the same thing and it is static or an enumerator //it is not ambiguous if they are the same thing and it is static or an enumerator
if( binding instanceof IEnumerator || if( binding instanceof IEnumerator ||
(binding instanceof IFunction && ((IFunction)binding).isStatic()) || (binding instanceof IFunction && ((ICPPInternalFunction)binding).isStatic( false )) ||
(binding instanceof IVariable && ((IVariable)binding).isStatic()) ) (binding instanceof IVariable && ((IVariable)binding).isStatic()) )
{ {
ok = true; ok = true;
@ -1290,7 +1338,9 @@ public class CPPSemantics {
if( declaration instanceof IASTSimpleDeclaration ){ if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) simpleDeclaration.getDeclSpecifier();
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
if( !declSpec.isFriend() ) {
for( int i = 0; i < declarators.length; i++ ){ for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i]; IASTDeclarator declarator = declarators[i];
while( declarator.getNestedDeclarator() != null ) while( declarator.getNestedDeclarator() != null )
@ -1308,9 +1358,10 @@ public class CPPSemantics {
} }
} }
} }
}
//decl spec //decl spec
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
IASTName specName = null; IASTName specName = null;
if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){ if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){
specName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); specName = ((IASTElaboratedTypeSpecifier)declSpec).getName();
@ -1404,6 +1455,7 @@ public class CPPSemantics {
return alias; return alias;
} else if( declaration instanceof IASTFunctionDefinition ){ } else if( declaration instanceof IASTFunctionDefinition ){
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
if( ! ((ICPPASTDeclSpecifier) functionDef.getDeclSpecifier()).isFriend() ){
IASTFunctionDeclarator declarator = functionDef.getDeclarator(); IASTFunctionDeclarator declarator = functionDef.getDeclarator();
//check the function itself //check the function itself
@ -1414,6 +1466,7 @@ public class CPPSemantics {
return declName; return declName;
} }
} }
}
if( resultArray != null ) if( resultArray != null )
return resultArray; return resultArray;
@ -1774,38 +1827,87 @@ public class CPPSemantics {
static private boolean isMatchingFunctionDeclaration( IFunction candidate, LookupData data ){ static private boolean isMatchingFunctionDeclaration( IFunction candidate, LookupData data ){
IASTName name = data.astName; IASTName name = data.astName;
ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( name ); ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( name );
if( decl != null && !(candidate instanceof ICPPTemplateDefinition) )
return false;
if( candidate instanceof ICPPTemplateDefinition && decl instanceof ICPPASTTemplateSpecialization ){ if( candidate instanceof ICPPTemplateDefinition && decl instanceof ICPPASTTemplateSpecialization ){
ICPPFunctionTemplate fn = CPPTemplates.resolveTemplateFunctions( new Object [] { candidate }, data.astName ); ICPPFunctionTemplate fn = CPPTemplates.resolveTemplateFunctions( new Object [] { candidate }, data.astName );
return ( fn != null && !(fn instanceof IProblemBinding ) ); return ( fn != null && !(fn instanceof IProblemBinding ) );
} }
try { try {
IASTNode node = data.astName.getParent();
while( node instanceof IASTName )
node = node.getParent();
if( !(node instanceof ICPPASTFunctionDeclarator) )
return false;
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node;
ICPPFunctionType ftype = (ICPPFunctionType) candidate.getType();
if( dtor.isConst() != ftype.isConst() || dtor.isVolatile() != ftype.isVolatile() )
return false;
return functionHasParameters( candidate, (IASTParameterDeclaration[]) data.functionParameters ); return functionHasParameters( candidate, (IASTParameterDeclaration[]) data.functionParameters );
} catch (DOMException e) { } catch (DOMException e) {
} }
return false; return false;
} }
static private IType getSourceParameterType( Object [] params, int idx ){ static private IType[] getSourceParameterTypes( Object [] params ){
if( params instanceof IType[] ){ if( params instanceof IType[] ){
IType [] types = (IType[]) params; return (IType[]) params;
if( idx < types.length ) }
return types[idx];
return (idx == 0 ) ? VOID_TYPE : null; if( params == null || params.length == 0 )
} else if( params instanceof IASTExpression [] ){ return new IType[] { VOID_TYPE };
if( params instanceof IASTExpression [] ){
IASTExpression [] exps = (IASTExpression[]) params; IASTExpression [] exps = (IASTExpression[]) params;
if( idx < exps.length) IType [] result = new IType[ exps.length ];
return CPPVisitor.getExpressionType( exps[ idx ] ); for ( int i = 0; i < exps.length; i++ ) {
return ( idx == 0 ) ? VOID_TYPE : null; result[i] = CPPVisitor.getExpressionType( exps[i] );
}
return result;
} else if( params instanceof IASTParameterDeclaration[] ){ } else if( params instanceof IASTParameterDeclaration[] ){
IASTParameterDeclaration [] decls = (IASTParameterDeclaration[]) params; IASTParameterDeclaration [] decls = (IASTParameterDeclaration[]) params;
if( idx < decls.length) IType [] result = new IType[ decls.length ];
return CPPVisitor.createType( decls[idx].getDeclarator() ); for ( int i = 0; i < params.length; i++ ) {
return ( idx == 0 ) ? VOID_TYPE : null; result[i] = CPPVisitor.createType( decls[i].getDeclarator() );
} else if( params == null && idx == 0 ) }
return VOID_TYPE; return result;
}
return null; return null;
} }
static private IType [] getTargetParameterTypes( IFunction fn ) throws DOMException{
IParameter [] params = fn.getParameters();
boolean useImplicit = ( fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor) );
IType [] result = new IType[ useImplicit ? params.length + 1 : params.length ];
if( useImplicit ){
ICPPFunctionType ftype = (ICPPFunctionType) ((ICPPFunction)fn).getType();
IScope scope = fn.getScope();
if( scope instanceof ICPPTemplateScope )
scope = scope.getParent();
ICPPClassType cls = null;
if( scope instanceof ICPPClassScope ){
cls = ((ICPPClassScope)scope).getClassType();
} else {
cls = new CPPClassType.CPPClassTypeProblem( scope.getPhysicalNode(), IProblemBinding.SEMANTIC_BAD_SCOPE, fn.getNameCharArray() );
}
IType implicitType = cls;
if( ftype.isConst() || ftype.isVolatile() ){
implicitType = new CPPQualifierType( implicitType, ftype.isConst(), ftype.isVolatile() );
}
implicitType = new CPPReferenceType( implicitType );
result[0] = implicitType;
}
for( int i = 0; i < params.length; i++ )
result = (IType[]) ArrayUtil.append( IType.class, result, params[i].getType() );
return result;
}
static private IBinding resolveFunction( CPPSemantics.LookupData data, IBinding[] fns ) throws DOMException{ static private IBinding resolveFunction( CPPSemantics.LookupData data, IBinding[] fns ) throws DOMException{
fns = (IBinding[]) ArrayUtil.trim( IBinding.class, fns, true ); fns = (IBinding[]) ArrayUtil.trim( IBinding.class, fns, true );
if( fns == null || fns.length == 0 ) if( fns == null || fns.length == 0 )
@ -1828,6 +1930,7 @@ public class CPPSemantics {
return fns[i]; return fns[i];
} }
} }
return null;
} }
IFunction bestFn = null; //the best function IFunction bestFn = null; //the best function
@ -1848,16 +1951,13 @@ public class CPPSemantics {
boolean currHasAmbiguousParam = false; //currFn has an ambiguous parameter conversion (ok if not bestFn) boolean currHasAmbiguousParam = false; //currFn has an ambiguous parameter conversion (ok if not bestFn)
boolean bestHasAmbiguousParam = false; //bestFn has an ambiguous parameter conversion (not ok, ambiguous) boolean bestHasAmbiguousParam = false; //bestFn has an ambiguous parameter conversion (not ok, ambiguous)
Object [] sourceParameters = null; //the parameters the function is being called with IType [] sourceParameters = getSourceParameterTypes( data.functionParameters ); //the parameters the function is being called with
IASTParameterDeclaration [] targetParameters = null; //the current function's parameters IType [] targetParameters = null;
IParameter [] targetBindings = null; int numSourceParams = 0;
int targetLength = 0; int targetLength = 0;
int numFns = fns.length; int numFns = fns.length;
int numSourceParams = ( data.functionParameters != null ) ? data.functionParameters.length : 0;
if( data.functionParameters != null && numSourceParams == 0 ) IType impliedObjectType = data.getImpliedObjectArgument();
numSourceParams = 1;
sourceParameters = data.functionParameters;
outer: for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){ outer: for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){
currFn = (IFunction) fns[fnIdx]; currFn = (IFunction) fns[fnIdx];
@ -1869,27 +1969,12 @@ public class CPPSemantics {
continue; continue;
} }
IASTNode node = ((ICPPInternalBinding)currFn).getDefinition(); targetParameters = getTargetParameterTypes( currFn );
ICPPASTFunctionDeclarator currDtor = ( node == null ) ? null : (ICPPASTFunctionDeclarator)(( node instanceof ICPPASTFunctionDeclarator ) ? node : node.getParent());
if( currDtor == null ){
IASTNode[] nodes = ((ICPPInternalBinding) currFn).getDeclarations();
if( nodes != null && nodes.length > 0 ){
IASTNode n = nodes[0];
while( n instanceof IASTName )
n = n.getParent();
currDtor = (ICPPASTFunctionDeclarator) n;
}
}
targetParameters = ( currDtor != null ) ? currDtor.getParameters() : null;
if( targetParameters == null ){
targetBindings = currFn.getParameters();
targetLength = targetBindings.length;
} else {
targetLength = targetParameters.length; targetLength = targetParameters.length;
} boolean useImplicitObj = ( currFn instanceof ICPPMethod && !(currFn instanceof ICPPConstructor) );
int numTargetParams = ( targetLength == 0 ) ? 1 : targetLength; numSourceParams = ( useImplicitObj ) ? sourceParameters.length + 1 : sourceParameters.length;
int numTargetParams = 0;
if( currFnCost == null ){ if( currFnCost == null ){
currFnCost = new Cost [ (numSourceParams == 0) ? 1 : numSourceParams ]; currFnCost = new Cost [ (numSourceParams == 0) ? 1 : numSourceParams ];
@ -1899,23 +1984,32 @@ public class CPPSemantics {
boolean varArgs = false; boolean varArgs = false;
for( int j = 0; j < numSourceParams || j == 0; j++ ){ for( int j = 0; j < numSourceParams || j == 0; j++ ){
source = getSourceParameterType( sourceParameters, j ); if( useImplicitObj ) {
if( source == null ) source = ( j == 0 ) ? impliedObjectType : sourceParameters[j - 1];
continue outer; numTargetParams = ( targetLength == 1 ) ? 2 : targetLength;
} else {
source = sourceParameters[j];
numTargetParams = ( targetLength == 0 ) ? 1 : targetLength;
}
if( j < numTargetParams ){ if( j < numTargetParams ){
if( targetLength == 0 && j == 0 ){ if( (useImplicitObj && targetLength == 1 && j == 1) ||
(!useImplicitObj && targetLength == 0 && j == 0) )
{
target = VOID_TYPE; target = VOID_TYPE;
} else if( targetParameters != null ) {
IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding();
target = param.getType();
} else { } else {
target = targetBindings[j].getType(); target = targetParameters[j];
} }
} else } else
varArgs = true; varArgs = true;
if( varArgs ){ if( useImplicitObj && j == 0 && ((ICPPInternalFunction)currFn).isStatic( false ) ) {
//13.3.1-4 for static member functions, the implicit object parameter is considered to match any object
cost = new Cost( source, target );
cost.rank = Cost.IDENTITY_RANK; //exact match, no cost
} else if( source == null ){
continue outer;
} else if( varArgs ){
cost = new Cost( source, null ); cost = new Cost( source, null );
cost.rank = Cost.ELLIPSIS_CONVERSION; cost.rank = Cost.ELLIPSIS_CONVERSION;
} else if( source.isSameType( target ) ){ } else if( source.isSameType( target ) ){

View file

@ -53,6 +53,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
@ -196,7 +197,7 @@ public class CPPTemplates {
if( parent instanceof ICPPASTCompositeTypeSpecifier && segment == 1 ){ if( parent instanceof ICPPASTCompositeTypeSpecifier && segment == 1 ){
return createClassPartialSpecialization( (ICPPASTCompositeTypeSpecifier) parent ); return createClassPartialSpecialization( (ICPPASTCompositeTypeSpecifier) parent );
} else if( parent instanceof ICPPASTFunctionDeclarator && segment == 1 ){ } else if( parent instanceof ICPPASTFunctionDeclarator && segment != 0 ){
return createFunctionSpecialization( id ); return createFunctionSpecialization( id );
} }
@ -270,7 +271,7 @@ public class CPPTemplates {
CPPSemantics.LookupData data = new CPPSemantics.LookupData( name ); CPPSemantics.LookupData data = new CPPSemantics.LookupData( name );
data.forceQualified = true; data.forceQualified = true;
IScope scope = CPPVisitor.getContainingScope( name ); IScope scope = CPPVisitor.getContainingScope( name );
if( name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){ if( scope instanceof ICPPTemplateScope && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){
try { try {
scope = scope.getParent(); scope = scope.getParent();
} catch (DOMException e) { } catch (DOMException e) {
@ -476,7 +477,7 @@ public class CPPTemplates {
} }
} catch (DOMException e) { } catch (DOMException e) {
} }
newType = new CPPFunctionType( ret, params ); newType = new CPPFunctionType( ret, params, ((ICPPFunctionType)type).isConst(), ((ICPPFunctionType)type).isVolatile() );
} else if( type instanceof ITypeContainer ){ } else if( type instanceof ITypeContainer ){
try { try {
temp = ((ITypeContainer) type).getType(); temp = ((ITypeContainer) type).getType();

View file

@ -95,6 +95,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
@ -524,10 +525,16 @@ public class CPPVisitor {
else { else {
if( internal.getDefinition() == null ) if( internal.getDefinition() == null )
((ICPPInternalBinding)function).addDefinition( name ); ((ICPPInternalBinding)function).addDefinition( name );
else else {
IASTNode def = internal.getDefinition();
if( def instanceof IASTDeclarator )
def = ((IASTDeclarator)def).getName();
if( def != name )
return new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION, name.toCharArray() ); return new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION, name.toCharArray() );
} }
}
return function; return function;
} }
} }
@ -1317,7 +1324,7 @@ public class CPPVisitor {
returnType = getPointerTypes( returnType, fnDtor ); returnType = getPointerTypes( returnType, fnDtor );
} }
IType type = new CPPFunctionType( returnType, pTypes ); IType type = new CPPFunctionType( returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile() );
IASTDeclarator nested = fnDtor.getNestedDeclarator(); IASTDeclarator nested = fnDtor.getNestedDeclarator();
if( nested != null ) { if( nested != null ) {
return createType( type, nested ); return createType( type, nested );
@ -1460,6 +1467,42 @@ public class CPPVisitor {
return type; return type;
} }
public static IType getThisType( IScope scope ){
try {
IASTNode node = null;
while( scope != null ){
if( scope instanceof ICPPBlockScope ){
node = ((ICPPBlockScope)scope).getPhysicalNode();
if( node.getParent() instanceof IASTFunctionDefinition )
break;
}
scope = scope.getParent();
}
if( node != null && node.getParent() instanceof IASTFunctionDefinition ){
IASTFunctionDefinition def = (IASTFunctionDefinition) node.getParent();
IASTName fName = def.getDeclarator().getName();
IBinding binding = fName.resolveBinding();
if( binding != null && binding instanceof ICPPMethod ){
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) def.getDeclarator();
IScope s = binding.getScope();
if( s instanceof ICPPTemplateScope )
s = s.getParent();
if( s instanceof ICPPClassScope ){
ICPPClassScope cScope = (ICPPClassScope) s;
IType type = cScope.getClassType();
if( dtor.isConst() || dtor.isVolatile() )
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile() );
type = new CPPPointerType( type );
return type;
}
}
}
} catch (DOMException e) {
return e.getProblem();
}
return null;
}
/** /**
* @param expression * @param expression
* @return * @return
@ -1493,38 +1536,7 @@ public class CPPVisitor {
switch( ((ICPPASTLiteralExpression) expression).getKind() ){ switch( ((ICPPASTLiteralExpression) expression).getKind() ){
case ICPPASTLiteralExpression.lk_this : { case ICPPASTLiteralExpression.lk_this : {
IScope scope = getContainingScope( expression ); IScope scope = getContainingScope( expression );
try { return getThisType( scope );
IASTNode node = null;
while( scope != null ){
if( scope instanceof ICPPBlockScope ){
node = ((ICPPBlockScope)scope).getPhysicalNode();
if( node.getParent() instanceof IASTFunctionDefinition )
break;
}
scope = scope.getParent();
}
if( node != null && node.getParent() instanceof IASTFunctionDefinition ){
IASTFunctionDefinition def = (IASTFunctionDefinition) node.getParent();
IASTName fName = def.getDeclarator().getName();
IBinding binding = fName.resolveBinding();
if( binding != null && binding instanceof ICPPMethod ){
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) def.getDeclarator();
IScope s = binding.getScope();
if( s instanceof ICPPTemplateScope )
s = s.getParent();
if( s instanceof ICPPClassScope ){
ICPPClassScope cScope = (ICPPClassScope) s;
IType type = cScope.getClassType();
if( dtor.isConst() || dtor.isVolatile() )
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile() );
type = new CPPPointerType( type );
return type;
}
}
}
} catch (DOMException e) {
}
break;
} }
case ICPPASTLiteralExpression.lk_true : case ICPPASTLiteralExpression.lk_true :
case ICPPASTLiteralExpression.lk_false: case ICPPASTLiteralExpression.lk_false:
@ -1629,6 +1641,9 @@ public class CPPVisitor {
} else if( expression instanceof IASTExpressionList ){ } else if( expression instanceof IASTExpressionList ){
IASTExpression [] exps = ((IASTExpressionList)expression).getExpressions(); IASTExpression [] exps = ((IASTExpressionList)expression).getExpressions();
return getExpressionType( exps[ exps.length - 1 ] ); return getExpressionType( exps[ exps.length - 1 ] );
} else if( expression instanceof ICPPASTTypeIdExpression ){
ICPPASTTypeIdExpression typeidExp = (ICPPASTTypeIdExpression) expression;
return createType( typeidExp.getTypeId() );
} }
return null; return null;
} }

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* 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 Apr 26, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
/**
* @author aniefer
*/
public interface ICPPInternalFunction extends ICPPInternalBinding {
public boolean isStatic( boolean resolveAll );
}