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 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. 2164ab3302SCarolineConcatto bool operator<(const MessageFixedText &x, const MessageFixedText &y) { 2264ab3302SCarolineConcatto return x.text().begin() < y.text().begin(); 2364ab3302SCarolineConcatto } 2464ab3302SCarolineConcatto 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 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 668670e499SCaroline Concatto void ParsingLog::Dump(llvm::raw_ostream &o, const CookedSource &cooked) const { 6764ab3302SCarolineConcatto for (const auto &posLog : perPos_) { 6864ab3302SCarolineConcatto const char *at{reinterpret_cast<const char *>(posLog.first)}; 6964ab3302SCarolineConcatto for (const auto &tagLog : posLog.second.perTag) { 7064ab3302SCarolineConcatto Message{at, tagLog.first}.Emit(o, cooked, true); 7164ab3302SCarolineConcatto auto &entry{tagLog.second}; 7264ab3302SCarolineConcatto o << " " << (entry.pass ? "pass" : "fail") << " " << entry.count << '\n'; 7364ab3302SCarolineConcatto entry.messages.Emit(o, cooked); 7464ab3302SCarolineConcatto } 7564ab3302SCarolineConcatto } 7664ab3302SCarolineConcatto } 77*1f879005STim Keith } // namespace Fortran::parser 78