InvokeEntry* lookupInvokeEntry(ObjectPtr callable, llvm::ArrayRef<TypePtr> argsKey, llvm::ArrayRef<ValueTempness> argsTempness, MatchFailureError &failures) { InvokeSet* invokeSet = lookupInvokeSet(callable, argsKey); map<vector<ValueTempness>,InvokeEntry*>::iterator iter = invokeSet->tempnessMap.find(argsTempness); if (iter != invokeSet->tempnessMap.end()) return iter->second; MatchResultPtr interfaceResult; if (invokeSet->interface != NULL) { interfaceResult = matchInvoke(invokeSet->interface, invokeSet->callable, invokeSet->argsKey); if (interfaceResult->matchCode != MATCH_SUCCESS) { failures.failedInterface = true; failures.failures.push_back(make_pair(invokeSet->interface, interfaceResult)); return NULL; } } MatchSuccessPtr match; vector<ValueTempness> tempnessKey; vector<uint8_t> forwardedRValueFlags; unsigned i = 0; while ((match = getMatch(invokeSet,i,failures)).ptr() != NULL) { if (matchTempness(match->code, argsTempness, match->callByName, tempnessKey, forwardedRValueFlags)) { break; } ++i; } if (!match) return NULL; iter = invokeSet->tempnessMap2.find(tempnessKey); if (iter != invokeSet->tempnessMap2.end()) { invokeSet->tempnessMap[argsTempness] = iter->second; return iter->second; } InvokeEntry* entry = newInvokeEntry(invokeSet, match, (MatchSuccess*)interfaceResult.ptr()); entry->forwardedRValueFlags = forwardedRValueFlags; invokeSet->tempnessMap2[tempnessKey] = entry; invokeSet->tempnessMap[argsTempness] = entry; return entry; }
void printMatchError(ostream &os, MatchResultPtr result) { switch (result->matchCode) { case MATCH_SUCCESS : assert(false); break; case MATCH_CALLABLE_ERROR : { MatchCallableError *e = (MatchCallableError*)result.ptr(); os << "callable pattern \"" << shortString(e->patternExpr->asString()); os << "\" did not match \""; printStaticName(os, e->callable); os << "\""; break; } case MATCH_ARITY_ERROR : { MatchArityError *e = (MatchArityError*)result.ptr(); os << "incorrect number of arguments: expected "; if (e->variadic) os << "at least "; os << e->expectedArgs << " arguments, got " << e->gotArgs << " arguments"; break; } case MATCH_ARGUMENT_ERROR : { MatchArgumentError *e = (MatchArgumentError *)result.ptr(); os << "pattern \"" << shortString(e->arg->type->asString()); os << "\" did not match type \""; printStaticName(os, e->type.ptr()); os << "\" of argument " << e->argIndex + 1; break; } case MATCH_MULTI_ARGUMENT_ERROR : { MatchMultiArgumentError *e = (MatchMultiArgumentError *)result.ptr(); os << "variadic argument type pattern did not match types of arguments "; os << "starting at " << e->argIndex + 1; break; } case MATCH_PREDICATE_ERROR : { MatchPredicateError *e = (MatchPredicateError *)result.ptr(); os << "predicate \"" << shortString(e->predicateExpr->asString()) << "\" failed"; break; } default : assert(false); break; } }
static MatchSuccessPtr findMatchingInvoke(llvm::ArrayRef<OverloadPtr> overloads, unsigned &overloadIndex, ObjectPtr callable, llvm::ArrayRef<TypePtr> argsKey, MatchFailureError &failures) { while (overloadIndex < overloads.size()) { OverloadPtr x = overloads[overloadIndex++]; MatchResultPtr result = matchInvoke(x, callable, argsKey); failures.failures.push_back(make_pair(x, result)); if (result->matchCode == MATCH_SUCCESS) { MatchSuccess *y = (MatchSuccess *)result.ptr(); return y; } } return NULL; }
InvokeEntry* lookupInvokeEntry(ObjectPtr callable, llvm::ArrayRef<PVData> args, MatchFailureError &failures) { vector<TypePtr> argTypes; vector<bool> argRValues; argTypes.reserve(args.size()); argRValues.reserve(args.size()); for (llvm::ArrayRef<PVData>::const_iterator arg = args.begin(); arg != args.end(); ++arg) { argTypes.push_back(arg->type); argRValues.push_back(arg->isRValue); } InvokeSet* invokeSet = lookupInvokeSet(callable, argTypes); if (invokeSet->evaluatingPredicate) { // matchInvoke calls the same lookupInvokeEntry error("predicate evaluation loop"); } invokeSet->evaluatingPredicate = true; FinallyClearEvaluatingPredicate FinallyClearEvaluatingPredicate(invokeSet); map<vector<bool>, InvokeEntry*>::iterator iter1 = invokeSet->tempnessMap.find(argRValues); if (iter1 != invokeSet->tempnessMap.end()) return iter1->second; MatchResultPtr interfaceResult; if (invokeSet->interface != NULL) { interfaceResult = matchInvoke(invokeSet->interface, invokeSet->callable, invokeSet->argsKey); if (interfaceResult->matchCode != MATCH_SUCCESS) { failures.failedInterface = true; failures.failures.push_back(make_pair(invokeSet->interface, interfaceResult)); return NULL; } } MatchSuccessPtr match; vector<ValueTempness> tempnessKey; vector<uint8_t> forwardedRValueFlags; unsigned i = 0; while ((match = getMatch(invokeSet,i,failures)).ptr() != NULL) { tempnessKey.clear(); forwardedRValueFlags.clear(); if (matchTempness(match->overload->code, argRValues, match->overload->callByName, tempnessKey, forwardedRValueFlags)) { break; } ++i; } if (!match) return NULL; map<vector<ValueTempness>, InvokeEntry*>::iterator iter2 = invokeSet->tempnessMap2.find(tempnessKey); if (iter2 != invokeSet->tempnessMap2.end()) { invokeSet->tempnessMap[argRValues] = iter2->second; return iter2->second; } InvokeEntry* entry = newInvokeEntry(invokeSet, match, (MatchSuccess*)interfaceResult.ptr()); entry->forwardedRValueFlags = forwardedRValueFlags; invokeSet->tempnessMap2[tempnessKey] = entry; invokeSet->tempnessMap[argRValues] = entry; if (_finalOverloadsEnabled) { MatchSuccessPtr match2; vector<ValueTempness> tempnessKey2; vector<uint8_t> forwardedRValueFlags2; unsigned j = invokeSet->nextOverloadIndex; while ((match2 = findMatchingInvoke(callableOverloads(callable), j, callable, argTypes, failures)).ptr() != NULL) { if (matchTempness(match2->overload->code, argRValues, match2->overload->callByName, tempnessKey2, forwardedRValueFlags2)) { break; } ++j; } if (match2 != NULL && !match2->overload->isDefault) { failures.ambiguousMatch = true; return NULL; } } return entry; }