Enhance VarPattern to capture a bit indicating whether the pattern was a var or let.

Previously we only used this information in the parser, but Sema needs to know as well.

NFC except in -dump-ast.



Swift SVN r25914
This commit is contained in:
Chris Lattner
2015-03-10 06:07:56 +00:00
parent 6423209466
commit db187f2183
8 changed files with 25 additions and 17 deletions

View File

@@ -757,14 +757,18 @@ public:
/// parsed as expressions referencing existing entities.
class VarPattern : public Pattern {
SourceLoc VarLoc;
bool IsLet; // True if this is a let pattern, false if a var pattern.
Pattern *SubPattern;
public:
VarPattern(SourceLoc loc, Pattern *sub, Optional<bool> implicit = None)
: Pattern(PatternKind::Var), VarLoc(loc), SubPattern(sub) {
VarPattern(SourceLoc loc, bool isLet, Pattern *sub,
Optional<bool> implicit = None)
: Pattern(PatternKind::Var), VarLoc(loc), IsLet(isLet), SubPattern(sub) {
if (implicit.hasValue() ? *implicit : !loc.isValid())
setImplicit();
}
bool isLet() const { return IsLet; }
SourceLoc getLoc() const { return VarLoc; }
SourceRange getSourceRange() const {
SourceLoc EndLoc = SubPattern->getSourceRange().End;

View File

@@ -51,7 +51,7 @@ const uint16_t VERSION_MAJOR = 0;
/// To ensure that two separate changes don't silently get merged into one
/// in source control, you should also update the comment to briefly
/// describe what change you made.
const uint16_t VERSION_MINOR = 177; // Last change: Flag for sib
const uint16_t VERSION_MINOR = 178; // Last change: VarPattern
using DeclID = Fixnum<31>;
using DeclIDField = BCFixed<31>;
@@ -1009,6 +1009,7 @@ namespace decls_block {
using VarPatternLayout = BCRecordLayout<
VAR_PATTERN,
BCFixed<1>, // isLet?
BCFixed<1> // implicit?
// The sub-pattern trails the record.
>;

View File

@@ -259,7 +259,7 @@ namespace {
OS << ')';
}
void visitVarPattern(VarPattern *P) {
printCommon(P, "pattern_var");
printCommon(P, P->isLet() ? "pattern_let" : "pattern_var");
OS << '\n';
printRec(P->getSubPattern());
OS << ')';

View File

@@ -498,7 +498,7 @@ void PrintAST::printPattern(const Pattern *pattern) {
case PatternKind::Var:
if (!Options.SkipIntroducerKeywords)
Printer << "var ";
Printer << (cast<VarPattern>(pattern)->isLet() ? "let " : "var ");
printPattern(cast<VarPattern>(pattern)->getSubPattern());
}
}

View File

@@ -390,7 +390,7 @@ Pattern *Pattern::clone(ASTContext &context,
case PatternKind::Var: {
auto var = cast<VarPattern>(this);
result = new(context) VarPattern(var->getLoc(),
result = new(context) VarPattern(var->getLoc(), var->isLet(),
var->getSubPattern()->clone(
context,
options|IsVar));
@@ -431,7 +431,7 @@ Pattern *Pattern::cloneForwardable(ASTContext &context, DeclContext *DC,
case PatternKind::Var: {
auto var = cast<VarPattern>(this);
result = new(context) VarPattern(var->getLoc(),
result = new(context) VarPattern(var->getLoc(), var->isLet(),
var->getSubPattern()->cloneForwardable(
context, DC, options|IsVar));
break;

View File

@@ -391,7 +391,8 @@ mapParsedParameters(Parser &parser,
// If 'var' or 'let' was specified explicitly, create a pattern for it.
if (specifierKind != Parser::ParsedParameter::InOut &&
letVarInOutLoc.isValid()) {
param = new (ctx) VarPattern(letVarInOutLoc, param);
bool isLet = specifierKind == Parser::ParsedParameter::Let;
param = new (ctx) VarPattern(letVarInOutLoc, isLet, param);
}
if (var)
@@ -802,7 +803,8 @@ ParserResult<Pattern> Parser::parsePatternVarOrLet() {
return makeParserCodeCompletionResult<Pattern>();
if (subPattern.isNull())
return nullptr;
return makeParserResult(new (Context) VarPattern(varLoc, subPattern.get()));
return makeParserResult(new (Context) VarPattern(varLoc, isLet,
subPattern.get()));
}
/// \brief Determine whether this token can start a binding name, whether an
@@ -978,21 +980,22 @@ ParserResult<Pattern> Parser::parseMatchingPattern() {
ParserResult<Pattern> Parser::parseMatchingPatternVarOrVal() {
assert((Tok.is(tok::kw_let) || Tok.is(tok::kw_var)) && "expects val or var");
bool isVal = Tok.is(tok::kw_let);
bool isLet = Tok.is(tok::kw_let);
SourceLoc varLoc = consumeToken();
// 'var' and 'let' patterns shouldn't nest.
if (InVarOrLetPattern)
diagnose(varLoc, diag::var_pattern_in_var, unsigned(isVal));
diagnose(varLoc, diag::var_pattern_in_var, unsigned(isLet));
// In our recursive parse, remember that we're in a var/let pattern.
llvm::SaveAndRestore<decltype(InVarOrLetPattern)>
T(InVarOrLetPattern, isVal ? IVOLP_InLet : IVOLP_InVar);
T(InVarOrLetPattern, isLet ? IVOLP_InLet : IVOLP_InVar);
ParserResult<Pattern> subPattern = parseMatchingPattern();
if (subPattern.isNull())
return nullptr;
return makeParserResult(new (Context) VarPattern(varLoc, subPattern.get()));
return makeParserResult(new (Context) VarPattern(varLoc, isLet,
subPattern.get()));
}
// matching-pattern ::= 'is' type

View File

@@ -367,12 +367,12 @@ Pattern *ModuleFile::maybeReadPattern() {
return result;
}
case decls_block::VAR_PATTERN: {
bool isImplicit;
VarPatternLayout::readRecord(scratch, isImplicit);
bool isImplicit, isLet;
VarPatternLayout::readRecord(scratch, isLet, isImplicit);
Pattern *subPattern = maybeReadPattern();
assert(subPattern);
auto result = new (getContext()) VarPattern(SourceLoc(), subPattern,
auto result = new (getContext()) VarPattern(SourceLoc(), isLet, subPattern,
isImplicit);
result->setType(subPattern->getType());
return result;

View File

@@ -842,7 +842,7 @@ void Serializer::writePattern(const Pattern *pattern) {
auto var = cast<VarPattern>(pattern);
unsigned abbrCode = DeclTypeAbbrCodes[VarPatternLayout::Code];
VarPatternLayout::emitRecord(Out, ScratchRecord, abbrCode,
VarPatternLayout::emitRecord(Out, ScratchRecord, abbrCode, var->isLet(),
var->isImplicit());
writePattern(var->getSubPattern());
break;