mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add a basic TypeLoc; start threading it through the parser.
Doug, please double-check that this is going in the right direction... Swift SVN r2146
This commit is contained in:
49
include/swift/AST/TypeLoc.h
Normal file
49
include/swift/AST/TypeLoc.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//===--- TypeLoc.h - Swift Language Type Locations --------------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See http://swift.org/LICENSE.txt for license information
|
||||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the TypeLoc class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_TYPELOC_H
|
||||
#define SWIFT_TYPELOC_H
|
||||
|
||||
#include "swift/Basic/SourceLoc.h"
|
||||
|
||||
namespace swift {
|
||||
class ASTContext;
|
||||
|
||||
/// TypeLoc - Provides source location information for a parsed type.
|
||||
/// A TypeLoc* is stored in AST nodes which use an explicitly written type.
|
||||
class TypeLoc {
|
||||
private:
|
||||
TypeLoc(SourceRange Range);
|
||||
// FIXME: Currently, there's only one kind of TypeLoc; we need multiple kinds
|
||||
// for more accurate source location information.
|
||||
SourceRange Range;
|
||||
|
||||
void *operator new(size_t Bytes) throw() = delete;
|
||||
void operator delete(void *Data) throw() = delete;
|
||||
void *operator new(size_t Bytes, void *Mem) throw() = delete;
|
||||
void *operator new(size_t Bytes, ASTContext &C,
|
||||
unsigned Alignment = 8);
|
||||
public:
|
||||
SourceRange getSourceRange() {
|
||||
return Range;
|
||||
}
|
||||
|
||||
static TypeLoc *get(ASTContext &Context, SourceRange Range);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/AST.h"
|
||||
#include "swift/AST/TypeLoc.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/SmallMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
@@ -831,3 +832,17 @@ void SubstArchetypeType::print(raw_ostream &OS) const {
|
||||
getSubstType()->print(OS);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TypeLoc implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
TypeLoc::TypeLoc(SourceRange Range) : Range(Range) {}
|
||||
|
||||
void *TypeLoc::operator new(size_t Bytes, ASTContext &C,
|
||||
unsigned Alignment) {
|
||||
return C.Allocate(Bytes, Alignment);
|
||||
}
|
||||
|
||||
TypeLoc *TypeLoc::get(ASTContext &Context, SourceRange Range) {
|
||||
return new (Context) TypeLoc(Range);
|
||||
}
|
||||
|
||||
@@ -476,7 +476,8 @@ bool Parser::parseInheritance(SmallVectorImpl<Type> &Inherited) {
|
||||
do {
|
||||
// Parse the inherited type (which must be a protocol).
|
||||
Type Ty;
|
||||
if (parseTypeIdentifier(Ty))
|
||||
TypeLoc *Loc;
|
||||
if (parseTypeIdentifier(Ty, Loc))
|
||||
return true;
|
||||
|
||||
// Record the type.
|
||||
@@ -503,9 +504,10 @@ Decl *Parser::parseDeclExtension() {
|
||||
SourceLoc ExtensionLoc = consumeToken(tok::kw_extension);
|
||||
|
||||
Type Ty;
|
||||
SourceLoc TyLoc = Tok.getLoc();
|
||||
SourceLoc TyStartLoc = Tok.getLoc();
|
||||
TypeLoc *TyLoc;
|
||||
SourceLoc LBLoc, RBLoc;
|
||||
if (parseTypeIdentifier(Ty))
|
||||
if (parseTypeIdentifier(Ty, TyLoc))
|
||||
return nullptr;
|
||||
|
||||
// Parse optional inheritance clause.
|
||||
@@ -517,7 +519,7 @@ Decl *Parser::parseDeclExtension() {
|
||||
return nullptr;
|
||||
|
||||
ExtensionDecl *ED
|
||||
= new (Context) ExtensionDecl(ExtensionLoc, Ty, TyLoc,
|
||||
= new (Context) ExtensionDecl(ExtensionLoc, Ty, TyStartLoc,
|
||||
Context.AllocateCopy(Inherited),
|
||||
CurDeclContext);
|
||||
ContextChange CC(*this, ED);
|
||||
@@ -547,6 +549,7 @@ TypeAliasDecl *Parser::parseDeclTypeAlias(bool WantDefinition) {
|
||||
|
||||
Identifier Id;
|
||||
Type Ty;
|
||||
TypeLoc *TyLoc;
|
||||
SourceLoc IdLoc = Tok.getLoc();
|
||||
if (parseIdentifier(Id, diag::expected_identifier_in_decl, "typealias"))
|
||||
return nullptr;
|
||||
@@ -558,7 +561,7 @@ TypeAliasDecl *Parser::parseDeclTypeAlias(bool WantDefinition) {
|
||||
|
||||
if (WantDefinition || Tok.is(tok::equal)) {
|
||||
if (parseToken(tok::equal, diag::expected_equal_in_typealias) ||
|
||||
parseType(Ty, diag::expected_type_in_typealias))
|
||||
parseType(Ty, TyLoc, diag::expected_type_in_typealias))
|
||||
return nullptr;
|
||||
|
||||
if (!WantDefinition) {
|
||||
@@ -760,7 +763,8 @@ bool Parser::parseGetSet(bool HasContainerType, Pattern *Indices,
|
||||
|
||||
// Getter has type: () -> T.
|
||||
Type FuncTy = ElementTy;
|
||||
if (buildFunctionSignature(Params, FuncTy)) {
|
||||
TypeLoc *FuncLoc = nullptr;
|
||||
if (buildFunctionSignature(Params, FuncTy, FuncLoc)) {
|
||||
skipUntilDeclRBrace();
|
||||
Invalid = true;
|
||||
break;
|
||||
@@ -882,7 +886,8 @@ bool Parser::parseGetSet(bool HasContainerType, Pattern *Indices,
|
||||
|
||||
// Getter has type: (value : T) -> ()
|
||||
Type FuncTy = TupleType::getEmpty(Context);
|
||||
if (buildFunctionSignature(Params, FuncTy)) {
|
||||
TypeLoc *FuncLoc = nullptr;
|
||||
if (buildFunctionSignature(Params, FuncTy, FuncLoc)) {
|
||||
skipUntilDeclRBrace();
|
||||
Invalid = true;
|
||||
break;
|
||||
@@ -1137,7 +1142,8 @@ FuncDecl *Parser::parseDeclFunc(bool hasContainerType) {
|
||||
Params.push_back(buildImplicitThisParameter());
|
||||
|
||||
Type FuncTy;
|
||||
if (parseFunctionSignature(Params, FuncTy))
|
||||
TypeLoc *FuncTyLoc;
|
||||
if (parseFunctionSignature(Params, FuncTy, FuncTyLoc))
|
||||
return 0;
|
||||
|
||||
// Enter the arguments for the function into a new function-body scope. We
|
||||
@@ -1226,6 +1232,7 @@ bool Parser::parseDeclOneOf(SmallVectorImpl<Decl*> &Decls) {
|
||||
SourceLoc NameLoc;
|
||||
StringRef Name;
|
||||
Type EltType;
|
||||
TypeLoc *EltTypeLoc;
|
||||
};
|
||||
SmallVector<OneOfElementInfo, 8> ElementInfos;
|
||||
|
||||
@@ -1244,7 +1251,7 @@ bool Parser::parseDeclOneOf(SmallVectorImpl<Decl*> &Decls) {
|
||||
|
||||
// See if we have a type specifier for this oneof element. If so, parse it.
|
||||
if (consumeIf(tok::colon) &&
|
||||
parseTypeAnnotation(ElementInfo.EltType,
|
||||
parseTypeAnnotation(ElementInfo.EltType, ElementInfo.EltTypeLoc,
|
||||
diag::expected_type_oneof_element)) {
|
||||
skipUntil(tok::r_brace);
|
||||
return true;
|
||||
@@ -1563,7 +1570,9 @@ bool Parser::parseDeclSubscript(bool HasContainerType,
|
||||
|
||||
// type
|
||||
Type ElementTy;
|
||||
if (parseTypeAnnotation(ElementTy, diag::expected_type_subscript))
|
||||
TypeLoc *ElementTyLoc;
|
||||
if (parseTypeAnnotation(ElementTy, ElementTyLoc,
|
||||
diag::expected_type_subscript))
|
||||
return true;
|
||||
if (checkFullyTyped(ElementTy))
|
||||
Invalid = true;
|
||||
|
||||
@@ -131,7 +131,8 @@ NullablePtr<Expr> Parser::parseExprNew() {
|
||||
|
||||
// FIXME: this should probably be type-simple.
|
||||
Type elementTy;
|
||||
if (parseTypeIdentifier(elementTy))
|
||||
TypeLoc *elementLoc;
|
||||
if (parseTypeIdentifier(elementTy, elementLoc))
|
||||
return nullptr;
|
||||
|
||||
// TODO: we should probably allow a tuple-expr here as an initializer.
|
||||
@@ -584,6 +585,7 @@ NullablePtr<Expr> Parser::parseExprFunc() {
|
||||
|
||||
SmallVector<Pattern*, 4> Params;
|
||||
Type Ty;
|
||||
TypeLoc *Loc;
|
||||
if (Tok.is(tok::l_brace)) {
|
||||
// If the func-signature isn't present, then this is a ()->() function.
|
||||
Params.push_back(TuplePattern::create(Context, SourceLoc(),
|
||||
@@ -594,7 +596,7 @@ NullablePtr<Expr> Parser::parseExprFunc() {
|
||||
} else if (Tok.isNotAnyLParen()) {
|
||||
diagnose(Tok, diag::func_decl_without_paren);
|
||||
return 0;
|
||||
} else if (parseFunctionSignature(Params, Ty)) {
|
||||
} else if (parseFunctionSignature(Params, Ty, Loc)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ bool Parser::checkFullyTyped(Pattern *pattern, Type &funcTy) {
|
||||
/// func-signature-result:
|
||||
/// '->' type
|
||||
bool Parser::parseFunctionSignature(SmallVectorImpl<Pattern*> ¶ms,
|
||||
Type &type) {
|
||||
Type &type, TypeLoc *&loc) {
|
||||
// Parse curried function argument clauses as long as we can.
|
||||
do {
|
||||
NullablePtr<Pattern> pattern = parsePatternTuple();
|
||||
@@ -168,7 +168,7 @@ bool Parser::parseFunctionSignature(SmallVectorImpl<Pattern*> ¶ms,
|
||||
|
||||
// If there's a trailing arrow, parse the rest as the result type.
|
||||
if (consumeIf(tok::arrow)) {
|
||||
if (parseType(type))
|
||||
if (parseType(type, loc))
|
||||
return true;
|
||||
|
||||
checkFullyTyped(type);
|
||||
@@ -176,16 +176,17 @@ bool Parser::parseFunctionSignature(SmallVectorImpl<Pattern*> ¶ms,
|
||||
// Otherwise, we implicitly return ().
|
||||
} else {
|
||||
type = TupleType::getEmpty(Context);
|
||||
loc = nullptr;
|
||||
}
|
||||
|
||||
// Now build up the function type. We require all function
|
||||
// signatures to be fully-typed: that is, all top-down paths to a
|
||||
// leaf pattern must pass through a TypedPattern.
|
||||
return buildFunctionSignature(params, type);
|
||||
return buildFunctionSignature(params, type, loc);
|
||||
}
|
||||
|
||||
bool Parser::buildFunctionSignature(SmallVectorImpl<Pattern*> ¶ms,
|
||||
Type &type) {
|
||||
Type &type, TypeLoc *&loc) {
|
||||
// Now build up the function type. We require all function
|
||||
// signatures to be fully-typed: that is, all top-down paths to a
|
||||
// leaf pattern must pass through a TypedPattern.
|
||||
@@ -215,7 +216,8 @@ NullablePtr<Pattern> Parser::parsePattern() {
|
||||
// Now parse an optional type annotation.
|
||||
if (consumeIf(tok::colon)) {
|
||||
Type type;
|
||||
if (parseTypeAnnotation(type))
|
||||
TypeLoc *loc;
|
||||
if (parseTypeAnnotation(type, loc))
|
||||
return nullptr;
|
||||
|
||||
pattern = new (Context) TypedPattern(pattern.get(), type);
|
||||
|
||||
@@ -16,25 +16,27 @@
|
||||
|
||||
#include "Parser.h"
|
||||
#include "swift/AST/Attr.h"
|
||||
#include "swift/AST/TypeLoc.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
using namespace swift;
|
||||
|
||||
bool Parser::parseTypeAnnotation(Type &result) {
|
||||
return parseTypeAnnotation(result, diag::expected_type);
|
||||
bool Parser::parseTypeAnnotation(Type &result, TypeLoc *&resultLoc) {
|
||||
return parseTypeAnnotation(result, resultLoc, diag::expected_type);
|
||||
}
|
||||
|
||||
/// parseTypeAnnotation
|
||||
/// type-annotation:
|
||||
/// attribute-list type
|
||||
bool Parser::parseTypeAnnotation(Type &result, Diag<> message) {
|
||||
bool Parser::parseTypeAnnotation(Type &result, TypeLoc *&resultLoc,
|
||||
Diag<> message) {
|
||||
// Parse attributes.
|
||||
DeclAttributes attrs;
|
||||
parseAttributeList(attrs);
|
||||
|
||||
// Parse the type.
|
||||
if (parseType(result, message))
|
||||
if (parseType(result, resultLoc, message))
|
||||
return true;
|
||||
|
||||
// Apply those attributes that do apply.
|
||||
@@ -45,6 +47,9 @@ bool Parser::parseTypeAnnotation(Type &result, Diag<> message) {
|
||||
if (!attrs.isByrefHeap()) quals |= LValueType::Qual::NonHeap;
|
||||
result = LValueType::get(result, quals, Context);
|
||||
attrs.Byref = false; // so that the empty() check below works
|
||||
resultLoc = TypeLoc::get(Context,
|
||||
SourceRange(attrs.LSquareLoc,
|
||||
resultLoc->getSourceRange().End));
|
||||
}
|
||||
|
||||
// Handle the auto_closure attribute.
|
||||
@@ -73,8 +78,8 @@ bool Parser::parseTypeAnnotation(Type &result, Diag<> message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseType(Type &Result) {
|
||||
return parseType(Result, diag::expected_type);
|
||||
bool Parser::parseType(Type &Result, TypeLoc *&ResultLoc) {
|
||||
return parseType(Result, ResultLoc, diag::expected_type);
|
||||
}
|
||||
|
||||
/// parseType
|
||||
@@ -91,24 +96,24 @@ bool Parser::parseType(Type &Result) {
|
||||
/// type-tuple
|
||||
/// type-composition
|
||||
///
|
||||
bool Parser::parseType(Type &Result, Diag<> MessageID) {
|
||||
bool Parser::parseType(Type &Result, TypeLoc *&ResultLoc, Diag<> MessageID) {
|
||||
// Parse type-simple first.
|
||||
SourceLoc TypeLoc = Tok.getLoc();
|
||||
SourceLoc StartLoc = Tok.getLoc();
|
||||
bool isTupleType = false;
|
||||
switch (Tok.getKind()) {
|
||||
case tok::identifier:
|
||||
if (parseTypeIdentifier(Result))
|
||||
if (parseTypeIdentifier(Result, ResultLoc))
|
||||
return true;
|
||||
break;
|
||||
case tok::kw_protocol:
|
||||
if (parseTypeComposition(Result))
|
||||
if (parseTypeComposition(Result, ResultLoc))
|
||||
return true;
|
||||
break;
|
||||
case tok::l_paren:
|
||||
case tok::l_paren_space: {
|
||||
isTupleType = true;
|
||||
SourceLoc LPLoc = consumeToken(), RPLoc;
|
||||
if (parseTypeTupleBody(LPLoc, Result) ||
|
||||
if (parseTypeTupleBody(LPLoc, Result, ResultLoc) ||
|
||||
parseMatchingToken(tok::r_paren, RPLoc,
|
||||
diag::expected_rparen_tuple_type_list,
|
||||
LPLoc, diag::opening_paren))
|
||||
@@ -124,19 +129,24 @@ bool Parser::parseType(Type &Result, Diag<> MessageID) {
|
||||
if (consumeIf(tok::arrow)) {
|
||||
// If the argument was not syntactically a tuple type, report an error.
|
||||
if (!isTupleType) {
|
||||
diagnose(TypeLoc, diag::expected_function_argument_must_be_paren);
|
||||
diagnose(StartLoc, diag::expected_function_argument_must_be_paren);
|
||||
}
|
||||
|
||||
Type SecondHalf;
|
||||
if (parseType(SecondHalf, diag::expected_type_function_result))
|
||||
TypeLoc *SecondHalfLoc;
|
||||
if (parseType(SecondHalf, SecondHalfLoc,
|
||||
diag::expected_type_function_result))
|
||||
return true;
|
||||
Result = FunctionType::get(Result, SecondHalf, Context);
|
||||
SourceRange FnTypeRange{ ResultLoc->getSourceRange().Start,
|
||||
SecondHalfLoc->getSourceRange().End };
|
||||
ResultLoc = TypeLoc::get(Context, FnTypeRange);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there is a square bracket without a space, we have an array.
|
||||
if (Tok.is(tok::l_square))
|
||||
return parseTypeArray(Result);
|
||||
return parseTypeArray(Result, ResultLoc);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -146,7 +156,8 @@ bool Parser::parseType(Type &Result, Diag<> MessageID) {
|
||||
/// type-identifier:
|
||||
/// identifier ('.' identifier)*
|
||||
///
|
||||
bool Parser::parseTypeIdentifier(Type &Result) {
|
||||
bool Parser::parseTypeIdentifier(Type &Result, TypeLoc *&ResultLoc) {
|
||||
SourceLoc StartLoc = Tok.getLoc();
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
diagnose(Tok.getLoc(), diag::expected_identifier_for_type);
|
||||
return true;
|
||||
@@ -155,7 +166,7 @@ bool Parser::parseTypeIdentifier(Type &Result) {
|
||||
SmallVector<IdentifierType::Component, 4> Components;
|
||||
Components.push_back(IdentifierType::Component(Tok.getLoc(),
|
||||
Context.getIdentifier(Tok.getText())));
|
||||
consumeToken(tok::identifier);
|
||||
SourceLoc EndLoc = consumeToken(tok::identifier);
|
||||
|
||||
while (consumeIf(tok::period)) {
|
||||
SourceLoc Loc = Tok.getLoc();
|
||||
@@ -163,6 +174,7 @@ bool Parser::parseTypeIdentifier(Type &Result) {
|
||||
if (parseIdentifier(Name, diag::expected_identifier_in_dotted_type))
|
||||
return true;
|
||||
Components.push_back(IdentifierType::Component(Loc, Name));
|
||||
EndLoc = Loc;
|
||||
}
|
||||
|
||||
// Lookup element #0 through our current scope chains in case it is some thing
|
||||
@@ -172,6 +184,7 @@ bool Parser::parseTypeIdentifier(Type &Result) {
|
||||
auto Ty = IdentifierType::getNew(Context, Components);
|
||||
UnresolvedIdentifierTypes.emplace_back(Ty, CurDeclContext);
|
||||
Result = Ty;
|
||||
ResultLoc = TypeLoc::get(Context, SourceRange(StartLoc, EndLoc));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -183,7 +196,7 @@ bool Parser::parseTypeIdentifier(Type &Result) {
|
||||
/// type-composition-list:
|
||||
/// type-identifier (',' type-identifier)*
|
||||
///
|
||||
bool Parser::parseTypeComposition(Type &Result) {
|
||||
bool Parser::parseTypeComposition(Type &Result, TypeLoc *&ResultLoc) {
|
||||
SourceLoc ProtocolLoc = consumeToken(tok::kw_protocol);
|
||||
|
||||
// Check for the starting '<'.
|
||||
@@ -207,7 +220,8 @@ bool Parser::parseTypeComposition(Type &Result) {
|
||||
do {
|
||||
// Parse the type-identifier.
|
||||
Type Protocol;
|
||||
if (parseTypeIdentifier(Protocol)) {
|
||||
TypeLoc *ProtocolLoc;
|
||||
if (parseTypeIdentifier(Protocol, ProtocolLoc)) {
|
||||
Invalid = true;
|
||||
break;
|
||||
}
|
||||
@@ -223,6 +237,7 @@ bool Parser::parseTypeComposition(Type &Result) {
|
||||
} while (true);
|
||||
|
||||
// Check for the terminating '>'.
|
||||
SourceLoc EndLoc = Tok.getLoc();
|
||||
if (!startsWithGreater(Tok)) {
|
||||
if (!Invalid) {
|
||||
diagnose(Tok.getLoc(), diag::expected_rangle_protocol);
|
||||
@@ -232,14 +247,15 @@ bool Parser::parseTypeComposition(Type &Result) {
|
||||
// Skip until we hit the '>'.
|
||||
skipUntil(tok::oper);
|
||||
if (startsWithGreater(Tok))
|
||||
consumeStartingGreater();
|
||||
EndLoc = consumeStartingGreater();
|
||||
|
||||
} else {
|
||||
consumeStartingGreater();
|
||||
EndLoc = consumeStartingGreater();
|
||||
}
|
||||
|
||||
Result = ProtocolCompositionType::get(Context, ProtocolLoc,
|
||||
Context.AllocateCopy(Protocols));
|
||||
ResultLoc = TypeLoc::get(Context, SourceRange(ProtocolLoc, EndLoc));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -251,7 +267,7 @@ bool Parser::parseTypeComposition(Type &Result) {
|
||||
/// type-tuple-element:
|
||||
/// identifier value-specifier
|
||||
/// type-annotation
|
||||
bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result, TypeLoc *&ResultLoc) {
|
||||
SmallVector<TupleTypeElt, 8> Elements;
|
||||
bool HadExpr = false;
|
||||
|
||||
@@ -269,7 +285,8 @@ bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
|
||||
NullablePtr<Expr> init;
|
||||
Type type;
|
||||
if ((HadError = parseValueSpecifier(type, init)))
|
||||
TypeLoc *loc;
|
||||
if ((HadError = parseValueSpecifier(type, loc, init)))
|
||||
break;
|
||||
|
||||
HadExpr |= init.isNonNull();
|
||||
@@ -279,7 +296,8 @@ bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
|
||||
// Otherwise, this has to be a type.
|
||||
Type type;
|
||||
if ((HadError = parseTypeAnnotation(type)))
|
||||
TypeLoc *typeLoc;
|
||||
if ((HadError = parseTypeAnnotation(type, typeLoc)))
|
||||
break;
|
||||
|
||||
Elements.push_back(TupleTypeElt(type, Identifier(), nullptr));
|
||||
@@ -304,6 +322,7 @@ bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
if (Elements.size() == 1 && !Elements.back().hasName() && !HadEllipsis) {
|
||||
assert(!HadExpr && "Only TupleTypes have default values");
|
||||
Result = ParenType::get(Context, Elements.back().getType());
|
||||
ResultLoc = TypeLoc::get(Context, SourceRange(LPLoc, Tok.getLoc()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -327,6 +346,7 @@ bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
if (HadExpr)
|
||||
TypesWithDefaultValues.emplace_back(TT, CurDeclContext);
|
||||
Result = TT;
|
||||
ResultLoc = TypeLoc::get(Context, SourceRange(LPLoc, Tok.getLoc()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -340,14 +360,16 @@ bool Parser::parseTypeTupleBody(SourceLoc LPLoc, Type &Result) {
|
||||
/// type-array '[' ']'
|
||||
/// type-array '[' expr ']'
|
||||
///
|
||||
bool Parser::parseTypeArray(Type &result) {
|
||||
bool Parser::parseTypeArray(Type &result, TypeLoc *&resultLoc) {
|
||||
SourceLoc lsquareLoc = Tok.getLoc();
|
||||
consumeToken(tok::l_square);
|
||||
|
||||
// Handle the [] production, meaning an array slice.
|
||||
if (consumeIf(tok::r_square)) {
|
||||
if (Tok.is(tok::r_square)) {
|
||||
SourceLoc rsquareLoc = consumeToken(tok::r_square);
|
||||
|
||||
// If we're starting another square-bracket clause, recurse.
|
||||
if (Tok.is(tok::l_square) && parseTypeArray(result)) {
|
||||
if (Tok.is(tok::l_square) && parseTypeArray(result, resultLoc)) {
|
||||
return true;
|
||||
|
||||
// Propagate an error type out.
|
||||
@@ -357,6 +379,8 @@ bool Parser::parseTypeArray(Type &result) {
|
||||
|
||||
// Just build a normal array slice type.
|
||||
result = ArraySliceType::get(result, lsquareLoc, Context);
|
||||
SourceRange arrayRange{ resultLoc->getSourceRange().Start, rsquareLoc };
|
||||
resultLoc = TypeLoc::get(Context, arrayRange);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -370,7 +394,7 @@ bool Parser::parseTypeArray(Type &result) {
|
||||
return true;
|
||||
|
||||
// If we're starting another square-bracket clause, recurse.
|
||||
if (Tok.is(tok::l_square) && parseTypeArray(result)) {
|
||||
if (Tok.is(tok::l_square) && parseTypeArray(result, resultLoc)) {
|
||||
return true;
|
||||
|
||||
// If we had a semantic error on the size or if the base type is invalid,
|
||||
|
||||
@@ -260,7 +260,8 @@ bool Parser::parseMatchingToken(tok K, SourceLoc &TokLoc, Diag<> ErrorDiag,
|
||||
/// ':' type-annotation
|
||||
/// ':' type-annotation '=' expr
|
||||
/// '=' expr
|
||||
bool Parser::parseValueSpecifier(Type &Ty, NullablePtr<Expr> &Init) {
|
||||
bool Parser::parseValueSpecifier(Type &Ty, TypeLoc *&Loc,
|
||||
NullablePtr<Expr> &Init) {
|
||||
// Diagnose when we don't have a type or an expression.
|
||||
if (Tok.isNot(tok::colon) && Tok.isNot(tok::equal)) {
|
||||
diagnose(Tok, diag::expected_type_or_init);
|
||||
@@ -271,7 +272,7 @@ bool Parser::parseValueSpecifier(Type &Ty, NullablePtr<Expr> &Init) {
|
||||
|
||||
// Parse the type if present.
|
||||
if (consumeIf(tok::colon) &&
|
||||
parseTypeAnnotation(Ty, diag::expected_type))
|
||||
parseTypeAnnotation(Ty, Loc, diag::expected_type))
|
||||
return true;
|
||||
|
||||
// Parse the initializer, if present.
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace swift {
|
||||
class DiagnosticEngine;
|
||||
class Lexer;
|
||||
class ScopeInfo;
|
||||
class TypeLoc;
|
||||
class TupleType;
|
||||
|
||||
struct OneOfElementInfo;
|
||||
@@ -201,7 +202,7 @@ public:
|
||||
SourceLoc OtherLoc, Diag<> OtherNote,
|
||||
tok SkipToTok = tok::unknown);
|
||||
|
||||
bool parseValueSpecifier(Type &Ty, NullablePtr<Expr> &Init);
|
||||
bool parseValueSpecifier(Type &Ty, TypeLoc *&Loc, NullablePtr<Expr> &Init);
|
||||
|
||||
void parseBraceItemList(SmallVectorImpl<ExprStmtOrDecl> &Decls,
|
||||
bool IsTopLevel);
|
||||
@@ -262,21 +263,22 @@ public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Type Parsing
|
||||
|
||||
bool parseType(Type &Result);
|
||||
bool parseType(Type &Result, Diag<> ID);
|
||||
bool parseTypeAnnotation(Type &Result);
|
||||
bool parseTypeAnnotation(Type &Result, Diag<> ID);
|
||||
bool parseTypeIdentifier(Type &Result);
|
||||
bool parseTypeComposition(Type &Result);
|
||||
bool parseTypeTupleBody(SourceLoc LPLoc, Type &Result);
|
||||
|
||||
bool parseTypeArray(Type &result);
|
||||
bool parseType(Type &Result, TypeLoc *&ResultLoc);
|
||||
bool parseType(Type &Result, TypeLoc *&ResultLoc, Diag<> ID);
|
||||
bool parseTypeAnnotation(Type &Result, TypeLoc *&ResultLoc);
|
||||
bool parseTypeAnnotation(Type &Result, TypeLoc *&ResultLoc, Diag<> ID);
|
||||
bool parseTypeIdentifier(Type &Result, TypeLoc *&ResultLoc);
|
||||
bool parseTypeComposition(Type &Result, TypeLoc *&ResultLoc);
|
||||
bool parseTypeTupleBody(SourceLoc LPLoc, Type &Result, TypeLoc *&ResultLoc);
|
||||
bool parseTypeArray(Type &result, TypeLoc *&ResultLoc);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Pattern Parsing
|
||||
|
||||
bool parseFunctionSignature(SmallVectorImpl<Pattern*> ¶ms, Type &type);
|
||||
bool buildFunctionSignature(SmallVectorImpl<Pattern*> ¶ms, Type &type);
|
||||
bool parseFunctionSignature(SmallVectorImpl<Pattern*> ¶ms, Type &type,
|
||||
TypeLoc *&loc);
|
||||
bool buildFunctionSignature(SmallVectorImpl<Pattern*> ¶ms, Type &type,
|
||||
TypeLoc *&loc);
|
||||
NullablePtr<Pattern> parsePattern();
|
||||
NullablePtr<Pattern> parsePatternTuple();
|
||||
NullablePtr<Pattern> parsePatternAtom();
|
||||
|
||||
Reference in New Issue
Block a user