// 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 {};
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() {}
namespace Fortran::parser {
+Parsing::Parsing() {}
+Parsing::Parsing(AllSources &s) : cooked_{s} {}
+
+Parsing::~Parsing() {}
+
void Parsing::Prescan(const std::string &path, Options options) {
options_ = 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_; }
return origin_[low];
}
-CookedSource::CookedSource() {}
+CookedSource::CookedSource() : allSources_{new AllSources} {}
+CookedSource::CookedSource(AllSources &s) : allSources_{&s} {}
CookedSource::~CookedSource() {}
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();
}
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;
#include "source.h"
#include "../common/idioms.h"
#include "../common/interval.h"
+#include "../common/reference-counted.h"
#include <cstddef>
#include <map>
#include <memory>
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();
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 {
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;
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_;
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);