@@ -583,24 +583,37 @@ static unsigned getMaxBitmapSize(const CounterMappingContext &Ctx,
583
583
return MaxBitmapID + (SizeInBits / CHAR_BIT);
584
584
}
585
585
586
+ // / This holds the DecisionRegion and MCDCBranch(es) under it.
587
+ // / Also traverses Expansion(s).
586
588
struct DecisionRow {
589
+ // / The subject
587
590
const CounterMappingRegion *DecisionRegion;
591
+
592
+ // / They are reflected from `DecisionRegion` for convenience.
588
593
LineColPair DecisionStartLoc;
589
594
LineColPair DecisionEndLoc;
590
595
596
+ // / This is passed to `MCDCRecordProcessor`, so this should be compatible to
597
+ // / `ArrayRef<const CounterMappingRegion *>`.
591
598
SmallVector<const CounterMappingRegion *, 6 > Branches;
599
+
600
+ // / Each `ID` in `Branches` should be unique.
592
601
DenseSet<CounterMappingRegion::MCDCConditionID> IDs;
602
+
603
+ // / Relevant `Expansion`(s) should be caught to find expanded Branches.
593
604
SmallVector<const CounterMappingRegion *> Expansions;
594
605
595
606
DecisionRow (const CounterMappingRegion &Decision)
596
607
: DecisionRegion(&Decision), DecisionStartLoc(Decision.startLoc()),
597
608
DecisionEndLoc (Decision.endLoc()) {}
598
609
610
+ // / Determine whether `R` is included in `DecisionRegion`.
599
611
bool inDecisionRegion (const CounterMappingRegion &R) {
600
612
return (R.FileID == DecisionRegion->FileID &&
601
613
R.startLoc () >= DecisionStartLoc && R.endLoc () <= DecisionEndLoc);
602
614
}
603
615
616
+ // / Determin whether `R` is pointed by any of Expansions.
604
617
bool inExpansions (const CounterMappingRegion &R) {
605
618
return any_of (Expansions, [&](const auto &Expansion) {
606
619
return (Expansion->ExpandedFileID == R.FileID );
@@ -613,26 +626,35 @@ struct DecisionRow {
613
626
Completed,
614
627
};
615
628
629
+ // / Add `Branch` into the Decision
616
630
UpdateResult updateBranch (const CounterMappingRegion &Branch) {
617
631
auto ID = Branch.MCDCParams .ID ;
632
+ assert (ID > 0 && " MCDCBranch.ID should begin with 1" );
618
633
619
634
if (!IDs.contains (ID) &&
620
635
(inDecisionRegion (Branch) || inExpansions (Branch))) {
621
636
assert (Branches.size () < DecisionRegion->MCDCParams .NumConditions );
622
637
638
+ // Put `ID=1` in front of `Branches` for convenience
639
+ // even if `Branches` is not topological.
623
640
if (ID == 1 )
624
641
Branches.insert (Branches.begin (), &Branch);
625
642
else
626
643
Branches.push_back (&Branch);
627
644
645
+ // Mark `ID` as `assigned`.
628
646
IDs.insert (ID);
647
+
648
+ // `Completed` when `Branches` is full
629
649
return (Branches.size () == DecisionRegion->MCDCParams .NumConditions
630
650
? UpdateResult::Completed
631
651
: UpdateResult::Updated);
632
652
} else
633
653
return UpdateResult::NotFound;
634
654
}
635
655
656
+ // / Record `Expansion` if it is dominated to the Decision.
657
+ // / Each `Expansion` may nest.
636
658
bool updateExpansion (const CounterMappingRegion &Expansion) {
637
659
if (inDecisionRegion (Expansion) || inExpansions (Expansion)) {
638
660
Expansions.push_back (&Expansion);
@@ -702,6 +724,7 @@ Error CoverageMapping::loadFunctionRecord(
702
724
FunctionRecord Function (OrigFuncName, Record.Filenames );
703
725
for (const auto &Region : Record.MappingRegions ) {
704
726
if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion) {
727
+ // Start recording `Region` as the `Decision`
705
728
Decisions.emplace_back (Region);
706
729
continue ;
707
730
}
0 commit comments