mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
b7d57f3bcd
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
65 lines
1.8 KiB
C++
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
|