1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Resolution of template parameters in two phases, bug 252554.

This commit is contained in:
Markus Schorn 2008-11-04 08:55:46 +00:00
parent 98a2fa70c3
commit b64db6fe09
31 changed files with 421 additions and 403 deletions

View file

@ -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.dom.ast.gnu.cpp.IGPPPointerType;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; 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 { public void testBug84692() throws Exception {
// also tests bug 234042. // also tests bug 234042.
AbstractCPPASTName.sAllowRecursionBindings= false; CPPASTNameBase.sAllowRecursionBindings= false;
IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP); IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP);
CPPNameCollector col = new CPPNameCollector(); CPPNameCollector col = new CPPNameCollector();

View file

@ -2940,16 +2940,17 @@ public class AST2TemplateTests extends AST2BaseTest {
// These intermediate assertions will not hold until deferred non-type arguments are // These intermediate assertions will not hold until deferred non-type arguments are
// correctly modelled // correctly modelled
/*
ICPPClassType tid= ba.assertNonProblem("This<I>::T", 7, ICPPClassType.class); ICPPClassType tid= ba.assertNonProblem("This<I>::T", 7, ICPPClassType.class);
assertFalse(tid instanceof ICPPSpecialization); assertFalse(tid instanceof ICPPSpecialization);
ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class); 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>(I)", 4, ICPPClassType.class); ICPPClassType clazz= ba.assertNonProblem("That<I>(I)", 4, ICPPClassType.class);
ICPPConstructor ctor= ba.assertNonProblem("That<I>(I)", 7, ICPPConstructor.class); ICPPConstructor ctor= ba.assertNonProblem("That<I>(I)", 7, ICPPConstructor.class);
ICPPTemplateNonTypeParameter np1 = ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
assertSame(np, np1);
} }
// template<typename I> // template<typename I>

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,7 +9,6 @@
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.testplugin.util; package org.eclipse.cdt.core.testplugin.util;
import java.lang.reflect.Method; 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.ElementChangedEvent;
import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.testplugin.TestScannerProvider; 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.CoreException;
import org.eclipse.core.runtime.ILogListener; import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -57,7 +56,7 @@ public class BaseTestCase extends TestCase {
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
AbstractCPPASTName.sAllowRecursionBindings= true; CPPASTNameBase.sAllowRecursionBindings= true;
} }
@Override @Override

View file

@ -6,13 +6,17 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * Doug Schaefer (IBM) - Initial API and implementation
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; 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 interface IType extends Cloneable {
public static final IType[] EMPTY_TYPE_ARRAY = new IType[0]; public static final IType[] EMPTY_TYPE_ARRAY = new IType[0];
@ -21,8 +25,10 @@ public interface IType extends Cloneable {
public Object clone(); public Object clone();
/** /**
* is the given type the same as this type? * Test whether this type is the same as the given one. A typedef is considered to be the same type as
* @param type * 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); public boolean isSameType(IType type);
} }

View file

@ -37,7 +37,7 @@ public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplat
* Returns the arguments of this partial specialization. * Returns the arguments of this partial specialization.
* @since 5.1 * @since 5.1
*/ */
public ICPPTemplateArgument[] getTemplateArguments(); public ICPPTemplateArgument[] getTemplateArguments() throws DOMException;
/** /**
* @deprecated use {@link #getTemplateArguments()}, instead. * @deprecated use {@link #getTemplateArguments()}, instead.

View file

@ -15,6 +15,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
/** /**
* Template parameters of type template * Template parameters of type template
*
* @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, ICPPClassTemplate { public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, ICPPClassTemplate {
@ -24,4 +26,14 @@ public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, IC
* Return the default value for this parameter, or <code>null</code>. * Return the default value for this parameter, or <code>null</code>.
*/ */
public IType getDefault() throws DOMException; 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);
} }

View file

@ -24,4 +24,13 @@ public interface ICPPTemplateTypeParameter extends ICPPTemplateParameter, IType
*/ */
public IType getDefault() throws DOMException; 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);
} }

View file

