From d4891a2e74c5e97430e32bd76373398420e02cb4 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Wed, 6 Apr 2005 15:01:04 +0000 Subject: [PATCH] Templates - better handling of function templates - basic handling of class specializations - The binding for a templated declaration is now a ICPPTemplateDefinition itself instead of being a normal binding owned by a template definition. --- .../parser/tests/ast2/AST2TemplateTests.java | 164 ++++++++++- .../core/dom/ast/cpp/ICPPClassTemplate.java | 21 ++ .../cdt/core/dom/ast/cpp/ICPPConstructor.java | 4 +- .../dom/ast/cpp/ICPPFunctionTemplate.java | 21 ++ .../dom/ast/cpp/ICPPTemplateDefinition.java | 17 +- ...nstance.java => ICPPTemplateInstance.java} | 2 +- .../cpp/CPPASTTemplateSpecialization.java | 43 ++- .../dom/parser/cpp/CPPClassInstanceScope.java | 7 +- .../core/dom/parser/cpp/CPPClassScope.java | 5 +- .../core/dom/parser/cpp/CPPClassTemplate.java | 231 +++++++++++++++ .../cpp/CPPClassTemplateSpecialization.java | 58 ++++ .../core/dom/parser/cpp/CPPClassType.java | 12 +- .../parser/cpp/CPPConstructorTemplate.java | 41 +++ .../core/dom/parser/cpp/CPPDelegate.java | 18 +- .../core/dom/parser/cpp/CPPEnumeration.java | 18 +- .../core/dom/parser/cpp/CPPEnumerator.java | 18 +- .../core/dom/parser/cpp/CPPFunction.java | 16 +- .../dom/parser/cpp/CPPFunctionTemplate.java | 210 ++++++++++++++ .../core/dom/parser/cpp/CPPInstance.java | 19 +- .../core/dom/parser/cpp/CPPLabel.java | 18 +- .../dom/parser/cpp/CPPMethodTemplate.java | 41 +++ .../core/dom/parser/cpp/CPPNamespace.java | 18 +- .../dom/parser/cpp/CPPNamespaceAlias.java | 14 +- .../core/dom/parser/cpp/CPPParameter.java | 14 +- .../core/dom/parser/cpp/CPPScope.java | 6 +- .../core/dom/parser/cpp/CPPSemantics.java | 137 +++++++-- .../dom/parser/cpp/CPPTemplateDefinition.java | 239 ++++++++++----- .../dom/parser/cpp/CPPTemplateParameter.java | 16 + .../core/dom/parser/cpp/CPPTemplateScope.java | 19 +- .../core/dom/parser/cpp/CPPTemplates.java | 273 ++++++++++++++++-- .../core/dom/parser/cpp/CPPTypedef.java | 18 +- .../core/dom/parser/cpp/CPPVariable.java | 15 +- .../core/dom/parser/cpp/CPPVisitor.java | 117 ++++---- .../dom/parser/cpp/ICPPInternalBinding.java | 9 +- 34 files changed, 1632 insertions(+), 247 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionTemplate.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/{ICPPInstance.java => ICPPTemplateInstance.java} (94%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplate.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplate.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 8e56f2df2ae..c7efbf1562b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -15,17 +15,23 @@ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +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.ICPPField; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPInstance; +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.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; 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.ICPPVariable; import org.eclipse.cdt.core.parser.ParserLanguage; @@ -40,8 +46,9 @@ public class AST2TemplateTests extends AST2BaseTest { tu.accept(col); assertEquals( col.size(), 4 ); + ICPPClassTemplate A = (ICPPClassTemplate) col.getName(1).resolveBinding(); ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding(); - ICPPClassType A = (ICPPClassType) col.getName(1).resolveBinding(); + ICPPTemplateScope scope = (ICPPTemplateScope) T.getScope(); IScope s2 = A.getScope(); @@ -75,7 +82,7 @@ public class AST2TemplateTests extends AST2BaseTest { assertEquals( col.size(), 14 ); - ICPPClassType A = (ICPPClassType) col.getName(1).resolveBinding(); + ICPPClassTemplate A = (ICPPClassTemplate) col.getName(1).resolveBinding(); ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding(); ICPPField t1 = (ICPPField) col.getName(3).resolveBinding(); ICPPField t2 = (ICPPField) col.getName(5).resolveBinding(); @@ -88,23 +95,23 @@ public class AST2TemplateTests extends AST2BaseTest { ICPPClassType A_int = (ICPPClassType) col.getName(7).resolveBinding(); assertSame( A_int, a.getType() ); - assertTrue( A_int instanceof ICPPInstance ); - assertSame( ((ICPPInstance)A_int).getOriginalBinding(), A ); + assertTrue( A_int instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)A_int).getOriginalBinding(), A ); ICPPClassScope A_int_Scope = (ICPPClassScope) A_int.getCompositeScope(); - assertNotSame( A_int_Scope, A.getCompositeScope() ); + assertNotSame( A_int_Scope, ((ICompositeType) A).getCompositeScope() ); ICPPField t = (ICPPField) col.getName(11).resolveBinding(); - assertTrue( t instanceof ICPPInstance ); - assertSame( ((ICPPInstance)t).getOriginalBinding(), t1 ); + assertTrue( t instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)t).getOriginalBinding(), t1 ); assertSame( t.getScope(), A_int_Scope ); IType type = t.getType(); assertTrue( type instanceof IBasicType ); assertEquals( ((IBasicType)type).getType(), IBasicType.t_int ); t = (ICPPField) col.getName(13).resolveBinding(); - assertTrue( t instanceof ICPPInstance ); - assertSame( ((ICPPInstance)t).getOriginalBinding(), t2 ); + assertTrue( t instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)t).getOriginalBinding(), t2 ); assertSame( t.getScope(), A_int_Scope ); type = t.getType(); assertTrue( type instanceof IPointerType ); @@ -135,14 +142,143 @@ public class AST2TemplateTests extends AST2BaseTest { assertSame( ((IPointerType)ft.getParameterTypes()[0]).getType(), T ); ICPPClassType A_int = (ICPPClassType) col.getName(7).resolveBinding(); - assertTrue( A_int instanceof ICPPInstance ); - assertSame( ((ICPPInstance)A_int).getOriginalBinding(), A ); + assertTrue( A_int instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)A_int).getOriginalBinding(), A ); ICPPMethod f_int = (ICPPMethod) col.getName(11).resolveBinding(); - assertTrue( f_int instanceof ICPPInstance ); - assertSame( ((ICPPInstance)f_int).getOriginalBinding(), f ); + assertTrue( f_int instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)f_int).getOriginalBinding(), f ); ft = f_int.getType(); assertTrue( ft.getReturnType() instanceof IBasicType ); assertTrue( ((IPointerType)ft.getParameterTypes()[0]).getType() instanceof IBasicType ); } + + public void testBasicTemplateFunction() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template void f( T ); \n"); //$NON-NLS-1$ + buffer.append("template void f( T ) { \n"); //$NON-NLS-1$ + buffer.append(" T * d; \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + buffer.append("void foo() { \n"); //$NON-NLS-1$ + buffer.append(" f( 0 ); \n"); //$NON-NLS-1$ + buffer.append("} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept(col); + + ICPPFunctionTemplate f = (ICPPFunctionTemplate) col.getName(1).resolveBinding(); + ICPPTemplateParameter T = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + + IParameter p1 = (IParameter) col.getName(3).resolveBinding(); + + ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(4).resolveBinding(); + ICPPFunction f2 = (ICPPFunction) col.getName(5).resolveBinding(); + IParameter p2 = (IParameter) col.getName(7).resolveBinding(); + + assertSame( T, T2 ); + assertSame( f, f2 ); + assertSame( p1, p2 ); + assertSame( p1.getType(), T ); + + ICPPFunction f3 = (ICPPFunction) col.getName(11).resolveBinding(); + assertTrue( f3 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)f3).getOriginalBinding(), f ); + + assertInstances( col, T, 5 ); + } + + public void testStackOverflow() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template < class T > class pair { \n"); //$NON-NLS-1$ + buffer.append(" template < class U > pair( const pair & ); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept(col); + + assertTrue( col.getName(0).resolveBinding() instanceof ICPPTemplateParameter ); + ICPPClassTemplate pair = (ICPPClassTemplate) col.getName(1).resolveBinding(); + ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(2).resolveBinding(); + assertTrue( col.getName(3).resolveBinding() instanceof ICPPFunctionTemplate ); + ICPPTemplateInstance pi = (ICPPTemplateInstance) col.getName(4).resolveBinding(); + ICPPClassTemplate p = (ICPPClassTemplate) col.getName(5).resolveBinding(); + ICPPTemplateParameter U2 = (ICPPTemplateParameter) col.getName(6).resolveBinding(); + + assertSame( U, U2 ); + assertSame( pair, p ); + assertSame( pi.getOriginalBinding(), pair ); + } + + public void testBasicClassPartialSpecialization() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "template < class T > class A {}; \n "); //$NON-NLS-1$ + buffer.append( "template < class T > class A< T* > {}; \n "); //$NON-NLS-1$ + buffer.append( "template < class T > class A< T** > {}; \n "); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + ICPPClassTemplate A1 = (ICPPClassTemplate) col.getName(1).resolveBinding(); + ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(2).resolveBinding(); + ICPPClassTemplate A2 = (ICPPClassTemplate) col.getName(3).resolveBinding(); + ICPPTemplateParameter T3 = (ICPPTemplateParameter) col.getName(5).resolveBinding(); + ICPPClassTemplate A3 = (ICPPClassTemplate) col.getName(7).resolveBinding(); + ICPPTemplateParameter T4 = (ICPPTemplateParameter) col.getName(6).resolveBinding(); + + assertTrue( A2 instanceof ICPPTemplateSpecialization ); + assertTrue( ((ICPPTemplateSpecialization)A2).isPartialSpecialization() ); + assertNotSame( T1, T2 ); + assertNotSame( A1, A2 ); + assertNotSame( A1, A3 ); + assertNotSame( A2, A3 ); + assertSame( T2, T3 ); + assertNotSame( T2, T4 ); + } + + public void testStackOverflow_2() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "template < class T > class A { typedef int TYPE; }; \n"); //$NON-NLS-1$ + buffer.append( "template < class T > A::TYPE foo( T ); \n"); //$NON-NLS-1$ + buffer.append( "template < class T > A::TYPE foo( T ); \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPTemplateParameter T0 = (ICPPTemplateParameter) col.getName(0).resolveBinding(); + ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(3).resolveBinding(); + ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(12).resolveBinding(); + + assertNotSame( T0, T1 ); + assertSame( T1, T2 ); + + ICPPFunctionTemplate foo1 = (ICPPFunctionTemplate) col.getName(9).resolveBinding(); + ICPPFunctionTemplate foo2 = (ICPPFunctionTemplate) col.getName(18).resolveBinding(); + assertSame( foo1, foo2 ); + + assertInstances( col, T1, 6 ); + } + + public void testTemplateMemberDef() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append("template < class T > class A { \n"); //$NON-NLS-1$ + buffer.append(" void f(); \n"); //$NON-NLS-1$ + buffer.append("}; \n"); //$NON-NLS-1$ + buffer.append("template < class T > void A::f() { } \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector col = new CPPNameCollector(); + tu.accept( col ); + + ICPPMethod f1 = (ICPPMethod) col.getName(2).resolveBinding(); + ICPPMethod f2 = (ICPPMethod) col.getName(8).resolveBinding(); + + //TODO this isn't right, but its close enough for now + assertTrue( f2 instanceof ICPPTemplateInstance ); + assertSame( ((ICPPTemplateInstance)f2).getOriginalBinding(), f1 ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java new file mode 100644 index 00000000000..f15a25e29d1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java @@ -0,0 +1,21 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * @author aniefer + */ +public interface ICPPClassTemplate extends ICPPTemplateDefinition { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPConstructor.java index 1d4007147a3..8f8e3f07b98 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPConstructor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.DOMException; * @author aniefer */ public interface ICPPConstructor extends ICPPMethod { - + public static final ICPPConstructor [] EMPTY_CONSTRUCTOR_ARRAY = new ICPPConstructor[0]; /** * Whether or not this constructor was declared as explicit * diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionTemplate.java new file mode 100644 index 00000000000..6dd6adbdb16 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPFunctionTemplate.java @@ -0,0 +1,21 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * @author aniefer + */ +public interface ICPPFunctionTemplate extends ICPPTemplateDefinition { + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateDefinition.java index ea16d74b281..53c9885602c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateDefinition.java @@ -10,7 +10,6 @@ **********************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; -import org.eclipse.cdt.core.dom.ast.IBinding; /** * @author Doug Schaefer @@ -23,19 +22,5 @@ public interface ICPPTemplateDefinition extends ICPPBinding{ * a partial specialization will have the specialized parameter list * @return array of ICPPTemplateParameter */ - public ICPPTemplateParameter[] getParameters(); - - /** - * instantiate this template using the given arguments - * @param arguments - * @return - */ - public IBinding instantiate( ICPPASTTemplateId id ); - - /** - * returns the templated declaration for this template, - * will be either a ICPPClassType or a ICPPFunction - * @return - */ - public IBinding getTemplatedDeclaration(); + public ICPPTemplateParameter[] getTemplateParameters(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java similarity index 94% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPInstance.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java index 071ac04e517..f939524a0bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateInstance.java @@ -19,7 +19,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ -public interface ICPPInstance extends IBinding { +public interface ICPPTemplateInstance extends IBinding { /** * Get the original binding of which this is an instance of diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateSpecialization.java index a396abcc3e9..580e9cc0e42 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateSpecialization.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -12,15 +12,19 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +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.ICPPTemplateScope; /** * @author jcamelon */ public class CPPASTTemplateSpecialization extends CPPASTNode implements - ICPPASTTemplateSpecialization { + ICPPASTTemplateSpecialization, ICPPASTTemplateDeclaration { private IASTDeclaration declaration; + private ICPPTemplateScope templateScope; /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization#getDeclaration() @@ -48,4 +52,39 @@ public class CPPASTTemplateSpecialization extends CPPASTNode implements if( declaration != null ) if( !declaration.accept( action ) ) return false; return true; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration#isExported() + */ + public boolean isExported() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration#setExported(boolean) + */ + public void setExported(boolean value) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration#getTemplateParameters() + */ + public ICPPASTTemplateParameter[] getTemplateParameters() { + return ICPPASTTemplateParameter.EMPTY_TEMPLATEPARAMETER_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration#addTemplateParamter(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter) + */ + public void addTemplateParamter(ICPPASTTemplateParameter parm) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration#getScope() + */ + public ICPPTemplateScope getScope() { + if( templateScope == null ) + templateScope = new CPPTemplateScope( this ); + return templateScope; + } } 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 fe5f7c58cf7..dcf0f5dd9b5 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 @@ -21,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; @@ -35,7 +35,7 @@ public class CPPClassInstanceScope implements ICPPClassScope { private CharArrayObjectMap bindings; private ObjectMap instanceMap = ObjectMap.EMPTY_MAP; - private ICPPInstance instance; + private ICPPTemplateInstance instance; private boolean isFullyCached = false; /** * @param instance @@ -143,6 +143,9 @@ public class CPPClassInstanceScope implements ICPPClassScope { } public void addName(IASTName name) { + if( name instanceof ICPPASTQualifiedName ) + return; + if( bindings == null ) bindings = new CharArrayObjectMap(1); char [] c = name.toCharArray(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 06dde45dc1f..f4a3b691a41 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -128,6 +128,9 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } public void addName(IASTName name) { + if( name instanceof ICPPASTQualifiedName ) + return; + IASTNode parent = name.getParent(); if( parent instanceof IASTDeclarator ){ if( CPPVisitor.isConstructor( this, (IASTDeclarator) parent ) ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java new file mode 100644 index 00000000000..b20a3c791fc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -0,0 +1,231 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +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.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.ObjectMap; + +/** + * @author aniefer + */ +public class CPPClassTemplate extends CPPTemplateDefinition implements + ICPPClassTemplate, ICPPClassType, ICPPInternalBinding { + + /** + * @param decl + */ + public CPPClassTemplate(IASTName name) { + super(name); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplate#instantiate(org.eclipse.cdt.core.dom.ast.IASTNode[]) + */ + public IBinding instantiate(ICPPASTTemplateId templateId ) {//IASTNode[] arguments) { + ICPPTemplateParameter [] params = getTemplateParameters(); + IASTNode [] arguments = templateId.getTemplateArguments(); + + ObjectMap map = new ObjectMap(params.length); + if( arguments.length == params.length ){ + for( int i = 0; i < arguments.length; i++ ){ + IType t = CPPVisitor.createType( arguments[i] ); + map.put( params[i], t ); + } + } + + return CPPTemplates.createInstance( templateId, (ICPPScope) getScope(), this, map ); + } + + private void checkForDefinition(){ +// CPPClassType.FindDefinitionAction action = new FindDefinitionAction(); +// IASTNode node = CPPVisitor.getContainingBlockItem( getPhysicalNode() ).getParent(); +// +// node.accept( action ); +// definition = action.result; +// +// if( definition == null ){ +// node.getTranslationUnit().accept( action ); +// definition = action.result; +// } +// + return; + } + private ICPPASTCompositeTypeSpecifier getCompositeTypeSpecifier(){ + if( definition != null ){ + return (ICPPASTCompositeTypeSpecifier) definition.getParent(); + } + return null; + } + /** + * @param templateParameter + * @return + */ + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getBases() + */ + public ICPPBase [] getBases() { + if( definition == null ){ + checkForDefinition(); + if( definition == null ){ + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new ICPPBase [] { new CPPBaseClause.CPPBaseProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; + } + } + ICPPASTBaseSpecifier [] bases = getCompositeTypeSpecifier().getBaseSpecifiers(); + if( bases.length == 0 ) + return ICPPBase.EMPTY_BASE_ARRAY; + + ICPPBase [] bindings = new ICPPBase[ bases.length ]; + for( int i = 0; i < bases.length; i++ ){ + bindings[i] = new CPPBaseClause( bases[i] ); + } + + return bindings; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getFields() + */ + public IField[] getFields() throws DOMException { + if( definition == null ){ + checkForDefinition(); + if( definition == null ){ + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new IField [] { new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray() ) }; + } + } + + IField[] fields = getDeclaredFields(); + ICPPBase [] bases = getBases(); + for ( int i = 0; i < bases.length; i++ ) { + fields = (IField[]) ArrayUtil.addAll( IField.class, fields, bases[i].getBaseClass().getFields() ); + } + return (IField[]) ArrayUtil.trim( IField.class, fields ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ICompositeType#findField(java.lang.String) + */ + public IField findField(String name) throws DOMException { + IBinding [] bindings = CPPSemantics.findBindings( getCompositeScope(), name, true ); + IField field = null; + for ( int i = 0; i < bindings.length; i++ ) { + if( bindings[i] instanceof IField ){ + if( field == null ) + field = (IField) bindings[i]; + else { + IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : null; + return new CPPField.CPPFieldProblem( node, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, name.toCharArray() ); + } + } + } + return field; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredFields() + */ + public ICPPField[] getDeclaredFields() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getMethods() + */ + public ICPPMethod[] getMethods() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getAllDeclaredMethods() + */ + public ICPPMethod[] getAllDeclaredMethods() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getDeclaredMethods() + */ + public ICPPMethod[] getDeclaredMethods() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getConstructors() + */ + public ICPPConstructor[] getConstructors() { + return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType#getFriends() + */ + public IBinding[] getFriends() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getKey() + */ + public int getKey() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ICompositeType#getCompositeScope() + */ + public IScope getCompositeScope() { + if( definition != null ){ + ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) definition.getParent(); + return compSpec.getScope(); + } + return null; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + } + return null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java new file mode 100644 index 00000000000..d18d7573a65 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -0,0 +1,58 @@ +/********************************************************************** + * 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 5, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization; + +/** + * @author aniefer + */ +public class CPPClassTemplateSpecialization extends CPPClassTemplate implements + ICPPTemplateSpecialization { + + private IASTNode [] arguments; + /** + * @param name + */ + public CPPClassTemplateSpecialization(ICPPASTTemplateId name) { + super(name); + this.arguments = name.getTemplateArguments(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization#getArguments() + */ + public IASTNode[] getArguments() { + return arguments; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization#isPartialSpecialization() + */ + public boolean isPartialSpecialization() { + return getTemplateParameters().length > 0; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization#getPrimaryTemplateDefinition() + */ + public ICPPTemplateDefinition getPrimaryTemplateDefinition() { + ICPPASTTemplateId id = (ICPPASTTemplateId) getTemplateName(); + return (ICPPTemplateDefinition) id.getTemplateName().resolveBinding(); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 7061fcb46e0..ba47016a809 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -344,10 +344,14 @@ public class CPPClassType implements ICPPClassType, ICPPInternalBinding { return getElaboratedTypeSpecifier().getKind(); } - public void addDefinition( ICPPASTCompositeTypeSpecifier compSpec ){ - definition = compSpec.getName(); + public void addDefinition( IASTNode node ){ + if( node instanceof ICPPASTCompositeTypeSpecifier ) + definition = ((ICPPASTCompositeTypeSpecifier)node).getName(); } - public void addDeclaration( ICPPASTElaboratedTypeSpecifier elabSpec ) { + public void addDeclaration( IASTNode node ) { + if( !(node instanceof ICPPASTElaboratedTypeSpecifier) ) + return; + ICPPASTElaboratedTypeSpecifier elabSpec = (ICPPASTElaboratedTypeSpecifier) node; if( declarations == null ){ declarations = new IASTName[] { elabSpec.getName() }; return; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplate.java new file mode 100644 index 00000000000..a8e13fbc647 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplate.java @@ -0,0 +1,41 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; + +/** + * @author aniefer + */ +public class CPPConstructorTemplate extends CPPMethodTemplate implements + ICPPConstructor { + + /** + * @param name + */ + public CPPConstructorTemplate(IASTName name) { + super(name); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor#isExplicit() + */ + public boolean isExplicit() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java index 0f7b464e7e8..848a303410b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDelegate.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * 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 @@ -133,5 +133,21 @@ public class CPPDelegate implements ICPPDelegate, ICPPInternalBinding { delegate.setName( n ); return delegate; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java index 030757d5dbb..42d01f0792e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumeration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -149,4 +149,20 @@ public class CPPEnumeration implements IEnumeration, ICPPInternalBinding, ICPPBi public ICPPDelegate createDelegate( IASTName name ) { return new CPPEnumerationDelegate( name, this ); } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java index edee311f2d3..012ca3c2bcf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPEnumerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -135,4 +135,20 @@ public class CPPEnumerator implements IEnumerator, ICPPInternalBinding, ICPPBind return new CPPEnumeratorDelegate( name, this ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } + } 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 a2968dbafc7..734caee2e25 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -160,11 +160,21 @@ public class CPPFunction implements ICPPFunction, ICPPInternalBinding { return definition; } - public void addDefinition( ICPPASTFunctionDeclarator dtor ){ + public void addDefinition( IASTNode node ){ + if( node instanceof IASTName ) + node = node.getParent(); + if( !(node instanceof ICPPASTFunctionDeclarator) ) + return; + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node; updateParameterBindings( dtor ); definition = dtor; } - public void addDeclaration( ICPPASTFunctionDeclarator dtor ){ + public void addDeclaration( IASTNode node ){ + if( node instanceof IASTName ) + node = node.getParent(); + if( !(node instanceof ICPPASTFunctionDeclarator) ) + return; + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node; updateParameterBindings( dtor ); if( declarations == null ){ declarations = new ICPPASTFunctionDeclarator [] { dtor }; 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 new file mode 100644 index 00000000000..bcea75b440a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplate.java @@ -0,0 +1,210 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +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.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.parser.util.ObjectMap; + +/** + * @author aniefer + */ +public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFunctionTemplate, ICPPFunction { + IFunctionType type = null; + /** + * @param decl + */ + public CPPFunctionTemplate(IASTName name) { + super(name); + } + + public void addDefinition(IASTNode node) { + if( !(node instanceof IASTName) ) + return; + updateFunctionParameterBindings( (IASTName) node ); + super.addDefinition( node ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + if( !(node instanceof IASTName) ) + return; + updateFunctionParameterBindings( (IASTName) node ); + super.addDeclaration( node ); + } + /** + * @param name + */ + private void updateFunctionParameterBindings(IASTName paramName) { + IASTName defName = definition != null ? definition : declarations[0]; + ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) defName.getParent(); + IASTParameterDeclaration [] ops = orig.getParameters(); + IASTParameterDeclaration [] nps = ((ICPPASTFunctionDeclarator)paramName.getParent()).getParameters(); + CPPParameter temp = null; + for( int i = 0; i < nps.length; i++ ){ + temp = (CPPParameter) ops[i].getDeclarator().getName().getBinding(); + if( temp != null ){ + IASTName name = nps[i].getDeclarator().getName(); + name.setBinding( temp ); + temp.addDeclaration( name ); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplate#instantiate(org.eclipse.cdt.core.dom.ast.IASTNode[]) + */ + public IBinding instantiate(ICPPASTTemplateId templateId ) {//IASTNode[] arguments) { + ICPPTemplateParameter [] params = getTemplateParameters(); + IASTNode [] arguments = templateId.getTemplateArguments(); + + ObjectMap map = new ObjectMap(params.length); + if( arguments.length == params.length ){ + for( int i = 0; i < arguments.length; i++ ){ + IType t = CPPVisitor.createType( arguments[i] ); + map.put( params[i], t ); + } + } + + return CPPTemplates.createInstance( templateId, (ICPPScope) getScope(), this, map ); + } + + /** + * @param templateParameter + * @return + */ +// public IBinding resolveParameter(ICPPASTTemplateParameter templateParameter) { +// return null; +// } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() + */ + public IParameter[] getParameters() { + IASTName name = getTemplateName(); + IASTNode parent = name.getParent(); + if( parent instanceof ICPPASTQualifiedName ) + parent = parent.getParent(); + if( parent instanceof ICPPASTFunctionDeclarator ){ + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) parent; + IASTParameterDeclaration[] params = dtor.getParameters(); + int size = params.length; + IParameter [] result = new IParameter[ size ]; + if( size > 0 ){ + for( int i = 0; i < size; i++ ){ + IASTParameterDeclaration p = params[i]; + result[i] = (IParameter) p.getDeclarator().getName().resolveBinding(); + } + } + return result; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() + */ + public IScope getFunctionScope() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() + */ + public IFunctionType getType() { + if( type == null ) { + IASTName name = getTemplateName(); + IASTNode parent = name.getParent(); + while( parent.getParent() instanceof IASTDeclarator ) + parent = parent.getParent(); + + IType temp = CPPVisitor.createType( (IASTDeclarator)parent ); + if( temp instanceof IFunctionType ) + type = (IFunctionType) temp; + } + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#isStatic() + */ + public boolean isStatic() { + // TODO Auto-generated method stub + return false; + } + + /** + * @param param + * @return + */ + public IBinding resolveFunctionParameter(ICPPASTParameterDeclaration param) { + IASTName name = param.getDeclarator().getName(); + IBinding binding = name.getBinding(); + if( binding != null ) + return binding; + + ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent(); + IASTParameterDeclaration [] ps = fdtor.getParameters(); + int i = 0; + for( ; i < ps.length; i++ ){ + if( param == ps[i] ) + break; + } + + //create a new binding and set it for the corresponding parameter in all known defns and decls + binding = new CPPParameter( name ); + IASTParameterDeclaration temp = null; + if( definition != null ){ + IASTNode node = definition.getParent(); + if( node instanceof ICPPASTQualifiedName ) + node = node.getParent(); + temp = ((ICPPASTFunctionDeclarator)node).getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + if( n != name ) { + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } + } + if( declarations != null ){ + for( int j = 0; j < declarations.length && declarations[j] != null; j++ ){ + temp = ((ICPPASTFunctionDeclarator)declarations[j].getParent()).getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + if( n != name ) { + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } + + } + } + return binding; } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java index 44cb68a29b3..8f49206e267 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPInstance.java @@ -13,17 +13,18 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPInstance; 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.parser.util.ObjectMap; /** * @author aniefer */ -public class CPPInstance implements ICPPInstance { +public class CPPInstance implements ICPPTemplateInstance { private IBinding binding; private ObjectMap argMap; private ICPPScope scope; @@ -75,5 +76,19 @@ public class CPPInstance implements ICPPInstance { return argMap; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java index 06106a45ee0..815f116436b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -124,5 +124,21 @@ public class CPPLabel implements ILabel, ICPPInternalBinding, ICPPBinding { return null; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplate.java new file mode 100644 index 00000000000..70783b08276 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplate.java @@ -0,0 +1,41 @@ +/********************************************************************** + * 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 Mar 31, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; + +/** + * @author aniefer + */ +public class CPPMethodTemplate extends CPPFunctionTemplate implements + ICPPMethod { + + /** + * @param name + */ + public CPPMethodTemplate(IASTName name) { + super(name); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMember#getVisibility() + */ + public int getVisibility() { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java index 431d185d5bb..4a318af7131 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespace.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** @@ -216,4 +217,19 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding { return new CPPNamespaceDelegate( name, this ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + if( node instanceof IASTName ) + namespaceDefinitions = (IASTName[]) ArrayUtil.append( IASTName.class, namespaceDefinitions, node ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + addDefinition( node ); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceAlias.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceAlias.java index 33ba75c84de..997c9ec50c6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceAlias.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceAlias.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * 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 @@ -131,4 +131,16 @@ public class CPPNamespaceAlias implements ICPPNamespaceAlias, ICPPInternalBindin // TODO Auto-generated method stub return null; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java index ee59e05a5a1..8234861e9cc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -67,7 +67,10 @@ public class CPPParameter implements IParameter, ICPPInternalBinding, ICPPVariab return null; } - public void addDeclaration( IASTName name ){ + public void addDeclaration( IASTNode node ){ + if( !(node instanceof IASTName ) ) + return; + IASTName name = (IASTName) node; if( declarations == null ){ declarations = new IASTName [] { name }; return; @@ -179,4 +182,11 @@ public class CPPParameter implements IParameter, ICPPInternalBinding, ICPPVariab return new CPPParameterDelegate( name, this ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 627b3438f4f..09fc9e27d02 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -87,6 +87,10 @@ abstract public class CPPScope implements ICPPScope{ public void addName(IASTName name) { if( bindings == null ) bindings = new CharArrayObjectMap(1); + if( name instanceof ICPPASTQualifiedName ){ + //name belongs to a different scope, don't add it here + return; + } if( name instanceof ICPPASTTemplateId ) name = ((ICPPASTTemplateId)name).getTemplateName(); 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 32a46581d42..40bf3e83f5a 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 @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -81,6 +81,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; 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; @@ -88,7 +89,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; 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.ICPPScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition; @@ -131,6 +132,7 @@ public class CPPSemantics { public boolean considerConstructors = false; public Object foundItems = null; public Object [] functionParameters; + public IASTNode [] templateParameters; public ProblemBinding problem; @@ -446,16 +448,6 @@ public class CPPSemantics { binding = e.getProblem(); } } - if( binding != null && data.astName.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME ){ - try { - IScope scope = binding.getScope(); - if( scope instanceof ICPPTemplateScope ){ - binding = ((ICPPTemplateScope) scope).getTemplateDefinition(); - } - } catch (DOMException e) { - binding = e.getProblem(); - } - } if( binding instanceof ICPPClassType && data.considerConstructors ){ ICPPClassType cls = (ICPPClassType) binding; try { @@ -487,6 +479,11 @@ public class CPPSemantics { static private CPPSemantics.LookupData createLookupData( IASTName name, boolean considerAssociatedScopes ){ CPPSemantics.LookupData data = new CPPSemantics.LookupData( name ); IASTNode parent = name.getParent(); + + if( parent instanceof ICPPASTTemplateId ){ + data.templateParameters = ((ICPPASTTemplateId)parent).getTemplateArguments(); + parent = parent.getParent(); + } if( parent instanceof ICPPASTQualifiedName ){ parent = parent.getParent(); } @@ -1293,8 +1290,8 @@ public class CPPSemantics { if( node instanceof ICPPASTQualifiedName ) node = node.getParent(); if( node instanceof ICPPASTFunctionDeclarator ){ - if( binding instanceof CPPFunction ) - ((CPPFunction)binding).addDefinition( (ICPPASTFunctionDeclarator) node ); + if( binding instanceof ICPPInternalBinding ) + ((ICPPInternalBinding)binding).addDefinition( node ); } } } @@ -1389,7 +1386,8 @@ public class CPPSemantics { IBinding type = null; IBinding obj = null; IBinding temp = null; - IFunction[] fns = null; + ObjectSet fns = ObjectSet.EMPTY_SET; + ObjectSet templateFns = ObjectSet.EMPTY_SET; Object [] items = (Object[]) data.foundItems; for( int i = 0; i < items.length && items[i] != null; i++ ){ @@ -1421,7 +1419,15 @@ public class CPPSemantics { return new ProblemBinding( data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name ); } } else if( temp instanceof IFunction ){ - fns = (IFunction[]) ArrayUtil.append( IFunction.class, fns, temp ); + if( temp instanceof ICPPTemplateDefinition ){ + if( templateFns == ObjectSet.EMPTY_SET ) + templateFns = new ObjectSet(2); + templateFns.put( temp ); + } else { + if( fns == ObjectSet.EMPTY_SET ) + fns = new ObjectSet(2); + fns.put( temp ); + } } else { if( obj == null ) obj = temp; @@ -1433,28 +1439,45 @@ public class CPPSemantics { if( data.forUsingDeclaration() ){ IBinding [] bindings = null; if( obj != null ){ - if( fns != null ) return new ProblemBinding( data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name ); + if( fns.size() > 0 ) return new ProblemBinding( data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name ); // if( type == null ) return obj; bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, obj ); bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, type ); } else { // if( fns == null ) return type; bindings = (IBinding[]) ArrayUtil.append( IBinding.class, bindings, type ); - bindings = (IBinding[]) ArrayUtil.addAll( IBinding.class, bindings, fns ); + bindings = (IBinding[]) ArrayUtil.addAll( IBinding.class, bindings, fns.keyArray() ); } bindings = (IBinding[]) ArrayUtil.trim( IBinding.class, bindings ); ICPPUsingDeclaration composite = new CPPUsingDeclaration( data.astName, bindings ); return composite; } + int numTemplateFns = templateFns.size(); + if( numTemplateFns > 0 ){ + if( data.functionParameters != null && ( !data.forDefinition() || data.templateParameters != null ) ){ + IFunction [] fs = CPPTemplates.selectTemplateFunctions( templateFns, data.functionParameters, data.astName ); + if( fs != null && fs.length > 0){ + if( fns == ObjectSet.EMPTY_SET ) + fns = new ObjectSet( fs.length ); + fns.addAll( fs ); + } + } else { + if( fns == ObjectSet.EMPTY_SET ) + fns = new ObjectSet( templateFns.size() ); + fns.addAll( templateFns ); + } + } + int numFns = fns.size(); if( type != null ) { - if( data.typesOnly || (obj == null && fns == null) ) + if( data.typesOnly || (obj == null && numFns == 0 ) ) return type; } - if( fns != null){ + + if( numFns > 0 ){ if( obj != null ) return new ProblemBinding( data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.name ); - return resolveFunction( data, fns ); + return resolveFunction( data, (IBinding[]) ArrayUtil.trim( IBinding.class, fns.keyArray(), true ) ); } return obj; @@ -1468,8 +1491,7 @@ public class CPPSemantics { IASTNode node = params[0].getParent(); if( node instanceof ICPPASTFunctionDeclarator ){ - IFunctionType t2 = (IFunctionType) CPPVisitor.createType( (ICPPASTFunctionDeclarator) node ); - return ftype.equals( t2 ); + return isSameFunction( function, (IASTDeclarator) node ); } return false; } @@ -1488,11 +1510,26 @@ public class CPPSemantics { int size = functions.length; for( int i = 0; i < size && functions[i] != null; i++ ){ fName = (IFunction) functions[i]; - function = (ICPPASTFunctionDeclarator) ((ICPPInternalBinding)fName).getDefinition(); - if( function == null ){ + IASTNode def = ((ICPPInternalBinding)fName).getDefinition(); + if( def instanceof ICPPASTFunctionDeclarator ) + function = (ICPPASTFunctionDeclarator) def; + else if( def != null ){ + IASTNode p = def.getParent(); + if( p instanceof ICPPASTQualifiedName ) + p = p.getParent(); + function = (ICPPASTFunctionDeclarator) p; + } else { + function = null; + } + + if( function == null ) { IASTNode [] nodes = ((ICPPInternalBinding) fName).getDeclarations(); - if( nodes != null && nodes.length > 0 ) - function = (ICPPASTFunctionDeclarator) nodes[0]; + if( nodes != null && nodes.length > 0 ){ + IASTNode node = nodes[0]; + while( node instanceof IASTName ) + node = node.getParent(); + function = (ICPPASTFunctionDeclarator) node; + } } if( function == null ){ @@ -1586,6 +1623,14 @@ public class CPPSemantics { //reduce our set of candidate functions to only those who have the right number of parameters reduceToViable( data, fns ); + if( data.forDefinition() ){ + for (int i = 0; i < fns.length; i++) { + if( fns[i] != null ){ + return fns[i]; + } + } + } + IFunction bestFn = null; //the best function IFunction currFn = null; //the function currently under consideration Cost [] bestFnCost = null; //the cost of the best function @@ -1621,11 +1666,17 @@ public class CPPSemantics { if( currFn == null || bestFn == currFn ) continue; - ICPPASTFunctionDeclarator currDtor = (ICPPASTFunctionDeclarator) ((ICPPInternalBinding)currFn).getDefinition(); + 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 ) - currDtor = (ICPPASTFunctionDeclarator) nodes[0]; + 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; @@ -2021,8 +2072,9 @@ public class CPPSemantics { if( constructors.length == 1 && constructors[0] instanceof IProblemBinding ) constructor = null; else { - //the list out of Arrays.asList does not support remove, which we need - constructor = (ICPPConstructor) resolveFunction( data, constructors ); + IBinding binding = resolveFunction( data, constructors ); + if( binding instanceof ICPPConstructor ) + constructor = (ICPPConstructor) binding; } } if( constructor != null && constructor.isExplicit() ){ @@ -2435,4 +2487,25 @@ public class CPPSemantics { return (IBinding[]) ArrayUtil.trim( IBinding.class, result ); } + public static boolean isSameFunction(IFunction function, IASTDeclarator declarator) { + IASTNode parent = declarator.getParent(); + while( !(parent instanceof IASTDeclaration) ){ + parent = parent.getParent(); + } + boolean fnIsTemplate = ( function instanceof ICPPFunctionTemplate ); + boolean dtorIsTemplate = (parent.getPropertyInParent() == ICPPASTTemplateDeclaration.OWNED_DECLARATION ); + if( fnIsTemplate && dtorIsTemplate ){ + return CPPTemplates.isSameTemplate( (ICPPTemplateDefinition)function, declarator.getName() ); + } else if( fnIsTemplate ^ dtorIsTemplate ){ + return false; + } + IType type = null; + try { + type = function.getType(); + return type.equals( CPPVisitor.createType( declarator ) ); + } catch (DOMException e) { + } + return false; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 543965110c1..2e34b133702 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -13,109 +13,128 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; 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.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; 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.ICPPASTTemplatedTypeTemplateParameter; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.core.parser.util.ObjectMap; /** * @author aniefer */ -public class CPPTemplateDefinition implements ICPPTemplateDefinition { - private IASTDeclaration primaryDecl; - private IASTName name; +public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, ICPPInternalBinding { + //private IASTName templateName; + protected IASTName [] declarations = null; + protected IASTName definition = null; - public CPPTemplateDefinition( IASTDeclaration decl ) { - primaryDecl = decl; - name = getTemplateName( decl ); + private ICPPTemplateParameter [] templateParameters = null; + private ICPPTemplateSpecialization [] specializations = null; + + public CPPTemplateDefinition( IASTName name ) { + ASTNodeProperty prop = name.getPropertyInParent(); + if( prop == IASTCompositeTypeSpecifier.TYPE_NAME ){ + definition = name; + } else if( prop == IASTElaboratedTypeSpecifier.TYPE_NAME ) { + declarations = new IASTName [] { name }; + } else { + IASTNode parent = name.getParent(); + while( !(parent instanceof IASTDeclaration) ) + parent = parent.getParent(); + if( parent instanceof IASTFunctionDefinition ) + definition = name; + else + declarations = new IASTName [] { name }; + } + } + + public abstract IBinding instantiate( ICPPASTTemplateId templateId ); + + public ICPPTemplateSpecialization [] getSpecializations() { + return (ICPPTemplateSpecialization[]) ArrayUtil.trim( ICPPTemplateSpecialization.class, specializations ); + } + public void addSpecialization( ICPPTemplateSpecialization spec ){ + specializations = (ICPPTemplateSpecialization[]) ArrayUtil.append( ICPPTemplateSpecialization.class, specializations, spec ); + } - private IASTName getTemplateName( IASTDeclaration decl ){ - if( decl instanceof IASTSimpleDeclaration ){ - IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); - if( dtors.length > 0 ) - return dtors[0].getName(); - - IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration)decl).getDeclSpecifier(); - if( declSpec instanceof ICPPASTCompositeTypeSpecifier ) - return ((ICPPASTCompositeTypeSpecifier)declSpec).getName(); - } else if( decl instanceof IASTFunctionDefinition ){ - return ((IASTFunctionDefinition)decl).getDeclarator().getName(); + public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) { + IASTName name = CPPTemplates.getTemplateParameterName( templateParameter ); + IBinding binding = name.getBinding(); + if( binding != null ) + return binding; + + if( templateParameter.getParent() instanceof ICPPASTTemplatedTypeTemplateParameter ){ + + } + + ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) templateParameter.getParent(); + ICPPASTTemplateParameter [] ps = templateDecl.getTemplateParameters(); + + int i = 0; + for( ; i < ps.length; i++ ){ + if( templateParameter == ps[i] ) + break; + } + + //create a new binding and set it for the corresponding parameter in all known decls + binding = new CPPTemplateParameter( name ); + ICPPASTTemplateParameter temp = null; + ICPPASTTemplateDeclaration template = null; + int length = ( declarations != null ) ? declarations.length : 0; + int j = ( definition != null ) ? -1 : 0; + for( ; j < length; j++ ){ + template = ( j == -1 ) ? CPPTemplates.getTemplateDeclaration( definition ) + : CPPTemplates.getTemplateDeclaration( declarations[j] ); + temp = template.getTemplateParameters()[i]; + + IASTName n = CPPTemplates.getTemplateParameterName( temp ); + if( n != name ) { + n.setBinding( binding ); + } + } - return null; + return binding; + } + + public IASTName getTemplateName(){ + return definition != null ? definition : declarations[0]; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() */ public String getName() { - return name.toString(); + return getTemplateName().toString(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() */ public char[] getNameCharArray() { - return name.toCharArray(); + return getTemplateName().toCharArray(); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() */ public IScope getScope() { - return CPPVisitor.getContainingScope( primaryDecl ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplate#instantiate(org.eclipse.cdt.core.dom.ast.IASTNode[]) - */ - public IBinding instantiate(ICPPASTTemplateId templateId ) {//IASTNode[] arguments) { - IBinding decl = getTemplatedDeclaration(); - ICPPTemplateParameter [] params = getParameters(); - IASTNode [] arguments = templateId.getTemplateArguments(); - - ObjectMap map = new ObjectMap(params.length); - if( arguments.length == params.length ){ - for( int i = 0; i < arguments.length; i++ ){ - IType t = CPPVisitor.createType( arguments[i] ); - map.put( params[i], t ); - } - } - - return CPPTemplates.createInstance( templateId, (ICPPScope) getScope(), decl, map ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplate#getTemplatedDeclaration() - */ - public IBinding getTemplatedDeclaration() { - if( primaryDecl instanceof IASTSimpleDeclaration ){ - IASTSimpleDeclaration simple = (IASTSimpleDeclaration) primaryDecl; - if( simple.getDeclarators().length == 0 && simple.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier ){ - IASTCompositeTypeSpecifier compSpec = (IASTCompositeTypeSpecifier) simple.getDeclSpecifier(); - return compSpec.getName().resolveBinding(); - } - } else if( primaryDecl instanceof IASTFunctionDefinition ){ - - } - return null; + return CPPVisitor.getContainingScope( getTemplateName().getParent() ); } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName() */ @@ -143,25 +162,89 @@ public class CPPTemplateDefinition implements ICPPTemplateDefinition { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition#getParameters() */ - public ICPPTemplateParameter[] getParameters() { - ICPPASTTemplateDeclaration template = (ICPPASTTemplateDeclaration) primaryDecl.getParent(); - ICPPASTTemplateParameter [] params = template.getTemplateParameters(); - ICPPTemplateParameter p = null; - ICPPTemplateParameter [] result = null; - for (int i = 0; i < params.length; i++) { - if( params[i] instanceof ICPPASTSimpleTypeTemplateParameter ){ - p = (ICPPTemplateParameter) ((ICPPASTSimpleTypeTemplateParameter)params[i]).getName().resolveBinding(); - } else if( params[i] instanceof ICPPASTParameterDeclaration ) { - p = (ICPPTemplateParameter) ((ICPPASTParameterDeclaration)params[i]).getDeclarator().getName().resolveBinding(); - } else if( params[i] instanceof ICPPASTTemplatedTypeTemplateParameter ){ - p = (ICPPTemplateParameter) ((ICPPASTTemplatedTypeTemplateParameter)params[i]).getName().resolveBinding(); - } - - if( p != null ){ - result = (ICPPTemplateParameter[]) ArrayUtil.append( ICPPTemplateParameter.class, result, p ); + public ICPPTemplateParameter[] getTemplateParameters() { + if( templateParameters == null ){ + ICPPASTTemplateDeclaration template = CPPTemplates.getTemplateDeclaration( getTemplateName() ); + ICPPASTTemplateParameter [] params = template.getTemplateParameters(); + ICPPTemplateParameter p = null; + ICPPTemplateParameter [] result = null; + for (int i = 0; i < params.length; i++) { + if( params[i] instanceof ICPPASTSimpleTypeTemplateParameter ){ + p = (ICPPTemplateParameter) ((ICPPASTSimpleTypeTemplateParameter)params[i]).getName().resolveBinding(); + } else if( params[i] instanceof ICPPASTParameterDeclaration ) { + p = (ICPPTemplateParameter) ((ICPPASTParameterDeclaration)params[i]).getDeclarator().getName().resolveBinding(); + } else if( params[i] instanceof ICPPASTTemplatedTypeTemplateParameter ){ + p = (ICPPTemplateParameter) ((ICPPASTTemplatedTypeTemplateParameter)params[i]).getName().resolveBinding(); + } + + if( p != null ){ + result = (ICPPTemplateParameter[]) ArrayUtil.append( ICPPTemplateParameter.class, result, p ); + } } + templateParameters = (ICPPTemplateParameter[]) ArrayUtil.trim( ICPPTemplateParameter.class, result ); } - return (ICPPTemplateParameter[]) ArrayUtil.trim( ICPPTemplateParameter.class, result ); + return templateParameters; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + if( !(node instanceof IASTName) ) + return; + updateTemplateParameterBindings( (IASTName) node ); + definition = (IASTName) node; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + if( !(node instanceof IASTName) ) + return; + IASTName declName = (IASTName) node; + updateTemplateParameterBindings( declName ); + if( declarations == null ){ + declarations = new IASTName [] { declName }; + return; + } + declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, declName ); + } + + protected void updateTemplateParameterBindings( IASTName name ){ + IASTName orig = definition != null ? definition : declarations[0]; + ICPPASTTemplateDeclaration origTemplate = CPPTemplates.getTemplateDeclaration( orig ); + ICPPASTTemplateDeclaration newTemplate = CPPTemplates.getTemplateDeclaration( name ); + ICPPASTTemplateParameter [] ops = origTemplate.getTemplateParameters(); + ICPPASTTemplateParameter [] nps = newTemplate.getTemplateParameters(); + ICPPInternalBinding temp = null; + for( int i = 0; i < nps.length; i++ ){ + temp = (ICPPInternalBinding) CPPTemplates.getTemplateParameterName( ops[i] ).getBinding(); + if( temp != null ){ + IASTName n = CPPTemplates.getTemplateParameterName( nps[i] ); + n.setBinding( temp ); + temp.addDeclaration( name ); + } + } + } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDeclarations() + */ + public IASTNode[] getDeclarations() { + return declarations; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition() + */ + public IASTNode getDefinition() { + return definition; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#createDelegate(org.eclipse.cdt.core.dom.ast.IASTName) + */ + public ICPPDelegate createDelegate(IASTName name) { + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameter.java index 954ae8e97c9..4201d7d3ce1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateParameter.java @@ -124,4 +124,20 @@ public class CPPTemplateParameter implements ICPPTemplateParameter, IType, ICPPI // TODO Auto-generated method stub return null; } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java index 8cd8548cf59..5f46b1d0b4a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateScope.java @@ -14,10 +14,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; @@ -26,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; */ public class CPPTemplateScope extends CPPScope implements ICPPTemplateScope { - private ICPPTemplateDefinition primaryDefinition; + //private ICPPTemplateDefinition primaryDefinition; /** * @param physicalNode */ @@ -38,13 +36,14 @@ public class CPPTemplateScope extends CPPScope implements ICPPTemplateScope { * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope#getTemplateDefinition() */ public ICPPTemplateDefinition getTemplateDefinition() throws DOMException { - if( primaryDefinition == null ){ - //primaryDefinition = CPPTemplates.getTemplateDefinition( this ); - ICPPASTTemplateDeclaration template = (ICPPASTTemplateDeclaration) getPhysicalNode(); - IASTDeclaration decl = template.getDeclaration(); - return new CPPTemplateDefinition( decl ); - } - return primaryDefinition; +// if( primaryDefinition == null ){ +// //primaryDefinition = CPPTemplates.getTemplateDefinition( this ); +// ICPPASTTemplateDeclaration template = (ICPPASTTemplateDeclaration) getPhysicalNode(); +// IASTDeclaration decl = template.getDeclaration(); +// return new CPPTemplateDefinition( decl ); +// } +// return primaryDefinition; + return null; } /* (non-Javadoc) 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 bb3b4327a73..4fae0ac5d00 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 @@ -14,27 +14,43 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +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.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; 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.ICPPASTTemplatedTypeTemplateParameter; +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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; 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.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateSpecialization; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; /** @@ -52,21 +68,75 @@ public class CPPTemplates { return null; } - public static IBinding createBinding( ICPPASTTemplateParameter templateParameter ){ - ICPPTemplateScope scope = (ICPPTemplateScope) getContainingScope( templateParameter ); - IASTName name = getTemplateParameterName( templateParameter ); + private static ICPPTemplateDefinition getContainingTemplate( ICPPASTTemplateParameter param ){ + IASTNode parent = param.getParent(); IBinding binding = null; - - try { - binding = scope.getBinding( name, false ); - if( binding == null ){ - binding = new CPPTemplateParameter( name ); - scope.addName( name ); - } - } catch ( DOMException e ) { - binding = e.getProblem(); - } - + if( parent instanceof ICPPASTTemplateDeclaration ){ + ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent }; + + while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){ + parent = parent.getParent(); + templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.append( ICPPASTTemplateDeclaration.class, templates, parent ); + } + templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.trim( ICPPASTTemplateDeclaration.class, templates ); + + ICPPASTTemplateDeclaration templateDeclaration = templates[0]; + IASTDeclaration decl = templateDeclaration.getDeclaration(); + while( decl instanceof ICPPASTTemplateDeclaration ) + decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); + + IASTName name = null; + if( decl instanceof IASTSimpleDeclaration ){ + IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) decl; + IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); + if( dtors.length == 0 ){ + if( simpleDecl.getDeclSpecifier() instanceof ICPPASTCompositeTypeSpecifier ){ + name = ((ICPPASTCompositeTypeSpecifier)simpleDecl.getDeclSpecifier()).getName(); + } + } else { + IASTDeclarator dtor = dtors[0]; + while( dtor.getNestedDeclarator() != null ) + dtor = dtor.getNestedDeclarator(); + name = dtor.getName(); + } + } else if( decl instanceof IASTFunctionDefinition ){ + IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); + while( dtor.getNestedDeclarator() != null ) + dtor = dtor.getNestedDeclarator(); + name = dtor.getName(); + } + if( name == null ) + return null; + + if( name instanceof ICPPASTQualifiedName ){ + int idx = templates.length; + int i = 0; + IASTName [] ns = ((ICPPASTQualifiedName) name).getNames(); + for (int j = 0; j < ns.length; j++) { + if( ns[j] instanceof ICPPASTTemplateId ){ + ++i; + if( i == idx ){ + binding = ((ICPPASTTemplateId)ns[j]).getTemplateName().resolveBinding(); + break; + } + } + } + if( binding == null ) + binding = ns[ ns.length - 1 ].resolveBinding(); + } else { + binding = name.resolveBinding(); + } + } + return (binding instanceof ICPPTemplateDefinition) ? (ICPPTemplateDefinition) binding : null; + } + public static IBinding createBinding( ICPPASTTemplateParameter templateParameter ){ + ICPPTemplateDefinition template = getContainingTemplate( templateParameter ); + + IBinding binding = null; + if( template instanceof CPPTemplateDefinition ){ + binding = ((CPPTemplateDefinition)template).resolveTemplateParameter( templateParameter ); + } + return binding; } static public ICPPScope getContainingScope( IASTNode node ){ @@ -88,14 +158,44 @@ public class CPPTemplates { * @return */ public static IBinding createBinding(ICPPASTTemplateId id) { + IASTNode parent = id.getParent(); + if( parent instanceof ICPPASTCompositeTypeSpecifier ){ + return createClassPartialSpecialization( (ICPPASTCompositeTypeSpecifier) parent ); + } IASTName templateName = id.getTemplateName(); IBinding template = templateName.resolveBinding(); if( template != null && template instanceof ICPPTemplateDefinition ){ - return ((ICPPTemplateDefinition)template).instantiate( id ); + return ((CPPTemplateDefinition)template).instantiate( id ); } return template; } + protected static IBinding createClassPartialSpecialization( ICPPASTCompositeTypeSpecifier compSpec ){ + ICPPASTTemplateId id = (ICPPASTTemplateId) compSpec.getName(); + + IBinding binding = id.getTemplateName().resolveBinding(); + if( !(binding instanceof ICPPClassTemplate) ) + return null; //TODO: problem? + + CPPClassTemplate template = (CPPClassTemplate) binding; + ICPPTemplateSpecialization [] specializations = template.getSpecializations(); + ICPPTemplateSpecialization spec = null; + for (int i = 0; i < specializations.length; i++) { + if( isSameTemplate( specializations[i], id ) ){ + spec = specializations[i]; + break; + } + } + + if( spec != null ){ + ((ICPPInternalBinding)spec).addDefinition( id ); + return spec; + } + + spec = new CPPClassTemplateSpecialization( id ); + template.addSpecialization( spec ); + return spec; + } /** * @param scope * @return @@ -111,7 +211,7 @@ public class CPPTemplates { * @return */ public static IBinding createInstance( IASTName id, ICPPScope scope, IBinding decl, ObjectMap argMap) { - ICPPInstance instance = null; + ICPPTemplateInstance instance = null; if( decl instanceof ICPPClassType ){ instance = new CPPClassInstance( id, scope, decl, argMap ); } else if( decl instanceof ICPPField ){ @@ -167,4 +267,143 @@ public class CPPTemplates { return newType; } + + public static ICPPASTTemplateDeclaration getTemplateDeclaration( IASTName name ){ + if( name == null ) return null; + + IASTNode parent = name.getParent(); + while( !(parent instanceof ICPPASTTemplateDeclaration) ) + parent = parent.getParent(); + + if( parent == null ) return null; + + if( parent instanceof ICPPASTTemplateDeclaration ){ + ICPPASTTemplateDeclaration [] templates = new ICPPASTTemplateDeclaration [] { (ICPPASTTemplateDeclaration) parent }; + + while( parent.getParent() instanceof ICPPASTTemplateDeclaration ){ + parent = parent.getParent(); + templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.append( ICPPASTTemplateDeclaration.class, templates, parent ); + } + templates = (ICPPASTTemplateDeclaration[]) ArrayUtil.trim( ICPPASTTemplateDeclaration.class, templates ); + + if( name == null ) + return null; + + if( name.getParent() instanceof ICPPASTQualifiedName ){ + int idx = templates.length; + int i = 0; + IASTName [] ns = ((ICPPASTQualifiedName) name.getParent()).getNames(); + for (int j = 0; j < ns.length; j++) { + if( ns[j] instanceof ICPPASTTemplateId ){ + ++i; + } + if( ns[j] == name ){ + if( i <= idx ) + return templates[ i - 1 ]; + break; + } + } + } else { + return templates[0]; + } + } + return null; + + } + + private static class ClearBindingAction extends CPPASTVisitor { + public ObjectSet bindings = null; + public ClearBindingAction( ObjectSet bindings ) { + shouldVisitNames = true; + shouldVisitStatements = true; + this.bindings = bindings; + } + public int visit(IASTName name) { + if( name.getBinding() != null && bindings.containsKey( name.getBinding() ) ) + name.setBinding( null ); + return PROCESS_CONTINUE; + } + public int visit(IASTStatement statement) { + return PROCESS_SKIP; + } + } + /** + * @param definition + * @param declarator + * @return + */ + public static boolean isSameTemplate(ICPPTemplateDefinition definition, IASTName name) { + ICPPTemplateParameter [] defParams = definition.getTemplateParameters(); + ICPPASTTemplateDeclaration templateDecl = getTemplateDeclaration( name ); + ICPPASTTemplateParameter [] templateParams = templateDecl.getTemplateParameters(); + if( defParams.length != templateParams.length ) + return false; + + ObjectSet bindingsToClear = null; + for (int i = 0; i < templateParams.length; i++) { + IASTName tn = getTemplateParameterName( templateParams[i] ); + if( tn.getBinding() != null ) + return ( tn.getBinding() == defParams[i] ); + if( bindingsToClear == null ) + bindingsToClear = new ObjectSet( templateParams.length ); + tn.setBinding( defParams[i] ); + bindingsToClear.put( defParams[i] ); + } + + boolean result = false; + IASTNode parent = name.getParent(); + if( parent instanceof ICPPASTFunctionDeclarator ){ + IType type = CPPVisitor.createType( (IASTDeclarator) parent ); + try { + IType ftype = ((ICPPFunction)definition).getType(); + if( ftype.equals( type ) ) + result = true; + } catch (DOMException e) { + } + } else if( parent instanceof IASTDeclSpecifier ){ + if( name instanceof ICPPASTTemplateId ){ + if( definition instanceof ICPPTemplateSpecialization ){ + ICPPTemplateSpecialization spec = (ICPPTemplateSpecialization) definition; + IASTNode [] args = ((ICPPASTTemplateId)name).getTemplateArguments(); + if( args.length == spec.getArguments().length ){ + int i = 0; + for (; i < args.length; i++) { + IType t1 = CPPVisitor.createType( spec.getArguments()[i] ); + IType t2 = CPPVisitor.createType( args[i] ); + if( t1 != null && t2 != null && t1.equals( t2 ) ) + continue; + break; + } + result = ( i == args.length ); + } + } + } else { + result = CharArrayUtils.equals( definition.getNameCharArray(), name.toCharArray() ); + } + } + + if( bindingsToClear != null ){ + ClearBindingAction action = new ClearBindingAction( bindingsToClear ); + templateDecl.accept( action ); + } + + return result; + } + + static protected IFunction[] selectTemplateFunctions( ObjectSet templates, Object[] functionArguments, IASTName name ) {//IASTNode[] templateArguments ){ + IFunction [] instances = null; + if( name.getParent() instanceof ICPPASTTemplateId ) + name = (IASTName) name.getParent(); + if( name instanceof ICPPASTTemplateId ){ + Object [] keys = templates.keyArray(); + for (int i = 0; i < keys.length; i++) { + CPPTemplateDefinition templateDef = (CPPTemplateDefinition) keys[i]; + ICPPTemplateInstance temp = (ICPPTemplateInstance) templateDef.instantiate( (ICPPASTTemplateId) name ); + if( temp != null ) + instances = (IFunction[]) ArrayUtil.append( IFunction.class, instances, temp ); + } + } + return instances; + //TODO, instead of the above, do proper argument checking, deduction + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java index 2539f2c2270..0b9e585de9d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -177,4 +177,20 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding return new CPPTypedefDelegate( name, this ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDeclaration(IASTNode node) { + // TODO Auto-generated method stub + + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index 99712eac3d7..df114c0639b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -113,7 +113,10 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding { return true; } - public void addDeclaration( IASTName name ) { + public void addDeclaration( IASTNode node ) { + if( !(node instanceof IASTName) ) + return; + IASTName name = (IASTName) node; if( isDefinition( name ) ) definition = name; else @@ -242,4 +245,12 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding { return new CPPVariableDelegate( name, this ); } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode) + */ + public void addDefinition(IASTNode node) { + // TODO Auto-generated method stub + + } + } 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 779e8eca2d2..e77d7b4855c 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004 IBM Corporation and others. + * Copyright (c) 2004, 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 @@ -99,7 +99,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; @@ -324,11 +326,27 @@ public class CPPVisitor { name = ns[ ns.length - 1 ]; } ICPPScope scope = (ICPPScope) getContainingScope( name ); + boolean template = false; + if( scope instanceof ICPPTemplateScope ){ + template = true; + ICPPScope parentScope = null; + try { + parentScope = (ICPPScope) scope.getParent(); + } catch (DOMException e1) { + } + scope = parentScope; + } IBinding binding; + if( name instanceof ICPPASTTemplateId ){ + return CPPTemplates.createClassPartialSpecialization( compType ); + } try { - binding = scope.getBinding( compType.getName(), false ); + binding = scope.getBinding( name, false ); if( binding == null || !(binding instanceof ICPPClassType) ){ - binding = new CPPClassType( compType.getName() ); + if( template ) + binding = new CPPClassTemplate( name ); + else + binding = new CPPClassType( name ); scope.addName( compType.getName() ); } else { ((CPPClassType)binding).addDefinition( compType ); @@ -336,7 +354,6 @@ public class CPPVisitor { } catch ( DOMException e ) { binding = e.getProblem(); } - return binding; } private static IBinding createBinding( IASTDeclaration declaration ){ @@ -400,7 +417,17 @@ public class CPPVisitor { parent = parent.getParent(); } - ICPPScope scope = (ICPPScope) getContainingScope( parent ); + boolean template = false; + ICPPScope scope = (ICPPScope) getContainingScope( name ); + if( scope instanceof ICPPTemplateScope ){ + ICPPScope parentScope = null; + try { + template = true; + parentScope = (ICPPScope) scope.getParent(); + } catch (DOMException e1) { + } + scope = parentScope; + } if( parent instanceof IASTSimpleDeclaration && scope instanceof ICPPClassScope ){ ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)parent).getDeclSpecifier(); if( declSpec.isFriend() ){ @@ -421,7 +448,7 @@ public class CPPVisitor { IBinding binding; try { - binding = ( scope != null ) ? scope.getBinding( declarator.getName(), false ) : null; + binding = ( scope != null ) ? scope.getBinding( name, false ) : null; } catch ( DOMException e ) { binding = null; } @@ -429,37 +456,26 @@ public class CPPVisitor { if( declarator instanceof ICPPASTFunctionDeclarator ){ if( binding != null && binding instanceof IFunction ){ IFunction function = (IFunction) binding; - IFunctionType ftype; - try { - ftype = function.getType(); - IType type = createType( declarator ); - if( ftype.equals( type ) ){ - if( parent instanceof IASTSimpleDeclaration ) - ((CPPFunction)function).addDeclaration( (ICPPASTFunctionDeclarator) declarator ); - else - ((CPPFunction)function).addDefinition( (ICPPASTFunctionDeclarator) declarator ); - - return function; - } - } catch ( DOMException e1 ) { - } + if( CPPSemantics.isSameFunction( function, declarator ) ){ + if( parent instanceof IASTSimpleDeclaration ) + ((ICPPInternalBinding)function).addDeclaration( name ); + else + ((ICPPInternalBinding)function).addDefinition( name ); + + return function; + } } - if( scope instanceof ICPPTemplateScope ){ - ICPPScope parentScope = null; - try { - parentScope = (ICPPScope) scope.getParent(); - } catch (DOMException e1) { - } - if( parentScope instanceof ICPPClassScope ) - scope = parentScope; - } + if( scope instanceof ICPPClassScope ){ if( isConstructor( scope, declarator) ) - binding = new CPPConstructor( (ICPPASTFunctionDeclarator) declarator ); + binding = template ? (ICPPConstructor) new CPPConstructorTemplate( name ) + : new CPPConstructor( (ICPPASTFunctionDeclarator) declarator ); else - binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator ); + binding = template ? (ICPPMethod) new CPPMethodTemplate( name ) + : new CPPMethod( (ICPPASTFunctionDeclarator) declarator ); } else { - binding = new CPPFunction( (ICPPASTFunctionDeclarator) declarator ); + binding = template ? (ICPPFunction) new CPPFunctionTemplate( name ) + : new CPPFunction( (ICPPASTFunctionDeclarator) declarator ); } } else if( parent instanceof ICPPASTParameterDeclaration ){ ICPPASTParameterDeclaration param = (ICPPASTParameterDeclaration) parent; @@ -469,9 +485,11 @@ public class CPPVisitor { if( fDtor.getParent() instanceof IASTDeclarator || fDtor.getNestedDeclarator() != null ) return null; IBinding temp = fDtor.getName().resolveBinding(); - if( temp instanceof IFunction ){ + if( temp instanceof CPPFunction ){ CPPFunction function = (CPPFunction) temp; binding = function.resolveParameter( param ); + } else if( temp instanceof CPPFunctionTemplate ) { + binding = ((CPPFunctionTemplate)temp).resolveFunctionParameter( param ); } } else if( parent instanceof ICPPASTTemplateDeclaration ) { return CPPTemplates.createBinding( param ); @@ -480,7 +498,7 @@ public class CPPVisitor { IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ - binding = new CPPTypedef( declarator.getName() ); + binding = new CPPTypedef( name ); } else { IType t1 = null, t2 = null; @@ -493,14 +511,15 @@ public class CPPVisitor { } if( t1 != null && t2 != null ){ if( t1.equals( t2 ) ){ - ((CPPVariable)binding).addDeclaration( declarator.getName() ); + if( binding instanceof ICPPInternalBinding ) + ((ICPPInternalBinding)binding).addDeclaration( name ); } else { - binding = new ProblemBinding( declarator.getName(), IProblemBinding.SEMANTIC_INVALID_REDECLARATION, declarator.getName().toCharArray() ); + binding = new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, declarator.getName().toCharArray() ); } } else if( simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier ){ - binding = new CPPField( declarator.getName() ); + binding = new CPPField( name ); } else { - binding = new CPPVariable( declarator.getName() ); + binding = new CPPVariable( name ); } } } @@ -1344,22 +1363,15 @@ public class CPPVisitor { private static IType getBaseType( IASTDeclSpecifier declSpec ){ IType type = null; + IASTName name = null; if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ - IBinding binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding(); - if( binding instanceof IType) - type = (IType) binding; + name = ((ICPPASTCompositeTypeSpecifier) declSpec).getName(); } else if( declSpec instanceof ICPPASTNamedTypeSpecifier ){ - IBinding binding = ((ICPPASTNamedTypeSpecifier)declSpec).getName().resolveBinding(); - if( binding instanceof IType ) - type = (IType) binding; + name = ((ICPPASTNamedTypeSpecifier)declSpec).getName(); } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ){ - IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); - if( binding instanceof IType ) - type = (IType) binding; + name = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName(); } else if( declSpec instanceof IASTEnumerationSpecifier ){ - IBinding binding = ((IASTEnumerationSpecifier)declSpec).getName().resolveBinding(); - if( binding instanceof IType ) - type = (IType) binding; + name = ((IASTEnumerationSpecifier)declSpec).getName(); } else if( declSpec instanceof ICPPASTSimpleDeclSpecifier ){ ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) & @@ -1374,6 +1386,11 @@ public class CPPVisitor { type = new CPPBasicType( spec.getType(), bits ); } } + if( name != null ){ + IBinding binding = name.resolveBinding(); + if( binding instanceof IType ) + type = (IType) binding; + } return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java index dec990d0e9f..a0b0397d838 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalBinding.java @@ -16,16 +16,23 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; /** * @author aniefer */ -public interface ICPPInternalBinding { +public interface ICPPInternalBinding extends IBinding { //methods required by the CPPVisitor but not meant for the public interface IASTNode [] getDeclarations(); IASTNode getDefinition(); ICPPDelegate createDelegate( IASTName name ); + + /** + * @param declarator + */ + void addDefinition( IASTNode node ); + void addDeclaration( IASTNode node ); }