• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- include/flang/Parser/instrumented-parser.h --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef FORTRAN_PARSER_INSTRUMENTED_PARSER_H_
10 #define FORTRAN_PARSER_INSTRUMENTED_PARSER_H_
11 
12 #include "parse-state.h"
13 #include "user-state.h"
14 #include "flang/Parser/message.h"
15 #include "flang/Parser/provenance.h"
16 #include <cstddef>
17 #include <map>
18 
19 namespace llvm {
20 class raw_ostream;
21 }
22 
23 namespace Fortran::parser {
24 
25 class ParsingLog {
26 public:
ParsingLog()27   ParsingLog() {}
28 
29   void clear();
30 
31   bool Fails(const char *at, const MessageFixedText &tag, ParseState &);
32   void Note(const char *at, const MessageFixedText &tag, bool pass,
33       const ParseState &);
34   void Dump(llvm::raw_ostream &, const AllCookedSources &) const;
35 
36 private:
37   struct LogForPosition {
38     struct Entry {
EntryLogForPosition::Entry39       Entry() {}
40       bool pass{true};
41       int count{0};
42       bool deferred{false};
43       Messages messages;
44     };
45     std::map<MessageFixedText, Entry> perTag;
46   };
47   std::map<std::size_t, LogForPosition> perPos_;
48 };
49 
50 template <typename PA> class InstrumentedParser {
51 public:
52   using resultType = typename PA::resultType;
53   constexpr InstrumentedParser(const InstrumentedParser &) = default;
InstrumentedParser(const MessageFixedText & tag,const PA & parser)54   constexpr InstrumentedParser(const MessageFixedText &tag, const PA &parser)
55       : tag_{tag}, parser_{parser} {}
Parse(ParseState & state)56   std::optional<resultType> Parse(ParseState &state) const {
57     if (UserState * ustate{state.userState()}) {
58       if (ParsingLog * log{ustate->log()}) {
59         const char *at{state.GetLocation()};
60         if (log->Fails(at, tag_, state)) {
61           return std::nullopt;
62         }
63         Messages messages{std::move(state.messages())};
64         std::optional<resultType> result{parser_.Parse(state)};
65         log->Note(at, tag_, result.has_value(), state);
66         state.messages().Annex(std::move(messages));
67         return result;
68       }
69     }
70     return parser_.Parse(state);
71   }
72 
73 private:
74   const MessageFixedText tag_;
75   const PA parser_;
76 };
77 
78 template <typename PA>
instrumented(const MessageFixedText & tag,const PA & parser)79 inline constexpr auto instrumented(
80     const MessageFixedText &tag, const PA &parser) {
81   return InstrumentedParser{tag, parser};
82 }
83 } // namespace Fortran::parser
84 #endif // FORTRAN_PARSER_INSTRUMENTED_PARSER_H_
85