@ -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.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
/** /**
* Base implementation for all ambiguous nodes. * Base implementation for all ambiguous nodes.
@ -94,7 +95,7 @@ public abstract class ASTAmbiguousNode extends ASTNode {
int issues= 0; int issues= 0;
for (IASTName name : names) { for (IASTName name : names) {
try { try {
IBinding b = name.resolveBinding(); IBinding b= CPPASTNameBase.resolvePreBinding(name);
if (b instanceof IProblemBinding) { if (b instanceof IProblemBinding) {
issues++; issues++;
} }

View file

@ -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.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; 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;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; 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 + '?'; return o + "," + evaluate(cexpr.getNegativeResultExpression(), maxdepth) + "," + po + '?';
} }
if (e instanceof IASTIdExpression) { if (e instanceof IASTIdExpression) {
IBinding b= ((IASTIdExpression) e).getName().resolveBinding(); IBinding b= CPPASTNameBase.resolvePreBinding(((IASTIdExpression) e).getName());
if (b instanceof ICPPTemplateParameter) { if (b instanceof ICPPTemplateParameter) {
if (b instanceof ICPPTemplateNonTypeParameter) { if (b instanceof ICPPTemplateNonTypeParameter) {
return evaluate((ICPPTemplateParameter) b); return evaluate((ICPPTemplateParameter) b);

View file

@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.internal.core.parser.ParserMessages; 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. * Ambiguity node for deciding between type-id and id-expression in a template argument.
*/ */
public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements ICPPASTAmbiguousTemplateArgument { public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements ICPPASTAmbiguousTemplateArgument {
private List<IASTNode> fNodes; private List<IASTNode> fNodes;
/** /**
@ -47,6 +49,12 @@ public class CPPASTAmbiguousTemplateArgument extends CPPASTAmbiguity implements
} }
} }
@Override
protected IScope getAffectedScope() {
// a template argument does not introduce names to a parent scope.
return null;
}
@Override @Override
protected IASTNode[] getNodes() { protected IASTNode[] getNodes() {
return fNodes.toArray(new IASTNode[fNodes.size()]); return fNodes.toArray(new IASTNode[fNodes.size()]);

View file

@ -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. * 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; private char[] name;
public CPPASTName(char[] name) { public CPPASTName(char[] name) {
this.name = name; this.name = name;

View file

@ -21,7 +21,7 @@ import org.eclipse.core.runtime.Assert;
* Common base class for all sorts of c++ names: unqualified, qualified, operator and conversion * Common base class for all sorts of c++ names: unqualified, qualified, operator and conversion
* names plus template-ids * names plus template-ids
*/ */
public abstract class AbstractCPPASTName extends ASTNode implements IASTName { public abstract class CPPASTNameBase extends ASTNode implements IASTName {
/** /**
* For test-purposes, only. * 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. * 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) if (name == null)
return null; return null;
if (name instanceof AbstractCPPASTName) if (name instanceof CPPASTNameBase)
return ((AbstractCPPASTName) name).resolveIntermediateBinding(); return ((CPPASTNameBase) name).resolvePreBinding();
return name.resolveBinding(); return name.resolveBinding();
} }
/** /**
* Helper method to get intermediate bindings without casting the name. * 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) if (name == null)
return null; return null;
if (name instanceof AbstractCPPASTName) if (name instanceof CPPASTNameBase)
return ((AbstractCPPASTName) name).getIntermediateBinding(); return ((CPPASTNameBase) name).getPreBinding();
return name.resolveBinding();
return name.getBinding();
} }
private IBinding fBinding = null; 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. * Resolves the name at least up to the intermediate binding and returns it.
* @see ICPPTwoPhaseBinding * @see ICPPTwoPhaseBinding
*/ */
public IBinding resolveIntermediateBinding() { public IBinding resolvePreBinding() {
if (fBinding == null) { if (fBinding == null) {
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
fBinding= new RecursionResolvingBinding(this); fBinding= new RecursionResolvingBinding(this);
@ -94,11 +96,12 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName {
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
fBinding= new RecursionResolvingBinding(this); fBinding= new RecursionResolvingBinding(this);
} else { } else {
fIsFinal= false;
fBinding= createIntermediateBinding(); fBinding= createIntermediateBinding();
} }
} }
if (!fIsFinal) if (!fIsFinal)
resolveFinalBinding(); resolveFinalBinding(this);
return fBinding; 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. * Otherwise the intermediate or final binding for this name is returned.
* @see ICPPTwoPhaseBinding * @see ICPPTwoPhaseBinding
*/ */
public IBinding getIntermediateBinding() { public IBinding getPreBinding() {
final IBinding cand= fBinding; final IBinding cand= fBinding;
if (cand == null) if (cand == null)
return null; return null;
@ -122,23 +125,22 @@ public abstract class AbstractCPPASTName extends ASTNode implements IASTName {
return null; return null;
if (!fIsFinal) if (!fIsFinal)
resolveFinalBinding(); resolveFinalBinding(this);
return fBinding; return fBinding;
} }
private void resolveFinalBinding() { private void resolveFinalBinding(CPPASTNameBase astName) {
if (fBinding instanceof ICPPTwoPhaseBinding) { if (fBinding instanceof ICPPTwoPhaseBinding) {
ICPPTwoPhaseBinding lazyBinding= (ICPPTwoPhaseBinding) fBinding; ICPPTwoPhaseBinding intermediateBinding= (ICPPTwoPhaseBinding) fBinding;
if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) {
fBinding= new RecursionResolvingBinding(this); fBinding= new RecursionResolvingBinding(this);
} else { } else {
IBinding finalBinding= lazyBinding.resolveFinalBinding(); IBinding finalBinding= intermediateBinding.resolveFinalBinding(astName);
assert finalBinding.getClass().equals(lazyBinding.getClass());
fBinding= finalBinding; fBinding= finalBinding;
} }
} }
fIsFinal= true; fIsFinal= true;
} }

View file

@ -45,7 +45,7 @@ import org.eclipse.core.runtime.Assert;
* Qualified name, which can contain any other name (unqualified, operator-name, conversion name, * Qualified name, which can contain any other name (unqualified, operator-name, conversion name,
* template id). * template id).
*/ */
public class CPPASTQualifiedName extends AbstractCPPASTName public class CPPASTQualifiedName extends CPPASTNameBase
implements ICPPASTQualifiedName, IASTCompletionContext { implements ICPPASTQualifiedName, IASTCompletionContext {
private IASTName[] names = null; private IASTName[] names = null;
@ -57,9 +57,9 @@ public class CPPASTQualifiedName extends AbstractCPPASTName
} }
@Override @Override
public final IBinding resolveIntermediateBinding() { public final IBinding resolvePreBinding() {
// The full qualified name resolves to the same thing as the last name // The full qualified name resolves to the same thing as the last name
return resolveIntermediateBinding(getLastName()); return resolvePreBinding(getLastName());
} }
@Override @Override
@ -70,9 +70,9 @@ public class CPPASTQualifiedName extends AbstractCPPASTName
} }
@Override @Override
public final IBinding getIntermediateBinding() { public final IBinding getPreBinding() {
// The full qualified name resolves to the same thing as the last name // The full qualified name resolves to the same thing as the last name
return getIntermediateBinding(getLastName()); return getPreBinding(getLastName());
} }
@Override @Override

View file

@ -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) * Template ids consist of an unqualified name (or operator or conversion name)
* and an array of template arguments. * 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 IASTName templateName;
private IASTNode[] templateArguments = null; private IASTNode[] templateArguments = null;
public CPPASTTemplateId() { public CPPASTTemplateId() {

View file

@ -12,6 +12,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -35,7 +36,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
super(name); super(name);
} }
public ICPPTemplateArgument[] getTemplateArguments() { public ICPPTemplateArgument[] getTemplateArguments() throws DOMException {
if (arguments == null) { if (arguments == null) {
arguments= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) getTemplateName()); arguments= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) getTemplateName());
} }
@ -55,12 +56,20 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
} }
public ICPPTemplateParameterMap getTemplateParameterMap() { public ICPPTemplateParameterMap getTemplateParameterMap() {
return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments()); try {
return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments());
} catch (DOMException e) {
return CPPTemplateParameterMap.EMPTY;
}
} }
@Override @Override
public String toString() { 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 @Deprecated
@ -69,7 +78,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
} }
@Deprecated @Deprecated
public IType[] getArguments() { public IType[] getArguments() throws DOMException {
return CPPTemplates.getArguments(getTemplateArguments()); return CPPTemplates.getArguments(getTemplateArguments());
} }
} }

