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:
parent
1770a4b5f8
commit
c7ec133d42
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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.");
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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/"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user