mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Reimplement circularly check for protocol inheritance.
First, make it actually check for cycles properly. Second, pull it into the checking of the protocol itself, rather than keeping it as a separate pass that happens too late to be useful. Finally, put the unchecked/checking/checked bits into the AST to avoid having to keep a separate DenseMap just for this purpose. Fixes <rdar://problem/14750346>. Swift SVN r7324
This commit is contained in:
@@ -73,6 +73,16 @@ enum class DeclKind : uint8_t {
|
||||
#include "swift/AST/DeclNodes.def"
|
||||
};
|
||||
|
||||
/// Keeps track of stage of circularity checking for the given protocol.
|
||||
enum class CircularityCheck {
|
||||
/// Circularity has not yet been checked.
|
||||
Unchecked,
|
||||
/// We're currently checking circularity.
|
||||
Checking,
|
||||
// Circularity has already been checked.
|
||||
Checked
|
||||
};
|
||||
|
||||
/// Decl - Base class for all declarations in Swift.
|
||||
class alignas(8) Decl {
|
||||
// alignas(8) because we use three tag bits on Decl*.
|
||||
@@ -159,8 +169,11 @@ class alignas(8) Decl {
|
||||
/// If this is a compiler-known protocol, this will be a KnownProtocolKind
|
||||
/// value, plus one. Otherwise, it will be 0.
|
||||
unsigned KnownProtocol : 4;
|
||||
|
||||
/// The stage of the circularity check for this protocol.
|
||||
unsigned Circularity : 2;
|
||||
};
|
||||
enum { NumProtocolDeclBits = NumNominalTypeDeclBits + 8 };
|
||||
enum { NumProtocolDeclBits = NumNominalTypeDeclBits + 10 };
|
||||
static_assert(NumProtocolDeclBits <= 32, "fits in an unsigned");
|
||||
|
||||
class InfixOperatorDeclBitFields {
|
||||
@@ -1636,6 +1649,16 @@ public:
|
||||
assert(*getKnownProtocolKind() == kind && "not enough bits");
|
||||
}
|
||||
|
||||
/// Retrieve the status of circularity checking for protocol inheritance.
|
||||
CircularityCheck getCircularityCheck() const {
|
||||
return static_cast<CircularityCheck>(ProtocolDeclBits.Circularity);
|
||||
}
|
||||
|
||||
/// Record the current stage of circularity checking.
|
||||
void setCircularityCheck(CircularityCheck circularity) {
|
||||
ProtocolDeclBits.Circularity = static_cast<unsigned>(circularity);
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) {
|
||||
return D->getKind() == DeclKind::Protocol;
|
||||
|
||||
Reference in New Issue
Block a user