diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 08b80d79fa4..5e128e06319 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -111,7 +111,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerType; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.util.CharArrayUtils; -import org.eclipse.cdt.internal.core.dom.parser.cpp.AbstractCPPASTName; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; @@ -1671,7 +1671,7 @@ public class AST2CPPTests extends AST2BaseTest { // }; public void testBug84692() throws Exception { // also tests bug 234042. - AbstractCPPASTName.sAllowRecursionBindings= false; + CPPASTNameBase.sAllowRecursionBindings= false; IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP); CPPNameCollector col = new CPPNameCollector(); 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 3e6d75652f2..b8bf471b44d 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 @@ -2940,16 +2940,17 @@ public class AST2TemplateTests extends AST2BaseTest { // These intermediate assertions will not hold until deferred non-type arguments are // correctly modelled - /* ICPPClassType tid= ba.assertNonProblem("This::T", 7, ICPPClassType.class); assertFalse(tid instanceof ICPPSpecialization); ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class); - assertFalse(th1sCtor instanceof ICPPSpecialization);ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class); - */ + assertFalse(th1sCtor instanceof ICPPSpecialization); - ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class); + ICPPTemplateNonTypeParameter np = ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class); ICPPClassType clazz= ba.assertNonProblem("That(I)", 4, ICPPClassType.class); ICPPConstructor ctor= ba.assertNonProblem("That(I)", 7, ICPPConstructor.class); + + ICPPTemplateNonTypeParameter np1 = ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class); + assertSame(np, np1); } // template diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java index 32e3cc81c34..7da49e55736 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,6 @@ * Markus Schorn - initial API and implementation * Andrew Ferguson (Symbian) *******************************************************************************/ - package org.eclipse.cdt.core.testplugin.util; import java.lang.reflect.Method; @@ -32,7 +31,7 @@ import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.testplugin.TestScannerProvider; -import org.eclipse.cdt.internal.core.dom.parser.cpp.AbstractCPPASTName; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ILogListener; import org.eclipse.core.runtime.IProgressMonitor; @@ -57,7 +56,7 @@ public class BaseTestCase extends TestCase { @Override protected void setUp() throws Exception { - AbstractCPPASTName.sAllowRecursionBindings= true; + CPPASTNameBase.sAllowRecursionBindings= true; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java index 172b746df1d..ff6e6507084 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IType.java @@ -6,13 +6,17 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * Doug Schaefer (IBM) - Initial API and implementation * Sergey Prigogin (Google) + * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; + /** - * @author Doug Schaefer + * Interface for all c- and c++ types. */ public interface IType extends Cloneable { public static final IType[] EMPTY_TYPE_ARRAY = new IType[0]; @@ -21,8 +25,10 @@ public interface IType extends Cloneable { public Object clone(); /** - * is the given type the same as this type? - * @param type + * Test whether this type is the same as the given one. A typedef is considered to be the same type as + * it's target type. + * See {@link ICPPTemplateTemplateParameter#isSameType(IType)} or {@link ICPPTemplateTypeParameter#isSameType(IType)} + * for the semantics of comparing template parameters denoting types. */ public boolean isSameType(IType type); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java index 47f47537491..db99bf707a3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplatePartialSpecialization.java @@ -37,7 +37,7 @@ public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplat * Returns the arguments of this partial specialization. * @since 5.1 */ - public ICPPTemplateArgument[] getTemplateArguments(); + public ICPPTemplateArgument[] getTemplateArguments() throws DOMException; /** * @deprecated use {@link #getTemplateArguments()}, instead. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java index e5177ad11ca..a57c9f2ae53 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTemplateParameter.java @@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.IType; /** * Template parameters of type template + * + * @noimplement This interface is not intended to be implemented by clients. */ public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, ICPPClassTemplate { @@ -24,4 +26,14 @@ public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, IC * Return the default value for this parameter, or null. */ public IType getDefault() throws DOMException; + + /** + * Types containing template parameters need to be compared even before it is known to which + * binding the template parameter belongs to. Therefore {@link #isSameType(IType)} compares the + * kind and the parameter position of the template parameter, only. The name and the owner + * is ignored. + * + * @since 5.1 + */ + public boolean isSameType(IType type); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTypeParameter.java index de7946fe411..916419710a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPTemplateTypeParameter.java @@ -24,4 +24,13 @@ public interface ICPPTemplateTypeParameter extends ICPPTemplateParameter, IType */ public IType getDefault() throws DOMException; + /** + * Types containing template parameters need to be compared even before it is known to which + * binding the template parameter belongs to. Therefore {@link #isSameType(IType)} compares the + * kind and the parameter position of the template parameter, only. The name and the owner + * is ignored. + * + * @since 5.1 + */ + public boolean isSameType(IType type); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java index 41bc4dd13bc..d82d1d04134 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; /** * Base implementation for all ambiguous nodes. @@ -94,7 +95,7 @@ public abstract class ASTAmbiguousNode extends ASTNode { int issues= 0; for (IASTName name : names) { try { - IBinding b = name.resolveBinding(); + IBinding b= CPPASTNameBase.resolvePreBinding(name); if (b instanceof IProblemBinding) { issues++; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 711c664d534..e1592fcc53a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; @@ -199,7 +200,7 @@ public class Value implements IValue { return o + "," + evaluate(cexpr.getNegativeResultExpression(), maxdepth) + "," + po + '?'; } if (e instanceof IASTIdExpression) { - IBinding b= ((IASTIdExpression) e).getName().resolveBinding(); + IBinding b= CPPASTNameBase.resolvePreBinding(((IASTIdExpression) e).getName()); if (b instanceof ICPPTemplateParameter) { if (b instanceof ICPPTemplateNonTypeParameter) { return evaluate((ICPPTemplateParameter) b); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java index 0a043e2a3b3..4bf24160256 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousTemplateArgument.java @@ -17,6 +17,7 @@ import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.internal.core.parser.ParserMessages; @@ -25,6 +26,7 @@ import org.eclipse.cdt.internal.core.parser.ParserMessages; * Ambiguity node for deciding between type-id and id-expression in a template argument. */ public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements ICPPASTAmbiguousTemplateArgument { + private List fNodes; /** @@ -46,7 +48,13 @@ public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements } } } - + + @Override + protected IScope getAffectedScope() { + // a template argument does not introduce names to a parent scope. + return null; + } + @Override protected IASTNode[] getNodes() { return fNodes.toArray(new IASTNode[fNodes.size()]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index 5b710b92427..3da97b5bf72 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -37,7 +37,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; /** * Unqualified name, also base class for operator and conversion name. */ -public class CPPASTName extends AbstractCPPASTName implements IASTCompletionContext { +public class CPPASTName extends CPPASTNameBase implements IASTCompletionContext { private char[] name; public CPPASTName(char[] name) { this.name = name; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java similarity index 81% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPASTName.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java index feffc4375e0..125e32c41a1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java @@ -21,7 +21,7 @@ import org.eclipse.core.runtime.Assert; * Common base class for all sorts of c++ names: unqualified, qualified, operator and conversion * names plus template-ids */ -public abstract class AbstractCPPASTName extends ASTNode implements IASTName { +public abstract class CPPASTNameBase extends ASTNode implements IASTName { /** * For test-purposes, only. @@ -39,23 +39,25 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName { /** * Helper method to resolve intermediate bindings without casting the name. */ - public static IBinding resolveIntermediateBinding(IASTName name) { + public static IBinding resolvePreBinding(IASTName name) { if (name == null) return null; - if (name instanceof AbstractCPPASTName) - return ((AbstractCPPASTName) name).resolveIntermediateBinding(); + if (name instanceof CPPASTNameBase) + return ((CPPASTNameBase) name).resolvePreBinding(); + return name.resolveBinding(); } /** * Helper method to get intermediate bindings without casting the name. */ - public static IBinding getIntermediateBinding(IASTName name) { + public static IBinding getPreBinding(IASTName name) { if (name == null) return null; - if (name instanceof AbstractCPPASTName) - return ((AbstractCPPASTName) name).getIntermediateBinding(); - return name.resolveBinding(); + if (name instanceof CPPASTNameBase) + return ((CPPASTNameBase) name).getPreBinding(); + + return name.getBinding(); } private IBinding fBinding = null; @@ -78,7 +80,7 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName { * Resolves the name at least up to the intermediate binding and returns it. * @see ICPPTwoPhaseBinding */ - public IBinding resolveIntermediateBinding() { + public IBinding resolvePreBinding() { if (fBinding == null) { if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { fBinding= new RecursionResolvingBinding(this); @@ -94,11 +96,12 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName { if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { fBinding= new RecursionResolvingBinding(this); } else { + fIsFinal= false; fBinding= createIntermediateBinding(); } } if (!fIsFinal) - resolveFinalBinding(); + resolveFinalBinding(this); return fBinding; } @@ -108,7 +111,7 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName { * Otherwise the intermediate or final binding for this name is returned. * @see ICPPTwoPhaseBinding */ - public IBinding getIntermediateBinding() { + public IBinding getPreBinding() { final IBinding cand= fBinding; if (cand == null) return null; @@ -122,23 +125,22 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName { return null; if (!fIsFinal) - resolveFinalBinding(); + resolveFinalBinding(this); return fBinding; } - private void resolveFinalBinding() { + private void resolveFinalBinding(CPPASTNameBase astName) { if (fBinding instanceof ICPPTwoPhaseBinding) { - ICPPTwoPhaseBinding lazyBinding= (ICPPTwoPhaseBinding) fBinding; + ICPPTwoPhaseBinding intermediateBinding= (ICPPTwoPhaseBinding) fBinding; if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { fBinding= new RecursionResolvingBinding(this); } else { - IBinding finalBinding= lazyBinding.resolveFinalBinding(); - assert finalBinding.getClass().equals(lazyBinding.getClass()); - + IBinding finalBinding= intermediateBinding.resolveFinalBinding(astName); fBinding= finalBinding; } } + fIsFinal= true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java index 808e4b2e42e..b87b2e55b14 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java @@ -45,7 +45,7 @@ import org.eclipse.core.runtime.Assert; * Qualified name, which can contain any other name (unqualified, operator-name, conversion name, * template id). */ -public class CPPASTQualifiedName extends AbstractCPPASTName +public class CPPASTQualifiedName extends CPPASTNameBase implements ICPPASTQualifiedName, IASTCompletionContext { private IASTName[] names = null; @@ -57,9 +57,9 @@ public class CPPASTQualifiedName extends AbstractCPPASTName } @Override - public final IBinding resolveIntermediateBinding() { + public final IBinding resolvePreBinding() { // The full qualified name resolves to the same thing as the last name - return resolveIntermediateBinding(getLastName()); + return resolvePreBinding(getLastName()); } @Override @@ -70,9 +70,9 @@ public class CPPASTQualifiedName extends AbstractCPPASTName } @Override - public final IBinding getIntermediateBinding() { + public final IBinding getPreBinding() { // The full qualified name resolves to the same thing as the last name - return getIntermediateBinding(getLastName()); + return getPreBinding(getLastName()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java index c5ca1df62ba..a69135d1f22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java @@ -34,7 +34,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; * Template ids consist of an unqualified name (or operator or conversion name) * and an array of template arguments. */ -public class CPPASTTemplateId extends AbstractCPPASTName implements ICPPASTTemplateId, IASTAmbiguityParent { +public class CPPASTTemplateId extends CPPASTNameBase implements ICPPASTTemplateId, IASTAmbiguityParent { private IASTName templateName; private IASTNode[] templateArguments = null; public CPPASTTemplateId() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java index 914bbbc8363..35ea32c742b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -35,7 +36,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate super(name); } - public ICPPTemplateArgument[] getTemplateArguments() { + public ICPPTemplateArgument[] getTemplateArguments() throws DOMException { if (arguments == null) { arguments= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) getTemplateName()); } @@ -55,12 +56,20 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate } public ICPPTemplateParameterMap getTemplateParameterMap() { - return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments()); + try { + return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments()); + } catch (DOMException e) { + return CPPTemplateParameterMap.EMPTY; + } } @Override public String toString() { - return super.toString() + '<' + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true) + '>'; + try { + return super.toString() + '<' + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true) + '>'; + } catch (DOMException e) { + return super.toString() + '<' + e.getProblem().toString() + '>'; + } } @Deprecated @@ -69,7 +78,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate } @Deprecated - public IType[] getArguments() { + public IType[] getArguments() throws DOMException { return CPPTemplates.getArguments(getTemplateArguments()); } } 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 index 7ead5335a0b..72c793355fd 100644 --- 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 @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -39,6 +40,7 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate#getPartialSpecializations() */ public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { + // mstodo the partial specializations need to be specialized return ((ICPPClassTemplate) getSpecializedBinding()).getPartialSpecializations(); } @@ -77,11 +79,25 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization } public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) { - //should not occur mstodo- why not?? + // mstodo partial specializations for class template specializations. + // this is legal code: + // template class CT { + // template class NT { + // }; + // }; + // // creates a partial spec for the specialization of CT::NT + // template<> template class CT::NT { + // public: + // int spec; + // }; } @Override public String toString() { return getName(); } + + public IBinding resolveTemplateParameter(ICPPTemplateParameter param) { + return param; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java index 9f7710fdfd8..d1a26a37922 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java @@ -64,4 +64,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization } return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; } + + public IBinding resolveTemplateParameter(ICPPTemplateParameter param) { + return param; + } } 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 b020d8ac5be..1f6f95e4012 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 @@ -25,9 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.cpp.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.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; @@ -124,71 +122,6 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC } return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; } - - public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) { - IASTName name = CPPTemplates.getTemplateParameterName(templateParameter); - IASTName preferredName= name; - IBinding binding = name.getBinding(); - if (binding != null) - return binding; - - ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) templateParameter.getParent(); - ICPPASTTemplateParameter[] ps = templateDecl.getTemplateParameters(); - - int i = 0; - for (; i < ps.length; i++) { - if (templateParameter == ps[i]) - break; - } - - if (definition != null || (declarations != null && declarations.length > 0)) { - IASTName templateName = (definition != null) ? definition : declarations[0]; - ICPPASTTemplateDeclaration temp = CPPTemplates.getTemplateDeclaration(templateName); - ICPPASTTemplateParameter[] params = temp.getTemplateParameters(); - if (params.length > i) { - IASTName paramName = CPPTemplates.getTemplateParameterName(params[i]); - preferredName= paramName; - if (paramName.getBinding() != null) { - binding = paramName.getBinding(); - name.setBinding(binding); - if(binding instanceof ICPPInternalBinding) - ((ICPPInternalBinding)binding).addDeclaration(name); - return binding; - } - } - } - //create a new binding and set it for the corresponding parameter in all known decls - if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) { - binding = new CPPTemplateTypeParameter(preferredName); - } else if (templateParameter instanceof ICPPASTParameterDeclaration) { - binding = new CPPTemplateNonTypeParameter(preferredName); - } else { - binding = new CPPTemplateTemplateParameter(preferredName); - } - - int length = (declarations != null) ? declarations.length : 0; - int j = (definition != null) ? -1 : 0; - for (; j < length; j++) { - ICPPASTTemplateDeclaration template = (j == -1) - ? CPPTemplates.getTemplateDeclaration(definition) - : CPPTemplates.getTemplateDeclaration(declarations[j]); - if (template == null) - continue; - - ICPPASTTemplateParameter[] temp = template.getTemplateParameters(); - if (temp.length <= i) - continue; - - IASTName n = CPPTemplates.getTemplateParameterName(temp[i]); - if (n != null && n != name && n.getBinding() == null) { - n.setBinding(binding); - if (binding instanceof ICPPInternalBinding) - ((ICPPInternalBinding)binding).addDeclaration(n); - } - - } - return binding; - } public IASTName getTemplateName() { if (definition != null) @@ -313,20 +246,59 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC } ArrayUtil.remove(declarations, node); } - 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; - int end= Math.min(ops.length, nps.length); - for (int i = 0; i < end; i++) { - temp = (ICPPInternalBinding) CPPTemplates.getTemplateParameterName(ops[i]).getBinding(); - if (temp != null) { - IASTName n = CPPTemplates.getTemplateParameterName(nps[i]); - n.setBinding(temp); - temp.addDeclaration(n); + + public IBinding resolveTemplateParameter(ICPPTemplateParameter templateParameter) { + int pos= templateParameter.getParameterPosition() & 0xff; + + int tdeclLen= declarations == null ? 0 : declarations.length; + for (int i=-1; i or template). */ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements ICPPTemplateTypeParameter, IType, ICPPUnknownBinding { @@ -68,9 +68,12 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements public boolean isSameType(IType type) { if (type == this) return true; - if (type instanceof ITypedef || type instanceof IIndexType) + if (type instanceof ITypedef) return type.isSameType(this); - return false; + if (!(type instanceof ICPPTemplateTypeParameter)) + return false; + + return getParameterPosition() == ((ICPPTemplateParameter) type).getParameterPosition(); } public IASTName getUnknownName() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index 6dd90fefad5..3f7b9bff4a5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -6,7 +6,7 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Corporation - initial API and implementation + * Andrew Niefer (IBM Corporation) - initial API and implementation * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * Sergey Prigogin (Google) @@ -31,7 +31,8 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** - * @author aniefer + * Models the scope represented by an unknown binding such (e.g.: template type parameter). Used within + * the context of templates, only. */ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope { private final ICPPUnknownBinding binding; @@ -111,8 +112,12 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope { IBinding b; IASTNode parent = name.getParent(); if (parent instanceof ICPPASTTemplateId) { - ICPPTemplateArgument[] arguments = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) parent); - b = new CPPUnknownClassInstance(binding, name, arguments); + try { + ICPPTemplateArgument[] arguments = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) parent); + b = new CPPUnknownClassInstance(binding, name, arguments); + } catch (DOMException e) { + return e.getProblem(); + } } else { b = new CPPUnknownClass(binding, name); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java index e9d955ad0e6..66b033e39e9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalTemplate.java @@ -10,9 +10,14 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; + /** * Interface for templates from the ast. */ public interface ICPPInternalTemplate extends ICPPInternalBinding, ICPPInstanceCache { + + IBinding resolveTemplateParameter(ICPPTemplateParameter param); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTwoPhaseBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTwoPhaseBinding.java index 7c594f51742..4a005d54fac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTwoPhaseBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTwoPhaseBinding.java @@ -17,7 +17,8 @@ import org.eclipse.cdt.core.dom.ast.IBinding; * by the first step is an intermediate binding that can be replaced in a second * step before the binding is exposed via public API. *

- * The bindings of the two phases may not be equal, but they must have the same type. + * The bindings of the two phases may not be equal, but they must implement the + * same public interfaces. *

* This allows for having multiple bindings for one final binding and deferring * the act of unifying them to a later point in time. @@ -30,7 +31,7 @@ public interface ICPPTwoPhaseBinding extends IBinding { * {@code this} must be returned. *

Note, that the result of this operation is an instance of * {@link ICPPTwoPhaseBinding}, however it must resolve to itself using - * {@link #resolveFinalBinding()}. + * {@link #resolveFinalBinding(CPPASTNameBase)}. */ - ICPPTwoPhaseBinding resolveFinalBinding(); + IBinding resolveFinalBinding(CPPASTNameBase astName); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 96378c21c47..7cf7bbb7853 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -133,10 +133,10 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.Value; -import org.eclipse.cdt.internal.core.dom.parser.cpp.AbstractCPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding; @@ -170,13 +170,17 @@ public class CPPSemantics { // Set to true for debugging. public static boolean traceBindingResolution = false; + public static int traceIndent= 0; static protected IBinding resolveBinding(IASTName name) { if (traceBindingResolution) { - System.out.println("Resolving " + name); //$NON-NLS-1$ + for (int i = 0; i < traceIndent; i++) + System.out.print(" "); //$NON-NLS-1$ + System.out.println("Resolving " + name + ':' + ((ASTNode)name).getOffset()); //$NON-NLS-1$ + traceIndent++; } - if (name instanceof AbstractCPPASTName) { - ((AbstractCPPASTName) name).incResolutionDepth(); + if (name instanceof CPPASTNameBase) { + ((CPPASTNameBase) name).incResolutionDepth(); } // 1: get some context info off of the name to figure out what kind of lookup we want @@ -202,7 +206,11 @@ public class CPPSemantics { // 4: post processing binding = postResolution(binding, data); if (traceBindingResolution) { - System.out.println("Resolved " + name + " to " + DebugUtil.toStringWithClass(binding)); //$NON-NLS-1$ //$NON-NLS-2$ + traceIndent--; + for (int i = 0; i < traceIndent; i++) + System.out.print(" "); //$NON-NLS-1$ + System.out.println("Resolved " + name + ':' + ((ASTNode)name).getOffset() + //$NON-NLS-1$ + " to " + DebugUtil.toStringWithClass(binding) + ':' + System.identityHashCode(binding)); //$NON-NLS-1$ } return binding; } @@ -290,28 +298,27 @@ public class CPPSemantics { } if (binding instanceof ICPPClassType && data.considerConstructors) { - ICPPClassType cls = (ICPPClassType) binding; - if (data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) { - if (data.tu != null) { - ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; - ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); - IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); - cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls; - } - } - if (cls != null) { - try { - //force resolution of constructor bindings - IBinding[] ctors = cls.getConstructors(); - if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) { - //then use the class scope to resolve which one. - binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding(data.astName, true); - } - } catch (DOMException e) { - binding = e.getProblem(); - } - } - + try { + ICPPClassType cls = (ICPPClassType) binding; + if (data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) { + if (data.tu != null) { + ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; + ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); + IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); + cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls; + } + } + if (cls != null) { + //force resolution of constructor bindings + IBinding[] ctors = cls.getConstructors(); + if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) { + //then use the class scope to resolve which one. + binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding(data.astName, true); + } + } + } catch (DOMException e) { + binding = e.getProblem(); + } } // mstodo this looks like a hack? @@ -1563,7 +1570,7 @@ public class CPPSemantics { if (bindings[0] instanceof IBinding) { candidate= (IBinding) bindings[0]; } else if (bindings[0] instanceof IASTName) { - candidate= ((IASTName) bindings[0]).getBinding(); + candidate= CPPASTNameBase.getPreBinding((IASTName) bindings[0]); } else { return null; } @@ -1718,7 +1725,11 @@ public class CPPSemantics { } if (o instanceof IASTName) { IASTName on= (IASTName) o; - temp = checkResolvedNamesOnly ? on.getBinding() : on.resolveBinding(); + if (checkResolvedNamesOnly) { + temp = CPPASTNameBase.getPreBinding(on); + } else { + temp= CPPASTNameBase.resolvePreBinding(on); + } if (temp == null) continue; } else if (o instanceof IBinding) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 2d3e576bbae..b90eeeaa926 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -30,7 +30,6 @@ 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.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -44,7 +43,6 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IValue; -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.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; @@ -116,8 +114,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; @@ -399,42 +399,17 @@ public class CPPTemplates { } public static IBinding createBinding(ICPPASTTemplateParameter templateParameter) { - // mstodo allow incomplete bindings - ICPPTemplateDefinition template = getContainingTemplate(templateParameter); - - IBinding binding = null; - if (template instanceof CPPTemplateTemplateParameter) { - binding = ((CPPTemplateTemplateParameter) template).resolveTemplateParameter(templateParameter); - } else if (template instanceof CPPTemplateDefinition) { - binding = ((CPPTemplateDefinition) template).resolveTemplateParameter(templateParameter); - } else if (template != null) { - IASTName name = CPPTemplates.getTemplateParameterName(templateParameter); - binding = name.getBinding(); - - if (binding == null) { - ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) templateParameter.getParent(); - ICPPASTTemplateParameter[] ps = templateDecl.getTemplateParameters(); - - int i = 0; - for (; i < ps.length; i++) { - if (templateParameter == ps[i]) - break; - } - - try { - ICPPTemplateParameter[] params = template.getTemplateParameters(); - if (i < params.length) { - binding = params[i]; - name.setBinding(binding); - } - } catch (DOMException e) { - } - } - } - - return binding; + if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) { + return new CPPTemplateTypeParameter(((ICPPASTSimpleTypeTemplateParameter) templateParameter).getName()); + } + if (templateParameter instanceof ICPPASTTemplatedTypeTemplateParameter) { + return new CPPTemplateTemplateParameter(((ICPPASTTemplatedTypeTemplateParameter) templateParameter).getName()); + } + assert templateParameter instanceof ICPPASTParameterDeclaration; + final IASTDeclarator dtor = ((ICPPASTParameterDeclaration) templateParameter).getDeclarator(); + return new CPPTemplateNonTypeParameter(CPPVisitor.findInnermostDeclarator(dtor).getName()); } - + static public ICPPScope getContainingScope(IASTNode node) { while (node != null) { if (node instanceof ICPPASTTemplateParameter) { @@ -479,45 +454,44 @@ public class CPPTemplates { } else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) { return createFunctionSpecialization(id); } + + //a reference: class or function template? + IBinding template = null; + if (parent instanceof ICPPASTNamedTypeSpecifier || + parent instanceof ICPPASTElaboratedTypeSpecifier || + parent instanceof ICPPASTBaseSpecifier || + segment == 0) { + //class template + IASTName templateName = id.getTemplateName(); + template = templateName.resolveBinding(); + if (template instanceof ICPPClassTemplatePartialSpecialization) { + //specializations are selected during the instantiation, start with the primary template + try { + template = ((ICPPClassTemplatePartialSpecialization) template).getPrimaryClassTemplate(); + } catch (DOMException e) { + return e.getProblem(); + } + } else if (template instanceof ICPPSpecialization && !(template instanceof ICPPTemplateDefinition)) { + template = ((ICPPSpecialization) template).getSpecializedBinding(); + } + + if (template instanceof ICPPTemplateDefinition) { + ICPPTemplateArgument[] args= CPPTemplates.createTemplateArgumentArray(id); + IBinding instance= instantiate((ICPPTemplateDefinition) template, args); + return CPPSemantics.postResolution(instance, id); + } + } else { + //functions are instantiated as part of the resolution process + template = CPPVisitor.createBinding(id); + if (template instanceof ICPPTemplateInstance) { + IASTName templateName = id.getTemplateName(); + templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition()); + } + } + return template; } catch (DOMException e) { return e.getProblem(); } - - //a reference: class or function template? - IBinding template = null; - if (parent instanceof ICPPASTNamedTypeSpecifier || - parent instanceof ICPPASTElaboratedTypeSpecifier || - parent instanceof ICPPASTBaseSpecifier || - segment == 0) { - //class template - IASTName templateName = id.getTemplateName(); - template = templateName.resolveBinding(); - if (template instanceof ICPPClassTemplatePartialSpecialization) { - //specializations are selected during the instantiation, start with the primary template - try { - template = ((ICPPClassTemplatePartialSpecialization) template).getPrimaryClassTemplate(); - } catch (DOMException e) { - return e.getProblem(); - } - } else if (template instanceof ICPPSpecialization && !(template instanceof ICPPTemplateDefinition)) { - template = ((ICPPSpecialization) template).getSpecializedBinding(); - } - - if (template instanceof ICPPTemplateDefinition) { - ICPPTemplateArgument[] args= CPPTemplates.createTemplateArgumentArray(id); - IBinding instance= instantiate((ICPPTemplateDefinition) template, args); - return CPPSemantics.postResolution(instance, id); - } - } else { - //functions are instantiated as part of the resolution process - template = CPPVisitor.createBinding(id); - if (template instanceof ICPPTemplateInstance) { - IASTName templateName = id.getTemplateName(); - templateName.setBinding(((ICPPTemplateInstance) template).getTemplateDefinition()); - } - } - - return template; } protected static IBinding createExplicitClassInstantiation(ICPPASTElaboratedTypeSpecifier elabSpec) { @@ -528,12 +502,16 @@ public class CPPTemplates { } ICPPASTTemplateId id = (ICPPASTTemplateId) name; IBinding template = id.getTemplateName().resolveBinding(); - if (template instanceof ICPPClassTemplate) { - ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; - ICPPTemplateArgument[] args= createTemplateArgumentArray(id); - IBinding binding= instantiate(classTemplate, args); - if (binding != null) - return binding; + try { + if (template instanceof ICPPClassTemplate) { + ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; + ICPPTemplateArgument[] args= createTemplateArgumentArray(id); + IBinding binding= instantiate(classTemplate, args); + if (binding != null) + return binding; + } + } catch (DOMException e) { + return e.getProblem(); } return new ProblemBinding(elabSpec, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray()); } @@ -699,7 +677,11 @@ public class CPPTemplates { ICPPTemplateArgument[] templateArguments = null; if (name instanceof ICPPASTTemplateId) { - templateArguments= createTemplateArgumentArray((ICPPASTTemplateId) name); + try { + templateArguments= createTemplateArgumentArray((ICPPASTTemplateId) name); + } catch (DOMException e) { + return null; + } } int numArgs = (templateArguments != null) ? templateArguments.length : 0; @@ -1169,44 +1151,6 @@ public class CPPTemplates { return null; } - private static class ClearBindingAction extends CPPASTVisitor { - public ObjectSet bindings = null; - public ClearBindingAction(ObjectSet bindings) { - shouldVisitNames = true; - shouldVisitStatements = true; - this.bindings = bindings; - } - @Override - public int visit(IASTName name) { - if (name.getBinding() != null) { - IBinding binding = name.getBinding(); - boolean clear = bindings.containsKey(name.getBinding()); - if (!clear && binding instanceof ICPPTemplateInstance) { - ICPPTemplateArgument[] args = ((ICPPTemplateInstance) binding).getTemplateArguments(); - for (ICPPTemplateArgument arg : args) { - IType t= arg.getTypeValue(); - if (t instanceof IBinding) { - if (bindings.containsKey((IBinding)t)) { - clear = true; - break; - } - } - } - } - if (clear) { - if (binding instanceof ICPPInternalBinding) - ((ICPPInternalBinding) binding).removeDeclaration(name); - name.setBinding(null); - } - } - return PROCESS_CONTINUE; - } - @Override - public int visit(IASTStatement statement) { - return PROCESS_SKIP; - } - } - public static boolean isSameTemplate(ICPPTemplateDefinition definition, IASTName name) { ICPPTemplateParameter[] defParams = null; try { @@ -1222,24 +1166,9 @@ public class CPPTemplates { if (defParams.length != templateParams.length) return false; - // mstodo interesting side-effect, why not make this more explicit? - 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]); - if (defParams[i] instanceof ICPPInternalBinding) - ((ICPPInternalBinding) defParams[i]).addDeclaration(tn); - bindingsToClear.put(defParams[i]); - } - - boolean result = false; IASTNode parent = name.getParent(); - if (parent instanceof ICPPASTFunctionDeclarator) { - try { + try { + if (parent instanceof ICPPASTFunctionDeclarator) { IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) parent).getParameters(); IParameter[] ps = ((ICPPFunction) definition).getParameters(); if (ps.length == params.length) { @@ -1247,51 +1176,43 @@ public class CPPTemplates { for (; i < ps.length; i++) { IType t1 = CPPVisitor.createType(params[i].getDeclarator()); IType t2 = ps[i].getType(); - if (! t1.isSameType(t2)) { - break; - } + if (!t1.isSameType(t2)) + return false; } - if (i == ps.length) - result = true; + return true; } - } catch (DOMException e) { - } - } else if (parent instanceof IASTDeclSpecifier) { - if (name instanceof ICPPASTTemplateId) { - if (definition instanceof ICPPClassTemplatePartialSpecialization) { - ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition; - ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name); - ICPPTemplateArgument[] specArgs = spec.getTemplateArguments(); - if (args.length == specArgs.length) { - result= true; - for (int i=0; i < args.length; i++) { - if (!specArgs[i].isSameValue(args[i])) { - result= false; - break; + return false; + } + if (parent instanceof IASTDeclSpecifier) { + if (name instanceof ICPPASTTemplateId) { + if (definition instanceof ICPPClassTemplatePartialSpecialization) { + ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition; + ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name); + ICPPTemplateArgument[] specArgs = spec.getTemplateArguments(); + if (args.length == specArgs.length) { + for (int i=0; i < args.length; i++) { + if (!specArgs[i].isSameValue(args[i])) + return false; } } } - } - } else { - result = CharArrayUtils.equals(definition.getNameCharArray(), name.toCharArray()); + return true; + } + + return CharArrayUtils.equals(definition.getNameCharArray(), name.toCharArray()); } + } catch (DOMException e) { } - - // mstodo we should not add the binding in the first place?? - if (bindingsToClear != null && !result) { - ClearBindingAction action = new ClearBindingAction(bindingsToClear); - templateDecl.accept(action); - } - - return result; + return false; } /** * @param id the template id containing the template arguments * @return an array of template arguments, currently modeled as IType objects. The * empty IType array is returned if id is null + * @throws DOMException */ - static public ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) { + static public ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) throws DOMException { ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS; if (id != null) { IASTNode[] params= id.getTemplateArguments(); @@ -1299,12 +1220,8 @@ public class CPPTemplates { for (int i = 0; i < params.length; i++) { IASTNode param= params[i]; IType type= CPPVisitor.createType(param); - // prevent null pointer exception when the type cannot be determined - // happens when templates with still ambiguous template-ids are accessed during - // resolution of other template-id ambiguities. - // mstodo: fix by introducing partially resolved template parameters if (type == null) - type= new CPPBasicType(-1, 0); + throw new DOMException(new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, id.toCharArray())); if (param instanceof IASTExpression) { IValue value= Value.create((IASTExpression) param, Value.MAX_RECURSION_DEPTH); @@ -1361,7 +1278,11 @@ public class CPPTemplates { int numTemplateArgs = 0; ICPPTemplateArgument[] templateArguments = null; if (name instanceof ICPPASTTemplateId) { - templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name); + try { + templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name); + } catch (DOMException e) { + return new IFunction[0]; + } numTemplateArgs = templateArguments.length; } @@ -1829,16 +1750,16 @@ public class CPPTemplates { * arguments of the partial specialization */ static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization specialization) { - ICPPTemplateDefinition template = specialization; - ICPPTemplateArgument[] args= specialization.getTemplateArguments(); - - IType paramType = (IType) instantiate(template, args); - if (paramType == null) - return null; - - IParameter[] functionParameters = new IParameter[] { new CPPParameter(paramType) }; - try { + ICPPTemplateDefinition template = specialization; + ICPPTemplateArgument[] args= specialization.getTemplateArguments(); + + IType paramType = (IType) instantiate(template, args); + if (paramType == null) + return null; + + IParameter[] functionParameters = new IParameter[] { new CPPParameter(paramType) }; + return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters); } catch (DOMException e) { return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index b34890636f7..8fd46aaa9aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -147,6 +147,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplate; @@ -1032,7 +1033,7 @@ public class CPPVisitor { } if (name != null) { name= name.getLastName(); - IBinding binding = name.getBinding(); + IBinding binding = CPPASTNameBase.getPreBinding(name); if (binding == null) { binding = CPPSemantics.resolveBinding(name); name.setBinding(binding); @@ -1678,7 +1679,7 @@ public class CPPVisitor { } } if (name != null) { - IBinding binding = name.resolveBinding(); + IBinding binding = CPPASTNameBase.resolvePreBinding(name); if (binding instanceof ICPPConstructor) { try { type= ((ICPPConstructor) binding).getClassOwner(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java index 19296d53159..bb845915cec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java @@ -55,7 +55,13 @@ public class TemplateInstanceUtil { } public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { - return convert(cf, rbinding.getTemplateArguments()); + try { + return convert(cf, rbinding.getTemplateArguments()); + } catch (DOMException e) { + // index bindings don't throw DOMExceptions + assert false; + } + return ICPPTemplateArgument.EMPTY_ARGUMENTS; } public static IBinding getSpecializedBinding(ICompositesFactory cf, IIndexBinding rbinding) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index c5ba2171d84..40c8cc94ba4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -169,6 +169,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { partial.setArguments(args); } catch (CoreException e) { CCorePlugin.log(e); + } catch (DOMException e) { + CCorePlugin.log(e); } finally { partial = null; binding = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java index bf2beaa3a24..4ced778fcf3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTypeParameter.java @@ -20,9 +20,9 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; import org.eclipse.cdt.internal.core.Util; -import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -111,24 +111,11 @@ class PDOMCPPTemplateTypeParameter extends PDOMCPPBinding implements IPDOMMember if (type instanceof ITypedef) { return type.isSameType(this); } - - if (type instanceof PDOMNode) { - PDOMNode node= (PDOMNode) type; - if (node.getPDOM() == getPDOM()) { - return node.getRecord() == getRecord(); - } - } - - if (type instanceof ICPPTemplateTypeParameter && !(type instanceof ProblemBinding)) { - ICPPTemplateTypeParameter ttp= (ICPPTemplateTypeParameter) type; - try { - char[][] ttpName= ttp.getQualifiedNameCharArray(); - return hasQualifiedName(ttpName, ttpName.length - 1); - } catch (DOMException e) { - CCorePlugin.log(e); - } - } - return false; + + if (!(type instanceof ICPPTemplateTypeParameter)) + return false; + + return getParameterPosition() == ((ICPPTemplateParameter) type).getParameterPosition(); } public IType getDefault() { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexLabelProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexLabelProvider.java index 5fb7545750c..a937a22ceee 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexLabelProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexLabelProvider.java @@ -112,11 +112,15 @@ public class IndexLabelProvider extends LabelProvider { StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$ buffer.append(result); buffer.append('<'); - ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments(); - for (int i = 0; i < types.length; i++) { - if (i > 0) - buffer.append(','); - buffer.append(ASTTypeUtil.getArgumentString(types[i], false)); + try { + ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments(); + for (int i = 0; i < types.length; i++) { + if (i > 0) + buffer.append(','); + buffer.append(ASTTypeUtil.getArgumentString(types[i], false)); + } + } catch (DOMException e) { + buffer.append(e.getProblem().toString()); } buffer.append('>'); result = buffer.toString();