Skip to content

Commit 81483cc

Browse files
authored
Merge pull request #32161 from hamishknight/pipeline-parse
2 parents 8f0569d + db9a27e commit 81483cc

File tree

20 files changed

+251
-185
lines changed

20 files changed

+251
-185
lines changed

include/swift/AST/ASTContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,12 @@ class ASTContext final {
407407
array.size());
408408
}
409409

410+
template <typename T>
411+
MutableArrayRef<T>
412+
AllocateCopy(const std::vector<T> &vec,
413+
AllocationArena arena = AllocationArena::Permanent) const {
414+
return AllocateCopy(ArrayRef<T>(vec), arena);
415+
}
410416

411417
template<typename T>
412418
ArrayRef<T> AllocateCopy(const SmallVectorImpl<T> &vec,

include/swift/AST/ParseRequests.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTTypeIDs.h"
2020
#include "swift/AST/EvaluatorDependencies.h"
2121
#include "swift/AST/SimpleRequest.h"
22+
#include "swift/Syntax/SyntaxNodes.h"
2223

2324
namespace swift {
2425

@@ -81,10 +82,17 @@ class ParseAbstractFunctionBodyRequest :
8182
void cacheResult(BraceStmt *value) const;
8283
};
8384

85+
struct SourceFileParsingResult {
86+
ArrayRef<Decl *> TopLevelDecls;
87+
Optional<ArrayRef<Token>> CollectedTokens;
88+
Optional<llvm::MD5> InterfaceHash;
89+
Optional<syntax::SourceFileSyntax> SyntaxRoot;
90+
};
91+
8492
/// Parse the top-level decls of a SourceFile.
8593
class ParseSourceFileRequest
8694
: public SimpleRequest<
87-
ParseSourceFileRequest, ArrayRef<Decl *>(SourceFile *),
95+
ParseSourceFileRequest, SourceFileParsingResult(SourceFile *),
8896
RequestFlags::SeparatelyCached | RequestFlags::DependencySource> {
8997
public:
9098
using SimpleRequest::SimpleRequest;
@@ -93,13 +101,13 @@ class ParseSourceFileRequest
93101
friend SimpleRequest;
94102

95103
// Evaluation.
96-
ArrayRef<Decl *> evaluate(Evaluator &evaluator, SourceFile *SF) const;
104+
SourceFileParsingResult evaluate(Evaluator &evaluator, SourceFile *SF) const;
97105

98106
public:
99107
// Caching.
100108
bool isCached() const { return true; }
101-
Optional<ArrayRef<Decl *>> getCachedResult() const;
102-
void cacheResult(ArrayRef<Decl *> decls) const;
109+
Optional<SourceFileParsingResult> getCachedResult() const;
110+
void cacheResult(SourceFileParsingResult result) const;
103111

104112
public:
105113
evaluator::DependencySource

include/swift/AST/ParseTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ SWIFT_REQUEST(Parse, ParseAbstractFunctionBodyRequest,
2323
BraceStmt *(AbstractFunctionDecl *), SeparatelyCached,
2424
NoLocationInfo)
2525
SWIFT_REQUEST(Parse, ParseSourceFileRequest,
26-
ArrayRef<Decl *>(SourceFile *), SeparatelyCached,
26+
SourceFileParsingResult(SourceFile *), SeparatelyCached,
2727
NoLocationInfo)

include/swift/AST/SourceFile.h

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ class SourceFile final : public FileUnit {
3232
friend class ParseSourceFileRequest;
3333

3434
public:
35-
struct SourceFileSyntaxInfo;
36-
3735
/// Possible attributes for imports in source files.
3836
enum class ImportFlags {
3937
/// The imported module is exposed to anyone who imports the parent module.
@@ -110,12 +108,24 @@ class SourceFile final : public FileUnit {
110108
/// and adjust the client call 'performParseOnly'.
111109
DisablePoundIfEvaluation = 1 << 1,
112110

111+
/// Whether to build a syntax tree.
112+
BuildSyntaxTree = 1 << 2,
113+
114+
/// Whether to save the file's parsed tokens.
115+
CollectParsedTokens = 1 << 3,
116+
117+
/// Whether to compute the interface hash of the file.
118+
EnableInterfaceHash = 1 << 4,
119+
113120
/// Whether to suppress warnings when parsing. This is set for secondary
114121
/// files, as they get parsed multiple times.
115-
SuppressWarnings = 1 << 2
122+
SuppressWarnings = 1 << 5,
116123
};
117124
using ParsingOptions = OptionSet<ParsingFlags>;
118125

126+
/// Retrieve the parsing options specified in the LangOptions.
127+
static ParsingOptions getDefaultParsingOptions(const LangOptions &langOpts);
128+
119129
private:
120130
std::unique_ptr<SourceLookupCache> Cache;
121131
SourceLookupCache &getCache() const;
@@ -313,7 +323,6 @@ class SourceFile final : public FileUnit {
313323
llvm::StringMap<SourceFilePathInfo> getInfoForUsedFilePaths() const;
314324

315325
SourceFile(ModuleDecl &M, SourceFileKind K, Optional<unsigned> bufferID,
316-
bool KeepParsedTokens = false, bool KeepSyntaxTree = false,
317326
ParsingOptions parsingOpts = {}, bool isPrimary = false);
318327

319328
~SourceFile();
@@ -544,50 +553,35 @@ class SourceFile final : public FileUnit {
544553
/// Set the root refinement context for the file.
545554
void setTypeRefinementContext(TypeRefinementContext *TRC);
546555

547-
void enableInterfaceHash() {
548-
assert(!hasInterfaceHash());
549-
InterfaceHash.emplace();
550-
}
551-
556+
/// Whether this file has an interface hash available.
552557
bool hasInterfaceHash() const {
553-
return InterfaceHash.hasValue();
558+
return ParsingOpts.contains(ParsingFlags::EnableInterfaceHash);
554559
}
555560

556-
NullablePtr<llvm::MD5> getInterfaceHashPtr() {
557-
return InterfaceHash ? InterfaceHash.getPointer() : nullptr;
558-
}
559-
560-
void getInterfaceHash(llvm::SmallString<32> &str) const {
561-
// Copy to preserve idempotence.
562-
llvm::MD5 md5 = *InterfaceHash;
563-
llvm::MD5::MD5Result result;
564-
md5.final(result);
565-
llvm::MD5::stringifyResult(result, str);
566-
}
561+
/// Output this file's interface hash into the provided string buffer.
562+
void getInterfaceHash(llvm::SmallString<32> &str) const;
567563

568564
void dumpInterfaceHash(llvm::raw_ostream &out) {
569565
llvm::SmallString<32> str;
570566
getInterfaceHash(str);
571567
out << str << '\n';
572568
}
573569

574-
std::vector<Token> &getTokenVector();
575-
570+
/// If this source file has been told to collect its parsed tokens, retrieve
571+
/// those tokens.
576572
ArrayRef<Token> getAllTokens() const;
577573

578-
bool shouldCollectToken() const;
574+
/// Whether the parsed tokens of this source file should be saved, allowing
575+
/// them to be accessed from \c getAllTokens.
576+
bool shouldCollectTokens() const;
579577

580578
bool shouldBuildSyntaxTree() const;
581579

582-
bool canBeParsedInFull() const;
583-
584580
/// Whether the bodies of types and functions within this file can be lazily
585581
/// parsed.
586582
bool hasDelayedBodyParsing() const;
587583

588584
syntax::SourceFileSyntax getSyntaxRoot() const;
589-
void setSyntaxRoot(syntax::SourceFileSyntax &&Root);
590-
bool hasSyntaxRoot() const;
591585

592586
OpaqueTypeDecl *lookupOpaqueResultType(StringRef MangledName) override;
593587

@@ -602,10 +596,12 @@ class SourceFile final : public FileUnit {
602596

603597
private:
604598

605-
/// If not None, the underlying vector should contain tokens of this source file.
606-
Optional<std::vector<Token>> AllCorrectedTokens;
599+
/// If not \c None, the underlying vector contains the parsed tokens of this
600+
/// source file.
601+
Optional<ArrayRef<Token>> AllCollectedTokens;
607602

608-
std::unique_ptr<SourceFileSyntaxInfo> SyntaxInfo;
603+
/// The root of the syntax tree representing the source file.
604+
std::unique_ptr<syntax::SourceFileSyntax> SyntaxRoot;
609605
};
610606

611607
inline SourceFile::ParsingOptions operator|(SourceFile::ParsingFlags lhs,

include/swift/Parse/Parser.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/Expr.h"
2323
#include "swift/AST/DiagnosticsParse.h"
2424
#include "swift/AST/LayoutConstraint.h"
25+
#include "swift/AST/ParseRequests.h"
2526
#include "swift/AST/Pattern.h"
2627
#include "swift/AST/Stmt.h"
2728
#include "swift/Basic/OptionSet.h"
@@ -92,8 +93,11 @@ class ConsumeTokenReceiver {
9293
/// This is called to update the kind of a token whose start location is Loc.
9394
virtual void registerTokenKindChange(SourceLoc Loc, tok NewKind) {};
9495

95-
/// This is called when a source file is fully parsed.
96-
virtual void finalize() {};
96+
/// This is called when a source file is fully parsed. It returns the
97+
/// finalized vector of tokens, or \c None if the receiver isn't configured to
98+
/// record them.
99+
virtual Optional<std::vector<Token>> finalize() { return None; }
100+
97101
virtual ~ConsumeTokenReceiver() = default;
98102
};
99103

@@ -124,7 +128,10 @@ class Parser {
124128
/// Tracks parsed decls that LLDB requires to be inserted at the top-level.
125129
std::vector<Decl *> ContextSwitchedTopLevelDecls;
126130

127-
NullablePtr<llvm::MD5> CurrentTokenHash;
131+
/// The current token hash, or \c None if the parser isn't computing a hash
132+
/// for the token stream.
133+
Optional<llvm::MD5> CurrentTokenHash;
134+
128135
void recordTokenHash(const Token Tok) {
129136
if (!Tok.getText().empty())
130137
recordTokenHash(Tok.getText());
@@ -416,6 +423,14 @@ class Parser {
416423
return SyntaxContext->finalizeRoot();
417424
}
418425

426+
/// Retrieve the token receiver from the parser once it has finished parsing.
427+
std::unique_ptr<ConsumeTokenReceiver> takeTokenReceiver() {
428+
assert(Tok.is(tok::eof) && "not done parsing yet");
429+
auto *receiver = TokReceiver;
430+
TokReceiver = nullptr;
431+
return std::unique_ptr<ConsumeTokenReceiver>(receiver);
432+
}
433+
419434
//===--------------------------------------------------------------------===//
420435
// Routines to save and restore parser state.
421436

@@ -472,6 +487,9 @@ class Parser {
472487
void receive(Token tok) override {
473488
delayedTokens.push_back(tok);
474489
}
490+
Optional<std::vector<Token>> finalize() override {
491+
llvm_unreachable("Cannot finalize a DelayedTokenReciever");
492+
}
475493
~DelayedTokenReceiver() {
476494
if (!shouldTransfer)
477495
return;

include/swift/Parse/SyntaxParseActions.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ namespace swift {
2424

2525
class CharSourceRange;
2626
class ParsedTriviaPiece;
27+
class SourceFile;
2728
class SourceLoc;
2829
enum class tok;
2930

3031
namespace syntax {
31-
enum class SyntaxKind;
32+
class SourceFileSyntax;
33+
enum class SyntaxKind;
3234
}
3335

3436
typedef void *OpaqueSyntaxNode;
@@ -55,6 +57,12 @@ class SyntaxParseActions {
5557
ArrayRef<OpaqueSyntaxNode> elements,
5658
CharSourceRange range) = 0;
5759

60+
/// Attempt to realize an opaque raw syntax node for a source file into a
61+
/// SourceFileSyntax node. This will return \c None if the parsing action
62+
/// doesn't support the realization of syntax nodes.
63+
virtual Optional<syntax::SourceFileSyntax>
64+
realizeSyntaxRoot(OpaqueSyntaxNode root, const SourceFile &SF) = 0;
65+
5866
/// Discard raw syntax node.
5967
///
6068
/// FIXME: This breaks invariant that any recorded node will be a part of the

include/swift/SyntaxParse/SyntaxTreeCreator.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ namespace swift {
2323
class SourceFile;
2424

2525
namespace syntax {
26-
class SyntaxArena;
26+
class SyntaxArena;
27+
class SourceFileSyntax;
2728
}
2829

2930
/// Receives the parsed syntax info from the parser and constructs a persistent
@@ -51,7 +52,8 @@ class SyntaxTreeCreator: public SyntaxParseActions {
5152
RC<syntax::SyntaxArena> arena);
5253
~SyntaxTreeCreator();
5354

54-
void acceptSyntaxRoot(OpaqueSyntaxNode root, SourceFile &SF);
55+
Optional<syntax::SourceFileSyntax>
56+
realizeSyntaxRoot(OpaqueSyntaxNode root, const SourceFile &SF) override;
5557

5658
private:
5759
OpaqueSyntaxNode recordToken(tok tokenKind,

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
#include "swift/AST/TypeCheckRequests.h"
4545
#include "swift/AST/TypeLoc.h"
4646
#include "swift/AST/SwiftNameTranslation.h"
47-
#include "swift/Parse/Lexer.h"
47+
#include "swift/Parse/Lexer.h" // FIXME: Bad dependency
4848
#include "clang/Lex/MacroInfo.h"
4949
#include "llvm/ADT/SmallPtrSet.h"
5050
#include "llvm/ADT/SmallSet.h"

0 commit comments

Comments
 (0)