Requestify the Raw Value Accessor

Make getRawValueExpr() return a checked value.

This entails a strange kind of request that effectively acts like
a cache warmer.  In order to properly check the raw value expression for
a single case, we actually need all the other cases for the
autoincrementing synthesis logic.  The strategy is therefore to have the
request act at the level of the parent EnumDecl and check all the values
at once.  We also cache at the level of the EnumDecl so the cache
"warms" for all enum elements simultaneously.

The request also abuses TypeResolutionStage to act as an indicator for
how much information to compute.  In the minimal case, we will return
a complete accounting of (auto-incremented) raw values.  In the maximal
case we will also check and record types and emit diagnostics.  The
minimal case is uncached to support repeated evaluation.

Note that computing the interface type of an @objc enum decl *must*
force this request.  The enum's raw values are part of the ABI, and we
should not get all the way to IRGen before discovering that we cannot
possibly lay out the enum.  In the future, we might want to consider
moving this check earlier or have IRGen tolerate broken cases but for
now we will maintain the status quo and not have IRGen emit
diagnostics.
This commit is contained in:
Robert Widmann
2019-09-26 17:11:02 -07:00
parent da10020253
commit 2fe3ce8af8
19 changed files with 266 additions and 114 deletions

View File

@@ -916,7 +916,7 @@ bool ModelASTWalker::walkToDeclPre(Decl *D) {
EnumElemD->getName().getLength());
}
if (auto *E = EnumElemD->getRawValueExpr()) {
if (auto *E = EnumElemD->getRawValueUnchecked()) {
SourceRange ElemRange = E->getSourceRange();
SN.Elements.emplace_back(SyntaxStructureElementKind::InitExpr,
charSourceRangeFromSourceRange(SM, ElemRange));