1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[Remarks] Add support for prepending a path to external files

This helps with testing and debugging for paths that are assumed
absolute.

It also uses a FileError to provide the file path it's trying to open.

llvm-svn: 375008
This commit is contained in:
Francis Visoiu Mistrih 2019-10-16 15:40:59 +00:00
parent 1770a4b5f8
commit c7ec133d42
7 changed files with 58 additions and 22 deletions

View File

@ -39,6 +39,8 @@ public:
struct RemarkParser { struct RemarkParser {
/// The format of the parser. /// The format of the parser.
Format ParserFormat; Format ParserFormat;
/// Path to prepend when opening an external remark file.
std::string ExternalFilePrependPath;
RemarkParser(Format ParserFormat) : ParserFormat(ParserFormat) {} RemarkParser(Format ParserFormat) : ParserFormat(ParserFormat) {}
@ -82,7 +84,8 @@ createRemarkParser(Format ParserFormat, StringRef Buf,
Expected<std::unique_ptr<RemarkParser>> Expected<std::unique_ptr<RemarkParser>>
createRemarkParserFromMeta(Format ParserFormat, StringRef Buf, createRemarkParserFromMeta(Format ParserFormat, StringRef Buf,
Optional<ParsedStringTable> StrTab = None); Optional<ParsedStringTable> StrTab = None,
Optional<StringRef> ExternalFilePrependPath = None);
} // end namespace remarks } // end namespace remarks
} // end namespace llvm } // end namespace llvm

View File

@ -15,6 +15,7 @@
#include "BitstreamRemarkParser.h" #include "BitstreamRemarkParser.h"
#include "llvm/Remarks/BitstreamRemarkContainer.h" #include "llvm/Remarks/BitstreamRemarkContainer.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
using namespace llvm; using namespace llvm;
using namespace llvm::remarks; using namespace llvm::remarks;
@ -304,8 +305,9 @@ static Error advanceToMetaBlock(BitstreamParserHelper &Helper) {
} }
Expected<std::unique_ptr<BitstreamRemarkParser>> Expected<std::unique_ptr<BitstreamRemarkParser>>
remarks::createBitstreamParserFromMeta(StringRef Buf, remarks::createBitstreamParserFromMeta(
Optional<ParsedStringTable> StrTab) { StringRef Buf, Optional<ParsedStringTable> StrTab,
Optional<StringRef> ExternalFilePrependPath) {
BitstreamParserHelper Helper(Buf); BitstreamParserHelper Helper(Buf);
Expected<std::array<char, 4>> Magic = Helper.parseMagic(); Expected<std::array<char, 4>> Magic = Helper.parseMagic();
if (!Magic) if (!Magic)
@ -314,9 +316,14 @@ remarks::createBitstreamParserFromMeta(StringRef Buf,
if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size()))) if (Error E = validateMagicNumber(StringRef(Magic->data(), Magic->size())))
return std::move(E); return std::move(E);
return StrTab auto Parser =
? std::make_unique<BitstreamRemarkParser>(Buf, std::move(*StrTab)) StrTab ? std::make_unique<BitstreamRemarkParser>(Buf, std::move(*StrTab))
: std::make_unique<BitstreamRemarkParser>(Buf); : std::make_unique<BitstreamRemarkParser>(Buf);
if (ExternalFilePrependPath)
Parser->ExternalFilePrependPath = *ExternalFilePrependPath;
return std::move(Parser);
} }
Expected<std::unique_ptr<Remark>> BitstreamRemarkParser::next() { Expected<std::unique_ptr<Remark>> BitstreamRemarkParser::next() {
@ -409,13 +416,16 @@ Error BitstreamRemarkParser::processExternalFilePath(
std::make_error_code(std::errc::illegal_byte_sequence), std::make_error_code(std::errc::illegal_byte_sequence),
"Error while parsing BLOCK_META: missing external file path."); "Error while parsing BLOCK_META: missing external file path.");
SmallString<80> FullPath(ExternalFilePrependPath);
sys::path::append(FullPath, *ExternalFilePath);
// External file: open the external file, parse it, check if its metadata // External file: open the external file, parse it, check if its metadata
// matches the one from the separate metadata, then replace the current parser // matches the one from the separate metadata, then replace the current parser
// with the one parsing the remarks. // with the one parsing the remarks.
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
MemoryBuffer::getFile(*ExternalFilePath); MemoryBuffer::getFile(FullPath);
if (std::error_code EC = BufferOrErr.getError()) if (std::error_code EC = BufferOrErr.getError())
return errorCodeToError(EC); return createFileError(FullPath, EC);
TmpRemarkBuffer = std::move(*BufferOrErr); TmpRemarkBuffer = std::move(*BufferOrErr);
// Create a separate parser used for parsing the separate file. // Create a separate parser used for parsing the separate file.

View File

@ -73,9 +73,9 @@ private:
Error processExternalFilePath(Optional<StringRef> ExternalFilePath); Error processExternalFilePath(Optional<StringRef> ExternalFilePath);
}; };
Expected<std::unique_ptr<BitstreamRemarkParser>> Expected<std::unique_ptr<BitstreamRemarkParser>> createBitstreamParserFromMeta(
createBitstreamParserFromMeta(StringRef Buf, StringRef Buf, Optional<ParsedStringTable> StrTab = None,
Optional<ParsedStringTable> StrTab = None); Optional<StringRef> ExternalFilePrependPath = None);
} // end namespace remarks } // end namespace remarks
} // end namespace llvm } // end namespace llvm

View File

