brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · f0feecc Raw
123 lines · cpp
1//===- RemarkLinker.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// This file provides an implementation of the remark linker.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Remarks/RemarkLinker.h"14#include "llvm/ADT/StringRef.h"15#include "llvm/Object/ObjectFile.h"16#include "llvm/Object/SymbolicFile.h"17#include "llvm/Remarks/RemarkParser.h"18#include "llvm/Remarks/RemarkSerializer.h"19#include "llvm/Support/Error.h"20#include <optional>21 22using namespace llvm;23using namespace llvm::remarks;24 25namespace llvm {26class raw_ostream;27}28 29static Expected<StringRef>30getRemarksSectionName(const object::ObjectFile &Obj) {31  if (Obj.isMachO())32    return StringRef("__remarks");33  // ELF -> .remarks, but there is no ELF support at this point.34  return createStringError(std::errc::illegal_byte_sequence,35                           "Unsupported file format.");36}37 38Expected<std::optional<StringRef>>39llvm::remarks::getRemarksSectionContents(const object::ObjectFile &Obj) {40  Expected<StringRef> SectionName = getRemarksSectionName(Obj);41  if (!SectionName)42    return SectionName.takeError();43 44  for (const object::SectionRef &Section : Obj.sections()) {45    Expected<StringRef> MaybeName = Section.getName();46    if (!MaybeName)47      return MaybeName.takeError();48    if (*MaybeName != *SectionName)49      continue;50 51    if (Expected<StringRef> Contents = Section.getContents())52      return *Contents;53    else54      return Contents.takeError();55  }56  return std::optional<StringRef>{};57}58 59Remark &RemarkLinker::keep(std::unique_ptr<Remark> Remark) {60  StrTab.internalize(*Remark);61  auto Inserted = Remarks.insert(std::move(Remark));62  return **Inserted.first;63}64 65void RemarkLinker::setExternalFilePrependPath(StringRef PrependPathIn) {66  PrependPath = std::string(PrependPathIn);67}68 69Error RemarkLinker::link(StringRef Buffer, Format RemarkFormat) {70  Expected<std::unique_ptr<RemarkParser>> MaybeParser =71      createRemarkParserFromMeta(72          RemarkFormat, Buffer,73          PrependPath ? std::make_optional<StringRef>(*PrependPath)74                      : std::nullopt);75  if (!MaybeParser)76    return MaybeParser.takeError();77 78  RemarkParser &Parser = **MaybeParser;79 80  while (true) {81    Expected<std::unique_ptr<Remark>> Next = Parser.next();82    if (Error E = Next.takeError()) {83      if (E.isA<EndOfFileError>()) {84        consumeError(std::move(E));85        break;86      }87      return E;88    }89 90    assert(*Next != nullptr);91 92    if (shouldKeepRemark(**Next))93      keep(std::move(*Next));94  }95  return Error::success();96}97 98Error RemarkLinker::link(const object::ObjectFile &Obj, Format RemarkFormat) {99  Expected<std::optional<StringRef>> SectionOrErr =100      getRemarksSectionContents(Obj);101  if (!SectionOrErr)102    return SectionOrErr.takeError();103 104  if (std::optional<StringRef> Section = *SectionOrErr)105    return link(*Section, RemarkFormat);106  return Error::success();107}108 109Error RemarkLinker::serialize(raw_ostream &OS, Format RemarksFormat) const {110  Expected<std::unique_ptr<RemarkSerializer>> MaybeSerializer =111      createRemarkSerializer(RemarksFormat, OS,112                             std::move(const_cast<StringTable &>(StrTab)));113  if (!MaybeSerializer)114    return MaybeSerializer.takeError();115 116  std::unique_ptr<remarks::RemarkSerializer> Serializer =117      std::move(*MaybeSerializer);118 119  for (const Remark &R : remarks())120    Serializer->emit(R);121  return Error::success();122}123