View file

@ -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.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; 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.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; 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() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate#getPartialSpecializations()
*/ */
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException {
// mstodo the partial specializations need to be specialized
return ((ICPPClassTemplate) getSpecializedBinding()).getPartialSpecializations(); return ((ICPPClassTemplate) getSpecializedBinding()).getPartialSpecializations();
} }
@ -77,11 +79,25 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
} }
public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) { public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) {
//should not occur mstodo- why not?? // mstodo partial specializations for class template specializations.
// this is legal code:
// template<typename T> class CT {
// template<typename S> class NT {
// };
// };
// // creates a partial spec for the specialization of CT::NT
// template<> template<typename S> class CT<char>::NT<S*> {
// public:
// int spec;
// };
} }
@Override @Override
public String toString() { public String toString() {
return getName(); return getName();
} }
public IBinding resolveTemplateParameter(ICPPTemplateParameter param) {
return param;
}
} }

View file

@ -64,4 +64,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization
} }
return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY;
} }
public IBinding resolveTemplateParameter(ICPPTemplateParameter param) {
return param;
}
} }

View file

@ -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.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.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.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
@ -125,71 +123,6 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
return ICPPTemplateInstance.EMPTY_TEMPLATE_INSTANCE_ARRAY; 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() { public IASTName getTemplateName() {
if (definition != null) if (definition != null)
return definition; return definition;
@ -313,20 +246,59 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
} }
ArrayUtil.remove(declarations, node); ArrayUtil.remove(declarations, node);
} }
protected void updateTemplateParameterBindings(IASTName name) {
IASTName orig = definition != null ? definition : declarations[0]; public IBinding resolveTemplateParameter(ICPPTemplateParameter templateParameter) {
ICPPASTTemplateDeclaration origTemplate = CPPTemplates.getTemplateDeclaration(orig); int pos= templateParameter.getParameterPosition() & 0xff;
ICPPASTTemplateDeclaration newTemplate = CPPTemplates.getTemplateDeclaration(name);
ICPPASTTemplateParameter[] ops = origTemplate.getTemplateParameters(); int tdeclLen= declarations == null ? 0 : declarations.length;
ICPPASTTemplateParameter[] nps = newTemplate.getTemplateParameters(); for (int i=-1; i<tdeclLen; i++) {
ICPPInternalBinding temp = null; IASTName tdecl;
int end= Math.min(ops.length, nps.length); if (i == -1) {
for (int i = 0; i < end; i++) { tdecl= definition;
temp = (ICPPInternalBinding) CPPTemplates.getTemplateParameterName(ops[i]).getBinding(); if (tdecl == null)
if (temp != null) { continue;
IASTName n = CPPTemplates.getTemplateParameterName(nps[i]); } else {
n.setBinding(temp); tdecl= declarations[i];
temp.addDeclaration(n); if (tdecl == null)
break;
}
ICPPASTTemplateParameter[] params = CPPTemplates.getTemplateDeclaration(tdecl).getTemplateParameters();
if (pos < params.length) {
final IASTName oName = CPPTemplates.getTemplateParameterName(params[pos]);
return CPPASTNameBase.resolvePreBinding(oName);
}
}
return templateParameter;
}
final protected void updateTemplateParameterBindings(IASTName name) {
ICPPASTTemplateParameter[] updateParams = CPPTemplates.getTemplateDeclaration(name).getTemplateParameters();
int k=0;
int tdeclLen= declarations == null ? 0 : declarations.length;
for (int i=-1; i<tdeclLen && k<updateParams.length; i++) {
IASTName tdecl;
if (i == -1) {
tdecl= definition;
if (tdecl == null)
continue;
} else {
tdecl= declarations[i];
if (tdecl == null)
break;
}
ICPPASTTemplateParameter[] params = CPPTemplates.getTemplateDeclaration(tdecl).getTemplateParameters();
int end= Math.min(params.length, updateParams.length);
for (; k < end; k++) {
final IASTName oName = CPPTemplates.getTemplateParameterName(params[k]);
IBinding b= CPPASTNameBase.resolvePreBinding(oName);
IASTName n = CPPTemplates.getTemplateParameterName(updateParams[k]);
n.setBinding(b);
if (b instanceof ICPPInternalBinding) {
((ICPPInternalBinding) b).addDeclaration(n);
}
} }
} }
} }

