diff --git a/flang/lib/common/idioms.h b/flang/lib/common/idioms.h index ec3a6a44ac0e..61483b0490d9 100644 --- a/flang/lib/common/idioms.h +++ b/flang/lib/common/idioms.h @@ -132,7 +132,7 @@ template struct ListItemCount { // std::optional<>. template std::optional GetIf(const VARIANT &u) { - if (const A *x{std::get_if(&u)}) { + if (const A * x{std::get_if(&u)}) { return {*x}; } return {}; diff --git a/flang/lib/common/reference-counted.h b/flang/lib/common/reference-counted.h index f44f0a5ef09d..cf11684a767c 100644 --- a/flang/lib/common/reference-counted.h +++ b/flang/lib/common/reference-counted.h @@ -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 class ReferenceCounted { public: ReferenceCounted() {} diff --git a/flang/lib/parser/parsing.cc b/flang/lib/parser/parsing.cc index a91e7b895ebe..7b1205c739e5 100644 --- a/flang/lib/parser/parsing.cc +++ b/flang/lib/parser/parsing.cc @@ -25,6 +25,11 @@ namespace Fortran::parser { +Parsing::Parsing() {} +Parsing::Parsing(AllSources &s) : cooked_{s} {} + +Parsing::~Parsing() {} + void Parsing::Prescan(const std::string &path, Options options) { options_ = options; diff --git a/flang/lib/parser/parsing.h b/flang/lib/parser/parsing.h index a874df32b02f..313c5421d237 100644 --- a/flang/lib/parser/parsing.h +++ b/flang/lib/parser/parsing.h @@ -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_; } diff --git a/flang/lib/parser/provenance.cc b/flang/lib/parser/provenance.cc index 69e130dc6166..72eb28829f40 100644 --- a/flang/lib/parser/provenance.cc +++ b/flang/lib/parser/provenance.cc @@ -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 CookedSource::GetProvenanceRange( @@ -325,7 +326,8 @@ std::optional 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; diff --git a/flang/lib/parser/provenance.h b/flang/lib/parser/provenance.h index 23d60e8d401f..70b659228e7f 100644 --- a/flang/lib/parser/provenance.h +++ b/flang/lib/parser/provenance.h @@ -20,6 +20,7 @@ #include "source.h" #include "../common/idioms.h" #include "../common/interval.h" +#include "../common/reference-counted.h" #include #include #include @@ -108,7 +109,9 @@ private: std::vector provenanceMap_; }; -class AllSources { +// AllSources is reference-counted so that multiple instances of CookedSource +// can share an AllSources instance. +class AllSources : public common::ReferenceCounted { 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 GetProvenanceRange(CharBlock) const; @@ -215,7 +219,7 @@ public: std::ostream &Dump(std::ostream &) const; private: - AllSources allSources_; + common::CountedReference allSources_; CharBuffer buffer_; // before Marshal() std::string data_; // all of it, prescanned and preprocessed OffsetToProvenanceMappings provenanceMap_; diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index c9f459c3b6c9..ca11e34d2720 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -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);