/// 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)
+ Optional<SourceLocation> LocEnd, bool DeferRegion = false,
+ bool GapRegion = false)
: Count(Count), LocStart(LocStart), LocEnd(LocEnd),
- DeferRegion(DeferRegion) {}
+ DeferRegion(DeferRegion), GapRegion(GapRegion) {}
const Counter &getCounter() const { return Count; }
bool isDeferred() const { return DeferRegion; }
void setDeferred(bool Deferred) { DeferRegion = Deferred; }
+
+ bool isGap() const { return GapRegion; }
+
+ void setGap(bool Gap) { GapRegion = Gap; }
};
/// Spelling locations for the start and end of a source region.
// Find the spelling locations for the mapping region.
SpellingRegion SR{SM, LocStart, LocEnd};
assert(SR.isInSourceOrder() && "region start and end out of order");
- MappingRegions.push_back(CounterMappingRegion::makeRegion(
- Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
- SR.LineEnd, SR.ColumnEnd));
+
+ if (Region.isGap()) {
+ MappingRegions.push_back(CounterMappingRegion::makeGapRegion(
+ Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
+ SR.LineEnd, SR.ColumnEnd));
+ } else {
+ MappingRegions.push_back(CounterMappingRegion::makeRegion(
+ Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
+ SR.LineEnd, SR.ColumnEnd));
+ }
}
}
if (!SpellingRegion(SM, DR.getStartLoc(), DeferredEndLoc).isInSourceOrder())
return Index;
+ DR.setGap(true);
DR.setCounter(Count);
DR.setEndLoc(DeferredEndLoc);
handleFileExit(DeferredEndLoc);
case CounterMappingRegion::SkippedRegion:
OS << "Skipped,";
break;
+ case CounterMappingRegion::GapRegion:
+ OS << "Gap,";
+ break;
}
OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
void foo(int x) {
if (x == 0) {
return;
- } // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:2 = (#0 - #1)
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = (#0 - #1)
}
void fooo(int x) {
if (x == 0) {
return;
- } // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:3 = (#0 - #1)
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:3 = (#0 - #1)
if (x == 1) {
return;
- } // CHECK: [[@LINE]]:4 -> [[@LINE+2]]:2 = ((#0 - #1) - #2)
+ } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = ((#0 - #1) - #2)
}
// CHECK-LABEL: _Z3bari:
void bar(int x) {
IF (x)
- return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
IF (!x)
- return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = ((#0 - #1) - #2)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = ((#0 - #1) - #2)
foo(x);
}
int i = 0;
if (false)
- return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
if (false)
i++;
if (i + 100 > 0) { // CHECK: [[@LINE]]:20 -> [[@LINE+6]]:4 = #3
if (false) // CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:13 = #4
- return; // CHECK: [[@LINE]]:13 -> [[@LINE+2]]:5 = (#3 - #4)
+ return; // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:5 = (#3 - #4)
// CHECK: [[@LINE+1]]:5 -> [[@LINE+3]]:4 = (#3 - #4)
- return; // CHECK: [[@LINE]]:5 -> [[@LINE+4]]:3 = ((#0 - #1) - #3)
+ return; // CHECK: Gap,File 0, [[@LINE]]:5 -> [[@LINE+4]]:3 = ((#0 - #1) - #3)
}
if (false)
- return;
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:2
}
// CHECK-LABEL: _Z8for_loopv:
void for_loop() {
if (false)
- return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
for (int i = 0; i < 10; ++i) {
if (i % 2 == 0)
- continue; // CHECK: [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+ continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
if (i % 5 == 0)
- break; // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:5 = ((#2 - #3) - #4)
+ break; // CHECK: Gap,File 0, [[@LINE]]:12 -> [[@LINE+2]]:5 = ((#2 - #3) - #4)
int x = i; // CHECK: [[@LINE]]:5 -> [[@LINE+3]]:4 = ((#2 - #3) - #4)
return; // CHECK-NOT: [[@LINE]]:11 -> [[@LINE+2]]
// CHECK-LABEL: _Z10while_loopv:
void while_loop() {
if (false)
- return; // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+ return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
int x = 0;
while (++x < 10) {
if (x == 1)
- continue; // CHECK: [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+ continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
while (++x < 4) {
if (x == 3)
- break; // CHECK: [[@LINE]]:14 -> [[@LINE+2]]:7 = (#4 - #5)
+ break; // CHECK: Gap,File 0, [[@LINE]]:14 -> [[@LINE+2]]:7 = (#4 - #5)
while (++x < 5) {}
}
if (x == 0)
- throw Error(); // CHECK: [[@LINE]]:20 -> [[@LINE+2]]:5 = ((#2 - #3) - #7)
+ throw Error(); // CHECK: Gap,File 0, [[@LINE]]:20 -> [[@LINE+2]]:5 = ((#2 - #3) - #7)
while (++x < 9) {
if (x == 0)
// CHECK-LABEL: _Z5gotosv:
void gotos() {
if (false)
- goto out; // CHECK: [[@LINE]]:13 -> [[@LINE+2]]:3 = (#0 - #1)
+ goto out; // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:3 = (#0 - #1)
return; // CHECK: [[@LINE]]:3 -> [[@LINE+4]]:2 = (#0 - #1)
out:
- return; // CHECK: [[@LINE]]:8 -> [[@LINE+1]]:2 = 0
+ return; // CHECK: Gap,File 0, [[@LINE]]:8 -> [[@LINE+1]]:2 = 0
}
int main() {