Skip to content

Commit 3771f03

Browse files
committed
[Mangler] Fold context-signature logic into appendGenericSignature().
NFC refactoring to make it easier to uniformly suppress requirements of a generic signature that are satisfied by a context signature.
1 parent e4ff3a5 commit 3771f03

File tree

2 files changed

+80
-64
lines changed

2 files changed

+80
-64
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,17 @@ class ASTMangler : public Mangler {
195195

196196
void appendTypeList(Type listTy);
197197

198-
void appendGenericSignature(const GenericSignature *sig);
198+
/// Append a generic signature to the mangling.
199+
///
200+
/// \param sig The generic signature.
201+
///
202+
/// \param contextSig The signature of the known context. This function
203+
/// will only mangle the difference between \c sig and \c contextSig.
204+
///
205+
/// \returns \c true if a generic signature was appended, \c false
206+
/// if it was empty.
207+
bool appendGenericSignature(const GenericSignature *sig,
208+
GenericSignature *contextSig = nullptr);
199209

200210
void appendRequirement(const Requirement &reqt);
201211

@@ -218,10 +228,8 @@ class ASTMangler : public Mangler {
218228
void appendInitializerEntity(const VarDecl *var);
219229

220230
CanType getDeclTypeForMangling(const ValueDecl *decl,
221-
ArrayRef<GenericTypeParamType *> &genericParams,
222-
unsigned &initialParamIndex,
223-
ArrayRef<Requirement> &requirements,
224-
SmallVectorImpl<Requirement> &requirementsBuf);
231+
GenericSignature *&genericSig,
232+
GenericSignature *&parentGenericSig);
225233

226234
void appendDeclType(const ValueDecl *decl, bool isFunctionMangling = false);
227235

lib/AST/ASTMangler.cpp

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,11 +1537,57 @@ void ASTMangler::appendTypeList(Type listTy) {
15371537
}
15381538
}
15391539

