Skip to content

Commit 185a73e

Browse files
committed
Refactor diagnoseMemoryLayoutMigration [NFC]
1 parent 05f4594 commit 185a73e

File tree

1 file changed

+26
-36
lines changed

1 file changed

+26
-36
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,74 +2246,64 @@ bool AvailabilityWalker::diagnoseIncDecRemoval(const ValueDecl *D,
22462246
return false;
22472247
}
22482248

2249-
/// If this is a call to an unavailable sizeof family functions, diagnose it
2249+
/// If this is a call to an unavailable sizeof family function, diagnose it
22502250
/// with a fixit hint and return true. If not, or if we fail, return false.
22512251
bool AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
2252-
SourceRange R,
2253-
const AvailableAttr *Attr,
2254-
const ApplyExpr *call) {
2252+
SourceRange R,
2253+
const AvailableAttr *Attr,
2254+
const ApplyExpr *call) {
22552255

22562256
if (!D->getModuleContext()->isStdlibModule())
22572257
return false;
22582258

2259-
std::pair<StringRef, bool> KindValue
2260-
= llvm::StringSwitch<std::pair<StringRef, bool>>(D->getNameStr())
2261-
.Case("sizeof", {"size", false})
2262-
.Case("alignof", {"alignment", false})
2263-
.Case("strideof", {"stride", false})
2264-
.Default({});
2265-
2266-
if (KindValue.first.empty())
2259+
StringRef Property = llvm::StringSwitch<StringRef>(D->getNameStr())
2260+
.Case("sizeof", "size")
2261+
.Case("alignof", "alignment")
2262+
.Case("strideof", "stride")
2263+
.Default(StringRef());
2264+
if (Property.empty())
22672265
return false;
22682266

2269-
auto Kind = KindValue.first;
2270-
auto isValue = KindValue.second;
2271-
22722267
auto args = dyn_cast<ParenExpr>(call->getArg());
22732268
if (!args)
22742269
return false;
22752270

2276-
auto subject = args->getSubExpr();
2277-
if (!isValue) {
2278-
// sizeof(type(of: x)) is equivalent to sizeofValue(x)
2279-
if (auto DTE = dyn_cast<DynamicTypeExpr>(subject)) {
2280-
subject = DTE->getBase();
2281-
isValue = true;
2282-
}
2283-
}
2284-
22852271
EncodedDiagnosticMessage EncodedMessage(Attr->Message);
22862272
auto diag = TC.diagnose(R.Start, diag::availability_decl_unavailable_msg,
22872273
D->getFullName(), EncodedMessage.Message);
22882274
diag.highlight(R);
22892275

2276+
auto subject = args->getSubExpr();
2277+
22902278
StringRef Prefix = "MemoryLayout<";
22912279
StringRef Suffix = ">.";
2292-
if (isValue) {
2293-
auto valueType = subject->getType()->getRValueType();
2280+
2281+
if (auto DTE = dyn_cast<DynamicTypeExpr>(subject)) {
2282+
// Replace `sizeof(type(of: x))` with `MemoryLayout<X>.size`, where `X` is
2283+
// the static type of `x`. The previous spelling misleadingly hinted that
2284+
// `sizeof(_:)` might return the size of the *dynamic* type of `x`, when
2285+
// it is not the case.
2286+
auto valueType = DTE->getBase()->getType()->getRValueType();
22942287
if (!valueType || valueType->hasError()) {
2295-
// If we don't have a suitable argument, we cannot emit a fix-it.
2288+
// If we don't have a suitable argument, we can't emit a fixit.
22962289
return true;
22972290
}
2298-
2299-
// NOTE: We are destructively replacing the source text here.
2300-
// `sizeof(type(of: doSomething()))` => `MemoryLayout<T>.size`, where T is
2301-
// the return type of `doSomething()`. If that function has any side
2302-
// effects, this replacement will break the source.
2291+
// Note that in rare circumstances we may be destructively replacing the
2292+
// source text. For example, we'd replace `sizeof(type(of: doSomething()))`
2293+
// with `MemoryLayout<T>.size`, if T is the return type of `doSomething()`.
23032294
diag.fixItReplace(call->getSourceRange(),
2304-
(Prefix + valueType->getString() + Suffix + Kind).str());
2295+
(Prefix + valueType->getString() + Suffix + Property).str());
23052296
} else {
23062297
SourceRange PrefixRange(call->getStartLoc(), args->getLParenLoc());
23072298
SourceRange SuffixRange(args->getRParenLoc());
23082299

2309-
// We must truncate `.self`.
2310-
// E.g. sizeof(T.self) => MemoryLayout<T>.size
2300+
// We must remove `.self`.
23112301
if (auto *DSE = dyn_cast<DotSelfExpr>(subject))
23122302
SuffixRange.Start = DSE->getDotLoc();
23132303

23142304
diag
23152305
.fixItReplace(PrefixRange, Prefix)
2316-
.fixItReplace(SuffixRange, (Suffix + Kind).str());
2306+
.fixItReplace(SuffixRange, (Suffix + Property).str());
23172307
}
23182308

23192309
return true;

0 commit comments

Comments
 (0)