/** * Attempts to resolve the function using the parameters of a function call. * * @param args the arguments of a function call * @param point the name lookup context * @return the resolved or the original evaluation depending on whether function resolution * succeeded or not */ public ICPPEvaluation resolveFunction(ICPPEvaluation[] args, IASTNode point) { // Set up the LookupData. LookupData data; ICPPFunction[] functions = null; if (fFunctionSet == null) { data = new LookupData(fName, null, point); } else { functions = fFunctionSet.getBindings(); data = new LookupData( functions[0].getNameCharArray(), fFunctionSet.getTemplateArguments(), point); data.foundItems = functions; } data.setFunctionArguments(false, args); if (fImpliedObjectType != null) data.setImpliedObjectType(fImpliedObjectType); try { // Perform ADL if appropriate. if (!fQualified && fImpliedObjectType == null && !data.hasTypeOrMemberFunctionOrVariableResult()) { CPPSemantics.doKoenigLookup(data); Object[] foundItems = (Object[]) data.foundItems; if (foundItems != null && (functions == null || foundItems.length > functions.length)) { // ADL found additional functions. int start = functions == null ? 0 : functions.length; for (int i = start; i < foundItems.length; i++) { Object obj = foundItems[i]; if (obj instanceof ICPPFunction) { functions = ArrayUtil.append(ICPPFunction.class, functions, (ICPPFunction) obj); } else if (obj instanceof ICPPClassType) { functions = ArrayUtil.addAll( ICPPFunction.class, functions, ClassTypeHelper.getConstructors((ICPPClassType) obj, point)); } } // doKoenigLookup() may introduce duplicates into the result. These must be // eliminated to avoid resolveFunction() reporting an ambiguity. (Normally, when // lookup() and doKoenigLookup() are called on the same LookupData object, the // two functions coordinate using data stored in that object to eliminate // duplicates, but in this case lookup() was called before with a different // LookupData object and now we are only calling doKoenigLookup()). functions = ArrayUtil.removeDuplicates(functions); } } // Perform template instantiation and overload resolution. IBinding binding = CPPSemantics.resolveFunction(data, functions, true); if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding)) return new EvalBinding(binding, null, getTemplateDefinition()); } catch (DOMException e) { CCorePlugin.log(e); } return this; }
private Collection<IBinding> cppRemoveSecondaryBindings( Set<IBinding> primaryBindings, IASTName sourceName) { List<IBinding> result = new ArrayList<IBinding>(); String[] sourceQualifiedName = null; int funcArgCount = -1; if (sourceName != null) { final IBinding binding = sourceName.resolveBinding(); if (binding != null) { sourceQualifiedName = CPPVisitor.getQualifiedName(binding); if (binding instanceof ICPPUnknownBinding) { LookupData data = CPPSemantics.createLookupData(sourceName); if (data.isFunctionCall()) { funcArgCount = data.getFunctionArgumentCount(); } } } } for (Iterator<IBinding> iterator = primaryBindings.iterator(); iterator.hasNext(); ) { IBinding binding = iterator.next(); if (sourceQualifiedName != null) { String[] qualifiedName = CPPVisitor.getQualifiedName(binding); if (!Arrays.equals(qualifiedName, sourceQualifiedName)) { iterator.remove(); continue; } } if (funcArgCount != -1) { // For c++ we can check the number of parameters. if (binding instanceof ICPPFunction) { ICPPFunction f = (ICPPFunction) binding; if (f.getRequiredArgumentCount() > funcArgCount) { iterator.remove(); result.add(binding); continue; } if (!f.takesVarArgs() && !f.hasParameterPack()) { final IType[] parameterTypes = f.getType().getParameterTypes(); int maxArgs = parameterTypes.length; if (maxArgs == 1 && SemanticUtil.isVoidType(parameterTypes[0])) { maxArgs = 0; } if (maxArgs < funcArgCount) { iterator.remove(); result.add(binding); continue; } } } } } return result; }
private ICPPClassType getFirstCandidateForNamingClass(IASTName name) throws DOMException { LookupData data = new LookupData(name); isUnqualifiedLookup = !data.qualified(); ICPPScope scope = CPPSemantics.getLookupScope(name, data); while (scope != null && !(scope instanceof ICPPClassScope)) { scope = CPPSemantics.getParentScope(scope, data.tu); } if (scope instanceof ICPPClassScope) { return ((ICPPClassScope) scope).getClassType(); } return null; }