diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java index 61649f91dfc..8ca8d1041bd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecFailingTest.java @@ -732,6 +732,30 @@ public class AST2CPPSpecFailingTest extends AST2SpecBaseTest { } } + /** + [--Start Example(CPP 14.3-5): + template struct A { + ~A(); + }; + void f(A* p, A* q) { + p->A::~A(); // OK: destructor call + q->A::~A(); // OK: destructor call + } + --End Example] + */ + public void test14_3s5() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template struct A {\n"); //$NON-NLS-1$ + buffer.append("~A();\n"); //$NON-NLS-1$ + buffer.append("};\n"); //$NON-NLS-1$ + buffer.append("void f(A* p, A* q) {\n"); //$NON-NLS-1$ + buffer.append("p->A::~A(); // OK: destructor call\n"); //$NON-NLS-1$ + buffer.append("q->A::~A(); // 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): template 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<>(1); //template\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 void f(T&) { }\n"); //$NON-NLS-1$ buffer.append("}\n"); //$NON-NLS-1$ buffer.append("template void N::f(int&);\n"); //$NON-NLS-1$ - parse(buffer.toString(), ParserLanguage.CPP, true, 2); + parse(buffer.toString(), ParserLanguage.CPP, true, 3); } /** diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index 7c31b7622b2..fd2c1dfba86 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -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::Y::g(); // error: g is not a member of A::X::Y\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); } - /** - [--Start Example(CPP 14.3-5): - template struct A { - ~A(); - }; - void f(A* p, A* q) { - p->A::~A(); // OK: destructor call - q->A::~A(); // OK: destructor call - } - --End Example] - */ - public void test14_3s5() throws Exception { - StringBuffer buffer = new StringBuffer(); - buffer.append("template struct A {\n"); //$NON-NLS-1$ - buffer.append("~A();\n"); //$NON-NLS-1$ - buffer.append("};\n"); //$NON-NLS-1$ - buffer.append("void f(A* p, A* q) {\n"); //$NON-NLS-1$ - buffer.append("p->A::~A(); // OK: destructor call\n"); //$NON-NLS-1$ - buffer.append("q->A::~A(); // 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): template class Array { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 6e88a6b8529..6428ea95ee6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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.ICPPField; 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.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; @@ -3700,5 +3701,40 @@ public class AST2CPPTests extends AST2BaseTest { assertSame( bs[0], a1 ); 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 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java new file mode 100644 index 00000000000..ea5def694b7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionType.java @@ -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(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index 13859885cd0..cd86052c108 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -84,7 +84,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.ProblemBinding; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; /** * Created on Nov 5, 2004 @@ -1467,7 +1466,7 @@ public class CVisitor { IType [] pTypes = getParmTypes( declarator ); returnType = setupPointerChain( declarator.getPointerOperators(), returnType ); - IType type = new CPPFunctionType( returnType, pTypes ); + IType type = new CFunctionType( returnType, pTypes ); IASTDeclarator nested = declarator.getNestedDeclarator(); if( nested != null ) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java index b9b7d686474..71ec38342e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java @@ -123,8 +123,7 @@ public class CPPClassInstanceScope implements ICPPClassScope { * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getClassType() */ public ICPPClassType getClassType() { - // TODO Auto-generated method stub - return null; + return (ICPPClassType) instance; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index e24faa84b98..265e3082bac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -111,8 +111,7 @@ public class CPPDeferredClassInstance /*extends CPPInstance*/ implements * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() */ public ICPPConstructor[] getConstructors() throws DOMException { - // TODO Auto-generated method stub - return null; + return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java index 39148a3073b..2d8ca741a61 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredFunctionInstance.java @@ -32,7 +32,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; * @author aniefer */ public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements - ICPPFunction, ICPPTemplateInstance, ICPPInternalBinding { + ICPPFunction, ICPPTemplateInstance, ICPPInternalFunction { private IType[] arguments; private ICPPFunctionTemplate functionTemplate; @@ -244,4 +244,12 @@ public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements // 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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 57e92a7dcf1..114f30305a0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -43,9 +43,9 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; /** * @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 ) { super( name, binding ); } @@ -80,6 +80,9 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding { public boolean takesVarArgs() throws DOMException { return ((ICPPFunction)getBinding()).takesVarArgs(); } + public boolean isStatic( boolean resolveAll ) { + return ((ICPPInternalFunction)getBinding()).isStatic( resolveAll ); + } } public static class CPPFunctionProblem extends ProblemBinding implements ICPPFunction { public CPPFunctionProblem( IASTNode node, int id, char[] arg ) { @@ -386,8 +389,14 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic() */ - public boolean isStatic() { - if( (bits & FULLY_RESOLVED) == 0 ){ + public boolean isStatic( ) { + 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(); } @@ -407,13 +416,15 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding { } IASTFunctionDeclarator[] dtors = (IASTFunctionDeclarator[]) getDeclarations(); - for( int i = 0; i < dtors.length; i++ ){ - IASTNode parent = dtors[i].getParent(); - declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); - if( declSpec.getStorageClass() == IASTDeclSpecifier.sc_static ){ - bits |= 3 << 2; - return true; - } + if( dtors != null ) { + for( int i = 0; i < dtors.length; i++ ){ + IASTNode parent = dtors[i].getParent(); + declSpec = ((IASTSimpleDeclaration)parent).getDeclSpecifier(); + if( declSpec.getStorageClass() == IASTDeclSpecifier.sc_static ){ + bits |= 3 << 2; + return true; + } + } } bits |= 2 << 2; return false; @@ -551,5 +562,4 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding { } return false; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index f89aa9b7c55..c8b45bf2878 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -29,7 +29,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ -public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalBinding { +public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, ICPPInternalFunction { private IFunctionType type = null; private IParameter [] parameters = null; /** @@ -171,4 +171,11 @@ public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, IC public boolean takesVarArgs() throws DOMException { 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 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java index 275ed7174b4..680c7549b08 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -41,7 +41,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; /** * @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 CPPFunctionTemplateProblem(IASTNode node, int id, char[] arg) { super(node, id, arg); @@ -351,4 +351,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu 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 ); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java index 843003518e9..5fff1e6e321 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java @@ -15,16 +15,18 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; /** * @author aniefer */ -public class CPPFunctionType implements IFunctionType { - IType[] parameters = null; - IType returnType = null; +public class CPPFunctionType implements ICPPFunctionType { + private IType[] parameters = null; + private IType returnType = null; + private boolean isConst = false; + private boolean isVolatile = false; /** * @param returnType @@ -34,12 +36,18 @@ public class CPPFunctionType implements IFunctionType { this.returnType = returnType; 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 ){ if( o instanceof ITypedef ) return o.isSameType( this ); - if( o instanceof IFunctionType ){ - IFunctionType ft = (IFunctionType) o; + if( o instanceof ICPPFunctionType ){ + ICPPFunctionType ft = (ICPPFunctionType) o; IType [] fps; try { fps = ft.getParameterTypes(); @@ -58,9 +66,13 @@ public class CPPFunctionType implements IFunctionType { } catch ( DOMException e1 ) { return false; } - for( int i = 0; i < parameters.length; i++ ) + for( int i = 0; i < parameters.length; i++ ){ if( ! parameters[i].isSameType( fps[i] ) ) return false; + } + if( isConst != ft.isConst() || isVolatile != ft.isVolatile() ) + return false; + return true; } return false; @@ -88,4 +100,12 @@ public class CPPFunctionType implements IFunctionType { } return t; } + + public boolean isConst() { + return isConst; + } + + public boolean isVolatile() { + return isVolatile; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java index 54772a62756..cb6a1a0c089 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java @@ -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.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPClassScope; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -178,10 +179,13 @@ public class CPPImplicitMethod extends CPPMethod { IASTDeclarator [] ds = null; int di = -1; - if( members[i] instanceof IASTSimpleDeclaration ){ - ds = ((IASTSimpleDeclaration)members[i]).getDeclarators(); - } else if( members[i] instanceof IASTFunctionDefinition ){ - dtor = ((IASTFunctionDefinition) members[i]).getDeclarator(); + IASTDeclaration member = members[i]; + if( member instanceof ICPPASTTemplateDeclaration ) + member = ((ICPPASTTemplateDeclaration) member).getDeclaration(); + if( member instanceof IASTSimpleDeclaration ){ + ds = ((IASTSimpleDeclaration)member).getDeclarators(); + } else if( member instanceof IASTFunctionDefinition ){ + dtor = ((IASTFunctionDefinition) member).getDeclarator(); } if( ds != null && ds.length > 0 ){ di = 0; @@ -203,7 +207,10 @@ public class CPPImplicitMethod extends CPPMethod { } if( idx == ps.length ){ name.setBinding( this ); - addDeclaration( dtor ); + if( member instanceof IASTSimpleDeclaration ) + addDeclaration( dtor ); + else if( member instanceof IASTFunctionDefinition ) + addDefinition( dtor ); return members[i]; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index c0f0a363dbd..a6d0f0b0e1d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -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.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPASTFieldReference; 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.ICPPConstructor; 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.ICPPFunctionType; 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.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.ICPPTemplateDefinition; 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.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; @@ -199,11 +203,14 @@ public class CPPSemantics { public boolean forDefinition(){ if( astName == null ) return false; if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false; + IASTNode p1 = astName.getParent(); + while( p1 instanceof IASTName ) + p1 = p1.getParent(); + IASTNode p2 = p1.getParent(); - return ( ( p1 instanceof ICPPASTQualifiedName && p2 instanceof IASTDeclarator ) || - ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) || + return ( ( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) || ( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition)); } private boolean considerConstructors(){ @@ -283,6 +290,47 @@ public class CPPSemantics { return ((CharArrayObjectMap)foundItems).size() != 0; 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 @@ -596,11 +644,11 @@ public class CPPSemantics { } static private ObjectSet getAssociatedScopes( LookupData data ) { - Object [] ps = data.functionParameters; + IType [] ps = getSourceParameterTypes( data.functionParameters ); ObjectSet namespaces = new ObjectSet(2); ObjectSet classes = new ObjectSet(2); for( int i = 0; i < ps.length; i++ ){ - IType p = getSourceParameterType( ps, i ); + IType p = ps[i]; p = getUltimateType( p, true ); try { 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 if( binding instanceof IEnumerator || - (binding instanceof IFunction && ((IFunction)binding).isStatic()) || + (binding instanceof IFunction && ((ICPPInternalFunction)binding).isStatic( false )) || (binding instanceof IVariable && ((IVariable)binding).isStatic()) ) { ok = true; @@ -1290,27 +1338,30 @@ public class CPPSemantics { if( declaration instanceof IASTSimpleDeclaration ){ IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration; + ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) simpleDeclaration.getDeclSpecifier(); IASTDeclarator [] declarators = simpleDeclaration.getDeclarators(); - for( int i = 0; i < declarators.length; i++ ){ - IASTDeclarator declarator = declarators[i]; - while( declarator.getNestedDeclarator() != null ) - declarator = declarator.getNestedDeclarator(); - IASTName declaratorName = declarator.getName(); - scope.addName( declaratorName ); - if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) { - if( nameMatches( data, declaratorName ) ) { - if( resultName == null ) - resultName = declaratorName; - else if( resultArray == null ) - resultArray = new IASTName[] { resultName, declaratorName }; - else - resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, declaratorName ); + if( !declSpec.isFriend() ) { + for( int i = 0; i < declarators.length; i++ ){ + IASTDeclarator declarator = declarators[i]; + while( declarator.getNestedDeclarator() != null ) + declarator = declarator.getNestedDeclarator(); + IASTName declaratorName = declarator.getName(); + scope.addName( declaratorName ); + if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) { + if( nameMatches( data, declaratorName ) ) { + if( resultName == null ) + resultName = declaratorName; + else if( resultArray == null ) + resultArray = new IASTName[] { resultName, declaratorName }; + else + resultArray = (IASTName[]) ArrayUtil.append( IASTName.class, resultArray, declaratorName ); + } } } } //decl spec - IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier(); + IASTName specName = null; if( declarators.length == 0 && declSpec instanceof IASTElaboratedTypeSpecifier ){ specName = ((IASTElaboratedTypeSpecifier)declSpec).getName(); @@ -1404,16 +1455,18 @@ public class CPPSemantics { return alias; } else if( declaration instanceof IASTFunctionDefinition ){ IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration; - IASTFunctionDeclarator declarator = functionDef.getDeclarator(); - - //check the function itself - IASTName declName = declarator.getName(); - scope.addName( declName ); - - if( !data.typesOnly && nameMatches( data, declName ) ) { - return declName; + if( ! ((ICPPASTDeclSpecifier) functionDef.getDeclSpecifier()).isFriend() ){ + IASTFunctionDeclarator declarator = functionDef.getDeclarator(); + + //check the function itself + IASTName declName = declarator.getName(); + scope.addName( declName ); + + if( !data.typesOnly && nameMatches( data, declName ) ) { + return declName; + } } - } + } if( resultArray != null ) return resultArray; @@ -1774,38 +1827,87 @@ public class CPPSemantics { static private boolean isMatchingFunctionDeclaration( IFunction candidate, LookupData data ){ IASTName name = data.astName; ICPPASTTemplateDeclaration decl = CPPTemplates.getTemplateDeclaration( name ); + if( decl != null && !(candidate instanceof ICPPTemplateDefinition) ) + return false; + if( candidate instanceof ICPPTemplateDefinition && decl instanceof ICPPASTTemplateSpecialization ){ ICPPFunctionTemplate fn = CPPTemplates.resolveTemplateFunctions( new Object [] { candidate }, data.astName ); return ( fn != null && !(fn instanceof IProblemBinding ) ); } 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 ); } catch (DOMException e) { } return false; } - static private IType getSourceParameterType( Object [] params, int idx ){ + static private IType[] getSourceParameterTypes( Object [] params ){ if( params instanceof IType[] ){ - IType [] types = (IType[]) params; - if( idx < types.length ) - return types[idx]; - return (idx == 0 ) ? VOID_TYPE : null; - } else if( params instanceof IASTExpression [] ){ + return (IType[]) params; + } + + if( params == null || params.length == 0 ) + return new IType[] { VOID_TYPE }; + + if( params instanceof IASTExpression [] ){ IASTExpression [] exps = (IASTExpression[]) params; - if( idx < exps.length) - return CPPVisitor.getExpressionType( exps[ idx ] ); - return ( idx == 0 ) ? VOID_TYPE : null; + IType [] result = new IType[ exps.length ]; + for ( int i = 0; i < exps.length; i++ ) { + result[i] = CPPVisitor.getExpressionType( exps[i] ); + } + return result; } else if( params instanceof IASTParameterDeclaration[] ){ - IASTParameterDeclaration [] decls = (IASTParameterDeclaration[]) params; - if( idx < decls.length) - return CPPVisitor.createType( decls[idx].getDeclarator() ); - return ( idx == 0 ) ? VOID_TYPE : null; - } else if( params == null && idx == 0 ) - return VOID_TYPE; + IASTParameterDeclaration [] decls = (IASTParameterDeclaration[]) params; + IType [] result = new IType[ decls.length ]; + for ( int i = 0; i < params.length; i++ ) { + result[i] = CPPVisitor.createType( decls[i].getDeclarator() ); + } + return result; + } 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{ fns = (IBinding[]) ArrayUtil.trim( IBinding.class, fns, true ); if( fns == null || fns.length == 0 ) @@ -1828,6 +1930,7 @@ public class CPPSemantics { return fns[i]; } } + return null; } 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 bestHasAmbiguousParam = false; //bestFn has an ambiguous parameter conversion (not ok, ambiguous) - Object [] sourceParameters = null; //the parameters the function is being called with - IASTParameterDeclaration [] targetParameters = null; //the current function's parameters - IParameter [] targetBindings = null; + IType [] sourceParameters = getSourceParameterTypes( data.functionParameters ); //the parameters the function is being called with + IType [] targetParameters = null; + int numSourceParams = 0; int targetLength = 0; - int numFns = fns.length; - int numSourceParams = ( data.functionParameters != null ) ? data.functionParameters.length : 0; - if( data.functionParameters != null && numSourceParams == 0 ) - numSourceParams = 1; - sourceParameters = data.functionParameters; + + IType impliedObjectType = data.getImpliedObjectArgument(); outer: for( int fnIdx = 0; fnIdx < numFns; fnIdx++ ){ currFn = (IFunction) fns[fnIdx]; @@ -1868,28 +1968,13 @@ public class CPPSemantics { { continue; } - - IASTNode node = ((ICPPInternalBinding)currFn).getDefinition(); - 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; + + targetParameters = getTargetParameterTypes( currFn ); - if( targetParameters == null ){ - targetBindings = currFn.getParameters(); - targetLength = targetBindings.length; - } else { - targetLength = targetParameters.length; - } - int numTargetParams = ( targetLength == 0 ) ? 1 : targetLength; + targetLength = targetParameters.length; + boolean useImplicitObj = ( currFn instanceof ICPPMethod && !(currFn instanceof ICPPConstructor) ); + numSourceParams = ( useImplicitObj ) ? sourceParameters.length + 1 : sourceParameters.length; + int numTargetParams = 0; if( currFnCost == null ){ currFnCost = new Cost [ (numSourceParams == 0) ? 1 : numSourceParams ]; @@ -1899,23 +1984,32 @@ public class CPPSemantics { boolean varArgs = false; for( int j = 0; j < numSourceParams || j == 0; j++ ){ - source = getSourceParameterType( sourceParameters, j ); - if( source == null ) - continue outer; - + if( useImplicitObj ) { + source = ( j == 0 ) ? impliedObjectType : sourceParameters[j - 1]; + numTargetParams = ( targetLength == 1 ) ? 2 : targetLength; + } else { + source = sourceParameters[j]; + numTargetParams = ( targetLength == 0 ) ? 1 : targetLength; + } + if( j < numTargetParams ){ - if( targetLength == 0 && j == 0 ){ - target = VOID_TYPE; - } else if( targetParameters != null ) { - IParameter param = (IParameter) targetParameters[j].getDeclarator().getName().resolveBinding(); - target = param.getType(); - } else { - target = targetBindings[j].getType(); + if( (useImplicitObj && targetLength == 1 && j == 1) || + (!useImplicitObj && targetLength == 0 && j == 0) ) + { + target = VOID_TYPE; + } else { + target = targetParameters[j]; } } else 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.rank = Cost.ELLIPSIS_CONVERSION; } else if( source.isSameType( target ) ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index 5769824f983..3d2be62b6f9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -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.ICPPFunction; 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.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; @@ -196,7 +197,7 @@ public class CPPTemplates { if( parent instanceof ICPPASTCompositeTypeSpecifier && segment == 1 ){ return createClassPartialSpecialization( (ICPPASTCompositeTypeSpecifier) parent ); - } else if( parent instanceof ICPPASTFunctionDeclarator && segment == 1 ){ + } else if( parent instanceof ICPPASTFunctionDeclarator && segment != 0 ){ return createFunctionSpecialization( id ); } @@ -270,7 +271,7 @@ public class CPPTemplates { CPPSemantics.LookupData data = new CPPSemantics.LookupData( name ); data.forceQualified = true; IScope scope = CPPVisitor.getContainingScope( name ); - if( name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){ + if( scope instanceof ICPPTemplateScope && name.getPropertyInParent() != ICPPASTQualifiedName.SEGMENT_NAME ){ try { scope = scope.getParent(); } catch (DOMException e) { @@ -476,7 +477,7 @@ public class CPPTemplates { } } catch (DOMException e) { } - newType = new CPPFunctionType( ret, params ); + newType = new CPPFunctionType( ret, params, ((ICPPFunctionType)type).isConst(), ((ICPPFunctionType)type).isVolatile() ); } else if( type instanceof ITypeContainer ){ try { temp = ((ITypeContainer) type).getType(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index fece07adb4b..6d9eafb7822 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -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.ICPPASTTemplateParameter; 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.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; @@ -524,8 +525,14 @@ public class CPPVisitor { else { if( internal.getDefinition() == null ) ((ICPPInternalBinding)function).addDefinition( name ); - else - return new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION, name.toCharArray() ); + 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 function; @@ -1317,7 +1324,7 @@ public class CPPVisitor { returnType = getPointerTypes( returnType, fnDtor ); } - IType type = new CPPFunctionType( returnType, pTypes ); + IType type = new CPPFunctionType( returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile() ); IASTDeclarator nested = fnDtor.getNestedDeclarator(); if( nested != null ) { return createType( type, nested ); @@ -1460,6 +1467,42 @@ public class CPPVisitor { 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 * @return @@ -1493,38 +1536,7 @@ public class CPPVisitor { switch( ((ICPPASTLiteralExpression) expression).getKind() ){ case ICPPASTLiteralExpression.lk_this : { IScope scope = getContainingScope( expression ); - 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) { - } - break; + return getThisType( scope ); } case ICPPASTLiteralExpression.lk_true : case ICPPASTLiteralExpression.lk_false: @@ -1629,6 +1641,9 @@ public class CPPVisitor { } else if( expression instanceof IASTExpressionList ){ IASTExpression [] exps = ((IASTExpressionList)expression).getExpressions(); return getExpressionType( exps[ exps.length - 1 ] ); + } else if( expression instanceof ICPPASTTypeIdExpression ){ + ICPPASTTypeIdExpression typeidExp = (ICPPASTTypeIdExpression) expression; + return createType( typeidExp.getTypeId() ); } return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java new file mode 100644 index 00000000000..c75e72ec9ef --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalFunction.java @@ -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 ); +}