Skip to content

Commit 55082c4

Browse files
committed
Sema: Split off buildVarMemberRef() from buildMemberRef()
1 parent 1ddcdc7 commit 55082c4

File tree

1 file changed

+96
-71
lines changed

1 file changed

+96
-71
lines changed

lib/Sema/CSApply.cpp

Lines changed: 96 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,93 @@ namespace {
17431743
return forceUnwrapIfExpected(ref, memberLocator);
17441744
}
17451745

1746+
Expr *buildVarMemberRef(Expr *base, SourceLoc dotLoc,
1747+
bool baseIsInstance,
1748+
ConcreteDeclRef memberRef,
1749+
DeclNameLoc memberLoc,
1750+
Type containerTy,
1751+
Type refTy,
1752+
Type adjustedRefTy,
1753+
Type adjustedOpenedType,
1754+
AccessSemantics semantics,
1755+
ConstraintLocatorBuilder locator,
1756+
ConstraintLocatorBuilder memberLocator,
1757+
bool isSuper,
1758+
bool isUnboundInstanceMember,
1759+
bool Implicit) {
1760+
auto *varDecl = cast<VarDecl>(memberRef.getDecl());
1761+
1762+
bool loadImmediately = false;
1763+
auto resultType = [&loadImmediately](Type fnTy) -> Type {
1764+
Type resultTy = fnTy->castTo<FunctionType>()->getResult();
1765+
if (loadImmediately)
1766+
return LValueType::get(resultTy);
1767+
return resultTy;
1768+
};
1769+
1770+
// If we have an instance property that's treated as an rvalue
1771+
// but allows assignment (for initialization) in the current
1772+
// context, treat it as an rvalue that we immediately load.
1773+
// This is the AST that's expected by SILGen.
1774+
if (baseIsInstance && !resultType(refTy)->hasLValueType() &&
1775+
varDecl->mutability(dc, dyn_cast<DeclRefExpr>(base))
1776+
== StorageMutability::Initializable) {
1777+
loadImmediately = true;
1778+
}
1779+
1780+
if (isUnboundInstanceMember) {
1781+
assert(memberLocator.getBaseLocator() &&
1782+
cs.UnevaluatedRootExprs.count(
1783+
getAsExpr(memberLocator.getBaseLocator()->getAnchor())) &&
1784+
"Attempt to reference an instance member of a metatype");
1785+
auto baseInstanceTy = cs.getType(base)
1786+
->getInOutObjectType()->getMetatypeInstanceType();
1787+
base = new (ctx) UnevaluatedInstanceExpr(base, baseInstanceTy);
1788+
cs.cacheType(base);
1789+
base->setImplicit();
1790+
}
1791+
1792+
const auto hasDynamicSelf = refTy->hasDynamicSelfType();
1793+
1794+
auto memberRefExpr
1795+
= new (ctx) MemberRefExpr(base, dotLoc, memberRef,
1796+
memberLoc, Implicit, semantics);
1797+
memberRefExpr->setIsSuper(isSuper);
1798+
1799+
if (hasDynamicSelf) {
1800+
refTy = refTy->replaceDynamicSelfType(containerTy);
1801+
adjustedRefTy = adjustedRefTy->replaceDynamicSelfType(
1802+
containerTy);
1803+
}
1804+
1805+
cs.setType(memberRefExpr, resultType(refTy));
1806+
1807+
Expr *result = memberRefExpr;
1808+
result = adjustTypeForDeclReference(result, resultType(refTy),
1809+
resultType(adjustedRefTy),
1810+
locator);
1811+
closeExistentials(result, locator);
1812+
1813+
// If the property is of dynamic 'Self' type, wrap an implicit
1814+
// conversion around the resulting expression, with the destination
1815+
// type having 'Self' swapped for the appropriate replacement
1816+
// type -- usually the base object type.
1817+
if (hasDynamicSelf) {
1818+
const auto conversionTy = adjustedOpenedType;
1819+
if (!containerTy->isEqual(conversionTy)) {
1820+
result = cs.cacheType(new (ctx) CovariantReturnConversionExpr(
1821+
result, conversionTy));
1822+
}
1823+
}
1824+
1825+
// If we need to load, do so now.
1826+
if (loadImmediately) {
1827+
result = cs.addImplicitLoadExpr(result);
1828+
}
1829+
1830+
return forceUnwrapIfExpected(result, memberLocator);
1831+
}
1832+
17461833
/// Build a new member reference with the given base and member.
17471834
Expr *buildMemberRef(Expr *base, SourceLoc dotLoc,
17481835
SelectedOverload overload, DeclNameLoc memberLoc,
@@ -1974,79 +2061,17 @@ namespace {
19742061
}
19752062

19762063
// For properties, build member references.
1977-
if (auto *varDecl = dyn_cast<VarDecl>(member)) {
1978-
// \returns result of the given function type
1979-
bool loadImmediately = false;
1980-
auto resultType = [&loadImmediately](Type fnTy) -> Type {
1981-
Type resultTy = fnTy->castTo<FunctionType>()->getResult();
1982-
if (loadImmediately)
1983-
return LValueType::get(resultTy);
1984-
return resultTy;
1985-
};
1986-
1987-
// If we have an instance property that's treated as an rvalue
1988-
// but allows assignment (for initialization) in the current
1989-
// context, treat it as an rvalue that we immediately load.
1990-
// This is the AST that's expected by SILGen.
1991-
if (baseIsInstance && !resultType(refTy)->hasLValueType() &&
1992-
varDecl->mutability(dc, dyn_cast<DeclRefExpr>(base))
1993-
== StorageMutability::Initializable) {
1994-
loadImmediately = true;
1995-
}
1996-
1997-
if (isUnboundInstanceMember) {
1998-
assert(memberLocator.getBaseLocator() &&
1999-
cs.UnevaluatedRootExprs.count(
2000-
getAsExpr(memberLocator.getBaseLocator()->getAnchor())) &&
2001-
"Attempt to reference an instance member of a metatype");
2002-
auto baseInstanceTy = cs.getType(base)
2003-
->getInOutObjectType()->getMetatypeInstanceType();
2004-
base = new (ctx) UnevaluatedInstanceExpr(base, baseInstanceTy);
2005-
cs.cacheType(base);
2006-
base->setImplicit();
2007-
}
2008-
2009-
const auto hasDynamicSelf = refTy->hasDynamicSelfType();
2010-
2011-
auto memberRefExpr
2012-
= new (ctx) MemberRefExpr(base, dotLoc, memberRef,
2013-
memberLoc, Implicit, semantics);
2014-
memberRefExpr->setIsSuper(isSuper);
2015-
2016-
if (hasDynamicSelf) {
2017-
refTy = refTy->replaceDynamicSelfType(containerTy);
2018-
adjustedRefTy = adjustedRefTy->replaceDynamicSelfType(
2019-
containerTy);
2020-
}
2021-
2022-
cs.setType(memberRefExpr, resultType(refTy));
2023-
2024-
Expr *result = memberRefExpr;
2025-
result = adjustTypeForDeclReference(result, resultType(refTy),
2026-
resultType(adjustedRefTy),
2027-
locator);
2028-
closeExistentials(result, locator);
2029-
2030-
// If the property is of dynamic 'Self' type, wrap an implicit
2031-
// conversion around the resulting expression, with the destination
2032-
// type having 'Self' swapped for the appropriate replacement
2033-
// type -- usually the base object type.
2034-
if (hasDynamicSelf) {
2035-
const auto conversionTy = adjustedOpenedType;
2036-
if (!containerTy->isEqual(conversionTy)) {
2037-
result = cs.cacheType(new (ctx) CovariantReturnConversionExpr(
2038-
result, conversionTy));
2039-
}
2040-
}
2041-
2042-
// If we need to load, do so now.
2043-
if (loadImmediately) {
2044-
result = cs.addImplicitLoadExpr(result);
2045-
}
2046-
2047-
return forceUnwrapIfExpected(result, memberLocator);
2064+
if (isa<VarDecl>(member)) {
2065+
return buildVarMemberRef(base, dotLoc, baseIsInstance,
2066+
memberRef, memberLoc, containerTy,
2067+
refTy, adjustedRefTy, adjustedOpenedType,
2068+
semantics, locator, memberLocator,
2069+
isSuper, isUnboundInstanceMember, Implicit);
20482070
}
20492071

2072+
ASSERT(isa<AbstractFunctionDecl>(member) ||
2073+
isa<EnumElementDecl>(member));
2074+
20502075
Type refTySelf = refTy, adjustedRefTySelf = adjustedRefTy;
20512076

20522077
auto *func = dyn_cast<FuncDecl>(member);

0 commit comments

Comments
 (0)