summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Remarks/RemarkLinker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Remarks/RemarkLinker.cpp')
-rw-r--r--llvm/lib/Remarks/RemarkLinker.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/llvm/lib/Remarks/RemarkLinker.cpp b/llvm/lib/Remarks/RemarkLinker.cpp
new file mode 100644
index 00000000000..617ce770af6
--- /dev/null
+++ b/llvm/lib/Remarks/RemarkLinker.cpp
@@ -0,0 +1,126 @@
+//===- RemarkLinker.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an implementation of the remark linker.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Remarks/RemarkLinker.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Remarks/BitstreamRemarkContainer.h"
+#include "llvm/Remarks/RemarkParser.h"
+#include "llvm/Remarks/RemarkSerializer.h"
+#include "llvm/Support/Error.h"
+
+using namespace llvm;
+using namespace llvm::remarks;
+
+static Expected<StringRef>
+getRemarksSectionName(const object::ObjectFile &Obj) {
+ if (Obj.isMachO())
+ return StringRef("__remarks");
+ // ELF -> .remarks, but there is no ELF support at this point.
+ return createStringError(std::errc::illegal_byte_sequence,
+ "Unsupported file format.");
+}
+
+Expected<Optional<StringRef>>
+llvm::remarks::getRemarksSectionContents(const object::ObjectFile &Obj) {
+ Expected<StringRef> SectionName = getRemarksSectionName(Obj);
+ if (!SectionName)
+ return SectionName.takeError();
+
+ for (const object::SectionRef &Section : Obj.sections()) {
+ Expected<StringRef> MaybeName = Section.getName();
+ if (!MaybeName)
+ return MaybeName.takeError();
+ if (*MaybeName != *SectionName)
+ continue;
+
+ if (Expected<StringRef> Contents = Section.getContents())
+ return *Contents;
+ else
+ return Contents.takeError();
+ }
+ return Optional<StringRef>{};
+}
+
+Remark &RemarkLinker::keep(std::unique_ptr<Remark> Remark) {
+ StrTab.internalize(*Remark);
+ auto Inserted = Remarks.insert(std::move(Remark));
+ return **Inserted.first;
+}
+
+void RemarkLinker::setExternalFilePrependPath(StringRef PrependPathIn) {
+ PrependPath = PrependPathIn;
+}
+
+// Discard remarks with no source location.
+static bool shouldKeepRemark(const Remark &R) { return R.Loc.hasValue(); }
+
+Error RemarkLinker::link(StringRef Buffer, Optional<Format> RemarkFormat) {
+ if (!RemarkFormat) {
+ Expected<Format> ParserFormat = magicToFormat(Buffer);
+ if (!ParserFormat)
+ return ParserFormat.takeError();
+ RemarkFormat = *ParserFormat;
+ }
+
+ Expected<std::unique_ptr<RemarkParser>> MaybeParser =
+ createRemarkParserFromMeta(
+ *RemarkFormat, Buffer, /*StrTab=*/None,
+ PrependPath ? Optional<StringRef>(StringRef(*PrependPath))
+ : Optional<StringRef>(None));
+ if (!MaybeParser)
+ return MaybeParser.takeError();
+
+ RemarkParser &Parser = **MaybeParser;
+
+ while (true) {
+ Expected<std::unique_ptr<Remark>> Next = Parser.next();
+ if (Error E = Next.takeError()) {
+ if (E.isA<EndOfFileError>()) {
+ consumeError(std::move(E));
+ break;
+ }
+ return E;
+ }
+
+ assert(*Next != nullptr);
+
+ if (shouldKeepRemark(**Next))
+ keep(std::move(*Next));
+ }
+ return Error::success();
+}
+
+Error RemarkLinker::link(const object::ObjectFile &Obj,
+ Optional<Format> RemarkFormat) {
+ Expected<Optional<StringRef>> SectionOrErr = getRemarksSectionContents(Obj);
+ if (!SectionOrErr)
+ return SectionOrErr.takeError();
+
+ if (Optional<StringRef> Section = *SectionOrErr)
+ return link(*Section, RemarkFormat);
+ return Error::success();
+}
+
+Error RemarkLinker::serialize(raw_ostream &OS, Format RemarksFormat) const {
+ Expected<std::unique_ptr<RemarkSerializer>> MaybeSerializer =
+ createRemarkSerializer(RemarksFormat, SerializerMode::Standalone, OS,
+ std::move(const_cast<StringTable &>(StrTab)));
+ if (!MaybeSerializer)
+ return MaybeSerializer.takeError();
+
+ std::unique_ptr<remarks::RemarkSerializer> Serializer =
+ std::move(*MaybeSerializer);
+
+ for (const Remark &R : remarks())
+ Serializer->emit(R);
+ return Error::success();
+}
OpenPOWER on IntegriCloud