2727#include " llvm/ProfileData/InstrProf.h"
2828#include " llvm/Support/FileSystem.h"
2929
30- // This selects the coverage mapping format defined when `InstrProfData.inc`
31- // is textually included.
32- #define COVMAP_V3
33-
3430using namespace swift ;
3531using namespace irgen ;
3632
3733using llvm::coverage::CounterMappingRegion;
3834using llvm::coverage::CovMapVersion;
3935
36+ // This affects the coverage mapping format defined when `InstrProfData.inc`
37+ // is textually included. Note that it means 'version >= 3', not 'version == 3'.
38+ #define COVMAP_V3
39+
40+ // / This assert is here to make sure we make all the necessary code generation
41+ // / changes that are needed to support the new coverage mapping format. Note we
42+ // / cannot pin our version, as it must remain in sync with the version Clang is
43+ // / using.
44+ // / Do not bump without at least filing a bug and pinging a coverage maintainer.
45+ static_assert (CovMapVersion::CurrentVersion == CovMapVersion::Version6,
46+ " Coverage mapping emission needs updating" );
47+
4048static std::string getInstrProfSection (IRGenModule &IGM,
4149 llvm::InstrProfSectKind SK) {
4250 return llvm::getInstrProfSectionName (SK, IGM.Triple .getObjectFormat ());
@@ -77,18 +85,26 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
7785 }
7886
7987 std::vector<StringRef> Files;
80- for (const auto &M : Mappings)
88+ for (const auto &M : Mappings) {
8189 if (std::find (Files.begin (), Files.end (), M->getFilename ()) == Files.end ())
8290 Files.push_back (M->getFilename ());
83-
84- auto remapper = getOptions ().CoveragePrefixMap ;
91+ }
92+ const auto &Remapper = getOptions ().CoveragePrefixMap ;
8593
8694 llvm::SmallVector<std::string, 8 > FilenameStrs;
87- for (StringRef Name : Files) {
88- llvm::SmallString<256 > Path (Name);
89- llvm::sys::fs::make_absolute (Path);
90- FilenameStrs.push_back (remapper.remapPath (Path));
91- }
95+ FilenameStrs.reserve (Files.size () + 1 );
96+
97+ // First element needs to be the current working directory. Note if this
98+ // scheme ever changes, the FileID computation below will need updating.
99+ SmallString<256 > WorkingDirectory;
100+ llvm::sys::fs::current_path (WorkingDirectory);
101+ FilenameStrs.emplace_back (Remapper.remapPath (WorkingDirectory));
102+
103+ // Following elements are the filenames present. We use their relative path,
104+ // which llvm-cov will turn back into absolute paths using the working
105+ // directory element.
106+ for (auto Name : Files)
107+ FilenameStrs.emplace_back (Remapper.remapPath (Name));
92108
93109 // Encode the filenames.
94110 std::string Filenames;
@@ -112,13 +128,21 @@ void IRGenModule::emitCoverageMaps(ArrayRef<const SILCoverageMap *> Mappings) {
112128 const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash (NameValue);
113129 std::string FuncRecordName = " __covrec_" + llvm::utohexstr (NameHash);
114130
115- unsigned FileID =
116- std::find (Files.begin (), Files.end (), M->getFilename ()) - Files.begin ();
131+ // The file ID needs to be bumped by 1 to account for the working directory
132+ // as the first element.
133+ unsigned FileID = 1 +
134+ std::find (Files.begin (), Files.end (), M->getFilename ()) -
135+ Files.begin ();
136+ assert (FileID < FilenameStrs.size ());
137+
117138 std::vector<CounterMappingRegion> Regions;
118- for (const auto &MR : M->getMappedRegions ())
139+ for (const auto &MR : M->getMappedRegions ()) {
140+ // The SubFileID here is 0, because it's an index into VirtualFileMapping,
141+ // and we only ever have a single file associated for a function.
119142 Regions.emplace_back (CounterMappingRegion::makeRegion (
120- MR.Counter , /* FileID= */ 0 , MR.StartLine , MR.StartCol , MR.EndLine ,
143+ MR.Counter , /* SubFileID */ 0 , MR.StartLine , MR.StartCol , MR.EndLine ,
121144 MR.EndCol ));
145+ }
122146 // Append each function's regions into the encoded buffer.
123147 ArrayRef<unsigned > VirtualFileMapping (FileID);
124148 llvm::coverage::CoverageMappingWriter W (VirtualFileMapping,
0 commit comments