From 5881bf0050398f4bb2d9761167d06a9ecfc8a371 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Mon, 14 Sep 2020 13:39:52 -0700 Subject: [PATCH] [flang] More clean-up of CookedSource API The std::string holding the content of a CookedSource no longer needs to be exposed in its API after the recent work that allows the parsing context to hold multiple instances of a CookedSource. So clean the API. These changes were extracted from some work in progress that was made easier by the API changes. Differential Revision: https://reviews.llvm.org/D87635 --- flang/include/flang/Parser/parse-state.h | 2 +- flang/include/flang/Parser/provenance.h | 15 +++------------ flang/include/flang/Semantics/semantics.h | 4 ++-- flang/lib/Lower/OpenACC.cpp | 2 +- flang/lib/Parser/prescan.cpp | 19 ++++++++----------- flang/lib/Parser/provenance.cpp | 10 +++++++++- flang/tools/f18/f18.cpp | 2 +- flang/unittests/Evaluate/intrinsics.cpp | 4 ++-- 8 files changed, 27 insertions(+), 31 deletions(-) diff --git a/flang/include/flang/Parser/parse-state.h b/flang/include/flang/Parser/parse-state.h index 5d96e95e4da7..00291bac4dbb 100644 --- a/flang/include/flang/Parser/parse-state.h +++ b/flang/include/flang/Parser/parse-state.h @@ -36,7 +36,7 @@ class ParseState { public: // TODO: Add a constructor for parsing a normalized module file. ParseState(const CookedSource &cooked) - : p_{&cooked.data().front()}, limit_{&cooked.data().back() + 1} {} + : p_{cooked.AsCharBlock().begin()}, limit_{cooked.AsCharBlock().end()} {} ParseState(const ParseState &that) : p_{that.p_}, limit_{that.limit_}, context_{that.context_}, userState_{that.userState_}, inFixedForm_{that.inFixedForm_}, diff --git a/flang/include/flang/Parser/provenance.h b/flang/include/flang/Parser/provenance.h index 52aac931e899..1f0a0a90e701 100644 --- a/flang/include/flang/Parser/provenance.h +++ b/flang/include/flang/Parser/provenance.h @@ -167,6 +167,7 @@ public: const std::string &message, bool echoSourceLine = false) const; const SourceFile *GetSourceFile( Provenance, std::size_t *offset = nullptr) const; + const char *GetSource(ProvenanceRange) const; std::optional GetSourcePosition(Provenance) const; std::optional GetFirstFileProvenance() const; std::string GetPath(Provenance) const; // __FILE__ @@ -219,16 +220,7 @@ private: // single instances of CookedSource. class CookedSource { public: - const std::string &data() const { return data_; } - - bool Contains(const char *p) const { - return p >= &data_.front() && p <= &data_.back() + 1; - } - bool Contains(CharBlock range) const { - return !range.empty() && Contains(range.begin()) && - Contains(range.end() - 1); - } - + CharBlock AsCharBlock() const { return CharBlock{data_}; } std::optional GetProvenanceRange(CharBlock) const; std::optional GetCharBlock(ProvenanceRange) const; @@ -253,7 +245,6 @@ public: std::size_t BufferedBytes() const; void Marshal(AllSources &); // marshals text into one contiguous block void CompileProvenanceRangeToOffsetMappings(AllSources &); - std::string AcquireData() { return std::move(data_); } llvm::raw_ostream &Dump(llvm::raw_ostream &) const; private: @@ -276,7 +267,7 @@ public: template // const char * or CharBlock const CookedSource *Find(A x) const { for (const auto &c : cooked_) { - if (c.Contains(x)) { + if (c.AsCharBlock().Contains(x)) { return &c; } } diff --git a/flang/include/flang/Semantics/semantics.h b/flang/include/flang/Semantics/semantics.h index 4c2c0e75992a..de3d9aeac144 100644 --- a/flang/include/flang/Semantics/semantics.h +++ b/flang/include/flang/Semantics/semantics.h @@ -204,10 +204,10 @@ private: class Semantics { public: explicit Semantics(SemanticsContext &context, parser::Program &program, - const parser::CookedSource &cooked, bool debugModuleWriter = false) + parser::CharBlock charBlock, bool debugModuleWriter = false) : context_{context}, program_{program} { context.set_debugModuleWriter(debugModuleWriter); - context.globalScope().AddSourceRange(parser::CharBlock{cooked.data()}); + context.globalScope().AddSourceRange(charBlock); } SemanticsContext &context() const { return context_; } diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 7202d4ec0319..5c8c29e491d6 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1,4 +1,4 @@ -//===-- OpenMP.cpp -- OpenACC directive lowering --------------------------===// +//===-- OpenACC.cpp -- OpenACC directive lowering -------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp index 8e8e57c1334d..3eb909fc1ae8 100644 --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -62,11 +62,8 @@ static void NormalizeCompilerDirectiveCommentMarker(TokenSequence &dir) { void Prescanner::Prescan(ProvenanceRange range) { startProvenance_ = range.start(); - std::size_t offset{0}; - const SourceFile *source{ - allSources_.GetSourceFile(startProvenance_, &offset)}; - CHECK(source); - start_ = source->content().data() + offset; + start_ = allSources_.GetSource(range); + CHECK(start_); limit_ = start_ + range.size(); nextLine_ = start_; const bool beganInFixedForm{inFixedForm_}; @@ -75,7 +72,7 @@ void Prescanner::Prescan(ProvenanceRange range) { "too many nested INCLUDE/#include files, possibly circular"_err_en_US); return; } - while (nextLine_ < limit_) { + while (!IsAtEnd()) { Statement(); } if (inFixedForm_ != beganInFixedForm) { @@ -232,7 +229,7 @@ void Prescanner::Statement() { } TokenSequence Prescanner::TokenizePreprocessorDirective() { - CHECK(nextLine_ < limit_ && !inPreprocessorDirective_); + CHECK(!IsAtEnd() && !inPreprocessorDirective_); inPreprocessorDirective_ = true; BeginStatementAndAdvance(); TokenSequence tokens; @@ -360,7 +357,7 @@ void Prescanner::SkipCComments() { break; } } else if (inPreprocessorDirective_ && at_[0] == '\\' && at_ + 2 < limit_ && - at_[1] == '\n' && nextLine_ < limit_) { + at_[1] == '\n' && !IsAtEnd()) { BeginSourceLineAndAdvance(); } else { break; @@ -804,7 +801,7 @@ bool Prescanner::IsNextLinePreprocessorDirective() const { } bool Prescanner::SkipCommentLine(bool afterAmpersand) { - if (nextLine_ >= limit_) { + if (IsAtEnd()) { if (afterAmpersand && prescannerNesting_ > 0) { // A continuation marker at the end of the last line in an // include file inhibits the newline for that line. @@ -843,7 +840,7 @@ bool Prescanner::SkipCommentLine(bool afterAmpersand) { } const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) { - if (nextLine_ >= limit_) { + if (IsAtEnd()) { return nullptr; } tabInCurrentLine_ = false; @@ -995,7 +992,7 @@ bool Prescanner::FreeFormContinuation() { // arguments to span multiple lines. bool Prescanner::IsImplicitContinuation() const { return !inPreprocessorDirective_ && !inCharLiteral_ && - delimiterNesting_ > 0 && nextLine_ < limit_ && + delimiterNesting_ > 0 && !IsAtEnd() && ClassifyLine(nextLine_).kind == LineClassification::Kind::Source; } diff --git a/flang/lib/Parser/provenance.cpp b/flang/lib/Parser/provenance.cpp index bcb871bd7cb4..46a0dc926822 100644 --- a/flang/lib/Parser/provenance.cpp +++ b/flang/lib/Parser/provenance.cpp @@ -301,6 +301,14 @@ const SourceFile *AllSources::GetSourceFile( origin.u); } +const char *AllSources::GetSource(ProvenanceRange range) const { + Provenance start{range.start()}; + const Origin &origin{MapToOrigin(start)}; + return origin.covers.Contains(range) + ? &origin[origin.covers.MemberOffset(start)] + : nullptr; +} + std::optional AllSources::GetSourcePosition( Provenance prov) const { const Origin &origin{MapToOrigin(prov)}; @@ -402,7 +410,7 @@ const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const { std::optional CookedSource::GetProvenanceRange( CharBlock cookedRange) const { - if (!Contains(cookedRange)) { + if (!AsCharBlock().Contains(cookedRange)) { return std::nullopt; } ProvenanceRange first{provenanceMap_.Map(cookedRange.begin() - &data_[0])}; diff --git a/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp index a33a167686e4..54a905133db7 100644 --- a/flang/tools/f18/f18.cpp +++ b/flang/tools/f18/f18.cpp @@ -251,7 +251,7 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options, driver.dumpSymbols || driver.dumpUnparseWithSymbols || driver.getDefinition || driver.getSymbolsSources) { Fortran::semantics::Semantics semantics{semanticsContext, parseTree, - parsing.cooked(), driver.debugModuleWriter}; + parsing.cooked().AsCharBlock(), driver.debugModuleWriter}; semantics.Perform(); semantics.EmitMessages(llvm::errs()); if (driver.dumpSymbols) { diff --git a/flang/unittests/Evaluate/intrinsics.cpp b/flang/unittests/Evaluate/intrinsics.cpp index 4f2a21dfe604..52507b8ef8b6 100644 --- a/flang/unittests/Evaluate/intrinsics.cpp +++ b/flang/unittests/Evaluate/intrinsics.cpp @@ -26,10 +26,10 @@ public: } void Marshal() { cooked_.Marshal(allSources_); } parser::CharBlock operator()(const std::string &s) { - return {cooked_.data().data() + offsets_[s], s.size()}; + return {cooked_.AsCharBlock().begin() + offsets_[s], s.size()}; } parser::ContextualMessages Messages(parser::Messages &buffer) { - return parser::ContextualMessages{cooked_.data(), &buffer}; + return parser::ContextualMessages{cooked_.AsCharBlock(), &buffer}; } void Emit(llvm::raw_ostream &o, const parser::Messages &messages) { messages.Emit(o, allCookedSources_);