1540-
void ASTMangler::appendGenericSignature(const GenericSignature *sig) {
1540+
bool ASTMangler::appendGenericSignature(const GenericSignature *sig,
1541+
GenericSignature *contextSig) {
15411542
auto canSig = sig->getCanonicalSignature();
15421543
CurGenericSignature = canSig;
1543-
appendGenericSignatureParts(canSig->getGenericParams(), 0,
1544-
canSig->getRequirements());
1544+
1545+
unsigned initialParamDepth;
1546+
ArrayRef<GenericTypeParamType *> genericParams;
1547+
ArrayRef<Requirement> requirements;
1548+
SmallVector<Requirement, 4> requirementsBuffer;
1549+
if (contextSig) {
1550+
// If the signature is the same as the context signature, there's nothing
1551+
// to do.
1552+
if (contextSig->getCanonicalSignature() == canSig) {
1553+
return false;
1554+
}
1555+
1556+
// The signature depth starts above the depth of the context signature.
1557+
if (!contextSig->getGenericParams().empty()) {
1558+
initialParamDepth = contextSig->getGenericParams().back()->getDepth() + 1;
1559+
}
1560+
1561+
// Find the parameters at this depth (or greater).
1562+
genericParams = canSig->getGenericParams();
1563+
unsigned firstParam = genericParams.size();
1564+
while (firstParam > 1 &&
1565+
genericParams[firstParam-1]->getDepth() >= initialParamDepth)
1566+
--firstParam;
1567+
genericParams = genericParams.slice(firstParam);
1568+
1569+
for (auto &reqt : canSig->getRequirements()) {
1570+
// If the requirement is satisfied by the context signature,
1571+
// we don't need to mangle it here.
1572+
if (contextSig->isRequirementSatisfied(reqt))
1573+
continue;
1574+
1575+
// Mangle the requirement.
1576+
requirementsBuffer.push_back(reqt);
1577+
}
1578+
requirements = requirementsBuffer;
1579+
} else {
1580+
// Use the complete canonical signature.
1581+
initialParamDepth = 0;
1582+
genericParams = canSig->getGenericParams();
1583+
requirements = canSig->getRequirements();
1584+
}
1585+
1586+
if (genericParams.empty() && requirements.empty())
1587+
return false;
1588+
1589+
appendGenericSignatureParts(genericParams, initialParamDepth, requirements);
1590+
return true;
15451591
}
15461592

15471593
void ASTMangler::appendRequirement(const Requirement &reqt) {
@@ -1737,11 +1783,12 @@ static bool isMethodDecl(const Decl *decl) {
17371783
}
17381784

17391785
CanType ASTMangler::getDeclTypeForMangling(
1740-
const ValueDecl *decl,
1741-
ArrayRef<GenericTypeParamType *> &genericParams,
1742-
unsigned &initialParamDepth,
1743-
ArrayRef<Requirement> &requirements,
1744-
SmallVectorImpl<Requirement> &requirementsBuf) {
1786+
const ValueDecl *decl,
1787+
GenericSignature *&genericSig,
1788+
GenericSignature *&parentGenericSig) {
1789+
genericSig = nullptr;
1790+
parentGenericSig = nullptr;
1791+
17451792
auto &C = decl->getASTContext();
17461793
if (!decl->hasInterfaceType() || decl->getInterfaceType()->is<ErrorType>()) {
17471794
if (isa<AbstractFunctionDecl>(decl))
@@ -1750,21 +1797,14 @@ CanType ASTMangler::getDeclTypeForMangling(
17501797
return C.TheErrorType;
17511798
}
17521799

1753-
auto type = decl->getInterfaceType()->getCanonicalType();
17541800

1755-
initialParamDepth = 0;
1756-
CanGenericSignature sig;
1801+
CanType type = decl->getInterfaceType()->getCanonicalType();
17571802
if (auto gft = dyn_cast<GenericFunctionType>(type)) {
1758-
sig = gft.getGenericSignature();
1759-
CurGenericSignature = sig;
1760-
genericParams = sig->getGenericParams();
1761-
requirements = sig->getRequirements();
1803+
genericSig = gft.getGenericSignature();
1804+
CurGenericSignature = gft.getGenericSignature();
17621805

17631806
type = CanFunctionType::get(gft->getParams(), gft.getResult(),
17641807
gft->getExtInfo());
1765-
} else {
1766-
genericParams = {};
1767-
requirements = {};
17681808
}
17691809

17701810
if (!type->hasError()) {
@@ -1774,49 +1814,19 @@ CanType ASTMangler::getDeclTypeForMangling(
17741814
type = cast<AnyFunctionType>(type).getResult();
17751815
}
17761816

1777-
if (isMethodDecl(decl) || isa<SubscriptDecl>(decl)) {
1778-
// Drop generic parameters and requirements from the method's context.
1779-
auto parentGenericSig =
1780-
decl->getDeclContext()->getGenericSignatureOfContext();
1781-
if (parentGenericSig && sig) {
1782-
// The method's depth starts above the depth of the context.
1783-
if (!parentGenericSig->getGenericParams().empty())
1784-
initialParamDepth =
1785-
parentGenericSig->getGenericParams().back()->getDepth() + 1;
1786-
1787-
while (!genericParams.empty()) {
1788-
if (genericParams.front()->getDepth() >= initialParamDepth)
1789-
break;
1790-
genericParams = genericParams.slice(1);
1791-
}
1792-
1793-
requirementsBuf.clear();
1794-
for (auto &reqt : sig->getRequirements()) {
1795-
// If the requirement is satisfied by the enclosing context,
1796-
// we don't need to mangle it here.
1797-
if (parentGenericSig->isRequirementSatisfied(reqt))
1798-
continue;
1799-
1800-
// Mangle the requirement.
1801-
requirementsBuf.push_back(reqt);
1802-
}
1803-
requirements = requirementsBuf;
1804-
}
1805-
}
1817+
if (isMethodDecl(decl) || isa<SubscriptDecl>(decl))
1818+
parentGenericSig = decl->getDeclContext()->getGenericSignatureOfContext();
18061819
}
1807-
return type->getCanonicalType();
1820+
1821+
return type;
18081822
}
18091823

18101824
void ASTMangler::appendDeclType(const ValueDecl *decl, bool isFunctionMangling) {
1811-
ArrayRef<GenericTypeParamType *> genericParams;
1812-
unsigned initialParamDepth;
1813-
ArrayRef<Requirement> requirements;
1814-
SmallVector<Requirement, 4> requirementsBuf;
18151825
Mod = decl->getModuleContext();
1816-
auto type = getDeclTypeForMangling(decl,
1817-
genericParams, initialParamDepth,
1818-
requirements, requirementsBuf);
1819-
1826+
GenericSignature *genericSig = nullptr;
1827+
GenericSignature *parentGenericSig = nullptr;
1828+
auto type = getDeclTypeForMangling(decl, genericSig, parentGenericSig);
1829+
18201830
if (AnyFunctionType *FuncTy = type->getAs<AnyFunctionType>()) {
18211831

18221832
const ParameterList *Params = nullptr;
@@ -1841,9 +1851,7 @@ void ASTMangler::appendDeclType(const ValueDecl *decl, bool isFunctionMangling)
18411851
}
18421852

18431853
// Mangle the generic signature, if any.
1844-
if (!genericParams.empty() || !requirements.empty()) {
1845-
appendGenericSignatureParts(genericParams, initialParamDepth,
1846-
requirements);
1854+
if (genericSig && appendGenericSignature(genericSig, parentGenericSig)) {
18471855
// The 'F' function mangling doesn't need a 'u' for its generic signature.
18481856
if (!isFunctionMangling)
18491857
appendOperator("u");

0 commit comments

Comments
 (0)