Files
swift-mirror/lib/IRGen/ComputedWitnessIndex.h
T
Kavon Farvardin b7d57f3bcd Reparenting: use resilient indexing to access base witness table
Ordinary base protocols use fixed-indexing to access the base index.
That means adding another base protocol to an existing protocol
can break the order of the entries, and thus clients, because we
otherwise order the base entires with TypeDecl::compare.

Reparentable protocols are meant to be resilient to that, so we
order them at the end of the base entries list, just before the
other resilient entries in the witness table.

This patch completes the picture, by having the reparentable
protocol entries be indexed resiliently, in the same manner as
associated conformances.

The difference is that we can skip the call to
`swift_getAssociatedConformanceWitness`
and compute the index directly by finding the distance of the
descriptors, because we know all base protocol witness table
entries are eagarly instantiated.

Using this distance protects us from the ordering problems
of entries among all of the reparentable base protocols.

resolves rdar://173409851
2026-04-20 17:37:36 -07:00

65 lines
1.8 KiB
C++

//===--- ComputedWitnessIndex.h - Index into a witness table ----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2026 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Defines the ComputedWitnessIndex type, used to represent an index into a
// witness table, whether known at compile-time or is a computed value.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_COMPUTEDWITNESSINDEX_H
#define SWIFT_IRGEN_COMPUTEDWITNESSINDEX_H
#include "WitnessIndex.h"
#include "llvm/IR/Value.h"
namespace swift {
namespace irgen {
/// A class which encapsulates an either a computed or statically-known index
/// into a witness table.
/// FIXME(naming): this is more of a "generalized" or "maybe static" index.
class ComputedWitnessIndex {
union {
llvm::Value *ComputedValue;
WitnessIndex StaticValue;
};
bool hasStaticValue;
public:
/*implicit*/ ComputedWitnessIndex(WitnessIndex index)
: StaticValue(index), hasStaticValue(true) {}
explicit ComputedWitnessIndex(llvm::Value *index)
: ComputedValue(index), hasStaticValue(false) {}
bool isStatic() const { return hasStaticValue; }
std::optional<WitnessIndex> getStaticIndex() const {
if (isStatic())
return StaticValue;
return std::nullopt;
}
llvm::Value *getDynamicIndex() const {
if (isStatic())
return nullptr;
return ComputedValue;
}
};
} // end namespace irgen
} // end namespace swift
#endif