View file

@ -16,15 +16,18 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; 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.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
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.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
@ -32,13 +35,17 @@ import org.eclipse.core.runtime.PlatformObject;
/** /**
* Base implementation for template parameter bindings in the AST. * Base implementation for template parameter bindings in the AST.
*/ */
public abstract class CPPTemplateParameter extends PlatformObject implements ICPPTemplateParameter, ICPPInternalBinding { public abstract class CPPTemplateParameter extends PlatformObject
implements ICPPTemplateParameter, ICPPInternalBinding, ICPPTwoPhaseBinding {
private IASTName [] declarations; private IASTName [] declarations;
private final int position; private final int position;
public CPPTemplateParameter(IASTName name) { public CPPTemplateParameter(IASTName name) {
declarations = new IASTName[] {name}; declarations = new IASTName[] {name};
position= computeParameterPosition(name);
}
private int computeParameterPosition(IASTName name) {
int pos= -1; int pos= -1;
int nesting= -1; int nesting= -1;
ICPPASTTemplateParameter tp= null; ICPPASTTemplateParameter tp= null;
@ -70,7 +77,7 @@ public abstract class CPPTemplateParameter extends PlatformObject implements ICP
if (pos < 0) if (pos < 0)
pos= 0; pos= 0;
position= (nesting << 16) + pos; return (nesting << 16) + pos;
} }
@Override @Override
@ -106,6 +113,15 @@ public abstract class CPPTemplateParameter extends PlatformObject implements ICP
public IASTName getPrimaryDeclaration () { public IASTName getPrimaryDeclaration () {
return declarations[0]; return declarations[0];
} }
private ICPPASTTemplateParameter getASTTemplateParameter() {
IASTNode node= declarations[0];
while (node != null && !(node instanceof ICPPASTTemplateParameter))
node= node.getParent();
assert node != null;
return (ICPPASTTemplateParameter) node;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope()
*/ */
@ -204,4 +220,32 @@ public abstract class CPPTemplateParameter extends PlatformObject implements ICP
return CPPTemplates.getContainingTemplate((ICPPASTTemplateParameter) node); return CPPTemplates.getContainingTemplate((ICPPASTTemplateParameter) node);
} }
public IBinding resolveFinalBinding(CPPASTNameBase name) {
// check if the binding has been updated.
IBinding current= name.getPreBinding();
if (current != this)
return current;
ICPPTemplateDefinition template= CPPTemplates.getContainingTemplate(getASTTemplateParameter());
if (template instanceof ICPPInternalTemplate) {
return ((ICPPInternalTemplate) template).resolveTemplateParameter(this);
}
// problem finding the containing template
if (template == null) {
return this;
}
// use parameter from the index
try {
ICPPTemplateParameter[] params = template.getTemplateParameters();
final int pos= position & 0xff;
if (pos < params.length)
return params[pos];
} catch (DOMException e) {
return e.getProblem();
}
return new ProblemBinding(getPrimaryDeclaration(), IProblemBinding.SEMANTIC_DEFINITION_NOT_FOUND, getNameCharArray());
}
} }

View file

