From 6f4f772685b0d7b9c7e01da8c6f20d8403b1c45a Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Thu, 26 Jul 2018 14:33:41 -0700 Subject: [PATCH] [flang] Change how cooked source is saved Rather than save the entire CookedSource object in the module scope, all we need is the vector of characters that CharBlock has references into. This avoids the problem that CookedSource object has a dangling reference to an AllSources object (which shouldn't be needed by the CharBlocks in the symbol table, but is there). This also decouples Scope from parser classes other than CharBlock. Original-commit: flang-compiler/f18@fdbf5c841e9913009ba84ae0fe83b3021848bf5b Reviewed-on: https://github.com/flang-compiler/f18/pull/149 Tree-same-pre-rewrite: false --- flang/lib/parser/parsing.cc | 20 ++++++++++---------- flang/lib/parser/parsing.h | 8 +++----- flang/lib/parser/provenance.cc | 8 ++++---- flang/lib/parser/provenance.h | 12 +++++++----- flang/lib/semantics/mod-file.cc | 5 ++--- flang/lib/semantics/mod-file.h | 3 --- flang/lib/semantics/scope.h | 9 +++++---- flang/lib/semantics/symbol.cc | 3 --- 8 files changed, 31 insertions(+), 37 deletions(-) diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index ae835acb65e1..d2ca8a49a201 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -63,7 +63,7 @@ void Parsing::Prescan(const std::string &path, Options options) { preprocessor.Undefine(predef.first); } } - Prescanner prescanner{messages_, *cooked_, preprocessor, options.features}; + Prescanner prescanner{messages_, cooked_, preprocessor, options.features}; prescanner.set_fixedForm(options.isFixedForm) .set_fixedFormColumnLimit(options.fixedFormColumns) .set_encoding(options.encoding) @@ -75,30 +75,30 @@ void Parsing::Prescan(const std::string &path, Options options) { ProvenanceRange range{ allSources_.AddIncludedFile(*sourceFile, ProvenanceRange{})}; prescanner.Prescan(range); - cooked_->Marshal(); + cooked_.Marshal(); } void Parsing::DumpCookedChars(std::ostream &out) const { - UserState userState{*cooked_, LanguageFeatureControl{}}; - ParseState parseState{*cooked_}; + UserState userState{cooked_, LanguageFeatureControl{}}; + ParseState parseState{cooked_}; parseState.set_inFixedForm(options_.isFixedForm).set_userState(&userState); while (std::optional p{parseState.GetNextChar()}) { out << **p; } } -void Parsing::DumpProvenance(std::ostream &out) const { cooked_->Dump(out); } +void Parsing::DumpProvenance(std::ostream &out) const { cooked_.Dump(out); } void Parsing::DumpParsingLog(std::ostream &out) const { - log_.Dump(out, *cooked_); + log_.Dump(out, cooked_); } void Parsing::Parse(std::ostream *out) { - UserState userState{*cooked_, options_.features}; + UserState userState{cooked_, options_.features}; userState.set_debugOutput(out) .set_instrumentedParse(options_.instrumentedParse) .set_log(&log_); - ParseState parseState{*cooked_}; + ParseState parseState{cooked_}; parseState.set_inFixedForm(options_.isFixedForm) .set_encoding(options_.encoding) .set_userState(&userState); @@ -115,12 +115,12 @@ void Parsing::ClearLog() { log_.clear(); } bool Parsing::ForTesting(std::string path, std::ostream &err) { Prescan(path, Options{}); if (messages_.AnyFatalError()) { - messages_.Emit(err, *cooked_); + messages_.Emit(err, cooked_); err << "could not scan " << path << '\n'; return false; } Parse(); - messages_.Emit(err, *cooked_); + messages_.Emit(err, cooked_); if (!consumedWholeFile_) { EmitMessage(err, finalRestingPlace_, "parser FAIL; final position"); return false; diff --git a/flang/lib/parser/parsing.h b/flang/lib/parser/parsing.h index 334474f10909..5c6cf18029ac 100644 --- a/flang/lib/parser/parsing.h +++ b/flang/lib/parser/parsing.h @@ -50,8 +50,7 @@ public: bool consumedWholeFile() const { return consumedWholeFile_; } const char *finalRestingPlace() const { return finalRestingPlace_; } - CookedSource &cooked() { return *cooked_; } - std::unique_ptr MoveCooked() { return std::move(cooked_); } + CookedSource &cooked() { return cooked_; } Messages &messages() { return messages_; } std::optional &parseTree() { return parseTree_; } @@ -65,7 +64,7 @@ public: void EmitMessage(std::ostream &o, const char *at, const std::string &message, bool echoSourceLine = false) const { allSources_.EmitMessage( - o, cooked_->GetProvenanceRange(at).start(), message, echoSourceLine); + o, cooked_.GetProvenanceRange(at).start(), message, echoSourceLine); } bool ForTesting(std::string path, std::ostream &); @@ -73,8 +72,7 @@ public: private: Options options_; AllSources allSources_; - std::unique_ptr cooked_{ - std::make_unique(allSources_)}; + CookedSource cooked_{allSources_}; Messages messages_; bool consumedWholeFile_{false}; const char *finalRestingPlace_{nullptr}; diff --git a/flang/lib/parser/provenance.cc b/flang/lib/parser/provenance.cc index 0da5ad6dbc91..35993776aa00 100644 --- a/flang/lib/parser/provenance.cc +++ b/flang/lib/parser/provenance.cc @@ -303,19 +303,19 @@ const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const { } ProvenanceRange CookedSource::GetProvenanceRange(CharBlock cookedRange) const { - ProvenanceRange first{provenanceMap_.Map(cookedRange.begin() - &data_[0])}; + ProvenanceRange first{provenanceMap_.Map(cookedRange.begin() - &(*data_)[0])}; if (cookedRange.size() <= first.size()) { return first.Prefix(cookedRange.size()); } - ProvenanceRange last{provenanceMap_.Map(cookedRange.end() - &data_[0])}; + ProvenanceRange last{provenanceMap_.Map(cookedRange.end() - &(*data_)[0])}; return {first.start(), last.start() - first.start()}; } void CookedSource::Marshal() { CHECK(provenanceMap_.size() == buffer_.size()); provenanceMap_.Put(allSources_.AddCompilerInsertion("(after end of source)")); - data_.resize(buffer_.size()); - char *p{&data_[0]}; + data_ = std::make_unique>(buffer_.size()); + char *p{&(*data_)[0]}; for (char ch : buffer_) { *p++ = ch; } diff --git a/flang/lib/parser/provenance.h b/flang/lib/parser/provenance.h index 1c5ce2f67383..1a230b47c34e 100644 --- a/flang/lib/parser/provenance.h +++ b/flang/lib/parser/provenance.h @@ -184,14 +184,14 @@ class CookedSource { public: explicit CookedSource(AllSources &sources) : allSources_{sources} {} - std::size_t size() const { return data_.size(); } - const char &operator[](std::size_t n) const { return data_[n]; } - const char &at(std::size_t n) const { return data_.at(n); } + std::size_t size() const { return data_->size(); } + const char &operator[](std::size_t n) const { return (*data_)[n]; } + const char &at(std::size_t n) const { return data_->at(n); } AllSources &allSources() const { return allSources_; } bool IsValid(const char *p) const { - return p >= &data_.front() && p <= &data_.back() + 1; + return p >= &data_->front() && p <= &data_->back() + 1; } bool IsValid(CharBlock range) const { return !range.empty() && IsValid(range.begin()) && IsValid(range.end() - 1); @@ -211,12 +211,14 @@ public: provenanceMap_.Put(pm); } void Marshal(); // marshals all text into one contiguous block + std::unique_ptr> MoveChars() { return std::move(data_); } std::ostream &Dump(std::ostream &) const; private: AllSources &allSources_; CharBuffer buffer_; // before Marshal() - std::vector data_; // all of it, prescanned and preprocessed + // all source, prescanned and preprocessed: + std::unique_ptr> data_; OffsetToProvenanceMappings provenanceMap_; }; diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index 52d48a13694d..58fe7c2d5f63 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -364,15 +364,14 @@ bool ModFileReader::Read(const SourceName &modName) { modName.ToString(), *path)); return false; } - std::unique_ptr cooked_{parsing.MoveCooked()}; - ResolveNames(*parseTree, *cooked_, directories_); + ResolveNames(*parseTree, parsing.cooked(), directories_); const auto &it{Scope::globalScope.find(modName)}; if (it == Scope::globalScope.end()) { return false; } auto &modSymbol{*it->second}; - modSymbol.scope()->set_cookedSource(std::move(cooked_)); + modSymbol.scope()->set_chars(parsing.cooked().MoveChars()); modSymbol.set(Symbol::Flag::ModFile); return true; } diff --git a/flang/lib/semantics/mod-file.h b/flang/lib/semantics/mod-file.h index 3e516d55a171..ec2495846eb4 100644 --- a/flang/lib/semantics/mod-file.h +++ b/flang/lib/semantics/mod-file.h @@ -92,9 +92,6 @@ public: private: std::vector directories_; - parser::AllSources allSources_; - std::unique_ptr cooked_{ - std::make_unique(allSources_)}; std::vector errors_; std::optional FindModFile(const SourceName &); diff --git a/flang/lib/semantics/scope.h b/flang/lib/semantics/scope.h index 544435f3691c..860432fea39f 100644 --- a/flang/lib/semantics/scope.h +++ b/flang/lib/semantics/scope.h @@ -18,7 +18,6 @@ #include "attr.h" #include "symbol.h" #include "../common/idioms.h" -#include "../parser/parse-tree.h" #include #include #include @@ -106,9 +105,10 @@ public: DerivedTypeSpec &MakeDerivedTypeSpec(const SourceName &); - std::unique_ptr cooked_; - void set_cookedSource(std::unique_ptr cooked) { - cooked_ = std::move(cooked); + // For modules read from module files, this is the stream of characters + // that are referenced by SourceName objects. + void set_chars(std::unique_ptr> chars) { + chars_ = std::move(chars); } private: @@ -118,6 +118,7 @@ private: std::list children_; mapType symbols_; std::list derivedTypeSpecs_; + std::unique_ptr> chars_; // Storage for all Symbols. Every Symbol is in allSymbols and every Symbol* // or Symbol& points to one in there. diff --git a/flang/lib/semantics/symbol.cc b/flang/lib/semantics/symbol.cc index 4351e7b68cbb..89655d7ad91e 100644 --- a/flang/lib/semantics/symbol.cc +++ b/flang/lib/semantics/symbol.cc @@ -19,9 +19,6 @@ namespace Fortran::semantics { -std::ostream &operator<<(std::ostream &os, const parser::Name &name) { - return os << name.ToString(); -} std::ostream &operator<<(std::ostream &os, const parser::CharBlock &name) { return os << name.ToString(); }