1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Name resolution problems, bug 264988.

This commit is contained in:
Markus Schorn 2009-02-16 09:37:36 +00:00
parent d3ad2ee3d7
commit edc5df6d66
23 changed files with 456 additions and 177 deletions

View file

@ -2222,7 +2222,7 @@ public class AST2TemplateTests extends AST2BaseTest {
bh.assertNonProblem("f(a(x));", 1, ICPPFunction.class);
}
// // Brian W.'s example from bugzilla#167098
// // Brian W.'s example from bugzilla#167098
// template<class K>
// class D { //CPPClassTemplate
// public:
@ -3822,4 +3822,14 @@ public class AST2TemplateTests extends AST2BaseTest {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// template <typename T> class XT {
// void m(T t) {
// m(0); // ok with a conversion from 0 to T
// }
// };
public void testUnknownParameter_264988() throws Exception {
String code= getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2009 Symbian Software Systems 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
@ -56,6 +56,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecializationScope;
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.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.index.IIndexScope;
@ -1540,4 +1541,39 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
ICPPClassType owner= m.getClassOwner();
assertInstance(owner, ICPPClassTemplatePartialSpecialization.class);
}
// template<typename T> class XT {
// int f;
// void m();
// };
// template<typename T> void XT<T>::m() {
// m(); // 1
// f; // 1
// this->m(); // 2
// this->f; // 2
// };
public void testUnknownBindings_Bug264988() throws Exception {
ICPPMethod m= getBindingFromASTName("m(); // 1", 1, ICPPMethod.class);
assertFalse(m instanceof ICPPUnknownBinding);
m= getBindingFromASTName("m(); // 2", 1, ICPPMethod.class);
assertFalse(m instanceof ICPPUnknownBinding);
ICPPField f= getBindingFromASTName("f; // 1", 1, ICPPField.class);
assertFalse(f instanceof ICPPUnknownBinding);
f= getBindingFromASTName("f; // 2", 1, ICPPField.class);
assertFalse(f instanceof ICPPUnknownBinding);
}
// template <typename T= int> class XT;
// #include "header.h"
// template <typename T> class XT {};
// void test() {
// XT<> x;
// };
public void testDefaultTemplateArgInHeader_264988() throws Exception {
ICPPTemplateInstance ti= getBindingFromASTName("XT<>", 4, ICPPTemplateInstance.class);
}
}

View file

@ -19,4 +19,10 @@ import org.eclipse.cdt.core.dom.ast.DOMException;
*/
public interface ICPPClassTemplate extends ICPPTemplateDefinition, ICPPClassType {
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() throws DOMException;
/**
* Returns a deferred instance that allows lookups within this class template.
* @since 5.1
*/
public ICPPTemplateInstance asDeferredInstance() throws DOMException;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* Copyright (c) 2005, 2009 IBM Corporation 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
@ -21,8 +21,10 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
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.cpp.CPPASTVisitor;
@ -40,6 +42,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -53,11 +57,15 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
ICPPClassTemplate, ICPPClassType, ICPPInternalClassTemplate,
ICPPInternalClassTypeMixinHost {
private ICPPClassTemplate fIndexBinding= null;
private boolean checkedIndex= false;
private boolean checkedDefinition= false;
private class FindDefinitionAction extends CPPASTVisitor {
private char[] nameArray = CPPClassTemplate.this.getNameCharArray();
public IASTName result = null;
{
FindDefinitionAction() {
shouldVisitNames = true;
shouldVisitDeclarations = true;
shouldVisitDeclSpecifiers = true;
@ -110,6 +118,13 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
}
public void checkForDefinition() {
if (checkedDefinition)
return;
checkedDefinition= true;
if (definition != null)
return;
FindDefinitionAction action = new FindDefinitionAction();
IASTNode node = CPPVisitor.getContainingBlockItem(declarations[0]).getParent();
while (node instanceof ICPPASTTemplateDeclaration)
@ -121,8 +136,6 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
node.getTranslationUnit().accept(action);
definition = action.result;
}
return;
}
public void addPartialSpecialization(ICPPClassTemplatePartialSpecialization spec) {
@ -154,6 +167,18 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
return compSpec.getScope();
}
}
// Forward declarations must be backed up from the index.
checkForIndexBinding();
if (fIndexBinding != null) {
try {
IScope scope = fIndexBinding.getCompositeScope();
if (scope instanceof ICPPClassScope)
return (ICPPClassScope) scope;
} catch (DOMException e) {
// index bindings don't throw DOMExeptions.
}
}
return null;
}
@ -264,4 +289,33 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
checkForIndexBinding();
if (fIndexBinding != null) {
ICPPTemplateParameter[] params = fIndexBinding.getTemplateParameters();
if (paramPos < params.length) {
ICPPTemplateParameter param = params[paramPos];
return param.getDefaultValue();
}
}
return null;
}
private void checkForIndexBinding() {
if (checkedIndex)
return;
checkedIndex= true;
IASTTranslationUnit tu;
if (definition != null) {
tu= definition.getTranslationUnit();
} else {
tu= declarations[0].getTranslationUnit();
}
IIndex index= tu.getIndex();
if (index != null) {
fIndexBinding= (ICPPClassTemplate) index.adaptBinding(this);
}
}
}

