xref: /llvm-project/flang/lib/Parser/instrumented-parser.cpp (revision 92a541978618674ce112b2f500853218fed24db8)
164ab3302SCarolineConcatto //===-- lib/Parser/instrumented-parser.cpp --------------------------------===//
264ab3302SCarolineConcatto //
364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information.
564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
664ab3302SCarolineConcatto //
764ab3302SCarolineConcatto //===----------------------------------------------------------------------===//
864ab3302SCarolineConcatto 
964ab3302SCarolineConcatto #include "flang/Parser/instrumented-parser.h"
1064ab3302SCarolineConcatto #include "flang/Parser/message.h"
1164ab3302SCarolineConcatto #include "flang/Parser/provenance.h"
128670e499SCaroline Concatto #include "llvm/Support/raw_ostream.h"
1364ab3302SCarolineConcatto #include <map>
1464ab3302SCarolineConcatto 
1564ab3302SCarolineConcatto namespace Fortran::parser {
1664ab3302SCarolineConcatto 
clear()1764ab3302SCarolineConcatto void ParsingLog::clear() { perPos_.clear(); }
1864ab3302SCarolineConcatto 
1964ab3302SCarolineConcatto // In the logs, just use the addresses of the message texts to sort the
2064ab3302SCarolineConcatto // map keys.
operator <(const MessageFixedText & x,const MessageFixedText & y)2164ab3302SCarolineConcatto bool operator<(const MessageFixedText &x, const MessageFixedText &y) {
2264ab3302SCarolineConcatto   return x.text().begin() < y.text().begin();
2364ab3302SCarolineConcatto }
2464ab3302SCarolineConcatto 
Fails(const char * at,const MessageFixedText & tag,ParseState & state)2564ab3302SCarolineConcatto bool ParsingLog::Fails(
2664ab3302SCarolineConcatto     const char *at, const MessageFixedText &tag, ParseState &state) {
2764ab3302SCarolineConcatto   std::size_t offset{reinterpret_cast<std::size_t>(at)};
2864ab3302SCarolineConcatto   auto posIter{perPos_.find(offset)};
2964ab3302SCarolineConcatto   if (posIter == perPos_.end()) {
3064ab3302SCarolineConcatto     return false;
3164ab3302SCarolineConcatto   }
3264ab3302SCarolineConcatto   auto tagIter{posIter->second.perTag.find(tag)};
3364ab3302SCarolineConcatto   if (tagIter == posIter->second.perTag.end()) {
3464ab3302SCarolineConcatto     return false;
3564ab3302SCarolineConcatto   }
3664ab3302SCarolineConcatto   auto &entry{tagIter->second};
3764ab3302SCarolineConcatto   if (entry.deferred && !state.deferMessages()) {
3864ab3302SCarolineConcatto     return false; // don't fail fast, we want to generate messages
3964ab3302SCarolineConcatto   }
4064ab3302SCarolineConcatto   ++entry.count;
4164ab3302SCarolineConcatto   if (!state.deferMessages()) {
4264ab3302SCarolineConcatto     state.messages().Copy(entry.messages);
4364ab3302SCarolineConcatto   }
4464ab3302SCarolineConcatto   return !entry.pass;
4564ab3302SCarolineConcatto }
4664ab3302SCarolineConcatto 
Note(const char * at,const MessageFixedText & tag,bool pass,const ParseState & state)4764ab3302SCarolineConcatto void ParsingLog::Note(const char *at, const MessageFixedText &tag, bool pass,
4864ab3302SCarolineConcatto     const ParseState &state) {
4964ab3302SCarolineConcatto   std::size_t offset{reinterpret_cast<std::size_t>(at)};
5064ab3302SCarolineConcatto   auto &entry{perPos_[offset].perTag[tag]};
5164ab3302SCarolineConcatto   if (++entry.count == 1) {
5264ab3302SCarolineConcatto     entry.pass = pass;
5364ab3302SCarolineConcatto     entry.deferred = state.deferMessages();
5464ab3302SCarolineConcatto     if (!entry.deferred) {
5564ab3302SCarolineConcatto       entry.messages.Copy(state.messages());
5664ab3302SCarolineConcatto     }
5764ab3302SCarolineConcatto   } else {
5864ab3302SCarolineConcatto     CHECK(entry.pass == pass);
5964ab3302SCarolineConcatto     if (entry.deferred && !state.deferMessages()) {
6064ab3302SCarolineConcatto       entry.deferred = false;
6164ab3302SCarolineConcatto       entry.messages.Copy(state.messages());
6264ab3302SCarolineConcatto     }
6364ab3302SCarolineConcatto   }
6464ab3302SCarolineConcatto }
6564ab3302SCarolineConcatto 
Dump(llvm::raw_ostream & o,const AllCookedSources & allCooked) const66*92a54197Speter klausler void ParsingLog::Dump(
67*92a54197Speter klausler     llvm::raw_ostream &o, const AllCookedSources &allCooked) const {
6864ab3302SCarolineConcatto   for (const auto &posLog : perPos_) {
6964ab3302SCarolineConcatto     const char *at{reinterpret_cast<const char *>(posLog.first)};
7064ab3302SCarolineConcatto     for (const auto &tagLog : posLog.second.perTag) {
71*92a54197Speter klausler       Message{at, tagLog.first}.Emit(o, allCooked, true);
7264ab3302SCarolineConcatto       auto &entry{tagLog.second};
7364ab3302SCarolineConcatto       o << "  " << (entry.pass ? "pass" : "fail") << " " << entry.count << '\n';
74*92a54197Speter klausler       entry.messages.Emit(o, allCooked);
7564ab3302SCarolineConcatto     }
7664ab3302SCarolineConcatto   }
7764ab3302SCarolineConcatto }
781f879005STim Keith } // namespace Fortran::parser
79