Skip to content

Commit 799ab69

Browse files
committed
[parser] Introduce a helper struct for parsing type attributes rather than passing around a bunch of state.
Just refactoring before adding /another/ field to these APIs. It hurt to do so so I needed to refactor. NFCI.
1 parent aad2669 commit 799ab69

File tree

4 files changed

+80
-96
lines changed

4 files changed

+80
-96
lines changed

include/swift/Parse/Parser.h

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,33 +1193,42 @@ class Parser {
11931193
tok::kw_let);
11941194
}
11951195

1196-
ParserStatus parseTypeAttributeList(ParamDecl::Specifier &Specifier,
1197-
SourceLoc &SpecifierLoc,
1198-
SourceLoc &IsolatedLoc,
1199-
SourceLoc &ConstLoc,
1200-
SourceLoc &ResultDependsOnLoc,
1201-
TypeAttributes &Attributes) {
1202-
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
1203-
(canHaveParameterSpecifierContextualKeyword() &&
1204-
(Tok.getRawText().equals("__shared") ||
1205-
Tok.getRawText().equals("__owned") ||
1206-
Tok.getRawText().equals("consuming") ||
1207-
Tok.getRawText().equals("borrowing") ||
1208-
Tok.isContextualKeyword("isolated") ||
1209-
Tok.isContextualKeyword("_const") ||
1210-
Tok.getRawText().equals("_resultDependsOn"))))
1211-
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, IsolatedLoc,
1212-
ConstLoc, ResultDependsOnLoc,
1213-
Attributes);
1214-
return makeParserSuccess();
1215-
}
1196+
struct ParsedTypeAttributeList {
1197+
ParamDecl::Specifier Specifier = ParamDecl::Specifier::Default;
1198+
SourceLoc SpecifierLoc;
1199+
SourceLoc IsolatedLoc;
1200+
SourceLoc ConstLoc;
1201+
SourceLoc ResultDependsOnLoc;
1202+
TypeAttributes Attributes;
12161203

1217-
ParserStatus parseTypeAttributeListPresent(ParamDecl::Specifier &Specifier,
1218-
SourceLoc &SpecifierLoc,
1219-
SourceLoc &IsolatedLoc,
1220-
SourceLoc &ConstLoc,
1221-
SourceLoc &ResultDependsOnLoc,
1222-
TypeAttributes &Attributes);
1204+
/// Main entry point for parsing.
1205+
///
1206+
/// Inline we just have the fast path of failing to match. We call slowParse
1207+
/// that contains the outline of more complex implementation. This is HOT
1208+
/// code!
1209+
ParserStatus parse(Parser &P) {
1210+
auto &Tok = P.Tok;
1211+
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
1212+
(P.canHaveParameterSpecifierContextualKeyword() &&
1213+
(Tok.getRawText().equals("__shared") ||
1214+
Tok.getRawText().equals("__owned") ||
1215+
Tok.getRawText().equals("consuming") ||
1216+
Tok.getRawText().equals("borrowing") ||
1217+
Tok.getRawText().equals("transferring") ||
1218+
Tok.isContextualKeyword("isolated") ||
1219+
Tok.isContextualKeyword("_const") ||
1220+
Tok.getRawText().equals("_resultDependsOn"))))
1221+
return slowParse(P);
1222+
return makeParserSuccess();
1223+
}
1224+
1225+
TypeRepr *applyAttributesToType(Parser &P, TypeRepr *Type) const;
1226+
1227+
private:
1228+
/// An out of line implementation of the more complicated cases. This
1229+
/// ensures on the inlined fast path we handle the case of not matching.
1230+
ParserStatus slowParse(Parser &P);
1231+
};
12231232

