2018-02-07 22:18:36 +01:00
|
|
|
#ifndef FORTRAN_PROVENANCE_H_
|
|
|
|
#define FORTRAN_PROVENANCE_H_
|
|
|
|
#include "source.h"
|
2018-02-08 01:24:02 +01:00
|
|
|
#include <memory>
|
|
|
|
#include <ostream>
|
2018-02-07 22:18:36 +01:00
|
|
|
#include <string>
|
|
|
|
#include <variant>
|
|
|
|
namespace Fortran {
|
2018-02-08 01:24:02 +01:00
|
|
|
namespace parser {
|
2018-02-07 22:18:36 +01:00
|
|
|
|
|
|
|
using Provenance = size_t;
|
|
|
|
|
2018-02-08 01:24:02 +01:00
|
|
|
class ProvenanceRange {
|
|
|
|
public:
|
|
|
|
ProvenanceRange() {}
|
|
|
|
bool empty() const { return bytes_ == 0; }
|
|
|
|
Provenance start() const { return start_; }
|
|
|
|
size_t bytes() const { return bytes_; }
|
|
|
|
private:
|
|
|
|
Provenance start_{0};
|
|
|
|
size_t bytes_{0};
|
2018-02-07 22:18:36 +01:00
|
|
|
};
|
|
|
|
|
2018-02-08 01:24:02 +01:00
|
|
|
class AllOfTheSource;
|
|
|
|
|
|
|
|
class Origin {
|
2018-02-07 22:18:36 +01:00
|
|
|
public:
|
2018-02-08 01:24:02 +01:00
|
|
|
explicit Origin(const SourceFile &); // initial source file
|
|
|
|
Origin(const SourceFile &, ProvenanceRange); // included source file
|
|
|
|
Origin(ProvenanceRange def, ProvenanceRange use, // macro call
|
|
|
|
const std::string &expansion);
|
|
|
|
size_t size() const;
|
|
|
|
const char &operator[](size_t) const;
|
|
|
|
void Identify(std::ostream &, const AllOfTheSource &, size_t,
|
|
|
|
const std::string &indent) const;
|
2018-02-07 22:18:36 +01:00
|
|
|
private:
|
2018-02-08 01:24:02 +01:00
|
|
|
struct Inclusion {
|
|
|
|
const SourceFile &source;
|
|
|
|
};
|
|
|
|
struct Macro {
|
|
|
|
ProvenanceRange definition;
|
|
|
|
std::string expansion;
|
|
|
|
};
|
|
|
|
std::variant<Inclusion, Macro> u_;
|
|
|
|
ProvenanceRange replaces_;
|
|
|
|
};
|
2018-02-07 22:18:36 +01:00
|
|
|
|
2018-02-08 01:24:02 +01:00
|
|
|
class AllOfTheSource {
|
|
|
|
public:
|
|
|
|
AllOfTheSource() {}
|
|
|
|
AllOfTheSource(AllOfTheSource &&) = default;
|
|
|
|
AllOfTheSource &operator=(AllOfTheSource &&) = default;
|
|
|
|
size_t size() const { return bytes_; }
|
|
|
|
const char &operator[](Provenance) const;
|
|
|
|
AllOfTheSource &Add(Origin &&);
|
|
|
|
void Identify(std::ostream &, Provenance, const std::string &prefix) const;
|
|
|
|
private:
|
|
|
|
struct Chunk {
|
|
|
|
Chunk(Origin &&origin, size_t at) : origin{std::move(origin)}, start{at} {}
|
|
|
|
Origin origin;
|
|
|
|
size_t start;
|
2018-02-07 22:18:36 +01:00
|
|
|
};
|
2018-02-08 01:24:02 +01:00
|
|
|
const Chunk &MapToChunk(Provenance) const;
|
|
|
|
std::vector<Chunk> chunk_;
|
2018-02-07 22:18:36 +01:00
|
|
|
size_t bytes_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ProvenancedChar {
|
|
|
|
public:
|
|
|
|
using type = char;
|
|
|
|
char character() const { return static_cast<char>(packed_); }
|
|
|
|
Provenance provenance() const { return packed_ >> 8; }
|
|
|
|
private:
|
|
|
|
size_t packed_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ProvenancedString {
|
|
|
|
private:
|
|
|
|
class iterator {
|
|
|
|
public:
|
2018-02-08 01:24:02 +01:00
|
|
|
iterator(const AllOfTheSource &sources, Provenance at)
|
2018-02-07 22:18:36 +01:00
|
|
|
: sources_{&sources}, at_{at} {}
|
|
|
|
iterator(const iterator &that)
|
|
|
|
: sources_{that.sources_}, at_{that.at_} {}
|
2018-02-08 01:24:02 +01:00
|
|
|
iterator &operator=(const iterator &that) {
|
2018-02-07 22:18:36 +01:00
|
|
|
sources_ = that.sources_;
|
|
|
|
at_ = that.at_;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
const char &operator*() const;
|
|
|
|
iterator &operator++() {
|
|
|
|
++at_;
|
|
|
|
return *this;
|
|
|
|
}
|
2018-02-08 01:24:02 +01:00
|
|
|
iterator operator++(int) {
|
2018-02-07 22:18:36 +01:00
|
|
|
iterator result{*this};
|
|
|
|
++at_;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
bool operator<(const iterator &that) { return at_ < that.at_; }
|
|
|
|
bool operator<=(const iterator &that) { return at_ <= that.at_; }
|
|
|
|
bool operator==(const iterator &that) { return at_ == that.at_; }
|
|
|
|
bool operator!=(const iterator &that) { return at_ != that.at_; }
|
|
|
|
private:
|
2018-02-08 01:24:02 +01:00
|
|
|
const AllOfTheSource *sources_;
|
2018-02-07 22:18:36 +01:00
|
|
|
size_t at_;
|
|
|
|
};
|
|
|
|
|
2018-02-08 01:24:02 +01:00
|
|
|
iterator begin(const AllOfTheSource &sources) const {
|
2018-02-07 22:18:36 +01:00
|
|
|
return iterator(sources, start_);
|
|
|
|
}
|
2018-02-08 01:24:02 +01:00
|
|
|
iterator end(const AllOfTheSource &sources) const {
|
2018-02-07 22:18:36 +01:00
|
|
|
return iterator(sources, start_ + bytes_);
|
|
|
|
}
|
|
|
|
public:
|
|
|
|
size_t size() const { return bytes_; }
|
|
|
|
private:
|
|
|
|
Provenance start_;
|
|
|
|
size_t bytes_;
|
|
|
|
};
|
2018-02-08 01:24:02 +01:00
|
|
|
} // namespace parser
|
2018-02-07 22:18:36 +01:00
|
|
|
} // namespace Fortran
|
|
|
|
#endif // FORTRAN_PROVENANCE_H_
|