diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h --- a/clang/lib/CodeGen/CoverageMappingGen.h +++ b/clang/lib/CodeGen/CoverageMappingGen.h @@ -31,15 +31,29 @@ class Stmt; struct SkippedRange { + enum Kind { + PPIfElse, // Preprocessor #if/#else ... + EmptyLine, + Comment, + }; + SourceRange Range; // The location of token before the skipped source range. SourceLocation PrevTokLoc; // The location of token after the skipped source range. SourceLocation NextTokLoc; + // The nature of this skipped range + Kind RangeKind; + + bool isComment() { return RangeKind == Comment; } + bool isEmptyLine() { return RangeKind == EmptyLine; } + bool isPPIfElse() { return RangeKind == PPIfElse; } - SkippedRange(SourceRange Range, SourceLocation PrevTokLoc = SourceLocation(), + SkippedRange(SourceRange Range, Kind K, + SourceLocation PrevTokLoc = SourceLocation(), SourceLocation NextTokLoc = SourceLocation()) - : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc) {} + : Range(Range), PrevTokLoc(PrevTokLoc), NextTokLoc(NextTokLoc), + RangeKind(K) {} }; /// Stores additional source code information like skipped ranges which @@ -62,7 +76,7 @@ std::vector &getSkippedRanges() { return SkippedRanges; } - void AddSkippedRange(SourceRange Range); + void AddSkippedRange(SourceRange Range, SkippedRange::Kind RangeKind); void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override; diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -60,26 +60,27 @@ return CoverageInfo; } -void CoverageSourceInfo::AddSkippedRange(SourceRange Range) { +void CoverageSourceInfo::AddSkippedRange(SourceRange Range, + SkippedRange::Kind RangeKind) { if (EmptyLineCommentCoverage && !SkippedRanges.empty() && PrevTokLoc == SkippedRanges.back().PrevTokLoc && SourceMgr.isWrittenInSameFile(SkippedRanges.back().Range.getEnd(), Range.getBegin())) SkippedRanges.back().Range.setEnd(Range.getEnd()); else - SkippedRanges.push_back({Range, PrevTokLoc}); + SkippedRanges.push_back({Range, RangeKind, PrevTokLoc}); } void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range, SourceLocation) { - AddSkippedRange(Range); + AddSkippedRange(Range, SkippedRange::PPIfElse); } void CoverageSourceInfo::HandleEmptyline(SourceRange Range) { - AddSkippedRange(Range); + AddSkippedRange(Range, SkippedRange::EmptyLine); } bool CoverageSourceInfo::HandleComment(Preprocessor &PP, SourceRange Range) { - AddSkippedRange(Range); + AddSkippedRange(Range, SkippedRange::Comment); return false; } @@ -335,6 +336,8 @@ /// This shrinks the skipped range if it spans a line that contains a /// non-comment token. If shrinking the skipped range would make it empty, /// this returns None. + /// Note this function can potentially be expensive because + /// getSpellingLineNumber uses getLineNumber, which is expensive. Optional adjustSkippedRange(SourceManager &SM, SourceLocation LocStart, SourceLocation LocEnd, @@ -382,8 +385,13 @@ auto CovFileID = getCoverageFileID(LocStart); if (!CovFileID) continue; - Optional SR = - adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc, I.NextTokLoc); + Optional SR; + if (I.isComment()) + SR = adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc, + I.NextTokLoc); + else if (I.isPPIfElse() || I.isEmptyLine()) + SR = {SM, LocStart, LocEnd}; + if (!SR.hasValue()) continue; auto Region = CounterMappingRegion::makeSkipped(