@ -22,8 +22,6 @@ import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
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.ICPPASTTemplateParameter; 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.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
@ -87,21 +85,8 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
return templateParameters; return templateParameters;
} }
public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) { public IBinding resolveTemplateParameter(ICPPTemplateParameter templateParameter) {
IASTName name = CPPTemplates.getTemplateParameterName(templateParameter); return templateParameter;
IBinding binding = name.getBinding();
if (binding == null) {
//create a new binding and set it for the corresponding parameter in all known decls
if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter)
binding = new CPPTemplateTypeParameter(name);
else if (templateParameter instanceof ICPPASTParameterDeclaration)
binding = new CPPTemplateNonTypeParameter(name);
else
binding = new CPPTemplateTemplateParameter(name);
name.setBinding(binding);
}
return binding;
} }
public ICPPClassTemplatePartialSpecialization[] getTemplateSpecializations() throws DOMException { public ICPPClassTemplatePartialSpecialization[] getTemplateSpecializations() throws DOMException {
@ -176,12 +161,15 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
} }
public boolean isSameType(IType type) { public boolean isSameType(IType type) {
if (type == this) if (type == this)
return true; return true;
if (type instanceof ITypedef) if (type instanceof ITypedef)
return ((ITypedef)type).isSameType(this); return type.isSameType(this);
return false; if (!(type instanceof ICPPTemplateTemplateParameter))
} return false;
return getParameterPosition() == ((ICPPTemplateParameter) type).getParameterPosition();
}
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException {
return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY; return ICPPClassTemplatePartialSpecialization.EMPTY_PARTIAL_SPECIALIZATION_ARRAY;

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -19,12 +19,12 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; 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.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.index.IIndexType;
/** /**
* @author aniefer * The standard template parameter (template<typename T> or template<class T>).
*/ */
public class CPPTemplateTypeParameter extends CPPTemplateParameter implements public class CPPTemplateTypeParameter extends CPPTemplateParameter implements
ICPPTemplateTypeParameter, IType, ICPPUnknownBinding { ICPPTemplateTypeParameter, IType, ICPPUnknownBinding {
@ -68,9 +68,12 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements
public boolean isSameType(IType type) { public boolean isSameType(IType type) {
if (type == this) if (type == this)
return true; return true;
if (type instanceof ITypedef || type instanceof IIndexType) if (type instanceof ITypedef)
return type.isSameType(this); return type.isSameType(this);
return false; if (!(type instanceof ICPPTemplateTypeParameter))
return false;
return getParameterPosition() == ((ICPPTemplateParameter) type).getParameterPosition();
} }
public IASTName getUnknownName() { public IASTName getUnknownName() {

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Sergey Prigogin (Google) * 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; 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 { public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
private final ICPPUnknownBinding binding; private final ICPPUnknownBinding binding;
@ -111,8 +112,12 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
IBinding b; IBinding b;
IASTNode parent = name.getParent(); IASTNode parent = name.getParent();
if (parent instanceof ICPPASTTemplateId) { if (parent instanceof ICPPASTTemplateId) {
ICPPTemplateArgument[] arguments = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) parent); try {
b = new CPPUnknownClassInstance(binding, name, arguments); ICPPTemplateArgument[] arguments = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) parent);
b = new CPPUnknownClassInstance(binding, name, arguments);
} catch (DOMException e) {
return e.getProblem();
}
} else { } else {
b = new CPPUnknownClass(binding, name); b = new CPPUnknownClass(binding, name);
} }

View file

@ -10,9 +10,14 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
/** /**
* Interface for templates from the ast. * Interface for templates from the ast.
*/ */
public interface ICPPInternalTemplate extends ICPPInternalBinding, ICPPInstanceCache { public interface ICPPInternalTemplate extends ICPPInternalBinding, ICPPInstanceCache {
IBinding resolveTemplateParameter(ICPPTemplateParameter param);
} }

View file

@ -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 * by the first step is an intermediate binding that can be replaced in a second
* step before the binding is exposed via public API. * step before the binding is exposed via public API.
* <p> * <p>
* The bindings of the two phases may not be equal, but they must have the <b> same type</b>. * The bindings of the two phases may not be equal, but they must implement the
* same public interfaces.
* <p> * <p>
* This allows for having multiple bindings for one final binding and deferring * This allows for having multiple bindings for one final binding and deferring
* the act of unifying them to a later point in time. * 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. * {@code this} must be returned.
* <p> Note, that the result of this operation is an instance of * <p> Note, that the result of this operation is an instance of
* {@link ICPPTwoPhaseBinding}, however it must resolve to itself using * {@link ICPPTwoPhaseBinding}, however it must resolve to itself using
* {@link #resolveFinalBinding()}. * {@link #resolveFinalBinding(CPPASTNameBase)}.
*/ */
ICPPTwoPhaseBinding resolveFinalBinding(); IBinding resolveFinalBinding(CPPASTNameBase astName);
} }

View file

@ -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.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.Value; 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.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; 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.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.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
@ -170,13 +170,17 @@ public class CPPSemantics {
// Set to true for debugging. // Set to true for debugging.
public static boolean traceBindingResolution = false; public static boolean traceBindingResolution = false;
public static int traceIndent= 0;
static protected IBinding resolveBinding(IASTName name) { static protected IBinding resolveBinding(IASTName name) {
if (traceBindingResolution) { 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) { if (name instanceof CPPASTNameBase) {
((AbstractCPPASTName) name).incResolutionDepth(); ((CPPASTNameBase) name).incResolutionDepth();
} }
// 1: get some context info off of the name to figure out what kind of lookup we want // 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 // 4: post processing
binding = postResolution(binding, data); binding = postResolution(binding, data);
if (traceBindingResolution) { 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; return binding;
} }
@ -290,28 +298,27 @@ public class CPPSemantics {
} }
if (binding instanceof ICPPClassType && data.considerConstructors) { if (binding instanceof ICPPClassType && data.considerConstructors) {
ICPPClassType cls = (ICPPClassType) binding; try {
if (data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) { ICPPClassType cls = (ICPPClassType) binding;
if (data.tu != null) { if (data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) {
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; if (data.tu != null) {
ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id);
cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls; IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args);
} cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls;
} }
if (cls != null) { }
try { if (cls != null) {
//force resolution of constructor bindings //force resolution of constructor bindings
IBinding[] ctors = cls.getConstructors(); IBinding[] ctors = cls.getConstructors();
if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) { if (ctors.length > 0 && !(ctors[0] instanceof IProblemBinding)) {
//then use the class scope to resolve which one. //then use the class scope to resolve which one.
binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding(data.astName, true); binding = ((ICPPClassScope)cls.getCompositeScope()).getBinding(data.astName, true);
} }
} catch (DOMException e) { }
binding = e.getProblem(); } catch (DOMException e) {
} binding = e.getProblem();
} }
} }
// mstodo this looks like a hack? // mstodo this looks like a hack?
@ -1563,7 +1570,7 @@ public class CPPSemantics {
if (bindings[0] instanceof IBinding) { if (bindings[0] instanceof IBinding) {
candidate= (IBinding) bindings[0]; candidate= (IBinding) bindings[0];
} else if (bindings[0] instanceof IASTName) { } else if (bindings[0] instanceof IASTName) {
candidate= ((IASTName) bindings[0]).getBinding(); candidate= CPPASTNameBase.getPreBinding((IASTName) bindings[0]);
} else { } else {
return null; return null;
} }
@ -1718,7 +1725,11 @@ public class CPPSemantics {
} }
if (o instanceof IASTName) { if (o instanceof IASTName) {
IASTName on= (IASTName) o; IASTName on= (IASTName) o;
temp = checkResolvedNamesOnly ? on.getBinding() : on.resolveBinding(); if (checkResolvedNamesOnly) {
temp = CPPASTNameBase.getPreBinding(on);
} else {
temp= CPPASTNameBase.resolvePreBinding(on);
}
if (temp == null) if (temp == null)
continue; continue;
} else if (o instanceof IBinding) { } else if (o instanceof IBinding) {

View file

@ -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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; 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.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue; 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.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
@ -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.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; 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.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.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; 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.CPPTypedefSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
@ -399,40 +399,15 @@ public class CPPTemplates {
} }
public static IBinding createBinding(ICPPASTTemplateParameter templateParameter) { public static IBinding createBinding(ICPPASTTemplateParameter templateParameter) {
// mstodo allow incomplete bindings if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) {
ICPPTemplateDefinition template = getContainingTemplate(templateParameter); return new CPPTemplateTypeParameter(((ICPPASTSimpleTypeTemplateParameter) templateParameter).getName());
}
IBinding binding = null; if (templateParameter instanceof ICPPASTTemplatedTypeTemplateParameter) {
if (template instanceof CPPTemplateTemplateParameter) { return new CPPTemplateTemplateParameter(((ICPPASTTemplatedTypeTemplateParameter) templateParameter).getName());
binding = ((CPPTemplateTemplateParameter) template).resolveTemplateParameter(templateParameter); }
} else if (template instanceof CPPTemplateDefinition) { assert templateParameter instanceof ICPPASTParameterDeclaration;
binding = ((CPPTemplateDefinition) template).resolveTemplateParameter(templateParameter); final IASTDeclarator dtor = ((ICPPASTParameterDeclaration) templateParameter).getDeclarator();
} else if (template != null) { return new CPPTemplateNonTypeParameter(CPPVisitor.findInnermostDeclarator(dtor).getName());
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;
} }
static public ICPPScope getContainingScope(IASTNode node) { static public ICPPScope getContainingScope(IASTNode node) {
@ -479,45 +454,44 @@ public class CPPTemplates {
} else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) { } else if (parent instanceof ICPPASTFunctionDeclarator && segment != 0) {
return createFunctionSpecialization(id); 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) { } catch (DOMException e) {
return e.getProblem(); 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) { protected static IBinding createExplicitClassInstantiation(ICPPASTElaboratedTypeSpecifier elabSpec) {
@ -528,12 +502,16 @@ public class CPPTemplates {
} }
ICPPASTTemplateId id = (ICPPASTTemplateId) name; ICPPASTTemplateId id = (ICPPASTTemplateId) name;
IBinding template = id.getTemplateName().resolveBinding(); IBinding template = id.getTemplateName().resolveBinding();
if (template instanceof ICPPClassTemplate) { try {
ICPPClassTemplate classTemplate = (ICPPClassTemplate) template; if (template instanceof ICPPClassTemplate) {
ICPPTemplateArgument[] args= createTemplateArgumentArray(id); ICPPClassTemplate classTemplate = (ICPPClassTemplate) template;
IBinding binding= instantiate(classTemplate, args); ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
if (binding != null) IBinding binding= instantiate(classTemplate, args);
return binding; if (binding != null)
return binding;
}
} catch (DOMException e) {
return e.getProblem();
} }
return new ProblemBinding(elabSpec, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray()); return new ProblemBinding(elabSpec, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
} }
@ -699,7 +677,11 @@ public class CPPTemplates {
ICPPTemplateArgument[] templateArguments = null; ICPPTemplateArgument[] templateArguments = null;
if (name instanceof ICPPASTTemplateId) { 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; int numArgs = (templateArguments != null) ? templateArguments.length : 0;
@ -1169,44 +1151,6 @@ public class CPPTemplates {
return null; return null;
} }
private static class ClearBindingAction extends CPPASTVisitor {
public ObjectSet<IBinding> bindings = null;
public ClearBindingAction(ObjectSet<IBinding> 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) { public static boolean isSameTemplate(ICPPTemplateDefinition definition, IASTName name) {
ICPPTemplateParameter[] defParams = null; ICPPTemplateParameter[] defParams = null;
try { try {
@ -1222,24 +1166,9 @@ public class CPPTemplates {
if (defParams.length != templateParams.length) if (defParams.length != templateParams.length)
return false; return false;
// mstodo interesting side-effect, why not make this more explicit?
ObjectSet<IBinding> 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<IBinding>(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(); IASTNode parent = name.getParent();
if (parent instanceof ICPPASTFunctionDeclarator) { try {
try { if (parent instanceof ICPPASTFunctionDeclarator) {
IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) parent).getParameters(); IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) parent).getParameters();
IParameter[] ps = ((ICPPFunction) definition).getParameters(); IParameter[] ps = ((ICPPFunction) definition).getParameters();
if (ps.length == params.length) { if (ps.length == params.length) {
@ -1247,51 +1176,43 @@ public class CPPTemplates {
for (; i < ps.length; i++) { for (; i < ps.length; i++) {
IType t1 = CPPVisitor.createType(params[i].getDeclarator()); IType t1 = CPPVisitor.createType(params[i].getDeclarator());
IType t2 = ps[i].getType(); IType t2 = ps[i].getType();
if (! t1.isSameType(t2)) { if (!t1.isSameType(t2))
break; return false;
}
} }
if (i == ps.length) return true;
result = true;
} }
} catch (DOMException e) { return false;
} }
} else if (parent instanceof IASTDeclSpecifier) { if (parent instanceof IASTDeclSpecifier) {
if (name instanceof ICPPASTTemplateId) { if (name instanceof ICPPASTTemplateId) {
if (definition instanceof ICPPClassTemplatePartialSpecialization) { if (definition instanceof ICPPClassTemplatePartialSpecialization) {
ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition; ICPPClassTemplatePartialSpecialization spec = (ICPPClassTemplatePartialSpecialization) definition;
ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name); ICPPTemplateArgument[] args= createTemplateArgumentArray((ICPPASTTemplateId)name);
ICPPTemplateArgument[] specArgs = spec.getTemplateArguments(); ICPPTemplateArgument[] specArgs = spec.getTemplateArguments();
if (args.length == specArgs.length) { if (args.length == specArgs.length) {
result= true; for (int i=0; i < args.length; i++) {
for (int i=0; i < args.length; i++) { if (!specArgs[i].isSameValue(args[i]))
if (!specArgs[i].isSameValue(args[i])) { return false;
result= false;
break;
} }
} }
} }
return true;
} }
} else {
result = CharArrayUtils.equals(definition.getNameCharArray(), name.toCharArray()); return CharArrayUtils.equals(definition.getNameCharArray(), name.toCharArray());
} }
} catch (DOMException e) {
} }
return false;
// 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;
} }
/** /**
* @param id the template id containing the template arguments * @param id the template id containing the template arguments
* @return an array of template arguments, currently modeled as IType objects. The * @return an array of template arguments, currently modeled as IType objects. The
* empty IType array is returned if id is <code>null</code> * empty IType array is returned if id is <code>null</code>
* @throws DOMException
*/ */
static public ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) { static public ICPPTemplateArgument[] createTemplateArgumentArray(ICPPASTTemplateId id) throws DOMException {
ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS; ICPPTemplateArgument[] result= ICPPTemplateArgument.EMPTY_ARGUMENTS;
if (id != null) { if (id != null) {
IASTNode[] params= id.getTemplateArguments(); IASTNode[] params= id.getTemplateArguments();
@ -1299,12 +1220,8 @@ public class CPPTemplates {
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
IASTNode param= params[i]; IASTNode param= params[i];
IType type= CPPVisitor.createType(param); 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) if (type == null)
type= new CPPBasicType(-1, 0); throw new DOMException(new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TYPE, id.toCharArray()));
if (param instanceof IASTExpression) { if (param instanceof IASTExpression) {
IValue value= Value.create((IASTExpression) param, Value.MAX_RECURSION_DEPTH); IValue value= Value.create((IASTExpression) param, Value.MAX_RECURSION_DEPTH);
@ -1361,7 +1278,11 @@ public class CPPTemplates {
int numTemplateArgs = 0; int numTemplateArgs = 0;
ICPPTemplateArgument[] templateArguments = null; ICPPTemplateArgument[] templateArguments = null;
if (name instanceof ICPPASTTemplateId) { if (name instanceof ICPPASTTemplateId) {
templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name); try {
templateArguments = createTemplateArgumentArray((ICPPASTTemplateId) name);
} catch (DOMException e) {
return new IFunction[0];
}
numTemplateArgs = templateArguments.length; numTemplateArgs = templateArguments.length;
} }
@ -1829,16 +1750,16 @@ public class CPPTemplates {
* arguments of the partial specialization * arguments of the partial specialization
*/ */
static private ICPPFunctionTemplate classTemplateSpecializationToFunctionTemplate(ICPPClassTemplatePartialSpecialization 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 { 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); return new CPPImplicitFunctionTemplate(specialization.getTemplateParameters(), functionParameters);
} catch (DOMException e) { } catch (DOMException e) {
return null; return null;

View file

@ -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.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArrayType; 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.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplate;
@ -1032,7 +1033,7 @@ public class CPPVisitor {
} }
if (name != null) { if (name != null) {
name= name.getLastName(); name= name.getLastName();
IBinding binding = name.getBinding(); IBinding binding = CPPASTNameBase.getPreBinding(name);
if (binding == null) { if (binding == null) {
binding = CPPSemantics.resolveBinding(name); binding = CPPSemantics.resolveBinding(name);
name.setBinding(binding); name.setBinding(binding);
@ -1678,7 +1679,7 @@ public class CPPVisitor {
} }
} }
if (name != null) { if (name != null) {
IBinding binding = name.resolveBinding(); IBinding binding = CPPASTNameBase.resolvePreBinding(name);
if (binding instanceof ICPPConstructor) { if (binding instanceof ICPPConstructor) {
try { try {
type= ((ICPPConstructor) binding).getClassOwner(); type= ((ICPPConstructor) binding).getClassOwner();

View file

@ -55,7 +55,13 @@ public class TemplateInstanceUtil {
} }
public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { 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) { public static IBinding getSpecializedBinding(ICompositesFactory cf, IIndexBinding rbinding) {

View file

@ -169,6 +169,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
partial.setArguments(args); partial.setArguments(args);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} catch (DOMException e) {
CCorePlugin.log(e);
} finally { } finally {
partial = null; partial = null;
binding = null; binding = null;

View file

@ -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.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; 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.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.Util; 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.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
@ -112,23 +112,10 @@ class PDOMCPPTemplateTypeParameter extends PDOMCPPBinding implements IPDOMMember
return type.isSameType(this); return type.isSameType(this);
} }
if (type instanceof PDOMNode) { if (!(type instanceof ICPPTemplateTypeParameter))
PDOMNode node= (PDOMNode) type; return false;
if (node.getPDOM() == getPDOM()) {
return node.getRecord() == getRecord();
}
}
if (type instanceof ICPPTemplateTypeParameter && !(type instanceof ProblemBinding)) { return getParameterPosition() == ((ICPPTemplateParameter) type).getParameterPosition();
ICPPTemplateTypeParameter ttp= (ICPPTemplateTypeParameter) type;
try {
char[][] ttpName= ttp.getQualifiedNameCharArray();
return hasQualifiedName(ttpName, ttpName.length - 1);
} catch (DOMException e) {
CCorePlugin.log(e);
}
}
return false;
} }
public IType getDefault() { public IType getDefault() {

View file

@ -112,11 +112,15 @@ public class IndexLabelProvider extends LabelProvider {
StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$
buffer.append(result); buffer.append(result);
buffer.append('<'); buffer.append('<');
ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments(); try {
for (int i = 0; i < types.length; i++) { ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments();
if (i > 0) for (int i = 0; i < types.length; i++) {
buffer.append(','); if (i > 0)
buffer.append(ASTTypeUtil.getArgumentString(types[i], false)); buffer.append(',');
buffer.append(ASTTypeUtil.getArgumentString(types[i], false));
}
} catch (DOMException e) {
buffer.append(e.getProblem().toString());
} }
buffer.append('>'); buffer.append('>');
result = buffer.toString(); result = buffer.toString();