[flang] Change how cooked source is saved
authorTim Keith <tkeith@nvidia.com>
Thu, 26 Jul 2018 21:33:41 +0000 (14:33 -0700)
committerTim Keith <tkeith@nvidia.com>
Thu, 26 Jul 2018 23:03:31 +0000 (16:03 -0700)
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
flang/lib/parser/parsing.h
flang/lib/parser/provenance.cc
flang/lib/parser/provenance.h
flang/lib/semantics/mod-file.cc
flang/lib/semantics/mod-file.h
flang/lib/semantics/scope.h
flang/lib/semantics/symbol.cc

index ae835ac..d2ca8a4 100644 (file)
@@ -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<const char *> 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;
index 334474f..5c6cf18 100644 (file)
@@ -50,8 +50,7 @@ public:
 
   bool consumedWholeFile() const { return consumedWholeFile_; }
   const char *finalRestingPlace() const { return finalRestingPlace_; }
-  CookedSource &cooked() { return *cooked_; }
-  std::unique_ptr<CookedSource> MoveCooked() { return std::move(cooked_); }
+  CookedSource &cooked() { return cooked_; }
   Messages &messages() { return messages_; }
   std::optional<Program> &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<parser::CookedSource> cooked_{
-      std::make_unique<parser::CookedSource>(allSources_)};
+  CookedSource cooked_{allSources_};
   Messages messages_;
   bool consumedWholeFile_{false};
   const char *finalRestingPlace_{nullptr};
index 0da5ad6..3599377 100644 (file)
@@ -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<std::vector<char>>(buffer_.size());
+  char *p{&(*data_)[0]};
   for (char ch : buffer_) {
     *p++ = ch;
   }
index 1c5ce2f..1a230b4 100644 (file)
@@ -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<std::vector<char>> MoveChars() { return std::move(data_); }
   std::ostream &Dump(std::ostream &) const;
 
 private:
   AllSources &allSources_;
   CharBuffer buffer_;  // before Marshal()
-  std::vector<char> data_;  // all of it, prescanned and preprocessed
+  // all source, prescanned and preprocessed:
+  std::unique_ptr<std::vector<char>> data_;
   OffsetToProvenanceMappings provenanceMap_;
 };
 
index 52d48a1..58fe7c2 100644 (file)
@@ -364,15 +364,14 @@ bool ModFileReader::Read(const SourceName &modName) {
             modName.ToString(), *path));
     return false;
   }
-  std::unique_ptr<parser::CookedSource> 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;
 }
index 3e516d5..ec24958 100644 (file)
@@ -92,9 +92,6 @@ public:
 
 private:
   std::vector<std::string> directories_;
-  parser::AllSources allSources_;
-  std::unique_ptr<parser::CookedSource> cooked_{
-      std::make_unique<parser::CookedSource>(allSources_)};
   std::vector<parser::Message> errors_;
 
   std::optional<std::string> FindModFile(const SourceName &);
index 544435f..860432f 100644 (file)
@@ -18,7 +18,6 @@
 #include "attr.h"
 #include "symbol.h"
 #include "../common/idioms.h"
-#include "../parser/parse-tree.h"
 #include <list>
 #include <map>
 #include <string>
@@ -106,9 +105,10 @@ public:
 
   DerivedTypeSpec &MakeDerivedTypeSpec(const SourceName &);
 
-  std::unique_ptr<parser::CookedSource> cooked_;
-  void set_cookedSource(std::unique_ptr<parser::CookedSource> 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<std::vector<char>> chars) {
+    chars_ = std::move(chars);
   }
 
 private:
@@ -118,6 +118,7 @@ private:
   std::list<Scope> children_;
   mapType symbols_;
   std::list<DerivedTypeSpec> derivedTypeSpecs_;
+  std::unique_ptr<std::vector<char>> chars_;
 
   // Storage for all Symbols. Every Symbol is in allSymbols and every Symbol*
   // or Symbol& points to one in there.
index 4351e7b..89655d7 100644 (file)
@@ -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();
 }