12241233
bool parseConventionAttributeInternal(bool justChecking,
12251234
TypeAttributes::Convention &convention);
@@ -1447,12 +1456,6 @@ class Parser {
14471456
bool isImplicitlyUnwrappedOptionalToken(const Token &T) const;
14481457
SourceLoc consumeImplicitlyUnwrappedOptionalToken();
14491458

1450-
TypeRepr *applyAttributeToType(TypeRepr *Ty, const TypeAttributes &Attr,
1451-
ParamDecl::Specifier Specifier,
1452-
SourceLoc SpecifierLoc, SourceLoc IsolatedLoc,
1453-
SourceLoc ConstLoc,
1454-
SourceLoc ResultDependsOnLoc);
1455-
14561459
//===--------------------------------------------------------------------===//
14571460
// Pattern Parsing
14581461

lib/Parse/ParseDecl.cpp

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5129,14 +5129,11 @@ ParserStatus Parser::parseDeclModifierList(DeclAttributes &Attributes,
51295129
/// '@' attribute
51305130
/// '@' attribute attribute-list-clause
51315131
/// \endverbatim
5132-
ParserStatus Parser::parseTypeAttributeListPresent(
5133-
ParamDecl::Specifier &Specifier, SourceLoc &SpecifierLoc,
5134-
SourceLoc &IsolatedLoc, SourceLoc &ConstLoc, SourceLoc &ResultDependsOnLoc,
5135-
TypeAttributes &Attributes) {
5132+
ParserStatus Parser::ParsedTypeAttributeList::slowParse(Parser &P) {
51365133
PatternBindingInitializer *initContext = nullptr;
5137-
Specifier = ParamDecl::Specifier::Default;
5134+
auto &Tok = P.Tok;
51385135
while (Tok.is(tok::kw_inout) ||
5139-
(canHaveParameterSpecifierContextualKeyword() &&
5136+
(P.canHaveParameterSpecifierContextualKeyword() &&
51405137
(Tok.isContextualKeyword("__shared") ||
51415138
Tok.isContextualKeyword("__owned") ||
51425139
Tok.isContextualKeyword("isolated") ||
@@ -5147,31 +5144,31 @@ ParserStatus Parser::parseTypeAttributeListPresent(
51475144

51485145
if (Tok.isContextualKeyword("isolated")) {
51495146
if (IsolatedLoc.isValid()) {
5150-
diagnose(Tok, diag::parameter_specifier_repeated)
5151-
.fixItRemove(SpecifierLoc);
5147+
P.diagnose(Tok, diag::parameter_specifier_repeated)
5148+
.fixItRemove(SpecifierLoc);
51525149
}
5153-
IsolatedLoc = consumeToken();
5150+
IsolatedLoc = P.consumeToken();
51545151
continue;
51555152
}
51565153

51575154
if (Tok.isContextualKeyword("_const")) {
51585155
Tok.setKind(tok::contextual_keyword);
5159-
ConstLoc = consumeToken();
5156+
ConstLoc = P.consumeToken();
51605157
continue;
51615158
}
51625159

51635160
if (Tok.isContextualKeyword("_resultDependsOn")) {
5164-
if (!Context.LangOpts.hasFeature(Feature::NonescapableTypes)) {
5165-
diagnose(Tok, diag::requires_experimental_feature, "resultDependsOn",
5166-
false, getFeatureName(Feature::NonescapableTypes));
5161+
if (!P.Context.LangOpts.hasFeature(Feature::NonescapableTypes)) {
5162+
P.diagnose(Tok, diag::requires_experimental_feature, "resultDependsOn",
5163+
false, getFeatureName(Feature::NonescapableTypes));
51675164
}
5168-
ResultDependsOnLoc = consumeToken();
5165+
ResultDependsOnLoc = P.consumeToken();
51695166
continue;
51705167
}
51715168

51725169
if (SpecifierLoc.isValid()) {
5173-
diagnose(Tok, diag::parameter_specifier_repeated)
5174-
.fixItRemove(SpecifierLoc);
5170+
P.diagnose(Tok, diag::parameter_specifier_repeated)
5171+
.fixItRemove(SpecifierLoc);
51755172
} else {
51765173
if (Tok.is(tok::kw_inout)) {
51775174
Specifier = ParamDecl::Specifier::InOut;
@@ -5188,19 +5185,19 @@ ParserStatus Parser::parseTypeAttributeListPresent(
51885185
}
51895186
}
51905187
Tok.setKind(tok::contextual_keyword);
5191-
SpecifierLoc = consumeToken();
5188+
SpecifierLoc = P.consumeToken();
51925189
}
51935190

51945191
ParserStatus status;
51955192
while (Tok.is(tok::at_sign)) {
51965193
// Ignore @substituted in SIL mode and leave it for the type parser.
5197-
if (isInSILMode() && peekToken().getText() == "substituted")
5194+
if (P.isInSILMode() && P.peekToken().getText() == "substituted")
51985195
return status;
51995196

52005197
if (Attributes.AtLoc.isInvalid())
52015198
Attributes.AtLoc = Tok.getLoc();
5202-
SourceLoc AtLoc = consumeToken();
5203-
status |= parseTypeAttribute(Attributes, AtLoc, initContext);
5199+
SourceLoc AtLoc = P.consumeToken();
5200+
status |= P.parseTypeAttribute(Attributes, AtLoc, initContext);
52045201
if (status.isError())
52055202
return status;
52065203
}

lib/Parse/ParseType.cpp

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,29 @@
3232
using namespace swift;
3333

3434
TypeRepr *
35-
Parser::applyAttributeToType(TypeRepr *ty, const TypeAttributes &attrs,
36-
ParamDecl::Specifier specifier,
37-
SourceLoc specifierLoc, SourceLoc isolatedLoc,
38-
SourceLoc constLoc, SourceLoc resultDependsOnLoc) {
35+
Parser::ParsedTypeAttributeList::applyAttributesToType(Parser &p,
36+
TypeRepr *ty) const {
3937
// Apply those attributes that do apply.
40-
if (!attrs.empty()) {
41-
ty = new (Context) AttributedTypeRepr(attrs, ty);
38+
if (!Attributes.empty()) {
39+
ty = new (p.Context) AttributedTypeRepr(Attributes, ty);
4240
}
4341

4442
// Apply 'inout', 'consuming', or 'borrowing' modifiers.
45-
if (specifierLoc.isValid() &&
46-
specifier != ParamDecl::Specifier::Default) {
47-
ty = new (Context) OwnershipTypeRepr(ty, specifier, specifierLoc);
43+
if (SpecifierLoc.isValid() && Specifier != ParamDecl::Specifier::Default) {
44+
ty = new (p.Context) OwnershipTypeRepr(ty, Specifier, SpecifierLoc);
4845
}
49-
46+
5047
// Apply 'isolated'.
51-
if (isolatedLoc.isValid()) {
52-
ty = new (Context) IsolatedTypeRepr(ty, isolatedLoc);
48+
if (IsolatedLoc.isValid()) {
49+
ty = new (p.Context) IsolatedTypeRepr(ty, IsolatedLoc);
5350
}
5451

55-
if (constLoc.isValid()) {
56-
ty = new (Context) CompileTimeConstTypeRepr(ty, constLoc);
52+
if (ConstLoc.isValid()) {
53+
ty = new (p.Context) CompileTimeConstTypeRepr(ty, ConstLoc);
5754
}
5855

59-
if (resultDependsOnLoc.isValid()) {
60-
ty = new (Context) ResultDependsOnTypeRepr(ty, resultDependsOnLoc);
56+
if (ResultDependsOnLoc.isValid()) {
57+
ty = new (p.Context) ResultDependsOnTypeRepr(ty, ResultDependsOnLoc);
6158
}
6259

6360
return ty;
@@ -388,9 +385,11 @@ ParserResult<TypeRepr> Parser::parseSILBoxType(GenericParamList *generics,
388385
auto repr = SILBoxTypeRepr::create(Context, generics,
389386
LBraceLoc, Fields, RBraceLoc,
390387
LAngleLoc, Args, RAngleLoc);
388+
ParsedTypeAttributeList parsedAttributeList;
389+
parsedAttributeList.Specifier = ParamDecl::Specifier::LegacyOwned;
390+
parsedAttributeList.Attributes = attrs;
391391
return makeParserResult(
392-
applyAttributeToType(repr, attrs, ParamDecl::Specifier::LegacyOwned,
393-
SourceLoc(), SourceLoc(), SourceLoc(), SourceLoc()));
392+
parsedAttributeList.applyAttributesToType(*this, repr));
394393
}
395394

396395

@@ -408,14 +407,8 @@ ParserResult<TypeRepr> Parser::parseTypeScalar(
408407
ParserStatus status;
409408

410409
// Parse attributes.
411-
ParamDecl::Specifier specifier;
412-
SourceLoc specifierLoc;
413-
SourceLoc isolatedLoc;
414-
SourceLoc constLoc;
415-
SourceLoc resultDependsOnLoc;
416-
TypeAttributes attrs;
417-
status |= parseTypeAttributeList(specifier, specifierLoc, isolatedLoc,
418-
constLoc, resultDependsOnLoc, attrs);
410+
ParsedTypeAttributeList parsedAttributeList;
411+
status |= parsedAttributeList.parse(*this);
419412

420413
// Parse generic parameters in SIL mode.
421414
GenericParamList *generics = nullptr;
@@ -439,7 +432,7 @@ ParserResult<TypeRepr> Parser::parseTypeScalar(
439432
if (patternGenerics) {
440433
diagnose(Tok.getLoc(), diag::sil_function_subst_expected_function);
441434
}
442-
return parseSILBoxType(generics, attrs);
435+
return parseSILBoxType(generics, parsedAttributeList.Attributes);
443436
}
444437

445438
ParserResult<TypeRepr> ty = parseTypeSimpleOrComposition(MessageID, reason);
@@ -596,8 +589,7 @@ ParserResult<TypeRepr> Parser::parseTypeScalar(
596589
}
597590

598591
return makeParserResult(
599-
status, applyAttributeToType(tyR, attrs, specifier, specifierLoc,
600-
isolatedLoc, constLoc, resultDependsOnLoc));
592+
status, parsedAttributeList.applyAttributesToType(*this, tyR));
601593
}
602594

603595
/// parseType

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,21 +1122,15 @@ bool SILParser::parseSILType(SILType &Result,
11221122
}
11231123

11241124
// Parse attributes.
1125-
ParamDecl::Specifier specifier;
1126-
SourceLoc specifierLoc;
1127-
SourceLoc isolatedLoc;
1128-
SourceLoc constLoc;
1129-
SourceLoc resultDependsOnLoc;
1130-
TypeAttributes attrs;
1131-
P.parseTypeAttributeList(specifier, specifierLoc, isolatedLoc, constLoc,
1132-
resultDependsOnLoc, attrs);
1125+
Parser::ParsedTypeAttributeList parsedAttrs;
1126+
parsedAttrs.parse(P);
11331127

11341128
// Global functions are implicitly @convention(thin) if not specified otherwise.
1135-
if (IsFuncDecl && !attrs.has(TAK_convention)) {
1129+
if (IsFuncDecl && !parsedAttrs.Attributes.has(TAK_convention)) {
11361130
// Use a random location.
1137-
attrs.setAttr(TAK_convention, P.PreviousLoc);
1138-
attrs.ConventionArguments =
1139-
TypeAttributes::Convention::makeSwiftConvention("thin");
1131+
parsedAttrs.Attributes.setAttr(TAK_convention, P.PreviousLoc);
1132+
parsedAttrs.Attributes.ConventionArguments =
1133+
TypeAttributes::Convention::makeSwiftConvention("thin");
11401134
}
11411135

11421136
ParserResult<TypeRepr> TyR = P.parseType(diag::expected_sil_type);
@@ -1147,9 +1141,7 @@ bool SILParser::parseSILType(SILType &Result,
11471141
bindSILGenericParams(TyR.get());
11481142

11491143
// Apply attributes to the type.
1150-
auto *attrRepr =
1151-
P.applyAttributeToType(TyR.get(), attrs, specifier, specifierLoc,
1152-
isolatedLoc, constLoc, resultDependsOnLoc);
1144+
auto *attrRepr = parsedAttrs.applyAttributesToType(P, TyR.get());
11531145
auto Ty = performTypeResolution(attrRepr, /*IsSILType=*/true, OuterGenericSig,
11541146
OuterGenericParams);
11551147
if (OuterGenericSig) {

0 commit comments

Comments
 (0)