Skip to content

Commit 892a900

Browse files
committed
Track a discriminator for named declarations (except physical
vars) in local contexts, for future use in mangling. Swift SVN r10827
1 parent f08ee12 commit 892a900

File tree

4 files changed

+93
-10
lines changed

4 files changed

+93
-10
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,14 @@ class ValueDecl : public Decl {
11551155
/// function requires capturing it.
11561156
bool needsCapture() const;
11571157

1158+
/// Retrieve the context discriminator for this local value, which
1159+
/// is the index of this declaration in the sequence of
1160+
/// discriminated declarations with the same name in the current
1161+
/// context. Only local functions and variables with getters and
1162+
/// setters have discriminators.
1163+
unsigned getLocalDiscriminator() const;
1164+
void setLocalDiscriminator(unsigned index);
1165+
11581166
/// Retrieve the declaration that this declaration overrides, if any.
11591167
ValueDecl *getOverriddenDecl() const;
11601168

include/swift/Parse/Parser.h

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class Parser {
8282
unsigned VarPatternDepth = 0;
8383
bool GreaterThanIsOperator = true;
8484

85+
typedef llvm::DenseMap<Identifier, unsigned> LocalDiscriminatorMap;
86+
LocalDiscriminatorMap *LocalDiscriminators = nullptr;
87+
8588
DelayedParsingCallbacks *DelayedParseCB = nullptr;
8689

8790
bool isDelayedParsingEnabled() const { return DelayedParseCB != nullptr; }
@@ -110,25 +113,49 @@ class Parser {
110113

111114
/// A RAII object for temporarily changing CurDeclContext.
112115
class ContextChange {
116+
protected:
113117
Parser &P;
114118
DeclContext *OldContext;
119+
LocalDiscriminatorMap *OldDiscriminators;
115120
public:
116-
ContextChange(Parser &P, DeclContext *DC)
117-
: P(P), OldContext(P.CurDeclContext) {
121+
ContextChange(Parser &P, DeclContext *DC,
122+
LocalDiscriminatorMap *discriminators = nullptr)
123+
: P(P), OldContext(P.CurDeclContext),
124+
OldDiscriminators(P.LocalDiscriminators) {
118125
assert(DC && "pushing null context?");
119126
P.CurDeclContext = DC;
127+
P.LocalDiscriminators = discriminators;
120128
}
121129

122130
/// Prematurely pop the DeclContext installed by the constructor.
123131
/// Makes the destructor a no-op.
124132
void pop() {
125133
assert(OldContext && "already popped context!");
126-
P.CurDeclContext = OldContext;
134+
popImpl();
127135
OldContext = nullptr;
128136
}
129137

130138
~ContextChange() {
131-
if (OldContext) P.CurDeclContext = OldContext;
139+
if (OldContext) popImpl();
140+
}
141+
142+
private:
143+
void popImpl() {
144+
P.CurDeclContext = OldContext;
145+
P.LocalDiscriminators = OldDiscriminators;
146+
}
147+
};
148+
149+
/// A RAII object for parsing a new function/closure body.
150+
class ParseFunctionBody {
151+
LocalDiscriminatorMap LocalDiscriminators;
152+
ContextChange CC;
153+
public:
154+
ParseFunctionBody(Parser &P, DeclContext *DC)
155+
: CC(P, DC, &LocalDiscriminators) {}
156+
157+
void pop() {
158+
CC.pop();
132159
}
133160
};
134161

@@ -480,6 +507,8 @@ class Parser {
480507
bool isAssociatedType,
481508
DeclAttributes &Attributes);
482509

510+
void setLocalDiscriminator(ValueDecl *D);
511+
483512
/// \brief Add the variables in the given pattern to the current scope,
484513
/// collecting the variables in the vector \c Decls and applying
485514
/// \c Attributes and \c Static to each one.

lib/AST/ASTContext.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ struct ASTContext::Implementation {
9696
/// they were imported.
9797
llvm::DenseMap<swift::Decl *, ClangNode> ClangNodes;
9898

99+
/// \brief Map from local declarations to their discriminators.
100+
/// Missing entries implicitly have value 0.
101+
llvm::DenseMap<const ValueDecl *, unsigned> LocalDiscriminators;
102+
99103
/// \brief Structure that captures data that is segregated into different
100104
/// arenas.
101105
struct Arena {
@@ -701,6 +705,24 @@ void ASTContext::setClangNode(Decl *decl, ClangNode node) {
701705
Impl.ClangNodes[decl] = node;
702706
}
703707

708+
unsigned ValueDecl::getLocalDiscriminator() const {
709+
assert(getDeclContext()->isLocalContext());
710+
auto &discriminators = getASTContext().Impl.LocalDiscriminators;
711+
auto it = discriminators.find(this);
712+
if (it == discriminators.end())
713+
return 0;
714+
return it->second;
715+
}
716+
717+
void ValueDecl::setLocalDiscriminator(unsigned index) {
718+
assert(getDeclContext()->isLocalContext());
719+
if (!index) {
720+
assert(!getASTContext().Impl.LocalDiscriminators.count(this));
721+
return;
722+
}
723+
getASTContext().Impl.LocalDiscriminators.insert({this, index});
724+
}
725+
704726
void ASTContext::recordConformance(KnownProtocolKind protocolKind, Decl *decl) {
705727
assert(isa<NominalTypeDecl>(decl) || isa<ExtensionDecl>(decl));
706728
auto index = static_cast<unsigned>(protocolKind);

lib/Parse/ParseDecl.cpp

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,18 @@ void Parser::consumeDecl(ParserPosition BeginParserPosition, unsigned Flags,
465465
}
466466
}
467467

468+
void Parser::setLocalDiscriminator(ValueDecl *D) {
469+
// If we're not in a local context, this is unnecessary.
470+
if (!LocalDiscriminators) return;
471+
472+
Identifier name = D->getName();
473+
assert(!name.empty() &&
474+
"setting a local discriminator on an anonymous decl; "
475+
"maybe the name hasn't been set yet?");
476+
unsigned discriminator = (*LocalDiscriminators)[name]++;
477+
D->setLocalDiscriminator(discriminator);
478+
}
479+
468480
/// \brief Parse a single syntactic declaration and return a list of decl
469481
/// ASTs. This can return multiple results for var decls that bind to multiple
470482
/// values, structs that define a struct decl and a constructor, etc.
@@ -1160,7 +1172,7 @@ bool Parser::parseGetSet(bool HasContainerType, Pattern *Indices,
11601172
addFunctionParametersToScope(Get->getBodyParamPatterns(), Get);
11611173

11621174
// Establish the new context.
1163-
ContextChange CC(*this, Get);
1175+
ParseFunctionBody CC(*this, Get);
11641176

11651177
SmallVector<ASTNode, 16> Entries;
11661178
parseBraceItems(Entries, BraceItemListKind::Variable);
@@ -1281,7 +1293,7 @@ bool Parser::parseGetSet(bool HasContainerType, Pattern *Indices,
12811293
addFunctionParametersToScope(Set->getBodyParamPatterns(), Set);
12821294

12831295
// Establish the new context.
1284-
ContextChange CC(*this, Set);
1296+
ParseFunctionBody CC(*this, Set);
12851297

12861298
// Parse the body.
12871299
SmallVector<ASTNode, 16> Entries;
@@ -1334,6 +1346,8 @@ void Parser::parseDeclVarGetSet(Pattern &pattern, bool HasContainerType,
13341346
diagnose(pattern.getLoc(), diag::getset_missing_type);
13351347
TyLoc = TypeLoc::withoutLoc(ErrorType::get(Context));
13361348
}
1349+
1350+
setLocalDiscriminator(PrimaryVar);
13371351

13381352
SourceLoc LBLoc = consumeToken(tok::l_brace);
13391353

@@ -1684,6 +1698,7 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, unsigned Flags,
16841698

16851699
addFunctionParametersToScope(FD->getBodyParamPatterns(), FD);
16861700
setVarContext(FD->getArgParamPatterns(), FD);
1701+
setLocalDiscriminator(FD);
16871702

16881703
// Now that we have a context, update the generic parameters with that
16891704
// context.
@@ -1694,7 +1709,7 @@ Parser::parseDeclFunc(SourceLoc StaticLoc, unsigned Flags,
16941709
}
16951710

16961711
// Establish the new context.
1697-
ContextChange CC(*this, FD);
1712+
ParseFunctionBody CC(*this, FD);
16981713

16991714
// Check to see if we have a "{" to start a brace statement.
17001715
if (Tok.is(tok::l_brace)) {
@@ -1762,7 +1777,7 @@ bool Parser::parseAbstractFunctionBodyDelayed(AbstractFunctionDecl *AFD) {
17621777

17631778
// Re-enter the lexical scope.
17641779
Scope S(this, FunctionParserState->takeScope());
1765-
ContextChange CC(*this, AFD);
1780+
ParseFunctionBody CC(*this, AFD);
17661781

17671782
ParserResult<BraceStmt> Body =
17681783
parseBraceItemList(diag::func_decl_without_brace);
@@ -1810,6 +1825,7 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(unsigned Flags,
18101825

18111826
EnumDecl *UD = new (Context) EnumDecl(EnumLoc, EnumName, EnumNameLoc,
18121827
{ }, GenericParams, CurDeclContext);
1828+
setLocalDiscriminator(UD);
18131829

18141830
if (Attributes.isValid())
18151831
UD->getMutableAttrs() = Attributes;
@@ -2068,6 +2084,7 @@ ParserResult<StructDecl> Parser::parseDeclStruct(unsigned Flags,
20682084
{ },
20692085
GenericParams,
20702086
CurDeclContext);
2087+
setLocalDiscriminator(SD);
20712088

20722089
if (Attributes.isValid())
20732090
SD->getMutableAttrs() = Attributes;
@@ -2152,6 +2169,7 @@ ParserResult<ClassDecl> Parser::parseDeclClass(unsigned Flags,
21522169
// Create the class.
21532170
ClassDecl *CD = new (Context) ClassDecl(ClassLoc, ClassName, ClassNameLoc,
21542171
{ }, GenericParams, CurDeclContext);
2172+
setLocalDiscriminator(CD);
21552173

21562174
// Attach attributes.
21572175
if (Attributes.isValid())
@@ -2238,6 +2256,7 @@ parseDeclProtocol(unsigned Flags, DeclAttributes &Attributes) {
22382256
= new (Context) ProtocolDecl(CurDeclContext, ProtocolLoc, NameLoc,
22392257
ProtocolName,
22402258
Context.AllocateCopy(InheritedProtocols));
2259+
// No need to setLocalDiscriminator: protocols can't appear in local contexts.
22412260

22422261
if (Attributes.isValid())
22432262
Proto->getMutableAttrs() = Attributes;
@@ -2376,6 +2395,9 @@ ParserStatus Parser::parseDeclSubscript(bool HasContainerType,
23762395
SubscriptLoc, Indices.get(), ArrowLoc,
23772396
ElementTy.get(), DefRange,
23782397
Get, Set, CurDeclContext);
2398+
// No need to setLocalDiscriminator because subscripts cannot
2399+
// validly appear outside of type decls.
2400+
23792401
if (Attributes.isValid())
23802402
Subscript->getMutableAttrs() = Attributes;
23812403

@@ -2445,6 +2467,7 @@ Parser::parseDeclConstructor(unsigned Flags, DeclAttributes &Attributes) {
24452467
new (Context) ConstructorDecl(Context.getIdentifier("init"),
24462468
ConstructorLoc, ArgPattern, BodyPattern,
24472469
SelfDecl, GenericParams, CurDeclContext);
2470+
// No need to setLocalDiscriminator.
24482471

24492472
if (HasSelectorStyleSignature)
24502473
CD->setHasSelectorStyleSignature();
@@ -2482,7 +2505,7 @@ Parser::parseDeclConstructor(unsigned Flags, DeclAttributes &Attributes) {
24822505
}
24832506
} else {
24842507
// Parse the body.
2485-
ContextChange CC(*this, CD);
2508+
ParseFunctionBody CC(*this, CD);
24862509

24872510
if (!isDelayedParsingEnabled()) {
24882511
ParserResult<BraceStmt> Body = parseBraceItemList(diag::invalid_diagnostic);
@@ -2560,13 +2583,14 @@ parseDeclDestructor(unsigned Flags, DeclAttributes &Attributes) {
25602583
DestructorDecl *DD
25612584
= new (Context) DestructorDecl(Context.getIdentifier("destructor"),
25622585
DestructorLoc, SelfDecl, CurDeclContext);
2586+
// No need to setLocalDiscriminator.
25632587

25642588
SelfDecl->setDeclContext(DD);
25652589
addToScope(SelfDecl);
25662590

25672591
// Parse the body.
25682592
if (Tok.is(tok::l_brace)) {
2569-
ContextChange CC(*this, DD);
2593+
ParseFunctionBody CC(*this, DD);
25702594
if (!isDelayedParsingEnabled()) {
25712595
ParserResult<BraceStmt> Body = parseBraceItemList(diag::invalid_diagnostic);
25722596

0 commit comments

Comments
 (0)