@Override public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { short firstBytes = ITypeMarshalBuffer.EVAL_FUNCTION_SET; if (fQualified) firstBytes |= FLAG_QUALIFIED; if (fAddressOf) firstBytes |= FLAG_ADDRESS_OF; if (fFunctionSet != null) { firstBytes |= FLAG_HAS_FUNCTION_SET; final ICPPFunction[] bindings = fFunctionSet.getBindings(); final ICPPTemplateArgument[] args = fFunctionSet.getTemplateArguments(); if (args != null) firstBytes |= FLAG_HAS_TEMPLATE_ARGS; buffer.putShort(firstBytes); buffer.putInt(bindings.length); for (ICPPFunction binding : bindings) { buffer.marshalBinding(binding); } if (args != null) { buffer.putInt(args.length); for (ICPPTemplateArgument arg : args) { buffer.marshalTemplateArgument(arg); } } buffer.marshalType(fImpliedObjectType); } else { buffer.putShort(firstBytes); buffer.putCharArray(fName); } marshalTemplateDefinition(buffer); }
/** * 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 ICPPEvaluation instantiate( ICPPTemplateParameterMap tpMap, int packOffset, ICPPTypeSpecialization within, int maxdepth, IASTNode point) { if (fFunctionSet == null) return this; ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments(); ICPPTemplateArgument[] arguments = originalArguments; if (originalArguments != null) arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point); IBinding originalOwner = fFunctionSet.getOwner(); IBinding owner = originalOwner; if (owner instanceof ICPPUnknownBinding) { owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point); } else if (owner instanceof ICPPClassTemplate) { owner = resolveUnknown( CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner), tpMap, packOffset, within, point); } else if (owner instanceof IType) { IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point); if (type instanceof IBinding) owner = (IBinding) type; } ICPPFunction[] originalFunctions = fFunctionSet.getBindings(); ICPPFunction[] functions = originalFunctions; if (owner instanceof ICPPClassSpecialization && owner != originalOwner) { functions = new ICPPFunction[originalFunctions.length]; for (int i = 0; i < originalFunctions.length; i++) { functions[i] = (ICPPFunction) CPPTemplates.createSpecialization( (ICPPClassSpecialization) owner, originalFunctions[i], point); } } // No need to instantiate the implied object type. An EvalFunctioNSet should only be created // with an implied object type when that type is not dependent. if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions) return this; return new EvalFunctionSet( new CPPFunctionSet(functions, arguments, null), fQualified, fAddressOf, fImpliedObjectType, getTemplateDefinition()); }
@Override public boolean isTypeDependent() { if (fFunctionSet == null) return true; final ICPPTemplateArgument[] args = fFunctionSet.getTemplateArguments(); if (args != null) { for (ICPPTemplateArgument arg : args) { if (CPPTemplates.isDependentArgument(arg)) return true; } } for (ICPPFunction f : fFunctionSet.getBindings()) { if (f instanceof ICPPUnknownBinding) return true; } return false; }
@Override public boolean isConstantExpression(IASTNode point) { if (fFunctionSet == null) return false; for (ICPPFunction f : fFunctionSet.getBindings()) { if (!f.isConstexpr()) { return false; } } return true; }
@Override public int determinePackSize(ICPPTemplateParameterMap tpMap) { int r = CPPTemplates.PACK_SIZE_NOT_FOUND; if (fFunctionSet != null) { ICPPTemplateArgument[] templateArguments = fFunctionSet.getTemplateArguments(); for (ICPPTemplateArgument arg : templateArguments) { r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap)); } } return r; }