View file

@ -122,4 +122,9 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
public IType[] getArguments() throws DOMException {
return CPPTemplates.getArguments(getTemplateArguments());
}
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
// no default arguments for partial specializations
return null;
}
}

View file

@ -102,4 +102,8 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
}
return fDeferredInstance;
}
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
return null;
}
}

View file

@ -199,4 +199,8 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
public boolean isAnonymous() {
return false;
}
public ICPPDeferredClassInstance asDeferredInstance() {
return null;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation and others.
* Copyright (c) 2007, 2009 IBM Corporation 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
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
/**
* Interface for class templates used in the AST.
@ -24,4 +25,10 @@ public interface ICPPInternalClassTemplate extends ICPPInternalTemplate {
* Returns a deferred instance that allows lookups within this class template.
*/
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException;
/**
* Tries to obtain a default argument for a template parameter from the index.
* @throws DOMException
*/
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException;
}

View file

@ -185,6 +185,10 @@ public class CPPSemantics {
public static boolean traceBindingResolution = false;
public static int traceIndent= 0;
// special return value for costForFunctionCall
private static final Cost[] CONTAINS_DEPENDENT_TYPES = {};
static protected IBinding resolveBinding(IASTName name) {
if (traceBindingResolution) {
for (int i = 0; i < traceIndent; i++)
@ -518,7 +522,7 @@ public class CPPSemantics {
}
static private ObjectSet<IScope> getAssociatedScopes(LookupData data) {
IType[] ps = getSourceParameterTypes(data.functionParameters);
IType[] ps = getArgumentTypes(data.functionParameters);
ObjectSet<IScope> namespaces = new ObjectSet<IScope>(2);
ObjectSet<ICPPClassType> classes = new ObjectSet<ICPPClassType>(2);
for (IType p : ps) {
@ -1857,7 +1861,7 @@ public class CPPSemantics {
if (def && numArgs == 1) {
// check for parameter of type void
IType[] argTypes= getSourceParameterTypes(funcArgs);
IType[] argTypes= getArgumentTypes(funcArgs);
if (argTypes.length == 1) {
IType t= getNestedType(argTypes[0], TDEF);
if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
@ -1925,25 +1929,25 @@ public class CPPSemantics {
return false;
}
static private IType[] getSourceParameterTypes(Object[] params) {
if (params instanceof IType[]) {
return (IType[]) params;
static private IType[] getArgumentTypes(Object[] args) {
if (args instanceof IType[]) {
return (IType[]) args;
}
if (params == null || params.length == 0)
return new IType[] { VOID_TYPE };
if (args == null || args.length == 0)
return IType.EMPTY_TYPE_ARRAY;
if (params instanceof IASTExpression[]) {
IASTExpression[] exps = (IASTExpression[]) params;
if (args instanceof IASTExpression[]) {
IASTExpression[] exps = (IASTExpression[]) args;
IType[] result = new IType[exps.length];
for (int i = 0; i < exps.length; i++) {
result[i] = exps[i].getExpressionType();
}
return result;
} else if (params instanceof IASTParameterDeclaration[]) {
IASTParameterDeclaration[] decls = (IASTParameterDeclaration[]) params;
} else if (args instanceof IASTParameterDeclaration[]) {
IASTParameterDeclaration[] decls = (IASTParameterDeclaration[]) args;
IType[] result = new IType[decls.length];
for (int i = 0; i < params.length; i++) {
for (int i = 0; i < args.length; i++) {
result[i] = CPPVisitor.createType(decls[i].getDeclarator());
}
return result;
@ -1951,26 +1955,6 @@ public class CPPSemantics {
return null;
}
static private IType[] getTargetParameterTypes(IFunction fn) throws DOMException{
final ICPPFunctionType ftype = (ICPPFunctionType) fn.getType();
if (ftype == null)
return IType.EMPTY_TYPE_ARRAY;
final IType[] ptypes= ftype.getParameterTypes();
if (fn instanceof ICPPMethod == false || fn instanceof ICPPConstructor)
return ptypes;
final IType[] result = new IType[ptypes.length + 1];
System.arraycopy(ptypes, 0, result, 1, ptypes.length);
ICPPClassType owner= ((ICPPMethod) fn).getClassOwner();
if (owner instanceof ICPPClassTemplate) {
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
}
IType implicitType= SemanticUtil.addQualifiers(owner, ftype.isConst(), ftype.isVolatile());
result[0]= new CPPReferenceType(implicitType);
return result;
}
static IBinding resolveFunction(LookupData data, IFunction[] fns, boolean allowUDC) throws DOMException {
fns= (IFunction[]) ArrayUtil.trim(IFunction.class, fns);
if (fns == null || fns.length == 0)
@ -2008,110 +1992,56 @@ public class CPPSemantics {
}
}
}
if (firstViable == null)
return null;
if (data.forFunctionDeclaration())
if (firstViable == null || data.forFunctionDeclaration())
return firstViable;
// The parameters the function is being called with
final IType[] sourceParameters = getSourceParameterTypes(data.functionParameters);
if (CPPTemplates.containsDependentType(sourceParameters)) {
// The arguments the function is being called with
final Object[] args= data.functionParameters;
final IType[] argTypes = getArgumentTypes(data.functionParameters);
if (CPPTemplates.containsDependentType(argTypes)) {
if (viableCount == 1)
return firstViable;
return CPPUnknownFunction.createForSample(firstViable, data.astName);
}
IFunction bestFn = null; // the best function
IFunction currFn = null; // the function currently under consideration
Cost[] bestFnCost = null; // the cost of the best function
Cost[] currFnCost = null; // the cost for the current function
IASTExpression sourceExp;
IType source = null; // parameter we are called with
IType target = null; // function's parameter
int comparison;
Cost cost = null; // the cost of converting source to target
boolean hasWorse = false; // currFn has a worse parameter fit than bestFn
boolean hasBetter = false; // currFn has a better parameter fit than bestFn
boolean ambiguous = false; // ambiguity, 2 functions are equally good
boolean currHasAmbiguousParam = false; // currFn has an ambiguous parameter conversion (ok if not bestFn)
IFunction bestFn = null; // the best function
Cost[] bestFnCost = null; // the cost of the best function
boolean bestHasAmbiguousParam = false; // bestFn has an ambiguous parameter conversion (not ok, ambiguous)
final boolean sourceVoid = (data.functionParameters == null || data.functionParameters.length == 0);
final IType impliedObjectType = data.getImpliedObjectArgument();
final IType thisType = data.getImpliedObjectArgument();
// Loop over all functions
function_loop: for (int fnIdx = 0; fnIdx < fns.length; fnIdx++) {
currFn= fns[fnIdx];
if (currFn == null || bestFn == currFn) {
for (IFunction fn : fns) {
if (fn == null || bestFn == fn)
continue;
final Cost[] fnCost= costForFunctionCall(fn, thisType, argTypes, args, allowUDC);
if (fnCost == null)
continue;
if (fnCost == CONTAINS_DEPENDENT_TYPES) {
if (viableCount == 1)
return firstViable;
return CPPUnknownFunction.createForSample(firstViable, data.astName);
}
if (bestFnCost == null) {
bestFnCost= fnCost;
bestFn= fn;
continue;
}
final IType[] targetParameters = getTargetParameterTypes(currFn);
final int useImplicitObj = (currFn instanceof ICPPMethod && !(currFn instanceof ICPPConstructor)) ? 1 : 0;
final int sourceLen= Math.max(sourceParameters.length + useImplicitObj, 1);
if (currFnCost == null || currFnCost.length != sourceLen) {
currFnCost= new Cost[sourceLen];
}
boolean varArgs = false;
boolean isImpliedObject= false;
for (int j = 0; j < sourceLen; j++) {
if (useImplicitObj > 0) {
isImpliedObject= (j == 0);
source= isImpliedObject ? impliedObjectType : sourceParameters[j - 1];
Object se= isImpliedObject || data.functionParameters.length == 0 ? null : data.functionParameters[j - 1];
sourceExp= se instanceof IASTExpression ? (IASTExpression) se : null;
} else {
source = sourceParameters[j];
Object se= data.functionParameters.length == 0 ? null : data.functionParameters[j];
sourceExp= se instanceof IASTExpression ? (IASTExpression) se : null;
}
if (j < targetParameters.length) {
target = targetParameters[j];
} else if (currFn.takesVarArgs()) {
varArgs = true;
} else {
target = VOID_TYPE;
}
if (isImpliedObject && ASTInternal.isStatic(currFn, false)) {
// 13.3.1-4 for static member functions, the implicit object parameter is
// considered to match any object
cost = new Cost(source, target);
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
} else if (source == null) {
continue function_loop;
} else if (varArgs) {
cost = new Cost(source, null);
cost.rank = Cost.ELLIPSIS_CONVERSION;
} else if (source.isSameType(target) || (sourceVoid && j == useImplicitObj)) {
cost = new Cost(source, target);
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
} else {
cost= Conversions.checkImplicitConversionSequence(sourceExp,
source, target, allowUDC, isImpliedObject);
}
if (cost.rank < 0)
continue function_loop;
currFnCost[j] = cost;
}
hasWorse = false;
hasBetter = false;
boolean hasWorse = false;
boolean hasBetter = false;
boolean hasAmbiguousParam= false;
// In order for this function to be better than the previous best, it must
// have at least one parameter match that is better that the corresponding
// match for the other function, and none that are worse.
int len = (bestFnCost == null || currFnCost.length < bestFnCost.length) ? currFnCost.length : bestFnCost.length;
int len = Math.min(fnCost.length, bestFnCost.length);
for (int j = 1; j <= len; j++) {
Cost currCost = currFnCost[currFnCost.length - j];
Cost currCost = fnCost[fnCost.length - j];
if (currCost.rank < 0) {
hasWorse = true;
hasBetter = false;
@ -2120,54 +2050,53 @@ public class CPPSemantics {
// An ambiguity in the user defined conversion sequence is only a problem
// if this function turns out to be the best.
currHasAmbiguousParam = (currCost.userDefined == 1);
if (currCost.userDefined == Cost.AMBIGUOUS_USERDEFINED_CONVERSION)
hasAmbiguousParam = true;
if (bestFnCost != null) {
comparison = currCost.compare(bestFnCost[bestFnCost.length - j]);
int comparison = currCost.compare(bestFnCost[bestFnCost.length - j]);
hasWorse |= (comparison < 0);
hasBetter |= (comparison > 0);
} else {
hasBetter = true;
}
}
if (!hasWorse && !hasBetter) {
// If they are both template functions, we can order them that way
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
ICPPFunctionTemplate currAsTemplate= asTemplate(fn);
final boolean bestIsTemplate = bestAsTemplate != null;
final boolean currIsTemplate = currAsTemplate != null;
if (bestIsTemplate && currIsTemplate) {
int order = CPPTemplates.orderTemplateFunctions(bestAsTemplate, currAsTemplate);
if (order < 0) {
hasBetter= true;
} else if (order > 0) {
hasWorse= true;
}
} else if (bestIsTemplate != currIsTemplate) {
// We prefer normal functions over template functions, unless we specified template arguments
if (data.preferTemplateFunctions() == bestIsTemplate)
hasWorse = true;
else
hasBetter = true;
}
}
// If function has a parameter match that is better than the current best,
// and another that is worse (or everything was just as good, neither better nor worse),
// then this is an ambiguity (unless we find something better than both later).
ambiguous |= (hasWorse && hasBetter) || (!hasWorse && !hasBetter);
// mstodo if ambiguous ??
if (!hasWorse) {
// If they are both template functions, we can order them that way
ICPPFunctionTemplate bestAsTemplate= asTemplate(bestFn);
ICPPFunctionTemplate currAsTemplate= asTemplate(currFn);
if (bestAsTemplate != null && currAsTemplate != null) {
int order = CPPTemplates.orderTemplateFunctions(bestAsTemplate, currAsTemplate);
if (order < 0) {
hasBetter = true;
} else if (order > 0) {
ambiguous = false;
}
} else if (bestAsTemplate != null) {
// We prefer normal functions over template functions, unless we specified template arguments
if (data.preferTemplateFunctions())
ambiguous = false;
else
hasBetter = true;
} else if (currAsTemplate != null) {
if (data.preferTemplateFunctions())
hasBetter = true;
else
ambiguous = false;
}
if (hasBetter) {
// The new best function.
ambiguous = false;
bestFnCost = currFnCost;
bestHasAmbiguousParam = currHasAmbiguousParam;
currFnCost = null;
bestFn = currFn;
}
}
if (hasBetter == hasWorse) {
ambiguous= true;
// here we would need to store the costs to compare to a function that is better later on.
} else if (hasBetter && !hasWorse) {
bestFn= fn;
bestFnCost= fnCost;
bestHasAmbiguousParam= hasAmbiguousParam;
ambiguous= false;
// here we would have to compare to the functions that were previously ambiguous.
}
}
if (ambiguous || bestHasAmbiguousParam) {
@ -2177,6 +2106,94 @@ public class CPPSemantics {
return bestFn;
}
private static Cost[] costForFunctionCall(IFunction fn, IType thisType, IType[] argTypes, Object[] args,
boolean allowUDC) throws DOMException {
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
if (ftype == null)
return null;
IType implicitType= null;
final IType[] paramTypes= ftype.getParameterTypes();
if (fn instanceof ICPPMethod && !(fn instanceof ICPPConstructor)) {
implicitType = getImplicitType((ICPPMethod) fn, ftype.isConst(), ftype.isVolatile());
}
int k= 0;
Cost cost;
final int sourceLen= argTypes.length;
final Cost[] result;
if (implicitType == null) {
result= new Cost[sourceLen];
} else {
result= new Cost[sourceLen+1];
if (ASTInternal.isStatic(fn, false)) {
// 13.3.1-4 for static member functions, the implicit object parameter always matches
cost = new Cost(thisType, implicitType);
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
} else if (thisType == null) {
return null;
} else if (thisType.isSameType(implicitType)) {
cost = new Cost(thisType, implicitType);
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
} else {
if (CPPTemplates.isDependentType(implicitType))
return CONTAINS_DEPENDENT_TYPES;
cost = Conversions.checkImplicitConversionSequence(null, thisType, implicitType, false, true);
}
if (cost.rank < 0)
return null;
result[k++] = cost;
}
for (int j=0; j<sourceLen; j++) {
final IType argType= argTypes[j];
final Object arg= j < args.length ? args[j] : null;
final IASTExpression argExpr= (arg instanceof IASTExpression) ? (IASTExpression) arg : null;
if (argType == null)
return null;
IType paramType;
if (j < paramTypes.length) {
paramType= paramTypes[j];
} else if (!fn.takesVarArgs()) {
paramType= VOID_TYPE;
} else {
cost = new Cost(argType, null);
cost.rank = Cost.ELLIPSIS_CONVERSION;
result[k++]= cost;
continue;
}
if (argType.isSameType(paramType)) {
cost = new Cost(argType, paramType);
cost.rank = Cost.IDENTITY_RANK; // exact match, no cost
} else {
if (CPPTemplates.isDependentType(paramType))
return CONTAINS_DEPENDENT_TYPES;
cost = Conversions.checkImplicitConversionSequence(argExpr, argType, paramType, allowUDC, false);
}
if (cost.rank < 0)
return null;
result[k++] = cost;
}
return result;
}
private static IType getImplicitType(ICPPMethod m, final boolean isConst, final boolean isVolatile)
throws DOMException {
IType implicitType;
ICPPClassType owner= m.getClassOwner();
if (owner instanceof ICPPClassTemplate) {
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner);
}
implicitType= SemanticUtil.addQualifiers(owner, isConst, isVolatile);
implicitType= new CPPReferenceType(implicitType);
return implicitType;
}
private static IBinding resolveUserDefinedConversion(ICPPASTConversionName astName, IFunction[] fns) {
IType t= CPPVisitor.createType(astName.getTypeId());
if (t == null) {

View file

@ -175,7 +175,11 @@ public class CPPTemplates {
} else {
ICPPTemplateArgument defaultArg= param.getDefaultValue();
if (defaultArg == null) {
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
if (template instanceof ICPPInternalClassTemplate) {
defaultArg= ((ICPPInternalClassTemplate) template).getDefaultArgFromIndex(i);
}
if (defaultArg == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
}
arg= instantiateArgument(defaultArg, map, null);
arg= SemanticUtil.getSimplifiedArgument(arg);
@ -358,9 +362,9 @@ public class CPPTemplates {
* Instantiates the template for usage within its own body. May return <code>null</code>.
*/
public static ICPPClassType instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
if (template instanceof ICPPInternalClassTemplate) {
return ((ICPPInternalClassTemplate) template).asDeferredInstance();
}
ICPPTemplateInstance di= template.asDeferredInstance();
if (di instanceof ICPPClassType)
return (ICPPClassType) di;
ICPPTemplateArgument[] args;
if (template instanceof ICPPClassTemplatePartialSpecialization) {

View file

@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
@ -43,8 +44,8 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
}
@Override
public IScope getCompositeScope() throws DOMException {
return cf.getCompositeScope((IIndexScope) ((ICPPClassType) rbinding).getCompositeScope());
public ICPPClassScope getCompositeScope() throws DOMException {
return (ICPPClassScope) cf.getCompositeScope((IIndexScope) ((ICPPClassType) rbinding).getCompositeScope());
}
public ICPPClassType getSpecializedBinding() {

View file

@ -20,7 +20,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.CIndex;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
@ -71,4 +74,22 @@ public class CompositeCPPClassTemplate extends CompositeCPPClassType
public ICPPTemplateInstance[] getAllInstances() {
return CompositeInstanceCache.getCache(cf, rbinding).getAllInstances();
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) {
dci= createDeferredInstance();
cache.putDeferredInstance(dci);
}
return dci;
}
}
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
}

View file

@ -18,7 +18,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSp
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
@ -57,6 +60,23 @@ public class CompositeCPPClassTemplatePartialSpecializationSpecialization extend
return TemplateInstanceUtil.getTemplateArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding);
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) {
dci= createDeferredInstance();
cache.putDeferredInstance(dci);
}
return dci;
}
}
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
@Deprecated
public IType[] getArguments() {
return TemplateInstanceUtil.getArguments(cf, (ICPPClassTemplatePartialSpecialization) rbinding);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2009 Symbian Software Systems 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
@ -18,7 +18,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
@ -53,4 +56,22 @@ CompositeCPPClassSpecialization implements ICPPClassTemplate, ICPPInstanceCache{
public ICPPTemplateInstance[] getAllInstances() {
return CompositeInstanceCache.getCache(cf, rbinding).getAllInstances();
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) {
dci= createDeferredInstance();
cache.putDeferredInstance(dci);
}
return dci;
}
}
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2009 Symbian Software Systems 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
@ -15,13 +15,13 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexType;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
@ -163,7 +163,7 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
return result;
}
public IScope getCompositeScope() throws DOMException {
public ICPPScope getCompositeScope() throws DOMException {
return new CompositeCPPClassScope(cf, rbinding);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Symbian Software Systems and others.
* Copyright (c) 2007, 2009 Symbian Software Systems 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
@ -28,6 +28,7 @@ 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.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexType;
@ -146,4 +147,8 @@ public class CompositeCPPTemplateTemplateParameter extends CompositeCPPBinding
public boolean isAnonymous() {
return false;
}
public ICPPDeferredClassInstance asDeferredInstance() {
return null;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 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
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
@ -39,6 +40,7 @@ public class CompositeInstanceCache {
}
private final HashMap<String, ICPPTemplateInstance> fMap;
private ICPPDeferredClassInstance fDeferredInstance;
public CompositeInstanceCache() {
fMap= new HashMap<String, ICPPTemplateInstance>();
@ -81,4 +83,12 @@ public class CompositeInstanceCache {
synchronized public ICPPTemplateInstance[] getAllInstances() {
return fMap.values().toArray(new ICPPTemplateInstance[fMap.size()]);
}
public ICPPDeferredClassInstance getDeferredInstance() {
return fDeferredInstance;
}
public void putDeferredInstance(ICPPDeferredClassInstance dci) {
fDeferredInstance= dci;
}
}

View file

@ -131,7 +131,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
return newSpec;
}
public IScope getCompositeScope() throws DOMException {
public ICPPClassScope getCompositeScope() {
if (fScope == null) {
try {
if (hasDefinition()) {

View file

@ -33,7 +33,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@ -296,4 +299,21 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
}
return null;
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
PDOMInstanceCache cache= PDOMInstanceCache.getCache(this);
synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) {
dci= createDeferredInstance();
cache.putDeferredInstance(dci);
}
return dci;
}
}
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
}

View file

@ -29,7 +29,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
@ -185,4 +188,21 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
return new PDOMCPPClassTemplatePartialSpecializationSpecialization[0];
}
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
PDOMInstanceCache cache= PDOMInstanceCache.getCache(this);
synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) {
dci= createDeferredInstance();
cache.putDeferredInstance(dci);
}
return dci;
}
}
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
}

View file

@ -24,7 +24,6 @@ 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.IField;
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.cpp.ICPPBase;
@ -220,7 +219,7 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
}
}
public IScope getCompositeScope() throws DOMException {
public ICPPClassScope getCompositeScope() throws DOMException {
if (fScope == null) {
fScope= new PDOMCPPClassScope(this);
}

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
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.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
@ -344,4 +345,8 @@ public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding
}
return null;
}
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException {
return null;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 2009 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
@ -16,6 +16,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.NamedNodeCollector;
@ -47,6 +48,7 @@ public class PDOMInstanceCache {
}
private final HashMap<String, ICPPTemplateInstance> fMap;
private ICPPDeferredClassInstance fDeferredInstance;
public PDOMInstanceCache() {
fMap= new HashMap<String, ICPPTemplateInstance>();
@ -95,4 +97,12 @@ public class PDOMInstanceCache {
synchronized public ICPPTemplateInstance[] getAllInstances() {
return fMap.values().toArray(new ICPPTemplateInstance[fMap.size()]);
}
public ICPPDeferredClassInstance getDeferredInstance() {
return fDeferredInstance;
}
public void putDeferredInstance(ICPPDeferredClassInstance dci) {
fDeferredInstance= dci;
}
}