[flang] Track current statement location in SemanticsVisitor
authorTim Keith <tkeith@nvidia.com>
Tue, 26 Mar 2019 19:40:13 +0000 (12:40 -0700)
committerTim Keith <tkeith@nvidia.com>
Tue, 26 Mar 2019 19:40:13 +0000 (12:40 -0700)
Change `SemanticsVisitor` to track the location of the current
statement, if any, so that it's available through
`SemanticsContext::location()`

Add overloading of `SemanticsContext::Say()` that reports the
message at the location of the current statement if a `CharBlock`
is not provided.

Original-commit: flang-compiler/f18@5185c721ee9e2da8adcc4cad5a74acc0bf5c8d2d
Reviewed-on: https://github.com/flang-compiler/f18/pull/357

flang/lib/semantics/mod-file.cc
flang/lib/semantics/resolve-names.cc
flang/lib/semantics/semantics.cc
flang/lib/semantics/semantics.h

index cb16a24..ffa522a 100644 (file)
@@ -680,7 +680,7 @@ std::optional<std::string> ModFileReader::FindModFile(
           : "Cannot find module file for submodule '%s' of module '%s'"_err_en_US,
       name.ToString().data(), ancestor.data()}};
   attachments.AttachTo(error);
-  context_.Say(error);
+  context_.Say(std::move(error));
   return std::nullopt;
 }
 
index 678a0ea..5925e4a 100644 (file)
@@ -1063,7 +1063,7 @@ void ImplicitRules::SetType(const DeclTypeSpec &type, parser::Location lo,
   for (char ch = *lo; ch; ch = ImplicitRules::Incr(ch)) {
     auto res{map_.emplace(ch, &type)};
     if (!res.second && !isDefault) {
-      context_->Say(lo,
+      context_->messages().Say(lo,
           "More than one implicit type specified for '%s'"_err_en_US,
           std::string(1, ch).c_str());
     }
index 66af295..d778c96 100644 (file)
@@ -49,11 +49,23 @@ public:
   using BaseChecker::Leave;
   SemanticsVisitor(SemanticsContext &context)
     : C{context}..., context_{context} {}
+
   template<typename N> bool Pre(const N &node) {
     Enter(node);
     return true;
   }
   template<typename N> void Post(const N &node) { Leave(node); }
+
+  template<typename T> bool Pre(const parser::Statement<T> &node) {
+    context_.set_location(&node.source);
+    Enter(node);
+    return true;
+  }
+  template<typename T> void Post(const parser::Statement<T> &node) {
+    Leave(node);
+    context_.set_location(nullptr);
+  }
+
   bool Walk(const parser::Program &program) {
     parser::Walk(program, *this);
     return !context_.AnyFatalError();
index 1cf7342..0b47225 100644 (file)
@@ -82,8 +82,17 @@ public:
   const DeclTypeSpec &MakeLogicalType(int kind = 0);
 
   bool AnyFatalError() const;
-  template<typename... A> parser::Message &Say(A... args) {
-    return messages_.Say(std::forward<A>(args)...);
+
+  template<typename... A>
+  parser::Message &Say(const parser::CharBlock &at, A &&... args) {
+    return messages_.Say(at, std::forward<A>(args)...);
+  }
+  template<typename... A> parser::Message &Say(A &&... args) {
+    CHECK(location_);
+    return messages_.Say(*location_, std::forward<A>(args)...);
+  }
+  parser::Message &Say(parser::Message &&msg) {
+    return messages_.Say(std::move(msg));
   }
 
   const Scope &FindScope(const parser::CharBlock &) const;