aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CoverageMappingGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp312
1 files changed, 145 insertions, 167 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index 5c25c204cc0b..8a11da600e4a 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -104,26 +104,21 @@ class SourceMappingRegion {
/// The region's ending location.
Optional<SourceLocation> LocEnd;
- /// Whether this region should be emitted after its parent is emitted.
- bool DeferRegion;
-
/// Whether this region is a gap region. The count from a gap region is set
/// as the line execution count if there are no other regions on the line.
bool GapRegion;
public:
SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
- Optional<SourceLocation> LocEnd, bool DeferRegion = false,
- bool GapRegion = false)
- : Count(Count), LocStart(LocStart), LocEnd(LocEnd),
- DeferRegion(DeferRegion), GapRegion(GapRegion) {}
+ Optional<SourceLocation> LocEnd, bool GapRegion = false)
+ : Count(Count), LocStart(LocStart), LocEnd(LocEnd), GapRegion(GapRegion) {
+ }
SourceMappingRegion(Counter Count, Optional<Counter> FalseCount,
Optional<SourceLocation> LocStart,
- Optional<SourceLocation> LocEnd, bool DeferRegion = false,
- bool GapRegion = false)
+ Optional<SourceLocation> LocEnd, bool GapRegion = false)
: Count(Count), FalseCount(FalseCount), LocStart(LocStart),
- LocEnd(LocEnd), DeferRegion(DeferRegion), GapRegion(GapRegion) {}
+ LocEnd(LocEnd), GapRegion(GapRegion) {}
const Counter &getCounter() const { return Count; }
@@ -155,10 +150,6 @@ public:
return *LocEnd;
}
- bool isDeferred() const { return DeferRegion; }
-
- void setDeferred(bool Deferred) { DeferRegion = Deferred; }
-
bool isGap() const { return GapRegion; }
void setGap(bool Gap) { GapRegion = Gap; }
@@ -544,10 +535,6 @@ struct CounterCoverageMappingBuilder
/// A stack of currently live regions.
std::vector<SourceMappingRegion> RegionStack;
- /// The currently deferred region: its end location and count can be set once
- /// its parent has been popped from the region stack.
- Optional<SourceMappingRegion> DeferredRegion;
-
CounterExpressionBuilder Builder;
/// A location in the most recently visited file or macro.
@@ -556,8 +543,11 @@ struct CounterCoverageMappingBuilder
/// expressions cross file or macro boundaries.
SourceLocation MostRecentLocation;
- /// Location of the last terminated region.
- Optional<std::pair<SourceLocation, size_t>> LastTerminatedRegion;
+ /// Whether the visitor at a terminate statement.
+ bool HasTerminateStmt = false;
+
+ /// Gap region counter after terminate statement.
+ Counter GapRegionCounter;
/// Return a counter for the subtraction of \c RHS from \c LHS
Counter subtractCounters(Counter LHS, Counter RHS) {
@@ -590,77 +580,13 @@ struct CounterCoverageMappingBuilder
if (StartLoc && !FalseCount.hasValue()) {
MostRecentLocation = *StartLoc;
- completeDeferred(Count, MostRecentLocation);
}
- RegionStack.emplace_back(Count, FalseCount, StartLoc, EndLoc,
- FalseCount.hasValue());
+ RegionStack.emplace_back(Count, FalseCount, StartLoc, EndLoc);
return RegionStack.size() - 1;
}
- /// Complete any pending deferred region by setting its end location and
- /// count, and then pushing it onto the region stack.
- size_t completeDeferred(Counter Count, SourceLocation DeferredEndLoc) {
- size_t Index = RegionStack.size();
- if (!DeferredRegion)
- return Index;
-
- // Consume the pending region.
- SourceMappingRegion DR = DeferredRegion.getValue();
- DeferredRegion = None;
-
- // If the region ends in an expansion, find the expansion site.
- FileID StartFile = SM.getFileID(DR.getBeginLoc());
- if (SM.getFileID(DeferredEndLoc) != StartFile) {
- if (isNestedIn(DeferredEndLoc, StartFile)) {
- do {
- DeferredEndLoc = getIncludeOrExpansionLoc(DeferredEndLoc);
- } while (StartFile != SM.getFileID(DeferredEndLoc));
- } else {
- return Index;
- }
- }
-
- // The parent of this deferred region ends where the containing decl ends,
- // so the region isn't useful.
- if (DR.getBeginLoc() == DeferredEndLoc)
- return Index;
-
- // If we're visiting statements in non-source order (e.g switch cases or
- // a loop condition) we can't construct a sensible deferred region.
- if (!SpellingRegion(SM, DR.getBeginLoc(), DeferredEndLoc).isInSourceOrder())
- return Index;
-
- DR.setGap(true);
- DR.setCounter(Count);
- DR.setEndLoc(DeferredEndLoc);
- handleFileExit(DeferredEndLoc);
- RegionStack.push_back(DR);
- return Index;
- }
-
- /// Complete a deferred region created after a terminated region at the
- /// top-level.
- void completeTopLevelDeferredRegion(Counter Count,
- SourceLocation DeferredEndLoc) {
- if (DeferredRegion || !LastTerminatedRegion)
- return;
-
- if (LastTerminatedRegion->second != RegionStack.size())
- return;
-
- SourceLocation Start = LastTerminatedRegion->first;
- if (SM.getFileID(Start) != SM.getMainFileID())
- return;
-
- SourceMappingRegion DR = RegionStack.back();
- DR.setStartLoc(Start);
- DR.setDeferred(false);
- DeferredRegion = DR;
- completeDeferred(Count, DeferredEndLoc);
- }
-
size_t locationDepth(SourceLocation Loc) {
size_t Depth = 0;
while (Loc.isValid()) {
@@ -676,7 +602,6 @@ struct CounterCoverageMappingBuilder
/// function's \c SourceRegions.
void popRegions(size_t ParentIndex) {
assert(RegionStack.size() >= ParentIndex && "parent not in stack");
- bool ParentOfDeferredRegion = false;
while (RegionStack.size() > ParentIndex) {
SourceMappingRegion &Region = RegionStack.back();
if (Region.hasStartLoc()) {
@@ -746,32 +671,9 @@ struct CounterCoverageMappingBuilder
assert(SM.isWrittenInSameFile(Region.getBeginLoc(), EndLoc));
assert(SpellingRegion(SM, Region).isInSourceOrder());
SourceRegions.push_back(Region);
-
- if (ParentOfDeferredRegion) {
- ParentOfDeferredRegion = false;
-
- // If there's an existing deferred region, keep the old one, because
- // it means there are two consecutive returns (or a similar pattern).
- if (!DeferredRegion.hasValue() &&
- // File IDs aren't gathered within macro expansions, so it isn't
- // useful to try and create a deferred region inside of one.
- !EndLoc.isMacroID())
- DeferredRegion =
- SourceMappingRegion(Counter::getZero(), EndLoc, None);
}
- } else if (Region.isDeferred()) {
- assert(!ParentOfDeferredRegion && "Consecutive deferred regions");
- ParentOfDeferredRegion = true;
- }
RegionStack.pop_back();
-
- // If the zero region pushed after the last terminated region no longer
- // exists, clear its cached information.
- if (LastTerminatedRegion &&
- RegionStack.size() < LastTerminatedRegion->second)
- LastTerminatedRegion = None;
}
- assert(!ParentOfDeferredRegion && "Deferred region with no parent");
}
/// Return the currently active region.
@@ -955,8 +857,6 @@ struct CounterCoverageMappingBuilder
handleFileExit(StartLoc);
if (!Region.hasStartLoc())
Region.setStartLoc(StartLoc);
-
- completeDeferred(Region.getCounter(), StartLoc);
}
/// Mark \c S as a terminator, starting a zero region.
@@ -967,30 +867,56 @@ struct CounterCoverageMappingBuilder
if (!Region.hasEndLoc())
Region.setEndLoc(EndLoc);
pushRegion(Counter::getZero());
- auto &ZeroRegion = getRegion();
- ZeroRegion.setDeferred(true);
- LastTerminatedRegion = {EndLoc, RegionStack.size()};
+ HasTerminateStmt = true;
}
/// Find a valid gap range between \p AfterLoc and \p BeforeLoc.
Optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc,
SourceLocation BeforeLoc) {
+ // If AfterLoc is in function-like macro, use the right parenthesis
+ // location.
+ if (AfterLoc.isMacroID()) {
+ FileID FID = SM.getFileID(AfterLoc);
+ const SrcMgr::ExpansionInfo *EI = &SM.getSLocEntry(FID).getExpansion();
+ if (EI->isFunctionMacroExpansion())
+ AfterLoc = EI->getExpansionLocEnd();
+ }
+
+ size_t StartDepth = locationDepth(AfterLoc);
+ size_t EndDepth = locationDepth(BeforeLoc);
+ while (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc)) {
+ bool UnnestStart = StartDepth >= EndDepth;
+ bool UnnestEnd = EndDepth >= StartDepth;
+ if (UnnestEnd) {
+ assert(SM.isWrittenInSameFile(getStartOfFileOrMacro(BeforeLoc),
+ BeforeLoc));
+
+ BeforeLoc = getIncludeOrExpansionLoc(BeforeLoc);
+ assert(BeforeLoc.isValid());
+ EndDepth--;
+ }
+ if (UnnestStart) {
+ assert(SM.isWrittenInSameFile(AfterLoc,
+ getEndOfFileOrMacro(AfterLoc)));
+
+ AfterLoc = getIncludeOrExpansionLoc(AfterLoc);
+ assert(AfterLoc.isValid());
+ AfterLoc = getPreciseTokenLocEnd(AfterLoc);
+ assert(AfterLoc.isValid());
+ StartDepth--;
+ }
+ }
+ AfterLoc = getPreciseTokenLocEnd(AfterLoc);
// If the start and end locations of the gap are both within the same macro
// file, the range may not be in source order.
if (AfterLoc.isMacroID() || BeforeLoc.isMacroID())
return None;
- if (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc))
+ if (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc) ||
+ !SpellingRegion(SM, AfterLoc, BeforeLoc).isInSourceOrder())
return None;
return {{AfterLoc, BeforeLoc}};
}
- /// Find the source range after \p AfterStmt and before \p BeforeStmt.
- Optional<SourceRange> findGapAreaBetween(const Stmt *AfterStmt,
- const Stmt *BeforeStmt) {
- return findGapAreaBetween(getPreciseTokenLocEnd(getEnd(AfterStmt)),
- getStart(BeforeStmt));
- }
-
/// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc,
Counter Count) {
@@ -1015,15 +941,13 @@ struct CounterCoverageMappingBuilder
CoverageMappingModuleGen &CVM,
llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
const LangOptions &LangOpts)
- : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
- DeferredRegion(None) {}
+ : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
/// Write the mapping data to the output stream
void write(llvm::raw_ostream &OS) {
llvm::SmallVector<unsigned, 8> VirtualFileMapping;
gatherFileIDs(VirtualFileMapping);
SourceRegionFilter Filter = emitExpansionRegions();
- assert(!DeferredRegion && "Deferred region never completed");
emitSourceRegions(Filter);
gatherSkippedRegions();
@@ -1038,15 +962,32 @@ struct CounterCoverageMappingBuilder
void VisitStmt(const Stmt *S) {
if (S->getBeginLoc().isValid())
extendRegion(S);
+ const Stmt *LastStmt = nullptr;
+ bool SaveTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+ GapRegionCounter = Counter::getZero();
for (const Stmt *Child : S->children())
- if (Child)
+ if (Child) {
+ // If last statement contains terminate statements, add a gap area
+ // between the two statements. Skipping attributed statements, because
+ // they don't have valid start location.
+ if (LastStmt && HasTerminateStmt && !dyn_cast<AttributedStmt>(Child)) {
+ auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child));
+ if (Gap)
+ fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(),
+ GapRegionCounter);
+ SaveTerminateStmt = true;
+ HasTerminateStmt = false;
+ }
this->Visit(Child);
+ LastStmt = Child;
+ }
+ if (SaveTerminateStmt)
+ HasTerminateStmt = true;
handleFileExit(getEnd(S));
}
void VisitDecl(const Decl *D) {
- assert(!DeferredRegion && "Deferred region never completed");
-
Stmt *Body = D->getBody();
// Do not propagate region counts into system headers.
@@ -1064,11 +1005,6 @@ struct CounterCoverageMappingBuilder
propagateCounts(getRegionCounter(Body), Body,
/*VisitChildren=*/!Defaulted);
assert(RegionStack.empty() && "Regions entered but never exited");
-
- // Discard the last uncompleted deferred region in a decl, if one exists.
- // This prevents lines at the end of a function containing only whitespace
- // or closing braces from being marked as uncovered.
- DeferredRegion = None;
}
void VisitReturnStmt(const ReturnStmt *S) {
@@ -1102,8 +1038,6 @@ struct CounterCoverageMappingBuilder
void VisitLabelStmt(const LabelStmt *S) {
Counter LabelCount = getRegionCounter(S);
SourceLocation Start = getStart(S);
- completeTopLevelDeferredRegion(LabelCount, Start);
- completeDeferred(LabelCount, Start);
// We can't extendRegion here or we risk overlapping with our new region.
handleFileExit(Start);
pushRegion(LabelCount, Start);
@@ -1148,6 +1082,9 @@ struct CounterCoverageMappingBuilder
Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
BreakContinue BC = BreakContinueStack.pop_back_val();
+ bool BodyHasTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+
// Go back to handle the condition.
Counter CondCount =
addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
@@ -1155,14 +1092,18 @@ struct CounterCoverageMappingBuilder
adjustForOutOfOrderTraversal(getEnd(S));
// The body count applies to the area immediately after the increment.
- auto Gap = findGapAreaBetween(S->getCond(), S->getBody());
+ auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
Counter OutCount =
addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ if (BodyHasTerminateStmt)
+ HasTerminateStmt = true;
+ }
// Create Branch Region around condition.
createBranchRegion(S->getCond(), BodyCount,
@@ -1181,17 +1122,25 @@ struct CounterCoverageMappingBuilder
propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
BreakContinue BC = BreakContinueStack.pop_back_val();
+ bool BodyHasTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+
Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
propagateCounts(CondCount, S->getCond());
Counter OutCount =
addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ }
// Create Branch Region around condition.
createBranchRegion(S->getCond(), BodyCount,
subtractCounters(CondCount, BodyCount));
+
+ if (BodyHasTerminateStmt)
+ HasTerminateStmt = true;
}
void VisitForStmt(const ForStmt *S) {
@@ -1212,6 +1161,9 @@ struct CounterCoverageMappingBuilder
Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
BreakContinue BodyBC = BreakContinueStack.pop_back_val();
+ bool BodyHasTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+
// The increment is essentially part of the body but it needs to include
// the count for all the continue statements.
BreakContinue IncrementBC;
@@ -1230,15 +1182,18 @@ struct CounterCoverageMappingBuilder
}
// The body count applies to the area immediately after the increment.
- auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
- getStart(S->getBody()));
+ auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
subtractCounters(CondCount, BodyCount));
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ if (BodyHasTerminateStmt)
+ HasTerminateStmt = true;
+ }
// Create Branch Region around condition.
createBranchRegion(S->getCond(), BodyCount,
@@ -1260,9 +1215,11 @@ struct CounterCoverageMappingBuilder
Counter BackedgeCount = propagateCounts(BodyCount, S->getBody());
BreakContinue BC = BreakContinueStack.pop_back_val();
+ bool BodyHasTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+
// The body count applies to the area immediately after the range.
- auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
- getStart(S->getBody()));
+ auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
@@ -1270,8 +1227,12 @@ struct CounterCoverageMappingBuilder
addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
Counter OutCount =
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ if (BodyHasTerminateStmt)
+ HasTerminateStmt = true;
+ }
// Create Branch Region around condition.
createBranchRegion(S->getCond(), BodyCount,
@@ -1291,8 +1252,7 @@ struct CounterCoverageMappingBuilder
BreakContinue BC = BreakContinueStack.pop_back_val();
// The body count applies to the area immediately after the collection.
- auto Gap = findGapAreaBetween(getPreciseTokenLocEnd(S->getRParenLoc()),
- getStart(S->getBody()));
+ auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody()));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
@@ -1300,8 +1260,10 @@ struct CounterCoverageMappingBuilder
addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
Counter OutCount =
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ }
}
void VisitSwitchStmt(const SwitchStmt *S) {
@@ -1321,8 +1283,7 @@ struct CounterCoverageMappingBuilder
// the unreachable code at the beginning of the switch body.
size_t Index = pushRegion(Counter::getZero(), getStart(CS));
getRegion().setGap(true);
- for (const auto *Child : CS->children())
- Visit(Child);
+ Visit(Body);
// Set the end for the body of the switch, if it isn't already set.
for (size_t i = RegionStack.size(); i != Index; --i) {
@@ -1344,6 +1305,7 @@ struct CounterCoverageMappingBuilder
Counter ExitCount = getRegionCounter(S);
SourceLocation ExitLoc = getEnd(S);
pushRegion(ExitCount);
+ GapRegionCounter = ExitCount;
// Ensure that handleFileExit recognizes when the end location is located
// in a different file.
@@ -1386,6 +1348,8 @@ struct CounterCoverageMappingBuilder
else
pushRegion(Count, getStart(S));
+ GapRegionCounter = Count;
+
if (const auto *CS = dyn_cast<CaseStmt>(S)) {
Visit(CS->getLHS());
if (const Expr *RHS = CS->getRHS())
@@ -1411,7 +1375,7 @@ struct CounterCoverageMappingBuilder
propagateCounts(ParentCount, S->getCond());
// The 'then' count applies to the area immediately after the condition.
- auto Gap = findGapAreaBetween(S->getCond(), S->getThen());
+ auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen()));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount);
@@ -1420,17 +1384,25 @@ struct CounterCoverageMappingBuilder
Counter ElseCount = subtractCounters(ParentCount, ThenCount);
if (const Stmt *Else = S->getElse()) {
+ bool ThenHasTerminateStmt = HasTerminateStmt;
+ HasTerminateStmt = false;
+
// The 'else' count applies to the area immediately after the 'then'.
- Gap = findGapAreaBetween(S->getThen(), Else);
+ Gap = findGapAreaBetween(getEnd(S->getThen()), getStart(Else));
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount);
extendRegion(Else);
OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
+
+ if (ThenHasTerminateStmt)
+ HasTerminateStmt = true;
} else
OutCount = addCounters(OutCount, ElseCount);
- if (OutCount != ParentCount)
+ if (OutCount != ParentCount) {
pushRegion(OutCount);
+ GapRegionCounter = OutCount;
+ }
// Create Branch Region around condition.
createBranchRegion(S->getCond(), ThenCount,
@@ -1462,7 +1434,7 @@ struct CounterCoverageMappingBuilder
Counter ParentCount = getRegion().getCounter();
Counter TrueCount = getRegionCounter(E);
- Visit(E->getCond());
+ propagateCounts(ParentCount, E->getCond());
if (!isa<BinaryConditionalOperator>(E)) {
// The 'then' count applies to the area immediately after the condition.
@@ -1588,14 +1560,22 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
CoverageMappingModuleGen::CoverageMappingModuleGen(
CodeGenModule &CGM, CoverageSourceInfo &SourceInfo)
: CGM(CGM), SourceInfo(SourceInfo) {
- ProfilePrefixMap = CGM.getCodeGenOpts().ProfilePrefixMap;
+ CoveragePrefixMap = CGM.getCodeGenOpts().CoveragePrefixMap;
+}
+
+std::string CoverageMappingModuleGen::getCurrentDirname() {
+ if (!CGM.getCodeGenOpts().CoverageCompilationDir.empty())
+ return CGM.getCodeGenOpts().CoverageCompilationDir;
+
+ SmallString<256> CWD;
+ llvm::sys::fs::current_path(CWD);
+ return CWD.str().str();
}
std::string CoverageMappingModuleGen::normalizeFilename(StringRef Filename) {
llvm::SmallString<256> Path(Filename);
- llvm::sys::fs::make_absolute(Path);
llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true);
- for (const auto &Entry : ProfilePrefixMap) {
+ for (const auto &Entry : CoveragePrefixMap) {
if (llvm::sys::path::replace_path_prefix(Path, Entry.first, Entry.second))
break;
}
@@ -1674,18 +1654,17 @@ void CoverageMappingModuleGen::addFunctionMappingRecord(
// also processed by the CoverageMappingWriter which performs
// additional minimization operations such as reducing the number of
// expressions.
+ llvm::SmallVector<std::string, 16> FilenameStrs;
std::vector<StringRef> Filenames;
std::vector<CounterExpression> Expressions;
std::vector<CounterMappingRegion> Regions;
- llvm::SmallVector<std::string, 16> FilenameStrs;
- llvm::SmallVector<StringRef, 16> FilenameRefs;
- FilenameStrs.resize(FileEntries.size());
- FilenameRefs.resize(FileEntries.size());
+ FilenameStrs.resize(FileEntries.size() + 1);
+ FilenameStrs[0] = normalizeFilename(getCurrentDirname());
for (const auto &Entry : FileEntries) {
auto I = Entry.second;
FilenameStrs[I] = normalizeFilename(Entry.first->getName());
- FilenameRefs[I] = FilenameStrs[I];
}
+ ArrayRef<std::string> FilenameRefs = llvm::makeArrayRef(FilenameStrs);
RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames,
Expressions, Regions);
if (Reader.read())
@@ -1702,19 +1681,18 @@ void CoverageMappingModuleGen::emit() {
// Create the filenames and merge them with coverage mappings
llvm::SmallVector<std::string, 16> FilenameStrs;
- llvm::SmallVector<StringRef, 16> FilenameRefs;
- FilenameStrs.resize(FileEntries.size());
- FilenameRefs.resize(FileEntries.size());
+ FilenameStrs.resize(FileEntries.size() + 1);
+ // The first filename is the current working directory.
+ FilenameStrs[0] = normalizeFilename(getCurrentDirname());
for (const auto &Entry : FileEntries) {
auto I = Entry.second;
FilenameStrs[I] = normalizeFilename(Entry.first->getName());
- FilenameRefs[I] = FilenameStrs[I];
}
std::string Filenames;
{
llvm::raw_string_ostream OS(Filenames);
- CoverageFilenamesSectionWriter(FilenameRefs).write(OS);
+ CoverageFilenamesSectionWriter(FilenameStrs).write(OS);
}
auto *FilenamesVal =
llvm::ConstantDataArray::getString(Ctx, Filenames, false);
@@ -1772,7 +1750,7 @@ unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) {
auto It = FileEntries.find(File);
if (It != FileEntries.end())
return It->second;
- unsigned FileID = FileEntries.size();
+ unsigned FileID = FileEntries.size() + 1;
FileEntries.insert(std::make_pair(File, FileID));
return FileID;
}