brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · 6687aa1 Raw
79 lines · cpp
1//===-- lib/Parser/instrumented-parser.cpp --------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Parser/instrumented-parser.h"10#include "flang/Parser/message.h"11#include "flang/Parser/provenance.h"12#include "llvm/Support/raw_ostream.h"13#include <map>14 15namespace Fortran::parser {16 17void ParsingLog::clear() { perPos_.clear(); }18 19// In the logs, just use the addresses of the message texts to sort the20// map keys.21bool operator<(const MessageFixedText &x, const MessageFixedText &y) {22  return x.text().begin() < y.text().begin();23}24 25bool ParsingLog::Fails(26    const char *at, const MessageFixedText &tag, ParseState &state) {27  std::size_t offset{reinterpret_cast<std::size_t>(at)};28  auto posIter{perPos_.find(offset)};29  if (posIter == perPos_.end()) {30    return false;31  }32  auto tagIter{posIter->second.perTag.find(tag)};33  if (tagIter == posIter->second.perTag.end()) {34    return false;35  }36  auto &entry{tagIter->second};37  if (entry.deferred && !state.deferMessages()) {38    return false; // don't fail fast, we want to generate messages39  }40  ++entry.count;41  if (!state.deferMessages()) {42    state.messages().Copy(entry.messages);43  }44  return !entry.pass;45}46 47void ParsingLog::Note(const char *at, const MessageFixedText &tag, bool pass,48    const ParseState &state) {49  std::size_t offset{reinterpret_cast<std::size_t>(at)};50  auto &entry{perPos_[offset].perTag[tag]};51  if (++entry.count == 1) {52    entry.pass = pass;53    entry.deferred = state.deferMessages();54    if (!entry.deferred) {55      entry.messages.Copy(state.messages());56    }57  } else {58    CHECK(entry.pass == pass);59    if (entry.deferred && !state.deferMessages()) {60      entry.deferred = false;61      entry.messages.Copy(state.messages());62    }63  }64}65 66void ParsingLog::Dump(67    llvm::raw_ostream &o, const AllCookedSources &allCooked) const {68  for (const auto &posLog : perPos_) {69    const char *at{reinterpret_cast<const char *>(posLog.first)};70    for (const auto &tagLog : posLog.second.perTag) {71      Message{at, tagLog.first}.Emit(o, allCooked, true);72      auto &entry{tagLog.second};73      o << "  " << (entry.pass ? "pass" : "fail") << " " << entry.count << '\n';74      entry.messages.Emit(o, allCooked);75    }76  }77}78} // namespace Fortran::parser79