@ -86,16 +86,19 @@ llvm::remarks::createRemarkParser(Format ParserFormat, StringRef Buf,
} }
Expected<std::unique_ptr<RemarkParser>> Expected<std::unique_ptr<RemarkParser>>
llvm::remarks::createRemarkParserFromMeta(Format ParserFormat, StringRef Buf, llvm::remarks::createRemarkParserFromMeta(
Optional<ParsedStringTable> StrTab) { Format ParserFormat, StringRef Buf, Optional<ParsedStringTable> StrTab,
Optional<StringRef> ExternalFilePrependPath) {
switch (ParserFormat) { switch (ParserFormat) {
// Depending on the metadata, the format can be either yaml or yaml-strtab, // Depending on the metadata, the format can be either yaml or yaml-strtab,
// regardless of the input argument. // regardless of the input argument.
case Format::YAML: case Format::YAML:
case Format::YAMLStrTab: case Format::YAMLStrTab:
return createYAMLParserFromMeta(Buf, std::move(StrTab)); return createYAMLParserFromMeta(Buf, std::move(StrTab),
std::move(ExternalFilePrependPath));
case Format::Bitstream: case Format::Bitstream:
return createBitstreamParserFromMeta(Buf, std::move(StrTab)); return createBitstreamParserFromMeta(Buf, std::move(StrTab),
std::move(ExternalFilePrependPath));
case Format::Unknown: case Format::Unknown:
return createStringError(std::make_error_code(std::errc::invalid_argument), return createStringError(std::make_error_code(std::errc::invalid_argument),
"Unknown remark parser format."); "Unknown remark parser format.");

View File

@ -15,6 +15,7 @@
#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringSwitch.h"
#include "llvm/Remarks/RemarkParser.h" #include "llvm/Remarks/RemarkParser.h"
#include "llvm/Support/Endian.h" #include "llvm/Support/Endian.h"
#include "llvm/Support/Path.h"
using namespace llvm; using namespace llvm;
using namespace llvm::remarks; using namespace llvm::remarks;
@ -109,7 +110,8 @@ static Expected<ParsedStringTable> parseStrTab(StringRef &Buf,
Expected<std::unique_ptr<YAMLRemarkParser>> Expected<std::unique_ptr<YAMLRemarkParser>>
remarks::createYAMLParserFromMeta(StringRef Buf, remarks::createYAMLParserFromMeta(StringRef Buf,
Optional<ParsedStringTable> StrTab) { Optional<ParsedStringTable> StrTab,
Optional<StringRef> ExternalFilePrependPath) {
// We now have a magic number. The metadata has to be correct. // We now have a magic number. The metadata has to be correct.
Expected<bool> isMeta = parseMagic(Buf); Expected<bool> isMeta = parseMagic(Buf);
if (!isMeta) if (!isMeta)
@ -138,11 +140,17 @@ remarks::createYAMLParserFromMeta(StringRef Buf,
// If it starts with "---", there is no external file. // If it starts with "---", there is no external file.
if (!Buf.startswith("---")) { if (!Buf.startswith("---")) {
// At this point, we expect Buf to contain the external file path. // At this point, we expect Buf to contain the external file path.
StringRef ExternalFilePath = Buf;
SmallString<80> FullPath;
if (ExternalFilePrependPath)
FullPath = *ExternalFilePrependPath;
sys::path::append(FullPath, ExternalFilePath);
// Try to open the file and start parsing from there. // Try to open the file and start parsing from there.
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
MemoryBuffer::getFile(Buf); MemoryBuffer::getFile(FullPath);
if (std::error_code EC = BufferOrErr.getError()) if (std::error_code EC = BufferOrErr.getError())
return errorCodeToError(EC); return createFileError(FullPath, EC);
// Keep the buffer alive. // Keep the buffer alive.
SeparateBuf = std::move(*BufferOrErr); SeparateBuf = std::move(*BufferOrErr);

View File

@ -111,7 +111,8 @@ protected:
Expected<std::unique_ptr<YAMLRemarkParser>> Expected<std::unique_ptr<YAMLRemarkParser>>
createYAMLParserFromMeta(StringRef Buf, createYAMLParserFromMeta(StringRef Buf,
Optional<ParsedStringTable> StrTab = None); Optional<ParsedStringTable> StrTab = None,
Optional<StringRef> ExternalFilePrependPath = None);
} // end namespace remarks } // end namespace remarks
} // end namespace llvm } // end namespace llvm

View File

@ -63,12 +63,15 @@ bool parseExpectError(const char (&Buf)[N], const char *Error) {
return StringRef(Stream.str()).contains(Error); return StringRef(Stream.str()).contains(Error);
} }
void parseExpectErrorMeta(StringRef Buf, const char *Error) { void parseExpectErrorMeta(StringRef Buf, const char *Error,
Optional<StringRef> ExternalFilePrependPath = None) {
std::string ErrorStr; std::string ErrorStr;
raw_string_ostream Stream(ErrorStr); raw_string_ostream Stream(ErrorStr);
Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser = Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
remarks::createRemarkParserFromMeta(remarks::Format::YAML, Buf); remarks::createRemarkParserFromMeta(remarks::Format::YAML, Buf,
/*StrTab=*/None,
std::move(ExternalFilePrependPath));
handleAllErrors(MaybeParser.takeError(), handleAllErrors(MaybeParser.takeError(),
[&](const ErrorInfoBase &EIB) { EIB.log(Stream); }); [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
@ -705,6 +708,14 @@ TEST(YAMLRemarks, ParsingBadMeta) {
"\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0"
"/path/", "/path/",
28), 30),
"No such file or directory"); "'/path/': No such file or directory");
parseExpectErrorMeta(StringRef("REMARKS\0"
"\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0"
"/path/",
30),
"'/baddir/path/': No such file or directory",
StringRef("/baddir/"));
} }