Skip to content

Commit c1a85c1

Browse files
authored
Merge pull request #62741 from DougGregor/local-named-discriminators
Rework computation of local discriminators for named entities.
2 parents 0e691c4 + 9df8541 commit c1a85c1

20 files changed

+255
-200
lines changed

include/swift/AST/Decl.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2292,10 +2292,14 @@ class GenericParameterReferenceInfo final {
22922292
/// ValueDecl - All named decls that are values in the language. These can
22932293
/// have a type, etc.
22942294
class ValueDecl : public Decl {
2295+
public:
2296+
enum : unsigned { InvalidDiscriminator = 0xFFFF };
2297+
2298+
private:
22952299
DeclName Name;
22962300
SourceLoc NameLoc;
22972301
llvm::PointerIntPair<Type, 3, OptionalEnum<AccessLevel>> TypeAndAccess;
2298-
unsigned LocalDiscriminator = 0;
2302+
unsigned LocalDiscriminator = InvalidDiscriminator;
22992303

23002304
struct {
23012305
/// Whether the "IsObjC" bit has been computed yet.
@@ -2582,6 +2586,12 @@ class ValueDecl : public Decl {
25822586
unsigned getLocalDiscriminator() const;
25832587
void setLocalDiscriminator(unsigned index);
25842588

2589+
/// Whether this declaration has a local discriminator.
2590+
bool hasLocalDiscriminator() const;
2591+
2592+
/// Return the "raw" local discriminator, without computing it.
2593+
unsigned getRawLocalDiscriminator() const { return LocalDiscriminator; }
2594+
25852595
/// Retrieve the declaration that this declaration overrides, if any.
25862596
ValueDecl *getOverriddenDecl() const;
25872597

include/swift/AST/TypeCheckRequests.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3850,7 +3850,7 @@ class SynthesizeRuntimeMetadataAttrGeneratorBody
38503850
/// Compute the local discriminators for the given declaration context.
38513851
///
38523852
/// This is a state-changing operation for closures within the context, which
3853-
/// produces the number of assigned discriminators.
3853+
/// produces the discriminator value that any subsequent requests should use.
38543854
class LocalDiscriminatorsRequest
38553855
: public SimpleRequest<LocalDiscriminatorsRequest,
38563856
unsigned(DeclContext *),

include/swift/Parse/LocalContext.h

Lines changed: 0 additions & 55 deletions
This file was deleted.

include/swift/Parse/Parser.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "swift/AST/Stmt.h"
2828
#include "swift/Basic/OptionSet.h"
2929
#include "swift/Parse/Lexer.h"
30-
#include "swift/Parse/LocalContext.h"
3130
#include "swift/Parse/PersistentParserState.h"
3231
#include "swift/Parse/Token.h"
3332
#include "swift/Parse/ParserPosition.h"
@@ -176,8 +175,6 @@ class Parser {
176175
bool InInactiveClauseEnvironment = false;
177176
bool InSwiftKeyPath = false;
178177

179-
LocalContext *CurLocalContext = nullptr;
180-
181178
/// Whether we should delay parsing nominal type, extension, and function
182179
/// bodies.
183180
bool isDelayedParsingEnabled() const;
@@ -241,18 +238,15 @@ class Parser {
241238
protected:
242239
Parser &P;
243240
DeclContext *OldContext; // null signals that this has been popped
244-
LocalContext *OldLocal;
245241

246242
ContextChange(const ContextChange &) = delete;
247243
ContextChange &operator=(const ContextChange &) = delete;
248244

249245
public:
250-
ContextChange(Parser &P, DeclContext *DC,
251-
LocalContext *newLocal = nullptr)
252-
: P(P), OldContext(P.CurDeclContext), OldLocal(P.CurLocalContext) {
246+
ContextChange(Parser &P, DeclContext *DC)
247+
: P(P), OldContext(P.CurDeclContext) {
253248
assert(DC && "pushing null context?");
254249
P.CurDeclContext = DC;
255-
P.CurLocalContext = newLocal;
256250
}
257251

258252
/// Prematurely pop the DeclContext installed by the constructor.
@@ -270,16 +264,15 @@ class Parser {
270264
private:
271265
void popImpl() {
272266
P.CurDeclContext = OldContext;
273-
P.CurLocalContext = OldLocal;
274267
}
275268
};
276269

277270
/// A RAII object for parsing a new local context.
278-
class ParseFunctionBody : public LocalContext {
271+
class ParseFunctionBody {
279272
private:
280273
ContextChange CC;
281274
public:
282-
ParseFunctionBody(Parser &P, DeclContext *DC) : CC(P, DC, this) {
275+
ParseFunctionBody(Parser &P, DeclContext *DC) : CC(P, DC) {
283276
assert(!isa<TopLevelCodeDecl>(DC) &&
284277
"top-level code should be parsed using TopLevelCodeContext!");
285278
}
@@ -990,8 +983,7 @@ class Parser {
990983
/// 'isLine = true' indicates parsing #line instead of #sourcelocation
991984
ParserStatus parseLineDirective(bool isLine = false);
992985

993-
void setLocalDiscriminator(ValueDecl *D);
994-
void setLocalDiscriminatorToParamList(ParameterList *PL);
986+
void recordLocalType(TypeDecl *TD);
995987

996988
/// Skip an `#if` configuration block containing only attributes.
997989
///

include/swift/Parse/PersistentParserState.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#define SWIFT_PARSE_PERSISTENTPARSERSTATE_H
1919

2020
#include "swift/Basic/SourceLoc.h"
21-
#include "swift/Parse/LocalContext.h"
2221

2322
namespace swift {
2423

@@ -54,9 +53,6 @@ class IDEInspectionDelayedDeclState {
5453
class PersistentParserState {
5554
std::unique_ptr<IDEInspectionDelayedDeclState> IDEInspectionDelayedDeclStat;
5655

57-
/// The local context for all top-level code.
58-
TopLevelContext TopLevelCode;
59-
6056
public:
6157
PersistentParserState();
6258
PersistentParserState(ASTContext &ctx) : PersistentParserState() { }
@@ -88,10 +84,6 @@ class PersistentParserState {
8884
assert(hasIDEInspectionDelayedDeclState());
8985
return std::move(IDEInspectionDelayedDeclStat);
9086
}
91-
92-
TopLevelContext &getTopLevelContext() {
93-
return TopLevelCode;
94-
}
9587
};
9688

9789
} // end namespace swift

lib/AST/Decl.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,13 +2696,55 @@ bool ValueDecl::isInstanceMember() const {
26962696
llvm_unreachable("bad DeclKind");
26972697
}
26982698

2699+
bool ValueDecl::hasLocalDiscriminator() const {
2700+
// Generic parameters and unnamed parameters never have local discriminators.
2701+
if (isa<GenericTypeParamDecl>(this) ||
2702+
(isa<ParamDecl>(this) && !hasName()))
2703+
return false;
2704+
2705+
// Opaque types never have local discriminators.
2706+
if (isa<OpaqueTypeDecl>(this))
2707+
return false;
2708+
2709+
// Accessors never have local discriminators.
2710+
if (isa<AccessorDecl>(this))
2711+
return false;
2712+
2713+
// Implicit and unnamed declarations never have local discriminators.
2714+
if (getBaseName().isSpecial())
2715+
return false;
2716+
2717+
// If we are not in a local context, there's nothing to do.
2718+
if (!getDeclContext()->isLocalContext())
2719+
return false;
2720+
2721+
return true;
2722+
}
2723+
26992724
unsigned ValueDecl::getLocalDiscriminator() const {
2725+
// If we have already assigned a local discriminator, we're done.
2726+
if (LocalDiscriminator != InvalidDiscriminator)
2727+
return LocalDiscriminator;
2728+
2729+
// If this declaration does not have a local discriminator, use 0 as a
2730+
// stand-in.
2731+
if (!hasLocalDiscriminator())
2732+
return 0;
2733+
2734+
// Assign local discriminators in this context.
2735+
evaluateOrDefault(
2736+
getASTContext().evaluator,
2737+
LocalDiscriminatorsRequest{getDeclContext()}, InvalidDiscriminator);
2738+
2739+
assert(LocalDiscriminator != InvalidDiscriminator);
2740+
27002741
return LocalDiscriminator;
27012742
}
27022743

27032744
void ValueDecl::setLocalDiscriminator(unsigned index) {
2704-
assert(getDeclContext()->isLocalContext());
2705-
assert(LocalDiscriminator == 0 && "LocalDiscriminator is set multiple times");
2745+
assert(hasLocalDiscriminator());
2746+
assert(LocalDiscriminator == InvalidDiscriminator &&
2747+
"LocalDiscriminator is set multiple times");
27062748
LocalDiscriminator = index;
27072749
}
27082750

lib/Index/Index.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
448448
StringScratchSpace stringStorage;
449449
ContainerTracker Containers;
450450

451+
// Contains a mapping for captures of the form [x], from the declared "x"
452+
// to the captured "x" in the enclosing scope.
453+
llvm::DenseMap<VarDecl *, VarDecl *> sameNamedCaptures;
454+
451455
bool getNameAndUSR(ValueDecl *D, ExtensionDecl *ExtD,
452456
StringRef &name, StringRef &USR) {
453457
auto &result = nameAndUSRCache[ExtD ? (Decl*)ExtD : D];
@@ -701,6 +705,26 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
701705
bool walkToExprPre(Expr *E) override {
702706
if (Cancelled)
703707
return false;
708+
709+
// Record any captures of the form [x], herso we can treat
710+
if (auto captureList = dyn_cast<CaptureListExpr>(E)) {
711+
for (const auto &capture : captureList->getCaptureList()) {
712+
auto declaredVar = capture.getVar();
713+
if (capture.PBD->getEqualLoc(0).isValid())
714+
continue;
715+
716+
VarDecl *capturedVar = nullptr;
717+
if (auto init = capture.PBD->getInit(0)) {
718+
if (auto declRef = dyn_cast<DeclRefExpr>(init))
719+
capturedVar = dyn_cast_or_null<VarDecl>(declRef->getDecl());
720+
}
721+
722+
if (capturedVar) {
723+
sameNamedCaptures[declaredVar] = capturedVar;
724+
}
725+
}
726+
}
727+
704728
ExprStack.push_back(E);
705729
Containers.activateContainersFor(E);
706730
handleMemberwiseInitRefs(E);
@@ -1611,6 +1635,15 @@ bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
16111635
if (auto *VD = dyn_cast<VarDecl>(D)) {
16121636
// Always base the symbol information on the canonical VarDecl
16131637
D = VD->getCanonicalVarDecl();
1638+
1639+
// Dig back to the original captured variable.
1640+
while (true) {
1641+
auto captured = sameNamedCaptures.find(cast<VarDecl>(D));
1642+
if (captured == sameNamedCaptures.end())
1643+
break;
1644+
1645+
D = captured->second;
1646+
}
16141647
}
16151648

16161649
Info.decl = D;

0 commit comments

Comments
 (0)