Refactor cast representation in AST and SIL, and implement 'is'.

Improve our representations of casts in the AST and SIL so that 'as!' and 'is' (and eventually 'as?') can share almost all of the same type-checking, SILGen, and IRGen code.

In the AST, we now represent 'as!' and 'is' as UnconditionalCheckedCastExpr and IsaExpr, respectively, with the semantic variations of cast (downcast, super-to-archetype, archetype-to-concrete, etc.) discriminated by an enum field. This keeps the user-visible syntactic and type behavior differences of the two forms cleanly separated for AST consumers.

At the SIL level, we transpose the representation so that the different cast semantics get their own instructions and the conditional/unconditional cast behavior is indicated by an enum, making it easy for IRGen to discriminate the different code paths for the different semantics. We also add an 'IsNonnull' instruction to cover the conditional-cast-result-to-boolean conversion common to all the forms of 'is'.

The upshot of all this is that 'x is T' now works for all the new archetype and existential cast forms supported by 'as!'.

Swift SVN r5737
This commit is contained in:
Joe Groff
2013-06-21 05:54:03 +00:00
parent be0f7b4c48
commit f072c48e45
28 changed files with 587 additions and 636 deletions

View File

@@ -894,19 +894,11 @@ public:
"downcast must convert to a class type");
}
void checkIsaInst(IsaInst *II) {
void checkIsNonnullInst(IsNonnullInst *II) {
require(II->getOperand().getType().getSwiftType()
->getClassOrBoundGenericClass(),
"isa operand must be a class type");
CanType testTy = II->getTestType().getSwiftRValueType();
if (auto *archetype = dyn_cast<ArchetypeType>(testTy))
require((bool)archetype->getSuperclass(),
"isa must test against a class type or base-class-constrained "
"archetype");
else
require(testTy->getClassOrBoundGenericClass(),
"isa must test against a class type or base-class-constrained "
"archetype");
->mayHaveSuperclass()
|| II->getOperand().getType().isAddress(),
"isa operand must be a class type or address");
}
void checkAddressToPointerInst(AddressToPointerInst *AI) {