/** * 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; }
@Override public IBinding[] getBindings(ScopeLookupData lookup) { try { if (lookup.getLookupName() instanceof ICPPASTConversionName) { BindingCollector visitor = new BindingCollector( fBinding.getLinkage(), Keywords.cOPERATOR, CONVERSION_FILTER, true, false, true); acceptViaCache(fBinding, visitor, true); return visitor.getBindings(); } final char[] nameChars = lookup.getLookupKey(); if (!lookup.isPrefixLookup()) { if (CharArrayUtils.equals(fBinding.getNameCharArray(), nameChars)) { if (CPPClassScope.shallReturnConstructors(lookup.getLookupName(), false)) { return ClassTypeHelper.getConstructors(fBinding, lookup.getLookupPoint()); } return new IBinding[] {getClassNameBinding()}; } return getBindingsViaCache( fBinding, nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE); } // Prefix lookup. BindingCollector visitor = new BindingCollector( fBinding.getLinkage(), nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, true, true, false); if (ContentAssistMatcherFactory.getInstance().match(nameChars, fBinding.getNameCharArray())) { // Add the class itself, constructors will be found during the visit. visitor.visit((IPDOMNode) getClassNameBinding()); } acceptViaCache(fBinding, visitor, true); return visitor.getBindings(); } catch (CoreException e) { CCorePlugin.log(e); } return null; }