mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-30 20:18:51 +00:00
[Coverage] Support overriding compilation directory
When making compilation relocatable, for example in distributed compilation scenarios, we want to set compilation dir to a relative value like `.` but this presents a problem when generating reports because if the file path is relative as well, for example `..`, you may end up writing files outside of the output directory. This change introduces a flag that allows overriding the compilation directory that's stored inside the profile with a different value that is absolute. Differential Revision: https://reviews.llvm.org/D100232
This commit is contained in:
parent
a0162a81b1
commit
8280ece0c9
llvm
include/llvm/ProfileData/Coverage
lib/ProfileData/Coverage
test/tools/llvm-cov
tools/llvm-cov
unittests/ProfileData
@ -603,7 +603,7 @@ public:
|
||||
/// Ignores non-instrumented object files unless all are not instrumented.
|
||||
static Expected<std::unique_ptr<CoverageMapping>>
|
||||
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
|
||||
ArrayRef<StringRef> Arches = None);
|
||||
ArrayRef<StringRef> Arches = None, StringRef CompilationDir = "");
|
||||
|
||||
/// The number of functions that couldn't have their profiles mapped.
|
||||
///
|
||||
|
@ -202,13 +202,15 @@ public:
|
||||
|
||||
static Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
|
||||
create(MemoryBufferRef ObjectBuffer, StringRef Arch,
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers);
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
|
||||
StringRef CompilationDir = "");
|
||||
|
||||
static Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
createCoverageReaderFromBuffer(StringRef Coverage, std::string &&FuncRecords,
|
||||
InstrProfSymtab &&ProfileNames,
|
||||
uint8_t BytesInAddress,
|
||||
support::endianness Endian);
|
||||
support::endianness Endian,
|
||||
StringRef CompilationDir = "");
|
||||
|
||||
Error readNextRecord(CoverageMappingRecord &Record) override;
|
||||
};
|
||||
@ -216,14 +218,17 @@ public:
|
||||
/// Reader for the raw coverage filenames.
|
||||
class RawCoverageFilenamesReader : public RawCoverageReader {
|
||||
std::vector<std::string> &Filenames;
|
||||
StringRef CompilationDir;
|
||||
|
||||
// Read an uncompressed sequence of filenames.
|
||||
Error readUncompressed(CovMapVersion Version, uint64_t NumFilenames);
|
||||
|
||||
public:
|
||||
RawCoverageFilenamesReader(StringRef Data,
|
||||
std::vector<std::string> &Filenames)
|
||||
: RawCoverageReader(Data), Filenames(Filenames) {}
|
||||
std::vector<std::string> &Filenames,
|
||||
StringRef CompilationDir = "")
|
||||
: RawCoverageReader(Data), Filenames(Filenames),
|
||||
CompilationDir(CompilationDir) {}
|
||||
RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
|
||||
RawCoverageFilenamesReader &
|
||||
operator=(const RawCoverageFilenamesReader &) = delete;
|
||||
|
@ -319,7 +319,8 @@ static Error handleMaybeNoDataFoundError(Error E) {
|
||||
|
||||
Expected<std::unique_ptr<CoverageMapping>>
|
||||
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
|
||||
StringRef ProfileFilename, ArrayRef<StringRef> Arches) {
|
||||
StringRef ProfileFilename, ArrayRef<StringRef> Arches,
|
||||
StringRef CompilationDir) {
|
||||
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
|
||||
if (Error E = ProfileReaderOrErr.takeError())
|
||||
return std::move(E);
|
||||
@ -336,8 +337,8 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
|
||||
MemoryBufferRef CovMappingBufRef =
|
||||
CovMappingBufOrErr.get()->getMemBufferRef();
|
||||
SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
|
||||
auto CoverageReadersOrErr =
|
||||
BinaryCoverageReader::create(CovMappingBufRef, Arch, Buffers);
|
||||
auto CoverageReadersOrErr = BinaryCoverageReader::create(
|
||||
CovMappingBufRef, Arch, Buffers, CompilationDir);
|
||||
if (Error E = CoverageReadersOrErr.takeError()) {
|
||||
E = handleMaybeNoDataFoundError(std::move(E));
|
||||
if (E)
|
||||
|
@ -138,7 +138,8 @@ Error RawCoverageFilenamesReader::read(CovMapVersion Version) {
|
||||
}
|
||||
|
||||
StringRef UncompressedFilenames(StorageBuf.data(), StorageBuf.size());
|
||||
RawCoverageFilenamesReader Delegate(UncompressedFilenames, Filenames);
|
||||
RawCoverageFilenamesReader Delegate(UncompressedFilenames, Filenames,
|
||||
CompilationDir);
|
||||
return Delegate.readUncompressed(Version, NumFilenames);
|
||||
}
|
||||
|
||||
@ -168,7 +169,11 @@ Error RawCoverageFilenamesReader::readUncompressed(CovMapVersion Version,
|
||||
if (sys::path::is_absolute(Filename)) {
|
||||
Filenames.push_back(Filename.str());
|
||||
} else {
|
||||
SmallString<256> P(CWD);
|
||||
SmallString<256> P;
|
||||
if (!CompilationDir.empty())
|
||||
P.assign(CompilationDir);
|
||||
else
|
||||
P.assign(CWD);
|
||||
llvm::sys::path::append(P, Filename);
|
||||
Filenames.push_back(static_cast<std::string>(P));
|
||||
}
|
||||
@ -520,7 +525,7 @@ struct CovMapFuncRecordReader {
|
||||
template <class IntPtrT, support::endianness Endian>
|
||||
static Expected<std::unique_ptr<CovMapFuncRecordReader>>
|
||||
get(CovMapVersion Version, InstrProfSymtab &P,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
|
||||
std::vector<std::string> &F);
|
||||
};
|
||||
|
||||
@ -535,6 +540,7 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
|
||||
// in \c Records.
|
||||
DenseMap<NameRefType, size_t> FunctionRecords;
|
||||
InstrProfSymtab &ProfileNames;
|
||||
StringRef CompilationDir;
|
||||
std::vector<std::string> &Filenames;
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
|
||||
|
||||
@ -594,9 +600,9 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
|
||||
public:
|
||||
VersionedCovMapFuncRecordReader(
|
||||
InstrProfSymtab &P,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
|
||||
std::vector<std::string> &F)
|
||||
: ProfileNames(P), Filenames(F), Records(R) {}
|
||||
: ProfileNames(P), CompilationDir(D), Filenames(F), Records(R) {}
|
||||
|
||||
~VersionedCovMapFuncRecordReader() override = default;
|
||||
|
||||
@ -629,7 +635,8 @@ public:
|
||||
return make_error<CoverageMapError>(coveragemap_error::malformed);
|
||||
size_t FilenamesBegin = Filenames.size();
|
||||
StringRef FilenameRegion(CovBuf, FilenamesSize);
|
||||
RawCoverageFilenamesReader Reader(FilenameRegion, Filenames);
|
||||
RawCoverageFilenamesReader Reader(FilenameRegion, Filenames,
|
||||
CompilationDir);
|
||||
if (auto Err = Reader.read(Version))
|
||||
return std::move(Err);
|
||||
CovBuf += FilenamesSize;
|
||||
@ -735,14 +742,14 @@ public:
|
||||
template <class IntPtrT, support::endianness Endian>
|
||||
Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
|
||||
CovMapVersion Version, InstrProfSymtab &P,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R, StringRef D,
|
||||
std::vector<std::string> &F) {
|
||||
using namespace coverage;
|
||||
|
||||
switch (Version) {
|
||||
case CovMapVersion::Version1:
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version1, IntPtrT, Endian>>(P, R, D, F);
|
||||
case CovMapVersion::Version2:
|
||||
case CovMapVersion::Version3:
|
||||
case CovMapVersion::Version4:
|
||||
@ -753,19 +760,19 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
|
||||
return std::move(E);
|
||||
if (Version == CovMapVersion::Version2)
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version2, IntPtrT, Endian>>(P, R, D, F);
|
||||
else if (Version == CovMapVersion::Version3)
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version3, IntPtrT, Endian>>(P, R, D, F);
|
||||
else if (Version == CovMapVersion::Version4)
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version4, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version4, IntPtrT, Endian>>(P, R, D, F);
|
||||
else if (Version == CovMapVersion::Version5)
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version5, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version5, IntPtrT, Endian>>(P, R, D, F);
|
||||
else if (Version == CovMapVersion::Version6)
|
||||
return std::make_unique<VersionedCovMapFuncRecordReader<
|
||||
CovMapVersion::Version6, IntPtrT, Endian>>(P, R, F);
|
||||
CovMapVersion::Version6, IntPtrT, Endian>>(P, R, D, F);
|
||||
}
|
||||
llvm_unreachable("Unsupported version");
|
||||
}
|
||||
@ -774,7 +781,7 @@ template <typename T, support::endianness Endian>
|
||||
static Error readCoverageMappingData(
|
||||
InstrProfSymtab &ProfileNames, StringRef CovMap, StringRef FuncRecords,
|
||||
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
|
||||
std::vector<std::string> &Filenames) {
|
||||
StringRef CompilationDir, std::vector<std::string> &Filenames) {
|
||||
using namespace coverage;
|
||||
|
||||
// Read the records in the coverage data section.
|
||||
@ -785,7 +792,7 @@ static Error readCoverageMappingData(
|
||||
return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
|
||||
Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
|
||||
CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
|
||||
Filenames);
|
||||
CompilationDir, Filenames);
|
||||
if (Error E = ReaderExpected.takeError())
|
||||
return E;
|
||||
auto Reader = std::move(ReaderExpected.get());
|
||||
@ -817,8 +824,9 @@ static const char *TestingFormatMagic = "llvmcovmtestdata";
|
||||
|
||||
Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
StringRef Coverage, std::string &&FuncRecords, InstrProfSymtab &&ProfileNames,
|
||||
uint8_t BytesInAddress, support::endianness Endian) {
|
||||
StringRef Coverage, std::string &&FuncRecords,
|
||||
InstrProfSymtab &&ProfileNames, uint8_t BytesInAddress,
|
||||
support::endianness Endian, StringRef CompilationDir) {
|
||||
std::unique_ptr<BinaryCoverageReader> Reader(
|
||||
new BinaryCoverageReader(std::move(FuncRecords)));
|
||||
Reader->ProfileNames = std::move(ProfileNames);
|
||||
@ -827,23 +835,23 @@ BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
if (Error E =
|
||||
readCoverageMappingData<uint32_t, support::endianness::little>(
|
||||
Reader->ProfileNames, Coverage, FuncRecordsRef,
|
||||
Reader->MappingRecords, Reader->Filenames))
|
||||
Reader->MappingRecords, CompilationDir, Reader->Filenames))
|
||||
return std::move(E);
|
||||
} else if (BytesInAddress == 4 && Endian == support::endianness::big) {
|
||||
if (Error E = readCoverageMappingData<uint32_t, support::endianness::big>(
|
||||
Reader->ProfileNames, Coverage, FuncRecordsRef,
|
||||
Reader->MappingRecords, Reader->Filenames))
|
||||
Reader->MappingRecords, CompilationDir, Reader->Filenames))
|
||||
return std::move(E);
|
||||
} else if (BytesInAddress == 8 && Endian == support::endianness::little) {
|
||||
if (Error E =
|
||||
readCoverageMappingData<uint64_t, support::endianness::little>(
|
||||
Reader->ProfileNames, Coverage, FuncRecordsRef,
|
||||
Reader->MappingRecords, Reader->Filenames))
|
||||
Reader->MappingRecords, CompilationDir, Reader->Filenames))
|
||||
return std::move(E);
|
||||
} else if (BytesInAddress == 8 && Endian == support::endianness::big) {
|
||||
if (Error E = readCoverageMappingData<uint64_t, support::endianness::big>(
|
||||
Reader->ProfileNames, Coverage, FuncRecordsRef,
|
||||
Reader->MappingRecords, Reader->Filenames))
|
||||
Reader->MappingRecords, CompilationDir, Reader->Filenames))
|
||||
return std::move(E);
|
||||
} else
|
||||
return make_error<CoverageMapError>(coveragemap_error::malformed);
|
||||
@ -851,7 +859,7 @@ BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
}
|
||||
|
||||
static Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
loadTestingFormat(StringRef Data) {
|
||||
loadTestingFormat(StringRef Data, StringRef CompilationDir) {
|
||||
uint8_t BytesInAddress = 8;
|
||||
support::endianness Endian = support::endianness::little;
|
||||
|
||||
@ -911,7 +919,7 @@ loadTestingFormat(StringRef Data) {
|
||||
}
|
||||
return BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
CoverageMapping, CoverageRecords.str(), std::move(ProfileNames),
|
||||
BytesInAddress, Endian);
|
||||
BytesInAddress, Endian, CompilationDir);
|
||||
}
|
||||
|
||||
/// Find all sections that match \p Name. There may be more than one if comdats
|
||||
@ -941,7 +949,8 @@ static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF,
|
||||
}
|
||||
|
||||
static Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) {
|
||||
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
|
||||
StringRef CompilationDir = "") {
|
||||
std::unique_ptr<ObjectFile> OF;
|
||||
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
|
||||
// If we have a universal binary, try to look up the object for the
|
||||
@ -1013,7 +1022,7 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch) {
|
||||
|
||||
return BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
|
||||
BytesInAddress, Endian);
|
||||
BytesInAddress, Endian, CompilationDir);
|
||||
}
|
||||
|
||||
/// Determine whether \p Arch is invalid or empty, given \p Bin.
|
||||
@ -1032,12 +1041,14 @@ static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
|
||||
Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
|
||||
BinaryCoverageReader::create(
|
||||
MemoryBufferRef ObjectBuffer, StringRef Arch,
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers) {
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
|
||||
StringRef CompilationDir) {
|
||||
std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
|
||||
|
||||
if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
|
||||
// This is a special format used for testing.
|
||||
auto ReaderOrErr = loadTestingFormat(ObjectBuffer.getBuffer());
|
||||
auto ReaderOrErr =
|
||||
loadTestingFormat(ObjectBuffer.getBuffer(), CompilationDir);
|
||||
if (!ReaderOrErr)
|
||||
return ReaderOrErr.takeError();
|
||||
Readers.push_back(std::move(ReaderOrErr.get()));
|
||||
@ -1070,7 +1081,8 @@ BinaryCoverageReader::create(
|
||||
}
|
||||
|
||||
return BinaryCoverageReader::create(
|
||||
ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers);
|
||||
ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
|
||||
CompilationDir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,7 +1095,7 @@ BinaryCoverageReader::create(
|
||||
return ChildBufOrErr.takeError();
|
||||
|
||||
auto ChildReadersOrErr = BinaryCoverageReader::create(
|
||||
ChildBufOrErr.get(), Arch, ObjectFileBuffers);
|
||||
ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir);
|
||||
if (!ChildReadersOrErr)
|
||||
return ChildReadersOrErr.takeError();
|
||||
for (auto &Reader : ChildReadersOrErr.get())
|
||||
@ -1102,7 +1114,7 @@ BinaryCoverageReader::create(
|
||||
return std::move(Readers);
|
||||
}
|
||||
|
||||
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch);
|
||||
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir);
|
||||
if (!ReaderOrErr)
|
||||
return ReaderOrErr.takeError();
|
||||
Readers.push_back(std::move(ReaderOrErr.get()));
|
||||
|
BIN
llvm/test/tools/llvm-cov/Inputs/compilation_dir.covmapping
Normal file
BIN
llvm/test/tools/llvm-cov/Inputs/compilation_dir.covmapping
Normal file
Binary file not shown.
8
llvm/test/tools/llvm-cov/Inputs/compilation_dir.proftext
Normal file
8
llvm/test/tools/llvm-cov/Inputs/compilation_dir.proftext
Normal file
@ -0,0 +1,8 @@
|
||||
main
|
||||
# Func Hash:
|
||||
0
|
||||
# Num Counters:
|
||||
1
|
||||
# Counter Values:
|
||||
1
|
||||
|
3
llvm/test/tools/llvm-cov/compilation_dir.c
Normal file
3
llvm/test/tools/llvm-cov/compilation_dir.c
Normal file
@ -0,0 +1,3 @@
|
||||
// RUN: llvm-profdata merge %S/Inputs/compilation_dir.proftext -o %t.profdata
|
||||
// RUN: llvm-cov show %S/Inputs/compilation_dir.covmapping -instr-profile=%t.profdata -compilation-dir=%S | FileCheck %s
|
||||
int main() {} // CHECK: [[@LINE]]| 1|int main() {}
|
@ -434,7 +434,8 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
|
||||
warning("profile data may be out of date - object is newer",
|
||||
ObjectFilename);
|
||||
auto CoverageOrErr =
|
||||
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches);
|
||||
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches,
|
||||
ViewOpts.CompilationDirectory);
|
||||
if (Error E = CoverageOrErr.takeError()) {
|
||||
error("Failed to load coverage: " + toString(std::move(E)),
|
||||
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "));
|
||||
@ -739,6 +740,10 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
|
||||
cl::alias NumThreadsA("j", cl::desc("Alias for --num-threads"),
|
||||
cl::aliasopt(NumThreads));
|
||||
|
||||
cl::opt<std::string> CompilationDirectory(
|
||||
"compilation-dir", cl::init(""),
|
||||
cl::desc("Directory used as a base for relative coverage mapping paths"));
|
||||
|
||||
auto commandLineParser = [&, this](int argc, const char **argv) -> int {
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
|
||||
ViewOpts.Debug = DebugDump;
|
||||
@ -873,6 +878,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
|
||||
ViewOpts.ShowInstantiationSummary = InstantiationSummary;
|
||||
ViewOpts.ExportSummaryOnly = SummaryOnly;
|
||||
ViewOpts.NumThreads = NumThreads;
|
||||
ViewOpts.CompilationDirectory = CompilationDirectory;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
@ -49,6 +49,7 @@ struct CoverageViewOptions {
|
||||
std::string ProjectTitle;
|
||||
std::string CreatedTimeStr;
|
||||
unsigned NumThreads;
|
||||
std::string CompilationDirectory;
|
||||
|
||||
/// Change the output's stream color if the colors are enabled.
|
||||
ColoredRawOstream colored_ostream(raw_ostream &OS,
|
||||
|
@ -900,7 +900,7 @@ INSTANTIATE_TEST_CASE_P(ParameterizedCovMapTest, CoverageMappingTest,
|
||||
std::pair<bool, bool>({true, true})),);
|
||||
|
||||
TEST(CoverageMappingTest, filename_roundtrip) {
|
||||
std::vector<std::string> Paths({"", "a", "b", "c", "d", "e"});
|
||||
std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
|
||||
|
||||
for (bool Compress : {false, true}) {
|
||||
std::string EncodedFilenames;
|
||||
@ -915,8 +915,37 @@ TEST(CoverageMappingTest, filename_roundtrip) {
|
||||
EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
|
||||
|
||||
ASSERT_EQ(ReadFilenames.size(), Paths.size());
|
||||
for (unsigned I = 1; I < Paths.size(); ++I)
|
||||
ASSERT_TRUE(ReadFilenames[I] == Paths[I]);
|
||||
for (unsigned I = 1; I < Paths.size(); ++I) {
|
||||
SmallString<256> P(Paths[0]);
|
||||
llvm::sys::path::append(P, Paths[I]);
|
||||
ASSERT_TRUE(ReadFilenames[I] == P);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CoverageMappingTest, filename_compilation_dir) {
|
||||
std::vector<std::string> Paths({"dir", "a", "b", "c", "d", "e"});
|
||||
|
||||
for (bool Compress : {false, true}) {
|
||||
std::string EncodedFilenames;
|
||||
{
|
||||
raw_string_ostream OS(EncodedFilenames);
|
||||
CoverageFilenamesSectionWriter Writer(Paths);
|
||||
Writer.write(OS, Compress);
|
||||
}
|
||||
|
||||
StringRef CompilationDir = "out";
|
||||
std::vector<std::string> ReadFilenames;
|
||||
RawCoverageFilenamesReader Reader(EncodedFilenames, ReadFilenames,
|
||||
CompilationDir);
|
||||
EXPECT_THAT_ERROR(Reader.read(CovMapVersion::CurrentVersion), Succeeded());
|
||||
|
||||
ASSERT_EQ(ReadFilenames.size(), Paths.size());
|
||||
for (unsigned I = 1; I < Paths.size(); ++I) {
|
||||
SmallString<256> P(CompilationDir);
|
||||
llvm::sys::path::append(P, Paths[I]);
|
||||
ASSERT_TRUE(ReadFilenames[I] == P);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user