[flang] Defer message accumulation until it is known that messages will be produced.
authorpeter klausler <pklausler@nvidia.com>
Tue, 17 Apr 2018 22:47:51 +0000 (15:47 -0700)
committerpeter klausler <pklausler@nvidia.com>
Tue, 17 Apr 2018 23:58:18 +0000 (16:58 -0700)
Original-commit: flang-compiler/f18@8485d44efd6a0b78b091b613d7c4d8eb95231533
Reviewed-on: https://github.com/flang-compiler/f18/pull/59

flang/lib/parser/basic-parsers.h
flang/lib/parser/parse-state.h
flang/lib/parser/parsing.cc

index 6fbf5f5f0df2eee67b86b7855b426624b4e2ca86..91098e06ce0b767973ddf05c740d01fb137461fe 100644 (file)
@@ -79,7 +79,6 @@ public:
   constexpr BacktrackingParser(const A &parser) : parser_{parser} {}
   std::optional<resultType> Parse(ParseState *state) const {
     Messages messages{std::move(state->messages())};
-    Message::Context context{state->context()};
     ParseState backtrack{*state};
     std::optional<resultType> result{parser_.Parse(state)};
     if (result.has_value()) {
@@ -88,7 +87,6 @@ public:
     } else {
       *state = std::move(backtrack);
       state->messages() = std::move(messages);
-      state->set_context(std::move(context));
     }
     return result;
   }
@@ -236,7 +234,6 @@ public:
   constexpr AlternativeParser(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
   std::optional<resultType> Parse(ParseState *state) const {
     Messages messages{std::move(state->messages())};
-    Message::Context context{state->context()};
     ParseState backtrack{*state};
     if (std::optional<resultType> ax{pa_.Parse(state)}) {
       messages.Annex(state->messages());
@@ -245,7 +242,6 @@ public:
     }
     ParseState paState{std::move(*state)};
     *state = std::move(backtrack);
-    state->set_context(std::move(context));
     if (std::optional<resultType> bx{pb_.Parse(state)}) {
       messages.Annex(state->messages());
       state->messages() = std::move(messages);
@@ -298,40 +294,32 @@ public:
   constexpr RecoveryParser(const RecoveryParser &) = default;
   constexpr RecoveryParser(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
   std::optional<resultType> Parse(ParseState *state) const {
-    Messages messages{std::move(state->messages())};
-    Message::Context context{state->context()};
-    ParseState backtrack{*state};
     bool originallyDeferred{state->deferMessages()};
-#if 0
-    state->set_deferMessages(true);
-#endif
-    std::optional<resultType> ax{pa_.Parse(state)};
-#if 0
-    if (!originallyDeferred && state->anyDeferredMessages()) {
-      CHECK(state->messages().empty());
+    ParseState backtrack{*state};
+    if (!originallyDeferred && state->messages().empty() &&
+        !state->anyErrorRecovery()) {
+      state->set_deferMessages(true);
+      if (std::optional<resultType> ax{pa_.Parse(state)}) {
+        if (!state->anyDeferredMessages() && !state->anyErrorRecovery()) {
+          state->set_deferMessages(false);
+          return ax;
+        }
+      }
       *state = backtrack;
-      state->set_context(context);
-      ax = pa_.Parse(state);
-      CHECK(!state->messages().empty());
     }
-#endif
-    if (ax.has_value()) {
+    Messages messages{std::move(state->messages())};
+    if (std::optional<resultType> ax{pa_.Parse(state)}) {
       messages.Annex(state->messages());
       state->messages() = std::move(messages);
-      state->set_context(std::move(context));
-      state->set_deferMessages(originallyDeferred);
       return ax;
     }
-    Messages paMessages{std::move(state->messages())};
+    messages.Annex(state->messages());
     *state = std::move(backtrack);
     state->set_deferMessages(true);
     std::optional<resultType> bx{pb_.Parse(state)};
-    CHECK(state->messages().empty());
     state->messages() = std::move(messages);
-    state->set_context(std::move(context));
     state->set_deferMessages(originallyDeferred);
     if (bx.has_value()) {
-      state->messages().Annex(paMessages);
       state->set_anyErrorRecovery();
     }
     return bx;
index 1f3c13cdfd93b17a43fdbd968df6a680f6b6279d..5cdbddb32781e692c425cff6cf6e29fd41379a74 100644 (file)
@@ -30,8 +30,9 @@ public:
     : p_{&cooked[0]}, limit_{p_ + cooked.size()}, messages_{cooked} {}
   ParseState(const ParseState &that)
     : p_{that.p_}, limit_{that.limit_}, messages_{that.messages_.cooked()},
-      userState_{that.userState_}, inFixedForm_{that.inFixedForm_},
-      encoding_{that.encoding_}, strictConformance_{that.strictConformance_},
+      context_{that.context_}, userState_{that.userState_},
+      inFixedForm_{that.inFixedForm_}, encoding_{that.encoding_},
+      strictConformance_{that.strictConformance_},
       warnOnNonstandardUsage_{that.warnOnNonstandardUsage_},
       warnOnDeprecatedUsage_{that.warnOnDeprecatedUsage_},
       anyErrorRecovery_{that.anyErrorRecovery_},
@@ -49,7 +50,7 @@ public:
       deferMessages_{that.deferMessages_}, anyDeferredMessages_{
                                                that.anyDeferredMessages_} {}
   ParseState &operator=(const ParseState &that) {
-    p_ = that.p_, limit_ = that.limit_;
+    p_ = that.p_, limit_ = that.limit_, context_ = that.context_;
     userState_ = that.userState_, inFixedForm_ = that.inFixedForm_;
     encoding_ = that.encoding_, strictConformance_ = that.strictConformance_;
     warnOnNonstandardUsage_ = that.warnOnNonstandardUsage_;
@@ -62,6 +63,7 @@ public:
   }
   ParseState &operator=(ParseState &&that) {
     p_ = that.p_, limit_ = that.limit_, messages_ = std::move(that.messages_);
+    context_ = std::move(that.context_);
     userState_ = that.userState_, inFixedForm_ = that.inFixedForm_;
     encoding_ = that.encoding_, strictConformance_ = that.strictConformance_;
     warnOnNonstandardUsage_ = that.warnOnNonstandardUsage_;
@@ -82,15 +84,8 @@ public:
   void set_anyConformanceViolation() { anyConformanceViolation_ = true; }
 
   UserState *userState() const { return userState_; }
-  void set_userState(UserState *u) { userState_ = u; }
-
-  Message::Context context() const { return context_; }
-  ParseState &set_context(const Message::Context &c) {
-    context_ = c;
-    return *this;
-  }
-  ParseState &set_context(Message::Context &&c) {
-    context_ = std::move(c);
+  ParseState &set_userState(UserState *u) {
+    userState_ = u;
     return *this;
   }
 
index f97c4cdf11f1da4a9bf5b41d36dbe070d45026a1..3b4f1aa3bfc884da04903e8c5858ff17eacb0f94 100644 (file)
@@ -85,8 +85,8 @@ void Parsing::Parse() {
   CHECK(
       !parseState.anyErrorRecovery() || parseState.messages().AnyFatalError());
   consumedWholeFile_ = parseState.IsAtEnd();
-  finalRestingPlace_ = parseState.GetLocation();
   messages_.Annex(parseState.messages());
+  finalRestingPlace_ = parseState.GetLocation();
 }
 
 bool Parsing::ForTesting(std::string path, std::ostream &err) {