[flang] Extend Message representation to cover ranges.
authorpeter klausler <pklausler@nvidia.com>
Fri, 20 Apr 2018 23:56:58 +0000 (16:56 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 23 Apr 2018 22:44:28 +0000 (15:44 -0700)
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
flang/lib/parser/interval.h
flang/lib/parser/message.cc
flang/lib/parser/message.h
flang/lib/parser/parse-state.h
flang/lib/parser/provenance.cc
flang/lib/parser/provenance.h

index 4719908..f5af886 100644 (file)
@@ -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;
index fc238b2..8d1e5b4 100644 (file)
@@ -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_; }
index f3f5024..640ab61 100644 (file)
@@ -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) {
index 7c3cc7c..975b7d4 100644 (file)
@@ -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};
index 3136917..8a39fd1 100644 (file)
@@ -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());
     }
   }
 
index 625020b..6da3d88 100644 (file)
@@ -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<int, int> 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() {
index a33dd97..83f2f86 100644 (file)
@@ -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); }