From d3c1a08e68e15d3b970450e7de7c7077fd7b0015 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Fri, 20 Apr 2018 16:56:58 -0700 Subject: [PATCH] [flang] Extend Message representation to cover ranges. Original-commit: flang-compiler/f18@314819c87f3f21fff715fd9c78b36f8a8bc77d6b Reviewed-on: https://github.com/flang-compiler/f18/pull/66 Tree-same-pre-rewrite: false --- flang/lib/parser/basic-parsers.h | 5 +++-- flang/lib/parser/interval.h | 3 +++ flang/lib/parser/message.cc | 18 +++++++-------- flang/lib/parser/message.h | 48 +++++++++++++++++++++------------------- flang/lib/parser/parse-state.h | 12 +++++----- flang/lib/parser/provenance.cc | 20 +++++++++++------ flang/lib/parser/provenance.h | 9 ++++++-- 7 files changed, 66 insertions(+), 49 deletions(-) diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 47199081..f5af886 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -1192,7 +1192,8 @@ public: 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; @@ -1223,7 +1224,7 @@ public: 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; diff --git a/flang/lib/parser/interval.h b/flang/lib/parser/interval.h index fc238b2..8d1e5b4 100644 --- a/flang/lib/parser/interval.h +++ b/flang/lib/parser/interval.h @@ -25,6 +25,9 @@ public: 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_; } diff --git a/flang/lib/parser/message.cc b/flang/lib/parser/message.cc index f3f5024..640ab61 100644 --- a/flang/lib/parser/message.cc +++ b/flang/lib/parser/message.cc @@ -38,8 +38,8 @@ MessageFormattedText::MessageFormattedText(MessageFixedText text, ...) } 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_); } @@ -89,21 +89,21 @@ std::string Message::ToString() const { 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) { diff --git a/flang/lib/parser/message.h b/flang/lib/parser/message.h index 7c3cc7c..975b7d4 100644 --- a/flang/lib/parser/message.h +++ b/flang/lib/parser/message.h @@ -100,38 +100,40 @@ public: 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; @@ -141,12 +143,12 @@ public: 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}; diff --git a/flang/lib/parser/parse-state.h b/flang/lib/parser/parse-state.h index 3136917..8a39fd1 100644 --- a/flang/lib/parser/parse-state.h +++ b/flang/lib/parser/parse-state.h @@ -149,25 +149,25 @@ public: 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()); } } diff --git a/flang/lib/parser/provenance.cc b/flang/lib/parser/provenance.cc index 625020b..6da3d88 100644 --- a/flang/lib/parser/provenance.cc +++ b/flang/lib/parser/provenance.cc @@ -128,15 +128,15 @@ ProvenanceRange AllSources::AddCompilerInsertion(std::string text) { 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 pos{inc.source.FindOffsetLineAndColumn(offset)}; o << prefix << "at line " << pos.first << ", column " << pos.second; if (echoSourceLine) { @@ -152,6 +152,7 @@ void AllSources::Identify(std::ostream &o, Provenance at, o << (ch == '\t' ? '\t' : ' '); } o << "^\n" << prefix; + // TODO mark a wider range } else { o << ' '; } @@ -173,7 +174,8 @@ void AllSources::Identify(std::ostream &o, Provenance at, 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"; @@ -275,8 +277,12 @@ const AllSources::Origin &AllSources::MapToOrigin(Provenance at) const { 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() { diff --git a/flang/lib/parser/provenance.h b/flang/lib/parser/provenance.h index a33dd973..83f2f86 100644 --- a/flang/lib/parser/provenance.h +++ b/flang/lib/parser/provenance.h @@ -1,6 +1,7 @@ #ifndef FORTRAN_PARSER_PROVENANCE_H_ #define FORTRAN_PARSER_PROVENANCE_H_ +#include "char-block.h" #include "char-buffer.h" #include "idioms.h" #include "interval.h" @@ -115,7 +116,7 @@ public: 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; @@ -178,9 +179,13 @@ public: 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); } -- 2.7.4