Parse: __shared and __owned should be contextual keywords

This was a source compatibility regression, someone actually had
an identifier named __shared.
This commit is contained in:
Slava Pestov
2017-10-24 17:26:07 -07:00
parent 4970d7d7e8
commit 93c80da77c
8 changed files with 51 additions and 45 deletions

View File

@@ -787,7 +787,10 @@ public:
bool parseTypeAttributeList(VarDecl::Specifier &Specifier,
SourceLoc &SpecifierLoc,
TypeAttributes &Attributes) {
if (Tok.isAny(tok::at_sign, tok::kw_inout, tok::kw___shared, tok::kw___owned))
if (Tok.isAny(tok::at_sign, tok::kw_inout) ||
(Tok.is(tok::identifier) &&
(Tok.getRawText().equals("__shared") ||
Tok.getRawText().equals("__owned"))))
return parseTypeAttributeListPresent(Specifier, SpecifierLoc, Attributes);
return false;
}

View File

@@ -179,13 +179,17 @@ public:
/// used
bool canBeArgumentLabel() const {
// Identifiers, escaped identifiers, and '_' can be argument labels.
if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__))
return true;
if (is(tok::identifier) || isEscapedIdentifier() || is(tok::kw__)) {
// ... except for '__shared' and '__owned'.
if (getRawText().equals("__shared") ||
getRawText().equals("__owned"))
return false;
// 'let', 'var', 'inout', '__shared', and '__owned'
// cannot be argument labels.
if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout,
tok::kw___owned, tok::kw___shared))
return true;
}
// 'let', 'var', and 'inout' cannot be argument labels.
if (isAny(tok::kw_let, tok::kw_var, tok::kw_inout))
return false;
// All other keywords can be argument labels.

View File

@@ -140,8 +140,6 @@ DECL_KEYWORD(struct)
DECL_KEYWORD(subscript)
DECL_KEYWORD(typealias)
DECL_KEYWORD(var)
DECL_KEYWORD(__shared)
DECL_KEYWORD(__owned)
DECL_KEYWORD(fileprivate)
DECL_KEYWORD(internal)

View File

@@ -1820,19 +1820,22 @@ bool Parser::parseTypeAttributeListPresent(VarDecl::Specifier &Specifier,
SourceLoc &SpecifierLoc,
TypeAttributes &Attributes) {
Specifier = VarDecl::Specifier::Owned;
while (Tok.isAny(tok::kw_inout, tok::kw___shared, tok::kw___owned)) {
while (Tok.is(tok::kw_inout) ||
(Tok.is(tok::identifier) &&
(Tok.getRawText().equals("__shared") ||
Tok.getRawText().equals("__owned")))) {
if (SpecifierLoc.isValid()) {
diagnose(Tok, diag::parameter_specifier_repeated)
.fixItRemove(SpecifierLoc);
} else {
if (Tok.is(tok::kw___owned)) {
Specifier = VarDecl::Specifier::Owned;
} else if (Tok.is(tok::kw_inout)) {
if (Tok.is(tok::kw_inout)) {
Specifier = VarDecl::Specifier::InOut;
} else if (Tok.is(tok::kw___shared)) {
Specifier = VarDecl::Specifier::Shared;
} else {
llvm_unreachable("unhandled specifier kind?");
} else if (Tok.is(tok::identifier)) {
if (Tok.getRawText().equals("__shared")) {
Specifier = VarDecl::Specifier::Shared;
} else if (Tok.getRawText().equals("__owned")) {
Specifier = VarDecl::Specifier::Owned;
}
}
}
SpecifierLoc = consumeToken();

View File

@@ -182,15 +182,18 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
// ('inout' | 'let' | 'var' | '__shared' | '__owned')?
bool hasSpecifier = false;
while (Tok.isAny(tok::kw_inout, tok::kw_let, tok::kw_var,
tok::kw___shared, tok::kw___owned)) {
while (Tok.isAny(tok::kw_inout, tok::kw_let, tok::kw_var) ||
(Tok.is(tok::identifier) &&
(Tok.getRawText().equals("__shared") ||
Tok.getRawText().equals("__owned")))) {
if (!hasSpecifier) {
if (Tok.is(tok::kw_inout)) {
// This case is handled later when mapping to ParamDecls for
// better fixits.
param.SpecifierKind = VarDecl::Specifier::InOut;
param.SpecifierLoc = consumeToken();
} else if (Tok.is(tok::kw___shared)) {
} else if (Tok.is(tok::identifier) &&
Tok.getRawText().equals("__shared")) {
// This case is handled later when mapping to ParamDecls for
// better fixits.
param.SpecifierKind = VarDecl::Specifier::Shared;

View File

@@ -175,13 +175,16 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID,
if (Tok.is(tok::kw_inout)) {
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::InOut;
} else if (Tok.is(tok::kw___shared)) {
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::Shared;
} else if (Tok.is(tok::kw___owned)) {
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::Owned;
} else if (Tok.is(tok::identifier)) {
if (Tok.getRawText().equals("__shared")) {
assert(false);
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::Shared;
} else if (Tok.getRawText().equals("__owned")) {
assert(false);
SpecifierLoc = consumeToken();
TypeSpecifier = VarDecl::Specifier::Owned;
}
}
switch (Tok.getKind()) {

View File

@@ -0,0 +1,10 @@
// RUN: %target-swift-frontend -typecheck %s
func __shared() {}
func __owned() {}
func foo() {
__shared()
__owned()
}

View File

@@ -1,23 +1,5 @@
{
key.results: [
{
key.kind: source.lang.swift.keyword,
key.name: "__owned",
key.sourcetext: "__owned",
key.description: "__owned",
key.typename: "",
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "__shared",
key.sourcetext: "__shared",
key.description: "__shared",
key.typename: "",
key.context: source.codecompletion.context.none,
key.num_bytes_to_erase: 0
},
{
key.kind: source.lang.swift.keyword,
key.name: "associatedtype",