SILDeclRef SILDeclRef::getOverriddenVTableEntry() const { SILDeclRef cur = *this, next = *this; do { cur = next; if (cur.requiresNewVTableEntry()) return cur; next = cur.getNextOverriddenVTableEntry(); } while (next); return cur; }
SILDeclRef SILDeclRef::getBaseOverriddenVTableEntry() const { // 'method' is the most final method in the hierarchy which we // haven't yet found a compatible override for. 'cur' is the method // we're currently looking at. Compatibility is transitive, // so we can forget our original method and just keep going up. SILDeclRef method = *this; SILDeclRef cur = method; while ((cur = cur.getNextOverriddenVTableEntry())) { method = cur; } return method; }
void CalleeCache::computeClassMethodCallees(ClassDecl *CD, SILDeclRef Method) { auto *CalledFn = M.lookUpFunctionInVTable(CD, Method); if (!CalledFn) return; bool canCallUnknown = !calleesAreStaticallyKnowable(M, Method); // Update the callees for this method and all the methods it // overrides by adding this function to their lists. do { auto &TheCallees = getOrCreateCalleesForMethod(Method); assert(TheCallees.getPointer() && "Unexpected null callees!"); TheCallees.getPointer()->push_back(CalledFn); if (canCallUnknown) TheCallees.setInt(true); Method = Method.getNextOverriddenVTableEntry(); } while (Method); }