[flang] Let multiple CookedSource instances share a ref-counted AllSources.
authorpeter klausler <pklausler@nvidia.com>
Fri, 27 Jul 2018 21:58:14 +0000 (14:58 -0700)
committerpeter klausler <pklausler@nvidia.com>
Fri, 27 Jul 2018 21:58:14 +0000 (14:58 -0700)
Original-commit: flang-compiler/f18@98a170e3e58b8937dd5770d2e0303aa9750b6f84
Reviewed-on: https://github.com/flang-compiler/f18/pull/151
Tree-same-pre-rewrite: false

flang/lib/common/idioms.h
flang/lib/common/reference-counted.h
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

index ec3a6a4..61483b0 100644 (file)
@@ -132,7 +132,7 @@ template<typename A> struct ListItemCount {
 // std::optional<>.
 template<typename A, typename VARIANT>
 std::optional<A> GetIf(const VARIANT &u) {
-  if (const A *x{std::get_if<A>(&u)}) {
+  if (const A * x{std::get_if<A>(&u)}) {
     return {*x};
   }
   return {};
index f44f0a5..cf11684 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Fortran::common {
 
-// A base class for reference-counted objects.
+// A base class for reference-counted objects.  Must be public.
 template<typename A> class ReferenceCounted {
 public:
   ReferenceCounted() {}
index a91e7b8..7b1205c 100644 (file)
 
 namespace Fortran::parser {
 
+Parsing::Parsing() {}
+Parsing::Parsing(AllSources &s) : cooked_{s} {}
+
+Parsing::~Parsing() {}
+
 void Parsing::Prescan(const std::string &path, Options options) {
   options_ = options;
 
index a874df3..313c542 100644 (file)
@@ -46,7 +46,10 @@ struct Options {
 
 class Parsing {
 public:
-  Parsing() {}
+  Parsing();
+  explicit Parsing(AllSources &);  // to share an extant AllSources instance
+
+  ~Parsing();
 
   bool consumedWholeFile() const { return consumedWholeFile_; }
   const char *finalRestingPlace() const { return finalRestingPlace_; }
index 69e130d..72eb288 100644 (file)
@@ -307,7 +307,8 @@ const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const {
   return origin_[low];
 }
 
-CookedSource::CookedSource() {}
+CookedSource::CookedSource() : allSources_{new AllSources} {}
+CookedSource::CookedSource(AllSources &s) : allSources_{&s} {}
 CookedSource::~CookedSource() {}
 
 std::optional<ProvenanceRange> CookedSource::GetProvenanceRange(
@@ -325,7 +326,8 @@ std::optional<ProvenanceRange> CookedSource::GetProvenanceRange(
 
 void CookedSource::Marshal() {
   CHECK(provenanceMap_.size() == buffer_.size());
-  provenanceMap_.Put(allSources_.AddCompilerInsertion("(after end of source)"));
+  provenanceMap_.Put(
+      allSources_->AddCompilerInsertion("(after end of source)"));
   data_ = buffer_.Marshal();
   buffer_.clear();
 }
@@ -381,7 +383,7 @@ std::ostream &AllSources::Dump(std::ostream &o) const {
 
 std::ostream &CookedSource::Dump(std::ostream &o) const {
   o << "CookedSource:\n";
-  allSources_.Dump(o);
+  allSources_->Dump(o);
   o << "CookedSource::provenanceMap_:\n";
   provenanceMap_.Dump(o);
   return o;
index 23d60e8..70b6592 100644 (file)
@@ -20,6 +20,7 @@
 #include "source.h"
 #include "../common/idioms.h"
 #include "../common/interval.h"
+#include "../common/reference-counted.h"
 #include <cstddef>
 #include <map>
 #include <memory>
@@ -108,7 +109,9 @@ private:
   std::vector<ContiguousProvenanceMapping> provenanceMap_;
 };
 
-class AllSources {
+// AllSources is reference-counted so that multiple instances of CookedSource
+// can share an AllSources instance.
+class AllSources : public common::ReferenceCounted<AllSources> {
 public:
   AllSources();
   ~AllSources();
@@ -184,10 +187,11 @@ private:
 class CookedSource {
 public:
   CookedSource();
+  explicit CookedSource(AllSources &);
   ~CookedSource();
 
-  AllSources &allSources() { return allSources_; }
-  const AllSources &allSources() const { return allSources_; }
+  AllSources &allSources() { return *allSources_; }
+  const AllSources &allSources() const { return *allSources_; }
   const std::string &data() const { return data_; }
 
   bool IsValid(const char *p) const {
@@ -196,7 +200,7 @@ public:
   bool IsValid(CharBlock range) const {
     return !range.empty() && IsValid(range.begin()) && IsValid(range.end() - 1);
   }
-  bool IsValid(ProvenanceRange r) const { return allSources_.IsValid(r); }
+  bool IsValid(ProvenanceRange r) const { return allSources_->IsValid(r); }
 
   std::optional<ProvenanceRange> GetProvenanceRange(CharBlock) const;
 
@@ -215,7 +219,7 @@ public:
   std::ostream &Dump(std::ostream &) const;
 
 private:
-  AllSources allSources_;
+  common::CountedReference<AllSources> allSources_;
   CharBuffer buffer_;  // before Marshal()
   std::string data_;  // all of it, prescanned and preprocessed
   OffsetToProvenanceMappings provenanceMap_;
index c9f459c..ca11e34 100644 (file)
@@ -353,6 +353,7 @@ bool ModFileReader::Read(const SourceName &modName) {
   if (!path.has_value()) {
     return false;
   }
+  // TODO: Construct parsing with an AllSources reference to share provenance
   parser::Parsing parsing;
   parsing.Prescan(*path, {});
   parsing.Parse(&std::cout);