if (result.has_value()) {
state.set_anyConformanceViolation();
if (state.warnOnNonstandardUsage()) {
- state.Say(at, "nonstandard usage"_en_US);
+ state.Say(
+ CharBlock{at, state.GetLocation()}, "nonstandard usage"_en_US);
}
}
return result;
if (result) {
state.set_anyConformanceViolation();
if (state.warnOnDeprecatedUsage()) {
- state.Say(at, "deprecated usage"_en_US);
+ state.Say(CharBlock{at, state.GetLocation()}, "deprecated usage"_en_US);
}
}
return result;
bool operator==(const Interval &that) const {
return start_ == that.start_ && size_ == that.size_;
}
+ bool operator!=(const Interval &that) const {
+ return start_ != that.start_ || size_ != that.size_;
+ }
const A &start() const { return start_; }
std::size_t size() const { return size_; }
}
void Message::Incorporate(Message &that) {
- if (provenance_ == that.provenance_ &&
- cookedSourceLocation_ == that.cookedSourceLocation_ &&
+ if (provenanceRange_.start() == that.provenanceRange_.start() &&
+ cookedSourceRange_.begin() == that.cookedSourceRange_.begin() &&
!expected_.empty()) {
expected_ = expected_.Union(that.expected_);
}
return s;
}
-Provenance Message::Emit(
+ProvenanceRange Message::Emit(
std::ostream &o, const CookedSource &cooked, bool echoSourceLine) const {
- Provenance provenance{provenance_};
- if (cookedSourceLocation_ != nullptr) {
- provenance = cooked.GetProvenance(cookedSourceLocation_).start();
+ ProvenanceRange provenanceRange{provenanceRange_};
+ if (cookedSourceRange_.begin() != nullptr) {
+ provenanceRange = cooked.GetProvenance(cookedSourceRange_);
}
- if (!context_ || context_->Emit(o, cooked, false) != provenance) {
- cooked.allSources().Identify(o, provenance, "", echoSourceLine);
+ if (!context_ || context_->Emit(o, cooked, false) != provenanceRange) {
+ cooked.allSources().Identify(o, provenanceRange, "", echoSourceLine);
}
o << " ";
if (isFatal_) {
o << "ERROR: ";
}
o << ToString() << '\n';
- return provenance;
+ return provenanceRange;
}
void Messages::Incorporate(Messages &that) {
Message &operator=(const Message &that) = default;
Message &operator=(Message &&that) = default;
- // TODO: Change these to cover ranges of provenance
- Message(Provenance p, MessageFixedText t)
- : provenance_{p}, fixedText_{t.str()},
+ Message(ProvenanceRange pr, MessageFixedText t)
+ : provenanceRange_{pr}, fixedText_{t.str()},
fixedBytes_{t.size()}, isFatal_{t.isFatal()} {}
- Message(Provenance p, MessageFormattedText &&s)
- : provenance_{p}, string_{s.MoveString()}, isFatal_{s.isFatal()} {}
- Message(Provenance p, MessageExpectedText t)
- : provenance_{p}, fixedText_{t.str()}, fixedBytes_{t.size()},
+ Message(ProvenanceRange pr, MessageFormattedText &&s)
+ : provenanceRange_{pr}, string_{s.MoveString()}, isFatal_{s.isFatal()} {}
+ Message(ProvenanceRange pr, MessageExpectedText t)
+ : provenanceRange_{pr}, fixedText_{t.str()}, fixedBytes_{t.size()},
isExpected_{true}, expected_{t.set()}, isFatal_{true} {}
- Message(const char *csl, MessageFixedText t)
- : cookedSourceLocation_{csl}, fixedText_{t.str()},
+ Message(CharBlock csr, MessageFixedText t)
+ : cookedSourceRange_{csr}, fixedText_{t.str()},
fixedBytes_{t.size()}, isFatal_{t.isFatal()} {}
- Message(const char *csl, MessageFormattedText &&s)
- : cookedSourceLocation_{csl}, string_{s.MoveString()}, isFatal_{
- s.isFatal()} {}
- Message(const char *csl, MessageExpectedText t)
- : cookedSourceLocation_{csl}, fixedText_{t.str()}, fixedBytes_{t.size()},
+ Message(CharBlock csr, MessageFormattedText &&s)
+ : cookedSourceRange_{csr}, string_{s.MoveString()}, isFatal_{s.isFatal()} {}
+ Message(CharBlock csr, MessageExpectedText t)
+ : cookedSourceRange_{csr}, fixedText_{t.str()}, fixedBytes_{t.size()},
isExpected_{true}, expected_{t.set()}, isFatal_{true} {}
bool operator<(const Message &that) const {
- if (cookedSourceLocation_ != nullptr) {
- return cookedSourceLocation_ < that.cookedSourceLocation_;
- } else if (that.cookedSourceLocation_ != nullptr) {
+ if (cookedSourceRange_.begin() != nullptr) {
+ return cookedSourceRange_.begin() < that.cookedSourceRange_.begin();
+ } else if (that.cookedSourceRange_.begin() != nullptr) {
return false;
} else {
- return provenance_ < that.provenance_;
+ return provenanceRange_.start() < that.provenanceRange_.start();
}
}
- Provenance provenance() const { return provenance_; }
- const char *cookedSourceLocation() const { return cookedSourceLocation_; }
+ ProvenanceRange provenanceRange() const { return provenanceRange_; }
+ Provenance provenance() const { return provenanceRange_.start(); }
+ CharBlock cookedSourceRange() const { return cookedSourceRange_; }
+ const char *cookedSourceLocation() const {
+ return cookedSourceRange_.begin();
+ }
Context context() const { return context_; }
Message &set_context(Message *c) {
context_ = c;
void Incorporate(Message &);
std::string ToString() const;
- Provenance Emit(
+ ProvenanceRange Emit(
std::ostream &, const CookedSource &, bool echoSourceLine = true) const;
private:
- Provenance provenance_;
- const char *cookedSourceLocation_{nullptr};
+ ProvenanceRange provenanceRange_;
+ CharBlock cookedSourceRange_;
const char *fixedText_{nullptr};
std::size_t fixedBytes_{0};
bool isExpected_{false};
void Say(MessageFormattedText &&t) { return Say(p_, std::move(t)); }
void Say(MessageExpectedText &&t) { return Say(p_, std::move(t)); }
- void Say(const char *at, MessageFixedText t) {
+ void Say(CharBlock range, MessageFixedText t) {
if (deferMessages_) {
anyDeferredMessages_ = true;
} else {
- messages_.Say(at, t).set_context(context_.get());
+ messages_.Say(range, t).set_context(context_.get());
}
}
- void Say(const char *at, MessageFormattedText &&t) {
+ void Say(CharBlock range, MessageFormattedText &&t) {
if (deferMessages_) {
anyDeferredMessages_ = true;
} else {
- messages_.Say(at, std::move(t)).set_context(context_.get());
+ messages_.Say(range, std::move(t)).set_context(context_.get());
}
}
- void Say(const char *at, MessageExpectedText &&t) {
+ void Say(CharBlock range, MessageExpectedText &&t) {
if (deferMessages_) {
anyDeferredMessages_ = true;
} else {
- messages_.Say(at, std::move(t)).set_context(context_.get());
+ messages_.Say(range, std::move(t)).set_context(context_.get());
}
}
return covers;
}
-void AllSources::Identify(std::ostream &o, Provenance at,
+void AllSources::Identify(std::ostream &o, ProvenanceRange range,
const std::string &prefix, bool echoSourceLine) const {
- CHECK(IsValid(at));
+ CHECK(IsValid(range));
static const std::string indented{prefix + " "};
- const Origin &origin{MapToOrigin(at)};
+ const Origin &origin{MapToOrigin(range.start())};
std::visit(
visitors{
[&](const Inclusion &inc) {
- std::size_t offset{origin.covers.MemberOffset(at)};
+ std::size_t offset{origin.covers.MemberOffset(range.start())};
std::pair<int, int> pos{inc.source.FindOffsetLineAndColumn(offset)};
o << prefix << "at line " << pos.first << ", column " << pos.second;
if (echoSourceLine) {
o << (ch == '\t' ? '\t' : ' ');
}
o << "^\n" << prefix;
+ // TODO mark a wider range
} else {
o << ' ';
}
o << prefix << "and expanded to\n"
<< indented << " " << mac.expansion << '\n'
<< indented << " ";
- for (std::size_t j{0}; origin.covers.OffsetMember(j) < at; ++j) {
+ for (std::size_t j{0};
+ origin.covers.OffsetMember(j) < range.start(); ++j) {
o << (mac.expansion[j] == '\t' ? '\t' : ' ');
}
o << "^\n";
return origin_[low];
}
-ProvenanceRange CookedSource::GetProvenance(const char *at) const {
- return provenanceMap_.Map(at - &data_[0]);
+ProvenanceRange CookedSource::GetProvenance(CharBlock cookedRange) const {
+ ProvenanceRange range{provenanceMap_.Map(cookedRange.begin() - &data_[0])};
+ if (cookedRange.size() < range.size()) {
+ return {range.start(), cookedRange.size()};
+ }
+ return range;
}
void CookedSource::Marshal() {
#ifndef FORTRAN_PARSER_PROVENANCE_H_
#define FORTRAN_PARSER_PROVENANCE_H_
+#include "char-block.h"
#include "char-buffer.h"
#include "idioms.h"
#include "interval.h"
bool IsValid(ProvenanceRange range) const {
return range.size() > 0 && range_.Contains(range);
}
- void Identify(std::ostream &, Provenance, const std::string &prefix,
+ void Identify(std::ostream &, ProvenanceRange, const std::string &prefix,
bool echoSourceLine = false) const;
const SourceFile *GetSourceFile(
Provenance, std::size_t *offset = nullptr) const;
bool IsValid(const char *p) const {
return p >= &data_.front() && p <= &data_.back() + 1;
}
+ bool IsValid(CharBlock range) const {
+ return range.empty() ||
+ (IsValid(range.begin()) && IsValid(range.end() - 1));
+ }
bool IsValid(Provenance p) const { return allSources_.IsValid(p); }
- ProvenanceRange GetProvenance(const char *) const;
+ ProvenanceRange GetProvenance(CharBlock) const;
void Put(const char *data, std::size_t bytes) { buffer_.Put(data, bytes); }
void Put(char ch) { buffer_.Put(&ch, 1); }