mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[AST] Explicitly track things marked __owned.
This commit is contained in:
@@ -212,6 +212,12 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
|
||||
// better fixits.
|
||||
param.SpecifierKind = VarDecl::Specifier::Shared;
|
||||
param.SpecifierLoc = consumeToken();
|
||||
} else if (Tok.is(tok::identifier) &&
|
||||
Tok.getRawText().equals("__owned")) {
|
||||
// This case is handled later when mapping to ParamDecls for
|
||||
// better fixits.
|
||||
param.SpecifierKind = VarDecl::Specifier::Owned;
|
||||
param.SpecifierLoc = consumeToken();
|
||||
} else {
|
||||
diagnose(Tok, diag::parameter_let_var_as_attr, Tok.getText())
|
||||
.fixItRemove(Tok.getLoc());
|
||||
@@ -352,6 +358,28 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
|
||||
return status;
|
||||
});
|
||||
}
|
||||
template <typename T>
|
||||
static TypeRepr *
|
||||
validateParameterWithSpecifier(Parser &parser,
|
||||
Parser::ParsedParameter ¶mInfo,
|
||||
StringRef specifierName) {
|
||||
auto type = paramInfo.Type;
|
||||
auto loc = paramInfo.SpecifierLoc;
|
||||
if (isa<SpecifierTypeRepr>(type)) {
|
||||
parser.diagnose(loc, diag::parameter_specifier_repeated).fixItRemove(loc);
|
||||
} else {
|
||||
llvm::SmallString<128> replacement(specifierName);
|
||||
replacement += " ";
|
||||
parser
|
||||
.diagnose(loc, diag::parameter_specifier_as_attr_disallowed,
|
||||
specifierName)
|
||||
.fixItRemove(loc)
|
||||
.fixItInsert(type->getStartLoc(), replacement);
|
||||
type = new (parser.Context) T(type, loc);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/// Map parsed parameters to a ParameterList.
|
||||
static ParameterList *
|
||||
@@ -384,28 +412,14 @@ mapParsedParameters(Parser &parser,
|
||||
if (auto type = paramInfo.Type) {
|
||||
// If 'inout' was specified, turn the type into an in-out type.
|
||||
if (paramInfo.SpecifierKind == VarDecl::Specifier::InOut) {
|
||||
auto InOutLoc = paramInfo.SpecifierLoc;
|
||||
if (isa<InOutTypeRepr>(type)) {
|
||||
parser.diagnose(InOutLoc, diag::parameter_specifier_repeated)
|
||||
.fixItRemove(InOutLoc);
|
||||
} else {
|
||||
parser.diagnose(InOutLoc, diag::inout_as_attr_disallowed, "'inout'")
|
||||
.fixItRemove(InOutLoc)
|
||||
.fixItInsert(type->getStartLoc(), "inout ");
|
||||
type = new (ctx) InOutTypeRepr(type, InOutLoc);
|
||||
}
|
||||
type = validateParameterWithSpecifier<InOutTypeRepr>(parser, paramInfo,
|
||||
"inout");
|
||||
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Shared) {
|
||||
auto SpecifierLoc = paramInfo.SpecifierLoc;
|
||||
if (isa<SharedTypeRepr>(type)) {
|
||||
parser.diagnose(SpecifierLoc, diag::parameter_specifier_repeated)
|
||||
.fixItRemove(SpecifierLoc);
|
||||
} else {
|
||||
parser.diagnose(SpecifierLoc, diag::inout_as_attr_disallowed,
|
||||
"'__shared'")
|
||||
.fixItRemove(SpecifierLoc)
|
||||
.fixItInsert(type->getStartLoc(), "__shared ");
|
||||
type = new (ctx) SharedTypeRepr(type, SpecifierLoc);
|
||||
}
|
||||
type = validateParameterWithSpecifier<SharedTypeRepr>(parser, paramInfo,
|
||||
"__shared");
|
||||
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Owned) {
|
||||
type = validateParameterWithSpecifier<OwnedTypeRepr>(parser, paramInfo,
|
||||
"__owned");
|
||||
}
|
||||
param->getTypeLoc() = TypeLoc(type);
|
||||
} else if (paramContext != Parser::ParameterContextKind::Closure) {
|
||||
@@ -424,14 +438,18 @@ mapParsedParameters(Parser &parser,
|
||||
case VarDecl::Specifier::Shared:
|
||||
specifier = "'shared'";
|
||||
break;
|
||||
case VarDecl::Specifier::Owned:
|
||||
specifier = "'owned'";
|
||||
break;
|
||||
case VarDecl::Specifier::Let:
|
||||
case VarDecl::Specifier::Var:
|
||||
llvm_unreachable("can't have let or var here");
|
||||
break;
|
||||
}
|
||||
parser.diagnose(paramInfo.SpecifierLoc, diag::specifier_must_have_type,
|
||||
specifier);
|
||||
paramInfo.SpecifierLoc = SourceLoc();
|
||||
paramInfo.SpecifierKind = VarDecl::Specifier::Owned;
|
||||
paramInfo.SpecifierKind = VarDecl::Specifier::Default;
|
||||
}
|
||||
return param;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user