diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 963cc56d81f..eb29a01bdb6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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 D { //CPPClassTemplate // public: @@ -3822,4 +3822,14 @@ public class AST2TemplateTests extends AST2BaseTest { String code= getAboveComment(); parseAndCheckBindings(code, ParserLanguage.CPP); } + + // template 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); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index cc7ee905811..a311cb41942 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -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 class XT { + // int f; + // void m(); + // }; + + // template void XT::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 class XT; + + // #include "header.h" + // template class XT {}; + // void test() { + // XT<> x; + // }; + public void testDefaultTemplateArgInHeader_264988() throws Exception { + ICPPTemplateInstance ti= getBindingFromASTName("XT<>", 4, ICPPTemplateInstance.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java index e767d490987..081f8a203ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassTemplate.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index 4df8c4e5308..16cd40ad9dc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -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); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java index 343dd9e949e..724f7901936 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java index 1c5500d1751..199f438deae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -102,4 +102,8 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization } return fDeferredInstance; } + + public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index e0e1a8e7ff8..725dcb6c740 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -199,4 +199,8 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement public boolean isAnonymous() { return false; } + + public ICPPDeferredClassInstance asDeferredInstance() { + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTemplate.java index 4358b9e4887..eef7ec92159 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalClassTemplate.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 0c80c898896..b5920819ac4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -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 getAssociatedScopes(LookupData data) { - IType[] ps = getSourceParameterTypes(data.functionParameters); + IType[] ps = getArgumentTypes(data.functionParameters); ObjectSet namespaces = new ObjectSet(2); ObjectSet classes = new ObjectSet(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; jnull. */ 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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index ea1d5e065db..cf1db4e1894 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -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() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java index a294b9a8c63..0ce421a673d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplate.java @@ -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()); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java index 4b26642bda8..9021844388d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplatePartialSpecializationSpecialization.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplateSpecialization.java index 8f32da43c07..cfea0aa6729 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassTemplateSpecialization.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java index c5101fda7f8..c551bbe11f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java index 192bc042948..e2b54c62884 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java index f9cc46853be..55dd9cf6963 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeInstanceCache.java @@ -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 fMap; + private ICPPDeferredClassInstance fDeferredInstance; public CompositeInstanceCache() { fMap= new HashMap(); @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index cea5cdd5b9c..a3dc58103f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -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()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java index d1d24d95149..4799d04b1a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplate.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java index 86cb78e5d98..5f4a38a7055 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java @@ -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()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index f8c109d6939..83652a91718 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java index a6a7bfeb2f1..59fedca0352 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java @@ -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; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMInstanceCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMInstanceCache.java index 66eb1e0346d..20e0c895d96 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMInstanceCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMInstanceCache.java @@ -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 fMap; + private ICPPDeferredClassInstance fDeferredInstance; public PDOMInstanceCache() { fMap= new HashMap(); @@ -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; + } }