Skip to content

Commit a5453f1

Browse files
committed
AST: Add new variant of swift::getParameterAt() which takes pack expansions into account
1 parent 0dfdf1c commit a5453f1

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8399,6 +8399,10 @@ ParameterList *getParameterList(ValueDecl *source);
83998399
/// there is none.
84008400
ParameterList *getParameterList(DeclContext *source);
84018401

8402+
/// Retrieve parameter declaration from the given source at given index, or
8403+
/// nullptr if the source does not have a parameter list.
8404+
const ParamDecl *getParameterAt(ConcreteDeclRef declRef, unsigned index);
8405+
84028406
/// Retrieve parameter declaration from the given source at given index, or
84038407
/// nullptr if the source does not have a parameter list.
84048408
const ParamDecl *getParameterAt(const ValueDecl *source, unsigned index);

include/swift/AST/ParameterList.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
namespace swift {
2626

27+
class SubstitutionMap;
28+
2729
/// This describes a list of parameters. Each parameter descriptor is tail
2830
/// allocated onto this list.
2931
class alignas(ParamDecl *) ParameterList final :
@@ -134,6 +136,8 @@ class alignas(ParamDecl *) ParameterList final :
134136
/// based on the interface types of the parameters in this list.
135137
void getParams(SmallVectorImpl<AnyFunctionType::Param> &params) const;
136138

139+
unsigned getOrigParamIndex(SubstitutionMap subMap, unsigned substIndex) const;
140+
137141
/// Return the full source range of this parameter.
138142
SourceRange getSourceRange() const;
139143
SourceLoc getStartLoc() const { return getSourceRange().Start; }

lib/AST/Decl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7743,6 +7743,17 @@ ParameterList *swift::getParameterList(DeclContext *source) {
77437743
return nullptr;
77447744
}
77457745

7746+
const ParamDecl *swift::getParameterAt(ConcreteDeclRef declRef,
7747+
unsigned index) {
7748+
auto *source = declRef.getDecl();
7749+
if (auto *params = getParameterList(const_cast<ValueDecl *>(source))) {
7750+
unsigned origIndex = params->getOrigParamIndex(declRef.getSubstitutions(),
7751+
index);
7752+
return params->get(origIndex);
7753+
}
7754+
return nullptr;
7755+
}
7756+
77467757
const ParamDecl *swift::getParameterAt(const ValueDecl *source,
77477758
unsigned index) {
77487759
if (auto *params = getParameterList(const_cast<ValueDecl *>(source))) {

lib/AST/ParameterPack.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "swift/AST/Types.h"
1919
#include "swift/AST/Decl.h"
20+
#include "swift/AST/ParameterList.h"
2021
#include "swift/AST/Type.h"
2122
#include "llvm/ADT/SmallVector.h"
2223

@@ -249,4 +250,32 @@ PackType *PackType::flattenPackTypes() {
249250
return this;
250251

251252
return PackType::get(getASTContext(), elts);
253+
}
254+
255+
unsigned ParameterList::getOrigParamIndex(SubstitutionMap subMap,
256+
unsigned substIndex) const {
257+
unsigned remappedIndex = substIndex;
258+
259+
for (unsigned i = 0, e = size(); i < e; ++i) {
260+
auto *param = get(i);
261+
auto paramType = param->getInterfaceType();
262+
263+
unsigned substCount = 1;
264+
if (auto *packExpansionType = paramType->getAs<PackExpansionType>()) {
265+
auto replacementType = packExpansionType->getCountType().subst(subMap);
266+
if (auto *packType = replacementType->getAs<PackType>()) {
267+
substCount = packType->getNumElements();
268+
}
269+
}
270+
271+
if (remappedIndex < substCount)
272+
return i;
273+
274+
remappedIndex -= substCount;
275+
}
276+
277+
llvm::errs() << "Invalid substituted argument index: " << substIndex << "\n";
278+
subMap.dump(llvm::errs());
279+
dump(llvm::errs());
280+
abort();
252281
}

lib/Sema/MiscDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
526526
return;
527527

528528
// Get underlying params for both callee and caller, if declared.
529-
auto *calleeParam = getParameterAt(callee.getDecl(), argIndex);
529+
auto *calleeParam = getParameterAt(callee, argIndex);
530530
auto *callerParam = dyn_cast_or_null<ParamDecl>(
531531
arg->getReferencedDecl(/*stopAtParenExpr=*/true).getDecl()
532532
);

0 commit comments

Comments
 (0)