https://github.com/ChuanqiXu9 created
https://github.com/llvm/llvm-project/pull/204517
Motivation: there are some macro likes:
```C++
#define CHECK(X) if (!X) { log_something(); exit(1); }
```
Then the branch coverage for such cases may always under 50%. It is enough if
we can make sure `CHECK(X)` is covered.
To implement this, this is more complicated than I thought. As we already have
ExpansionRegion, but we can't distinguish #include expansion and macro
expansion. So I have to introduce a new MacroExpansionRegion type.
This enables the new
--ignore-branch-in-macro flag to filter out branches inside macro expansions
(e.g. CHECK, ASSERT, VERIFY macros) from branch coverage statistics while
preserving branches from #include'd files.
Changes:
- Add MacroExpansionRegion (Type=6) to CoverageMapping
- Clang CodeGen emits MacroExpansionRegion for macro expansions
- llvm-cov: add --ignore-branch-in-macro to show/report/export subcommands
- Filter branches by FileID matching in branch counting logic
- Apply to LCOV/JSON exporters, summary info, and report views
- Update existing coverage mapping tests for new region type
- Add new tests for macro vs #include branch filtering
AI assisted.
>From 5f8d4c62b56b7e2938f2fdc7cbf3b4e2556f6c2d Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <[email protected]>
Date: Wed, 17 Jun 2026 10:28:33 +0800
Subject: [PATCH] [Coverage] Add MacroExpansionRegion and
--ignore-branch-in-macro
Motivation: there are some macro likes:
```C++
```
Then the branch coverage for such cases may always under 50%. It is enough
if we can make sure `CHECK(X)` is covered.
To implement this, this is more complicated than I thought. As we already
have ExpansionRegion, but we can't distinguish #include expansion and
macro expansion. So I have to introduce a new MacroExpansionRegion type.
This enables the new
--ignore-branch-in-macro flag to filter out branches inside macro
expansions (e.g. CHECK, ASSERT, VERIFY macros) from branch coverage
statistics while preserving branches from #include'd files.
Changes:
- Add MacroExpansionRegion (Type=6) to CoverageMapping
- Clang CodeGen emits MacroExpansionRegion for macro expansions
- llvm-cov: add --ignore-branch-in-macro to show/report/export subcommands
- Filter branches by FileID matching in branch counting logic
- Apply to LCOV/JSON exporters, summary info, and report views
- Update existing coverage mapping tests for new region type
- Add new tests for macro vs #include branch filtering
AI assisted.
---
clang/lib/CodeGen/CoverageMappingGen.cpp | 8 +-
clang/test/CoverageMapping/comment-in-macro.c | 4 +-
.../test/CoverageMapping/control-flow-macro.c | 4 +-
clang/test/CoverageMapping/if.cpp | 8 +-
clang/test/CoverageMapping/label.cpp | 2 +-
clang/test/CoverageMapping/loopmacro.c | 16 +--
.../CoverageMapping/macro-expansion-kind.c | 22 ++++
clang/test/CoverageMapping/macro-expansion.c | 2 +-
.../CoverageMapping/macro-expressions.cpp | 34 +++---
clang/test/CoverageMapping/macroception.c | 24 ++--
clang/test/CoverageMapping/macroparams.c | 4 +-
clang/test/CoverageMapping/macroparams2.c | 2 +-
clang/test/CoverageMapping/macros.c | 22 ++--
clang/test/CoverageMapping/macroscopes.cpp | 30 ++---
.../test/CoverageMapping/mcdc-scratch-space.c | 12 +-
.../CoverageMapping/mcdc-system-headers.cpp | 8 +-
clang/test/CoverageMapping/moremacros.c | 8 +-
clang/test/CoverageMapping/switchmacro.c | 6 +-
clang/test/CoverageMapping/system_macro.cpp | 4 +-
clang/test/CoverageMapping/trymacro.cpp | 6 +-
.../test/CoverageMapping/unreachable-macro.c | 2 +-
compiler-rt/include/profile/InstrProfData.inc | 2 +-
.../ProfileData/Coverage/CoverageMapping.h | 37 +++++-
.../Coverage/CoverageMappingReader.h | 14 ++-
.../llvm/ProfileData/InstrProfData.inc | 2 +-
.../ProfileData/Coverage/CoverageMapping.cpp | 8 +-
.../Coverage/CoverageMappingReader.cpp | 37 ++++--
.../Coverage/CoverageMappingWriter.cpp | 20 +--
.../tools/llvm-cov/Inputs/macro-filter-test.c | 24 ++++
.../tools/llvm-cov/Inputs/macro-filter-test.o | Bin 0 -> 3664 bytes
.../Inputs/macro-filter-test.proftext | 19 +++
.../tools/llvm-cov/Inputs/macro-vs-include.c | 34 ++++++
.../tools/llvm-cov/Inputs/macro-vs-include.o | Bin 0 -> 4760 bytes
.../llvm-cov/Inputs/macro-vs-include.proftext | 28 +++++
.../llvm-cov/macro-expansion-filter.test | 49 ++++++++
.../test/tools/llvm-cov/macro-vs-include.test | 38 ++++++
llvm/tools/llvm-cov/CodeCoverage.cpp | 40 +++++-
llvm/tools/llvm-cov/CoverageExporterJson.cpp | 30 +++--
llvm/tools/llvm-cov/CoverageExporterLcov.cpp | 57 +++++----
llvm/tools/llvm-cov/CoverageReport.cpp | 6 +-
llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 15 ++-
llvm/tools/llvm-cov/CoverageSummaryInfo.h | 3 +-
llvm/tools/llvm-cov/CoverageViewOptions.h | 2 +
.../ProfileData/CoverageMappingTest.cpp | 114 ++++++++++++++++++
44 files changed, 629 insertions(+), 178 deletions(-)
create mode 100644 clang/test/CoverageMapping/macro-expansion-kind.c
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-filter-test.c
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-filter-test.o
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-filter-test.proftext
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-vs-include.c
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-vs-include.o
create mode 100644 llvm/test/tools/llvm-cov/Inputs/macro-vs-include.proftext
create mode 100644 llvm/test/tools/llvm-cov/macro-expansion-filter.test
create mode 100644 llvm/test/tools/llvm-cov/macro-vs-include.test
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp
b/clang/lib/CodeGen/CoverageMappingGen.cpp
index c90afacbde293..739350d048ac9 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -604,7 +604,8 @@ class CoverageMappingBuilder {
assert(SR.isInSourceOrder() && "region start and end out of order");
MappingRegions.push_back(CounterMappingRegion::makeExpansion(
*ParentFileID, *ExpandedFileID, SR.LineStart, SR.ColumnStart,
- SR.LineEnd, SR.ColumnEnd));
+ SR.LineEnd, SR.ColumnEnd,
+ /*IsMacro=*/ExpandedLoc.isMacroID()));
}
return Filter;
}
@@ -2446,6 +2447,9 @@ static void dump(llvm::raw_ostream &OS, StringRef
FunctionName,
case CounterMappingRegion::ExpansionRegion:
OS << "Expansion,";
break;
+ case CounterMappingRegion::MacroExpansionRegion:
+ OS << "MacroExpansion,";
+ break;
case CounterMappingRegion::SkippedRegion:
OS << "Skipped,";
break;
@@ -2484,7 +2488,7 @@ static void dump(llvm::raw_ostream &OS, StringRef
FunctionName,
OS << "," << BranchParams->Conds[false] + 1 << "] ";
}
- if (R.Kind == CounterMappingRegion::ExpansionRegion)
+ if (R.isExpansion())
OS << " (Expanded file = " << R.ExpandedFileID << ")";
OS << "\n";
}
diff --git a/clang/test/CoverageMapping/comment-in-macro.c
b/clang/test/CoverageMapping/comment-in-macro.c
index 1afde46f1e4a5..9a05edfcfe402 100644
--- a/clang/test/CoverageMapping/comment-in-macro.c
+++ b/clang/test/CoverageMapping/comment-in-macro.c
@@ -4,8 +4,8 @@
#define x2 return 0
// CHECK: main
int main(void) { // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE+3]]:2 = #0
- x1; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:5 =
#0
- x2; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:5 =
#0
+ x1; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:3 ->
[[@LINE]]:5 = #0
+ x2; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:3 ->
[[@LINE]]:5 = #0
}
// CHECK-NEXT: File 1, 3:12 -> 3:14 = #0
// CHECK-NEXT: File 2, 4:12 -> 4:20 = #0
diff --git a/clang/test/CoverageMapping/control-flow-macro.c
b/clang/test/CoverageMapping/control-flow-macro.c
index b73ac989057db..f78dad28348d4 100644
--- a/clang/test/CoverageMapping/control-flow-macro.c
+++ b/clang/test/CoverageMapping/control-flow-macro.c
@@ -5,9 +5,9 @@
// CHECK: main
// CHECK-NEXT: File 0, {{[0-9]+}}:40 -> [[END:[0-9]+]]:2 = #0
int main(int argc, const char *argv[]) {
- // CHECK: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:6 = #0
+ // CHECK: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:6 = #0
ifc(1) return 0;
- // Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = (#0 - #1)
+ // MacroExpansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = (#0 - #1)
// File 0, [[@LINE+1]]:6 -> [[END]]:2 = (#0 - #1)
ifc(1) return 0;
return 0;
diff --git a/clang/test/CoverageMapping/if.cpp
b/clang/test/CoverageMapping/if.cpp
index b6fd525e930f9..73d5e8176f19e 100644
--- a/clang/test/CoverageMapping/if.cpp
+++ b/clang/test/CoverageMapping/if.cpp
@@ -121,8 +121,8 @@ int check_constexpr_init_with_if_def(int i) { //
CHECK-NEXT: [[@LINE]]:{{[0-9]
// CHECK-LABEL: _Z32check_macro_constexpr_if_skippedi:
int check_macro_constexpr_if_skipped(int i) { // CHECK-NEXT:
[[@LINE]]:{{[0-9]+}} -> {{[0-9]+}}:2 = #0
-#define IF_CONSTEXPR if constexpr // CHECK-NEXT: Expansion,File
0, [[@LINE+1]]:3 -> [[@LINE+1]]:15 = #0 (Expanded file = 1)
- IF_CONSTEXPR(false) { // CHECK-NEXT: Skipped,File 0,
[[@LINE]]:3 -> [[@LINE+2]]:4 = 0
+#define IF_CONSTEXPR if constexpr // CHECK-NEXT: Skipped,File 0,
[[@LINE+1]]:3 -> [[@LINE+3]]:4 = 0
+ IF_CONSTEXPR(false) { // CHECK-NEXT:
MacroExpansion,File 0, [[@LINE]]:3 -> [[@LINE]]:15 = #0 (Expanded file = 1)
i *= 2; // CHECK-NEXT: File 1,
[[@LINE-2]]:22 -> [[@LINE-2]]:34 = #0
}
return i;
@@ -227,8 +227,8 @@ constexpr int check_notconsteval_branch_kept(int i) { //
CHECK-NEXT: [[@LINE]]:{
// CHECK-LABEL: _Z32check_macro_consteval_if_skippedi:
constexpr int check_macro_consteval_if_skipped(int i) { // CHECK-NEXT:
[[@LINE]]:{{[0-9]+}} -> {{[0-9]+}}:2 = #0
-#define IF_RUNTIME if !consteval // CHECK-NEXT: Expansion,File
0, [[@LINE+1]]:3 -> [[@LINE+1]]:13 = #0 (Expanded file = 1)
- IF_RUNTIME { // CHECK-NEXT: Skipped,File 0,
[[@LINE]]:3 -> [[@LINE]]:14 = 0
+#define IF_RUNTIME if !consteval // CHECK-NEXT: Skipped,File 0,
[[@LINE+1]]:3 -> [[@LINE+1]]:14 = 0
+ IF_RUNTIME { // CHECK-NEXT:
MacroExpansion,File 0, [[@LINE]]:3 -> [[@LINE]]:13 = #0 (Expanded file = 1)
i *= 2; // CHECK-NEXT: File 0,
[[@LINE-1]]:14 -> [[@LINE+1]]:4 = #0
} // CHECK-NEXT: File 1,
[[@LINE-3]]:20 -> [[@LINE-3]]:33 = #0
return i;
diff --git a/clang/test/CoverageMapping/label.cpp
b/clang/test/CoverageMapping/label.cpp
index cf7cbe5d00f43..7bbe27253c509 100644
--- a/clang/test/CoverageMapping/label.cpp
+++ b/clang/test/CoverageMapping/label.cpp
@@ -54,7 +54,7 @@ void test2(int x) { // CHECK-NEXT: File 0,
[[@LINE]]:19 -> {{[0-9]+}}:2
void test3() {
if (0)
goto b; // CHECK: Gap,File 0, [[@LINE]]:12 -> [[@LINE+1]]:1 = (#0 - #1)
-a: // CHECK-NEXT: Expansion,File 0, [[@LINE]]:1 -> [[@LINE]]:2 =
[[retnCount:#[0-9]+]] (Expanded file = 1)
+a: // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:1 -> [[@LINE]]:2 =
[[retnCount:#[0-9]+]] (Expanded file = 1)
return; // CHECK-NEXT: File 0, [[@LINE-1]]:2 -> [[@LINE]]:9 = [[retnCount]]
}
#undef a
diff --git a/clang/test/CoverageMapping/loopmacro.c
b/clang/test/CoverageMapping/loopmacro.c
index 1fbb1139abf04..fc03bf8e3bb1a 100644
--- a/clang/test/CoverageMapping/loopmacro.c
+++ b/clang/test/CoverageMapping/loopmacro.c
@@ -3,27 +3,27 @@
// CHECK: main
// CHECK-NEXT: File 0, {{[0-9]+}}:16 -> {{[0-9]+}}:2 = #0
// CHECK-NEXT: File 0, {{[0-9]+}}:6 -> {{[0-9]+}}:4 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 0, {{[0-9]+}}:7 -> {{[0-9]+}}:20 = (#0 + #1)
+// CHECK-NEXT: MacroExpansion,File 0, {{[0-9]+}}:7 -> {{[0-9]+}}:20 = (#0 + #1)
// CHECK-NEXT: File 0, {{[0-9]+}}:12 -> {{[0-9]+}}:30 = (#0 + #1)
// CHECK-NEXT: Branch,File 0, {{[0-9]+}}:12 -> {{[0-9]+}}:30 = #1, #0
// CHECK-NEXT: File 1, [[@LINE+4]]:4 -> [[@LINE+6]]:23 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 1, [[@LINE+3]]:5 -> [[@LINE+3]]:16 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 1, [[@LINE+3]]:16 -> [[@LINE+3]]:21 = (#0 + #1)
+// CHECK-NEXT: MacroExpansion,File 1, [[@LINE+3]]:5 -> [[@LINE+3]]:16 = (#0 +
#1)
+// CHECK-NEXT: MacroExpansion,File 1, [[@LINE+3]]:16 -> [[@LINE+3]]:21 = (#0 +
#1)
#define INSERT_STRING(s, match_head) \
(UPDATE_HASH(ins_h, window[(s) + MIN_MATCH-1]), \
prev[(s) & WMASK] = match_head = head[ins_h], \
head[ins_h] = (s))
// CHECK-NEXT: File 2, [[@LINE+3]]:26 -> [[@LINE+3]]:66 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 2, [[@LINE+2]]:38 -> [[@LINE+2]]:45 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 2, [[@LINE+1]]:56 -> [[@LINE+1]]:65 = (#0 + #1)
+// CHECK-NEXT: MacroExpansion,File 2, [[@LINE+2]]:38 -> [[@LINE+2]]:45 = (#0 +
#1)
+// CHECK-NEXT: MacroExpansion,File 2, [[@LINE+1]]:56 -> [[@LINE+1]]:65 = (#0 +
#1)
#define UPDATE_HASH(h,c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
// CHECK-NEXT: File 3, [[@LINE+1]]:15 -> [[@LINE+1]]:21 = (#0 + #1)
#define WMASK 0xFFFF
// CHECK-NEXT: File 4, [[@LINE+4]]:18 -> [[@LINE+4]]:53 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:29 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 4, [[@LINE+2]]:30 -> [[@LINE+2]]:39 = (#0 + #1)
-// CHECK-NEXT: Expansion,File 4, [[@LINE+1]]:43 -> [[@LINE+1]]:52 = (#0 + #1)
+// CHECK-NEXT: MacroExpansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:29 = (#0 +
#1)
+// CHECK-NEXT: MacroExpansion,File 4, [[@LINE+2]]:30 -> [[@LINE+2]]:39 = (#0 +
#1)
+// CHECK-NEXT: MacroExpansion,File 4, [[@LINE+1]]:43 -> [[@LINE+1]]:52 = (#0 +
#1)
#define H_SHIFT ((HASH_BITS+MIN_MATCH-1)/MIN_MATCH)
// CHECK-NEXT: File 5, [[@LINE+1]]:19 -> [[@LINE+1]]:25 = (#0 + #1)
#define HASH_MASK 0xFFFF
diff --git a/clang/test/CoverageMapping/macro-expansion-kind.c
b/clang/test/CoverageMapping/macro-expansion-kind.c
new file mode 100644
index 0000000000000..ee229df353e11
--- /dev/null
+++ b/clang/test/CoverageMapping/macro-expansion-kind.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false
-fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping
-emit-llvm-only -main-file-name macro-expansion-kind.c %s | FileCheck %s
+
+// Test that macro expansions are marked as MacroExpansion in the coverage
+// mapping dump, distinguishing them from regular Expansion regions (#include).
+
+#define SIMPLE_MACRO(x) ((x) > 0 ? (x) : 0)
+
+// CHECK-LABEL: test_func:
+// CHECK: File 0, [[@LINE+1]]:22 -> [[@LINE+13]]:2 = #0
+void test_func(void) {
+ // CHECK: MacroExpansion,File 0, [[@LINE+1]]:16 -> [[@LINE+1]]:28
+ int result = SIMPLE_MACRO(42);
+
+ // CHECK: MacroExpansion,File 0, [[@LINE+1]]:13 -> [[@LINE+1]]:25
+ int val = SIMPLE_MACRO(1);
+
+ // CHECK: File 1,
+ int x = 0;
+ (void)result;
+ (void)val;
+ (void)x;
+}
diff --git a/clang/test/CoverageMapping/macro-expansion.c
b/clang/test/CoverageMapping/macro-expansion.c
index 4cd2c93437193..88022045ceadb 100644
--- a/clang/test/CoverageMapping/macro-expansion.c
+++ b/clang/test/CoverageMapping/macro-expansion.c
@@ -24,7 +24,7 @@
#define M2(x) do { if (x) {} } while (0)
// CHECK-NEXT: File 4, [[@LINE+5]]:15 -> [[@LINE+5]]:38 = #0
// CHECK-NEXT: File 4, [[@LINE+4]]:18 -> [[@LINE+4]]:28 = (#0 + #8)
-// CHECK-NEXT: Expansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:22 = (#0 + #8)
+// CHECK-NEXT: MacroExpansion,File 4, [[@LINE+3]]:20 -> [[@LINE+3]]:22 = (#0 +
#8)
// CHECK-NEXT: File 4, [[@LINE+2]]:36 -> [[@LINE+2]]:37 = (#0 + #8)
// CHECK-NEXT: Branch,File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = 0, #0
#define M3(x) do { M2(x); } while (0)
diff --git a/clang/test/CoverageMapping/macro-expressions.cpp
b/clang/test/CoverageMapping/macro-expressions.cpp
index 2b6a1b64c2594..3d31c237dfe42 100644
--- a/clang/test/CoverageMapping/macro-expressions.cpp
+++ b/clang/test/CoverageMapping/macro-expressions.cpp
@@ -58,33 +58,33 @@ void foo(int i) {
// CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:12 = #1
if (0) {}
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:11 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:11 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:16 = #2
// CHECK-NEXT: File 0, [[@LINE+1]]:16 -> [[@LINE+1]]:18 = #2
if (EXPR(i)) {}
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:9 -> [[@LINE+3]]:14 = (#0 + #3)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:9 -> [[@LINE+3]]:14 = (#0
+ #3)
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:20 = #3
// CHECK-NEXT: File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:22 = #3
for (;NEXPR(i);) {}
- // CHECK-NEXT: Expansion,File 0, [[@LINE+5]]:8 -> [[@LINE+5]]:14 = #0
- // CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:33 -> [[@LINE+4]]:35 = (#0 + #4)
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:43 -> [[@LINE+3]]:46 = #4
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+5]]:8 -> [[@LINE+5]]:14 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+4]]:33 -> [[@LINE+4]]:35 = (#0
+ #4)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:43 -> [[@LINE+3]]:46 = #4
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:50 -> [[@LINE+2]]:51 = #4
// CHECK: File 0, [[@LINE+1]]:51 -> [[@LINE+1]]:53 = #4
for (ASSIGN(DECL(int, j), 0); LT(j, i); INC(j)) {}
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:9 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:9 = #0
ASSIGN(DECL(int, k), 0);
- // CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:10 -> [[@LINE+4]]:12 = (#0 + #5)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+4]]:10 -> [[@LINE+4]]:12 = (#0
+ #5)
// CHECK-NEXT: Gap,File 0, [[@LINE+3]]:19 -> [[@LINE+3]]:20 = #5
// CHECK-NEXT: File 0, [[@LINE+2]]:20 -> [[@LINE+2]]:31 = #5
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:22 -> [[@LINE+1]]:25 = #5
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:22 -> [[@LINE+1]]:25 = #5
while (LT(k, i)) { INC(k); }
// CHECK-NEXT: File 0, [[@LINE+2]]:6 -> [[@LINE+2]]:8 = (#0 + #6)
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:16 -> [[@LINE+1]]:21 = (#0 + #6)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:16 -> [[@LINE+1]]:21 = (#0
+ #6)
do {} while (NEXPR(i));
- // CHECK-NEXT: Expansion,File 0, [[@LINE+5]]:8 -> [[@LINE+5]]:12 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+5]]:8 -> [[@LINE+5]]:12 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE+4]]:21 -> [[@LINE+4]]:22 = #7, #0
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:23 -> [[@LINE+3]]:26 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:23 -> [[@LINE+3]]:26 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:41 -> [[@LINE+2]]:42 = #7
// CHECK: File 0, [[@LINE+1]]:42 -> [[@LINE+1]]:44 = #7
for (DECL(int, j) : ARR(int, 1, 2, 3)) {}
@@ -92,21 +92,21 @@ void foo(int i) {
// CHECK-NEXT: File 0, [[@LINE+5]]:10 -> [[@LINE+5]]:11 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE+4]]:10 -> [[@LINE+4]]:11 = #8, (#0 -
#8)
// CHECK-NEXT: Gap,File 0, [[@LINE+3]]:13 -> [[@LINE+3]]:14 = #8
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #0
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:23 -> [[@LINE+1]]:29 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:23 -> [[@LINE+1]]:29 = #0
(void)(i ? PRIo64 : PRIu64);
// CHECK-NEXT: File 0, [[@LINE+6]]:10 -> [[@LINE+6]]:11 = #0
// CHECK: File 0, [[@LINE+5]]:14 -> [[@LINE+5]]:15 = #9
// CHECK-NEXT: File 0, [[@LINE+4]]:18 -> [[@LINE+4]]:33 = (#0 - #9)
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:22 = (#0 - #9)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:22 = (#0
- #9)
// CHECK: File 0, [[@LINE+2]]:28 -> [[@LINE+2]]:29 = #10
// CHECK-NEXT: File 0, [[@LINE+1]]:32 -> [[@LINE+1]]:33 = ((#0 - #9) - #10)
(void)(i ? i : EXPR(i) ? i : 0);
// CHECK-NEXT: File 0, [[@LINE+5]]:10 -> [[@LINE+5]]:11 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE+4]]:10 -> [[@LINE+4]]:11 = #11, (#0 -
#11)
// CHECK-NEXT: File 0, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = (#0 - #11)
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = (#0 -
#11)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:15 -> [[@LINE+2]]:19 = (#0
- #11)
// CHECK-NEXT: File 0, [[@LINE+1]]:26 -> [[@LINE+1]]:27 = ((#0 - #11) - #12)
(void)(i ?: EXPR(i) ?: 0);
}
@@ -128,10 +128,10 @@ void foo(int i) {
// CHECK-NEXT: File {{[0-9]+}}, 5:20 -> 5:23 = #0
// CHECK-NEXT: File {{[0-9]+}}, 9:25 -> 9:40 = #0
// CHECK-NEXT: File {{[0-9]+}}, 12:16 -> 12:42 = #0
-// CHECK-NEXT: Expansion,File {{[0-9]+}}, 12:16 -> 12:38 = #8
+// CHECK-NEXT: MacroExpansion,File {{[0-9]+}}, 12:16 -> 12:38 = #8
// CHECK-NEXT: File {{[0-9]+}}, 12:38 -> 12:42 = #8
// CHECK-NEXT: File {{[0-9]+}}, 13:16 -> 13:42 = #0
-// CHECK-NEXT: Expansion,File {{[0-9]+}}, 13:16 -> 13:38 = (#0 - #8)
+// CHECK-NEXT: MacroExpansion,File {{[0-9]+}}, 13:16 -> 13:38 = (#0 - #8)
// CHECK-NEXT: File {{[0-9]+}}, 13:38 -> 13:42 = (#0 - #8)
// CHECK-NEXT: File {{[0-9]+}}, 3:17 -> 3:20 = (#0 - #9)
// CHECK-NEXT: Branch,File {{[0-9]+}}, 3:17 -> 3:20 = #10, ((#0 - #9) - #10)
diff --git a/clang/test/CoverageMapping/macroception.c
b/clang/test/CoverageMapping/macroception.c
index 6d4b3ed427f7f..4ad23bed7f182 100644
--- a/clang/test/CoverageMapping/macroception.c
+++ b/clang/test/CoverageMapping/macroception.c
@@ -6,41 +6,41 @@
#define M11 M22
// CHECK-LABEL: main:
-// CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:16 -> [[@LINE+2]]:18 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:16 -> [[@LINE+2]]:18 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+3]]:2 = #0
int main(void) M1
return 0;
}
-// CHECK-NEXT: Expansion,File 1, 4:12 -> 4:14 = #0
+// CHECK-NEXT: MacroExpansion,File 1, 4:12 -> 4:14 = #0
// CHECK-NEXT: File 2, 3:12 -> 3:13 = #0
// CHECK-LABEL: func2:
// CHECK-NEXT: File 0, [[@LINE+2]]:18 -> [[@LINE+4]]:4 = #0
-// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
void func2(void) {
int x = 0;
M11
-// CHECK-NEXT: Expansion,File 1, 6:13 -> 6:16 = #0
+// CHECK-NEXT: MacroExpansion,File 1, 6:13 -> 6:16 = #0
// CHECK-NEXT: File 2, 5:13 -> 5:14 = #0
// CHECK-LABEL: func3:
-// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:20 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:20 = #0
// CHECK-NEXT: File 0, [[@LINE+2]]:20 -> [[@LINE+4]]:4 = #0
-// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
void func3(void) M1
int x = 0;
M11
-// CHECK-NEXT: Expansion,File 1, 4:12 -> 4:14 = #0
-// CHECK-NEXT: Expansion,File 2, 6:13 -> 6:16 = #0
+// CHECK-NEXT: MacroExpansion,File 1, 4:12 -> 4:14 = #0
+// CHECK-NEXT: MacroExpansion,File 2, 6:13 -> 6:16 = #0
// CHECK-NEXT: File 3, 3:12 -> 3:13 = #0
// CHECK-NEXT: File 4, 5:13 -> 5:14 = #0
// CHECK-LABEL: func4:
-// CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:20 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:18 -> [[@LINE+3]]:20 = #0
// CHECK-NEXT: File 0, [[@LINE+2]]:20 -> [[@LINE+2]]:24 = #0
-// CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:21 -> [[@LINE+1]]:24 = #0
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:21 -> [[@LINE+1]]:24 = #0
void func4(void) M1 M11
-// CHECK-NEXT: Expansion,File 1, 4:12 -> 4:14 = #0
-// CHECK-NEXT: Expansion,File 2, 6:13 -> 6:16 = #0
+// CHECK-NEXT: MacroExpansion,File 1, 4:12 -> 4:14 = #0
+// CHECK-NEXT: MacroExpansion,File 2, 6:13 -> 6:16 = #0
// CHECK-NEXT: File 3, 3:12 -> 3:13 = #0
// CHECK-NEXT: File 4, 5:13 -> 5:14 = #0
diff --git a/clang/test/CoverageMapping/macroparams.c
b/clang/test/CoverageMapping/macroparams.c
index 2f60cffbfdb77..282ece3644123 100644
--- a/clang/test/CoverageMapping/macroparams.c
+++ b/clang/test/CoverageMapping/macroparams.c
@@ -2,10 +2,10 @@
// CHECK: main
// CHECK-NEXT: File 0, {{[0-9]+}}:16 -> {{[0-9]+}}:2 = #0
-// CHECK-NEXT: Expansion,File 0, {{[0-9]+}}:3 -> {{[0-9]+}}:8 = #0
+// CHECK-NEXT: MacroExpansion,File 0, {{[0-9]+}}:3 -> {{[0-9]+}}:8 = #0
// CHECK-NEXT: File 1, [[@LINE+2]]:18 -> [[@LINE+2]]:27 = #0
-// CHECK-NEXT: Expansion,File 1, [[@LINE+1]]:18 -> [[@LINE+1]]:24 = #0
+// CHECK-NEXT: MacroExpansion,File 1, [[@LINE+1]]:18 -> [[@LINE+1]]:24 = #0
#define MACRO(X) MACRO2(x)
// CHECK-NEXT: File 2, [[@LINE+1]]:20 -> [[@LINE+1]]:28 = #0
#define MACRO2(X2) (X2 + 2)
diff --git a/clang/test/CoverageMapping/macroparams2.c
b/clang/test/CoverageMapping/macroparams2.c
index 7873b6ac12a9a..516516b4c4aa9 100644
--- a/clang/test/CoverageMapping/macroparams2.c
+++ b/clang/test/CoverageMapping/macroparams2.c
@@ -10,7 +10,7 @@ struct S {
int main(void) {
struct S arr[32] = { 0 };
int n = 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:33 -> [[@LINE+2]]:34 = #1
// CHECK-NEXT: File 0, [[@LINE+1]]:34 -> [[@LINE+3]]:4 = #1
if (MACRO(arr[n].j, arr[n].i)) {
diff --git a/clang/test/CoverageMapping/macros.c
b/clang/test/CoverageMapping/macros.c
index 00139f33229d5..f070de7a0ea25 100644
--- a/clang/test/CoverageMapping/macros.c
+++ b/clang/test/CoverageMapping/macros.c
@@ -11,7 +11,7 @@ void bar(void) {}
// CHECK: func
void func(void) { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+5]]:2 = #0
int i = 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #0
MACRO; // CHECK-NEXT: File 0, [[@LINE]]:8 -> [[@LINE+2]]:2 = 0
i = 2;
}
@@ -21,18 +21,18 @@ void func(void) { // CHECK-NEXT: File 0, [[@LINE]]:17 ->
[[@LINE+5]]:2 = #0
// CHECK-NEXT: func2
void func2(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+5]]:2 = #0
int i = 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:10 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:10 = #0
MACRO_1; // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:2 = 0
i = 2;
}
// CHECK-NEXT: File 1, 5:17 -> 5:32 = #0
-// CHECK-NEXT: Expansion,File 1, 5:25 -> 5:32 = 0
+// CHECK-NEXT: MacroExpansion,File 1, 5:25 -> 5:32 = 0
// CHECK-NEXT: File 2, 4:17 -> 4:22 = 0
// CHECK-NEXT: func3
void func3(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+3]]:2 = #0
- MACRO_2; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:10 = #0
- MACRO_2; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:10 = #0
+ MACRO_2; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:3 -> [[@LINE]]:10 =
#0
+ MACRO_2; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:3 -> [[@LINE]]:10 =
#0
}
// CHECK-NEXT: File 1, 4:17 -> 4:22 = #0
// CHECK-NEXT: File 2, 4:17 -> 4:22 = #0
@@ -45,7 +45,7 @@ void func4(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 ->
[[@LINE+8]]:2 = #0
// CHECK-NEXT: File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:14 = #1
// CHECK-NEXT: Branch,File 0, [[@LINE-2]]:9 -> [[@LINE-2]]:14 =
#2, (#1 - #2)
// CHECK-NEXT: Gap,File 0, [[@LINE-3]]:15 -> [[@LINE+1]]:7 = #2
- MACRO_2; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:7 -> [[@LINE]]:14 =
#2
+ MACRO_2; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:7 ->
[[@LINE]]:14 = #2
}
// CHECK-NEXT: File 1, 4:17 -> 4:22 = #2
// CHECK-NOT: File 1
@@ -56,9 +56,9 @@ void func5(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 ->
[[@LINE+6]]:2 = #0
if (i > 5) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 =
#1, (#0 - #1)
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = #1
- MACRO_3; // CHECK-NEXT: Expansion,File 0, [[@LINE]]:5 -> [[@LINE]]:12 = #1
+ MACRO_3; // CHECK-NEXT: MacroExpansion,File 0, [[@LINE]]:5 -> [[@LINE]]:12
= #1
}
-// CHECK-NEXT: Expansion,File 1, 6:17 -> 6:24 = #1
+// CHECK-NEXT: MacroExpansion,File 1, 6:17 -> 6:24 = #1
// CHECK-NEXT: File 2, 4:17 -> 4:22 = #1
// CHECK-NEXT: func6
@@ -69,7 +69,7 @@ void func6(unsigned count) { // CHECK-NEXT: File 0,
[[@LINE]]:28 -> [[@LINE+6]]:
// CHECK-NEXT: Gap,File 0, [[@LINE-2]]:17 ->
[[@LINE+1]]:9 = #2
GOTO begin; // CHECK-NEXT: File 0, [[@LINE]]:9 ->
[[@LINE]]:19 = #2
}
-// CHECK-NEXT: Expansion,File 0, [[@LINE-2]]:9 -> [[@LINE-2]]:13 = #2
+// CHECK-NEXT: MacroExpansion,File 0, [[@LINE-2]]:9 -> [[@LINE-2]]:13 = #2
// CHECK-NEXT: File 1, 7:14 -> 7:18 = #2
// Regression test for gap region between macros.
@@ -80,10 +80,10 @@ void func7(void) { // CHECK-NEXT: File 0, [[@LINE]]:18 ->
[[@LINE+6]]:2 = #0
int kk,ll; // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:8 = #0
if (k) // CHECK-NEXT: Branch,File 0, [[@LINE]]:7 -> [[@LINE]]:8 =
#1
m(k); // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:9 -> [[@LINE]]:5 = #1
- else // CHECK-NEXT: Expansion,File 0, [[@LINE-1]]:5 ->
[[@LINE-1]]:6 = #0
+ else // CHECK-NEXT: MacroExpansion,File 0, [[@LINE-1]]:5 ->
[[@LINE-1]]:6 = #0
l = m(l); // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:7 -> [[@LINE]]:5 =
(#0 - #1)
} // CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE-1]]:10 =
(#0 - #1)
- // CHECK-NEXT: Expansion,File 0, [[@LINE-2]]:9 ->
[[@LINE-2]]:10 = (#0 - #1)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE-2]]:9 ->
[[@LINE-2]]:10 = (#0 - #1)
// CHECK-NEXT: File 1, [[@LINE-9]]:14 -> [[@LINE-9]]:18 = #0
// CHECK-NEXT: File 1, [[@LINE-10]]:14 -> [[@LINE-10]]:17 =
#1
// CHECK-NEXT: File 2, [[@LINE-11]]:14 -> [[@LINE-11]]:17 =
(#0 - #1)
diff --git a/clang/test/CoverageMapping/macroscopes.cpp
b/clang/test/CoverageMapping/macroscopes.cpp
index 88a72116fa7dc..c7544157710cb 100644
--- a/clang/test/CoverageMapping/macroscopes.cpp
+++ b/clang/test/CoverageMapping/macroscopes.cpp
@@ -37,49 +37,49 @@
// CHECK-NEXT: File 0, [[@LINE+1]]:12 -> {{[0-9]+}}:2 = #0
int main() {
int x = 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:17 = #0
// CHECK-NEXT: File 0, [[@LINE+1]]:17 -> [[@LINE+7]]:15 = #1
starts_a_scope
x = x;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:14 = #1
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:14 = #1
some_code
x = x;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:15 = #1
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:15 = #1
ends_a_scope
- // CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:3 -> [[@LINE+4]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+4]]:3 -> [[@LINE+4]]:17 = #0
// CHECK-NEXT: File 0, [[@LINE+3]]:17 -> [[@LINE+5]]:15 = #4
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:5 -> [[@LINE+3]]:14 = #4
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:15 = #4
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:5 -> [[@LINE+3]]:14 = #4
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:15 = #4
starts_a_scope
some_code
ends_a_scope
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:17 = #0
// CHECK-NEXT: File 0, [[@LINE+2]]:17 -> [[@LINE+3]]:15 = #7
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:15 = #7
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:15 = #7
starts_a_scope
ends_a_scope
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:17 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+2]]:17 -> [[@LINE+3]]:5 = #8
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:16 = #8
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:16 = #8
starts_a_while
simple_stmt;
x = 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+5]]:3 -> [[@LINE+5]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+5]]:3 -> [[@LINE+5]]:17 = #0
// CHECK-NEXT: Gap,File 0, [[@LINE+4]]:17 -> [[@LINE+4]]:18 = #9
// CHECK-NEXT: File 0, [[@LINE+3]]:18 -> [[@LINE+5]]:15 = #9
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:5 -> [[@LINE+3]]:16 = #9
- // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:15 = #9
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:5 -> [[@LINE+3]]:16 = #9
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+3]]:3 -> [[@LINE+3]]:15 = #9
starts_a_while {
simple_stmt;
ends_a_scope
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:17 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:17 = #0
macro_with_for
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:19 = #0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:19 = #0
macro_with_while
return 0;
diff --git a/clang/test/CoverageMapping/mcdc-scratch-space.c
b/clang/test/CoverageMapping/mcdc-scratch-space.c
index 60e456948a518..0229f79a49c3e 100644
--- a/clang/test/CoverageMapping/mcdc-scratch-space.c
+++ b/clang/test/CoverageMapping/mcdc-scratch-space.c
@@ -19,7 +19,7 @@ int builtin_macro1(int a) {
// CHECK: pre0:
int pre0(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+3]]:20 = M:3, C:2
- // CHECK: Expansion,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:14 = #0 (Expanded
file = 1)
+ // CHECK: MacroExpansion,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:14 = #0
(Expanded file = 1)
return (PRE(a)
&& b_post);
// CHECK: Branch,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:20 = #2, (#1 - #2)
[2,0,0]
@@ -31,11 +31,11 @@ int pre0(int pre_a, int b_post) {
// CHECK: pre1:
int pre1(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:20 = M:3, C:2
- // CHECK: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:14 = #0 (Expanded
file = 1)
+ // CHECK: MacroExpansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:14 = #0
(Expanded file = 1)
// CHECK: Branch,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:20 = #2, (#1 - #2)
[2,0,0]
return (PRE(foo)
&& b_post);
- // CHECK: Expansion,File 1, 17:16 -> 17:20 = #0 (Expanded file = 2)
+ // CHECK: MacroExpansion,File 1, 17:16 -> 17:20 = #0 (Expanded file = 2)
// CHECK: Branch,File 2, 29:17 -> 29:22 = #1, (#0 - #1) [1,2,0]
}
@@ -47,7 +47,7 @@ int post0(int pre_a, int b_post) {
// CHECK: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:16 = (#0 - #1), #1
[1,0,2]
return (pre_a
|| POST(b));
- // CHECK: Expansion,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:18 = #1 (Expanded
file = 1)
+ // CHECK: MacroExpansion,File 0, [[@LINE-1]]:14 -> [[@LINE-1]]:18 = #1
(Expanded file = 1)
// CHECK: Branch,File 1, [[@LINE-9]]:17 -> [[@LINE-9]]:20 = (#1 - #2), #2
[2,0,0]
}
@@ -57,9 +57,9 @@ int post0(int pre_a, int b_post) {
int post1(int pre_a, int b_post) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+4]]:18 = M:3, C:2
// CHECK: Branch,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = (#0 - #1), #1
[1,0,2]
- // CHECK: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:18 = 0 (Expanded
file = 1)
+ // CHECK: MacroExpansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:18 = 0
(Expanded file = 1)
return (pre_a
|| POST(bar));
- // CHECK: Expansion,File 1, 42:17 -> 42:18 = #1 (Expanded file = 2)
+ // CHECK: MacroExpansion,File 1, 42:17 -> 42:18 = #1 (Expanded file = 2)
// CHECK: Branch,File 2, 54:18 -> 54:24 = (#1 - #2), #2 [2,0,0]
}
diff --git a/clang/test/CoverageMapping/mcdc-system-headers.cpp
b/clang/test/CoverageMapping/mcdc-system-headers.cpp
index cb1c8743c36e8..379550387f5db 100644
--- a/clang/test/CoverageMapping/mcdc-system-headers.cpp
+++ b/clang/test/CoverageMapping/mcdc-system-headers.cpp
@@ -16,7 +16,7 @@
// CHECK: _Z5func0i:
int func0(int a) {
// CHECK: Decision,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:21 = M:3, C:2
- // W_SYS: Expansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = #0 (Expanded
file = 1)
+ // W_SYS: MacroExpansion,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:16 = #0
(Expanded file = 1)
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = #1, 0 [1,2,0]
return (CONST && a);
// CHECK: Branch,File 0, [[@LINE-1]]:20 -> [[@LINE-1]]:21 = #2, (#1 - #2)
[2,0,0]
@@ -28,7 +28,7 @@ int func1(int a, int b) {
// CHECK: Decision,File 0, [[@LINE+2]]:11 -> [[@LINE+2]]:21 = M:3, C:2
// CHECK: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:12 = (#0 - #1), #1
[1,0,2]
return (a || EXPR1(b));
- // W_SYS: Expansion,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:21 = #1 (Expanded
file = 1)
+ // W_SYS: MacroExpansion,File 0, [[@LINE-1]]:16 -> [[@LINE-1]]:21 = #1
(Expanded file = 1)
// W_SYS: Branch,File 1, [[@LINE-24]]:18 -> [[@LINE-24]]:21 = (#1 - #2), #2
[2,0,0]
// X_SYS: Branch,File 0, [[@LINE-3]]:16 -> [[@LINE-3]]:16 = (#1 - #2), #2
[2,0,0]
}
@@ -37,8 +37,8 @@ int func1(int a, int b) {
int func2(int a, int b) {
// W_SYS: Decision,File 0, [[@LINE+5]]:11 -> [[@LINE+5]]:28 = M:4, C:3
// X_SYS: Decision,File 0, [[@LINE+4]]:11 -> [[@LINE+4]]:28 = M:3, C:2
- // W_SYS: Expansion,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:16 = #0 (Expanded
file = 1)
- // W_SYS: Expansion,File 0, [[@LINE+2]]:23 -> [[@LINE+2]]:28 = #1 (Expanded
file = 2)
+ // W_SYS: MacroExpansion,File 0, [[@LINE+3]]:11 -> [[@LINE+3]]:16 = #0
(Expanded file = 1)
+ // W_SYS: MacroExpansion,File 0, [[@LINE+2]]:23 -> [[@LINE+2]]:28 = #1
(Expanded file = 2)
// X_SYS: Branch,File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:11 = #1, (#0 - #1)
[1,2,0]
return (EXPR2(a) && EXPR1(a));
// W_SYS: Branch,File 1, [[@LINE-35]]:19 -> [[@LINE-35]]:22 = #3, (#0 - #3)
[1,3,0]
diff --git a/clang/test/CoverageMapping/moremacros.c
b/clang/test/CoverageMapping/moremacros.c
index 64e5c62bfac37..8ceadc99b5153 100644
--- a/clang/test/CoverageMapping/moremacros.c
+++ b/clang/test/CoverageMapping/moremacros.c
@@ -12,18 +12,18 @@ int main(int argc, const char *argv[]) {
// CHECK-NEXT: File 0, [[@LINE+5]]:7 -> [[@LINE+5]]:12 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE+4]]:7 -> [[@LINE+4]]:12 = #2, (#0 - #2)
// CHECK-NEXT: Gap,File 0, [[@LINE+3]]:13 -> [[@LINE+3]]:14 = #2
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #2
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #2
// CHECK-NEXT: File 0, [[@LINE+1]]:19 -> [[@LINE+4]]:8 = #2
if (!argc) LBRAC
return 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #2
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #2
RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+8]]:3 = (#0 - #2)
// CHECK-NEXT: File 0, [[@LINE+6]]:3 -> [[@LINE+17]]:2 = (#0 - #2)
// CHECK-NEXT: File 0, [[@LINE+5]]:7 -> [[@LINE+5]]:12 = (#0 - #2)
// CHECK-NEXT: Branch,File 0, [[@LINE+4]]:7 -> [[@LINE+4]]:12 = #3, ((#0 -
#2) - #3)
// CHECK-NEXT: Gap,File 0, [[@LINE+3]]:13 -> [[@LINE+3]]:14 = #3
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #3
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #3
// CHECK-NEXT: File 0, [[@LINE+1]]:19 -> [[@LINE+3]]:4 = #3
if (!argc) LBRAC
return 0;
@@ -34,7 +34,7 @@ int main(int argc, const char *argv[]) {
// CHECK: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
if (!argc) {
return 0;
- // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #4
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #4
RBRAC
}
diff --git a/clang/test/CoverageMapping/switchmacro.c
b/clang/test/CoverageMapping/switchmacro.c
index 4c98cc7d9403a..7e524ba2c8d13 100644
--- a/clang/test/CoverageMapping/switchmacro.c
+++ b/clang/test/CoverageMapping/switchmacro.c
@@ -11,14 +11,14 @@ int foo(int i) { // CHECK-NEXT: File 0, [[@LINE]]:16 ->
{{[0-9]+}}:2 = #0
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15
= #3, (#2 - #3)
return 0; // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
// CHECK-NEXT: File 0, [[@LINE-1]]:16 -> [[@LINE+3]]:5 = (#2
- #3)
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:8 = (#2 -
#3) (Expanded file = 1)
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:8 = (#2
- #3) (Expanded file = 1)
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
FOO(1);
case 0: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:13 = ((#2 +
#4) - #3)
// CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9
= #4, (#0 - #4)
return 2; // CHECK-NEXT: Gap,File 0, [[@LINE]]:14 -> [[@LINE+4]]:3 = 0
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
// CHECK-NEXT: File 0, [[@LINE+1]]:6 -> {{[0-9]+}}:11 = 0
FOO(1);
// CHECK-NEXT: File 0, [[@LINE+1]]:3 -> {{[0-9]+}}:11 = #5
@@ -41,7 +41,7 @@ default: ;
#define START2 switch (0) default:
void baz(void) {
for (;;)
- START2 return; // CHECK: Expansion,File 0, [[@LINE]]:5 -> [[@LINE]]:11 =
#1 (Expanded file = 1)
+ START2 return; // CHECK: MacroExpansion,File 0, [[@LINE]]:5 ->
[[@LINE]]:11 = #1 (Expanded file = 1)
}
int main(int argc, const char *argv[]) {
diff --git a/clang/test/CoverageMapping/system_macro.cpp
b/clang/test/CoverageMapping/system_macro.cpp
index 38bbb2efb7075..3c778b3f1e86d 100644
--- a/clang/test/CoverageMapping/system_macro.cpp
+++ b/clang/test/CoverageMapping/system_macro.cpp
@@ -30,12 +30,12 @@ template <bool f> bool SysTmpl() { return f; }
// CHECK-LABEL: doSomething
void doSomething(int x) { // CHECK: File 0, [[@LINE]]:25 -> {{[0-9:]+}} = #0
// WOSYS-NOT: Expansion,
- // W_SYS: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:7
+ // W_SYS: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:7
Func(x);
// CHECK: Gap,File 0, [[@LINE+1]]:10
return;
// WOSYS-NOT: Expansion,
- // W_SYS: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:11
+ // W_SYS: MacroExpansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:11
SomeType *f; // CHECK: File 0, [[@LINE]]:11 -> {{[0-9:]+}} = 0
}
diff --git a/clang/test/CoverageMapping/trymacro.cpp
b/clang/test/CoverageMapping/trymacro.cpp
index 22de2ccb07769..0c69299ef59b4 100644
--- a/clang/test/CoverageMapping/trymacro.cpp
+++ b/clang/test/CoverageMapping/trymacro.cpp
@@ -19,7 +19,7 @@ CATCH(...) {} // CHECK: [[@LINE]]:12 ->
[[@LINE]]:14 = #2
// CHECK: Z3fn4v:
#define TRY2 try { // CHECK-DAG: File 1, [[@LINE]]:18 -> [[@LINE]]:19 = #1
-void fn4() TRY2 // CHECK-DAG: Expansion,File 0, [[@LINE]]:12 -> [[@LINE]]:16 =
#1 (Expanded file = 1)
+void fn4() TRY2 // CHECK-DAG: MacroExpansion,File 0, [[@LINE]]:12 ->
[[@LINE]]:16 = #1 (Expanded file = 1)
for (;;)
return;
}
@@ -27,10 +27,10 @@ catch (...) {}
// CHECK: Z3fn5v:
#define TRY3 try { return; } catch (...) // CHECK-DAG: File 2, [[@LINE]]:18 ->
[[@LINE]]:29 = #1
-#define TRY4 try { TRY3 { return; } } catch (...) // CHECK-DAG: Expansion,File
1, [[@LINE]]:20 -> [[@LINE]]:24 = #1 (Expanded file = 2)
+#define TRY4 try { TRY3 { return; } } catch (...) // CHECK-DAG:
MacroExpansion,File 1, [[@LINE]]:20 -> [[@LINE]]:24 = #1 (Expanded file = 2)
void fn5() {
for (;;) {
- TRY4 { return; } // CHECK-DAG: Expansion,File 0, [[@LINE]]:5 ->
[[@LINE]]:9 = #1 (Expanded file = 1)
+ TRY4 { return; } // CHECK-DAG: MacroExpansion,File 0, [[@LINE]]:5 ->
[[@LINE]]:9 = #1 (Expanded file = 1)
} // CHECK-DAG: File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:21 =
#5
}
diff --git a/clang/test/CoverageMapping/unreachable-macro.c
b/clang/test/CoverageMapping/unreachable-macro.c
index 7956c973f6ce8..04a70c7458392 100644
--- a/clang/test/CoverageMapping/unreachable-macro.c
+++ b/clang/test/CoverageMapping/unreachable-macro.c
@@ -7,7 +7,7 @@ void counters_in_macro_following_unreachable(void) {
// CHECK-NEXT: File 0, [[@LINE-1]]:52 -> {{[0-9]+}}:2 = #0
return;
// CHECK-NEXT: Gap,File 0, [[@LINE-1]]:10 -> [[@LINE+3]]:3 = 0
- // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:8 = 0
+ // CHECK-NEXT: MacroExpansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:8 = 0
// CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+2]]:2 = 0
WHILE
}
diff --git a/compiler-rt/include/profile/InstrProfData.inc
b/compiler-rt/include/profile/InstrProfData.inc
index 8c092b5e0868b..be01da0b99994 100644
--- a/compiler-rt/include/profile/InstrProfData.inc
+++ b/compiler-rt/include/profile/InstrProfData.inc
@@ -756,7 +756,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Indexed profile format version (start from 1). */
#define INSTR_PROF_INDEX_VERSION 13
/* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 6
+#define INSTR_PROF_COVMAP_VERSION 7
/* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
* version for other variants of profile. We set the 8th most significant bit
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index a664b6b5fa560..bb2630da8a2a1 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -113,6 +113,15 @@ struct Counter {
static const unsigned EncodingTagMask = 0x3;
static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
EncodingTagBits + 1;
+ // Bit 2 is used to mark ExpansionRegion (both ExpansionRegion and
+ // MacroExpansionRegion). Bit 3 is used to distinguish MacroExpansionRegion
+ // from ExpansionRegion (Version8+). ExpandedFileID starts at bit 4 for both
+ // types.
+ static const unsigned EncodingExpansionRegionBit = 1 << EncodingTagBits;
+ static const unsigned EncodingMacroExpansionRegionBit =
+ 1 << EncodingCounterTagAndExpansionRegionTagBits;
+ static const unsigned EncodingTagBitsMacroExpansion =
+ EncodingCounterTagAndExpansionRegionTagBits + 1;
private:
CounterKind Kind = Zero;
@@ -257,7 +266,13 @@ struct CounterMappingRegion {
MCDCDecisionRegion,
/// A Branch Region can be extended to include IDs to facilitate MC/DC.
- MCDCBranchRegion
+ MCDCBranchRegion,
+
+ /// A MacroExpansionRegion is like an ExpansionRegion but specifically
+ /// represents a macro expansion (as opposed to an #include).
+ /// Added in Version8 to distinguish macro expansions from includes.
+ /// Must be at the end to preserve binary compatibility with old files.
+ MacroExpansionRegion
};
/// Primary Counter that is also used for Branch Regions (TrueCount).
@@ -287,6 +302,12 @@ struct CounterMappingRegion {
return (Kind == BranchRegion || Kind == MCDCBranchRegion);
}
+ bool isExpansion() const {
+ return Kind == ExpansionRegion || Kind == MacroExpansionRegion;
+ }
+
+ bool isMacroExpansion() const { return Kind == MacroExpansionRegion; }
+
CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID,
unsigned LineStart, unsigned ColumnStart,
unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
@@ -321,10 +342,11 @@ struct CounterMappingRegion {
static CounterMappingRegion
makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
- unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
- return CounterMappingRegion(Counter(), FileID, ExpandedFileID, LineStart,
- ColumnStart, LineEnd, ColumnEnd,
- ExpansionRegion);
+ unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd,
+ bool IsMacro = false) {
+ return CounterMappingRegion(
+ Counter(), FileID, ExpandedFileID, LineStart, ColumnStart, LineEnd,
+ ColumnEnd, IsMacro ? MacroExpansionRegion : ExpansionRegion);
}
static CounterMappingRegion
@@ -1484,7 +1506,10 @@ enum CovMapVersion {
Version6 = 5,
// Branch regions extended and Decision Regions added for MC/DC.
Version7 = 6,
- // The current version is Version7.
+ // MacroExpansionRegion kind added to distinguish macro expansions
+ // from #include expansions.
+ Version8 = 7,
+ // The current version is Version8.
CurrentVersion = INSTR_PROF_COVMAP_VERSION
};
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index e91ba9147a745..2f08131a70247 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -135,17 +135,19 @@ class RawCoverageMappingReader : public RawCoverageReader
{
std::vector<StringRef> &Filenames;
std::vector<CounterExpression> &Expressions;
std::vector<CounterMappingRegion> &MappingRegions;
+ CovMapVersion Version;
public:
- RawCoverageMappingReader(StringRef MappingData,
- ArrayRef<std::string> &TranslationUnitFilenames,
- std::vector<StringRef> &Filenames,
- std::vector<CounterExpression> &Expressions,
- std::vector<CounterMappingRegion> &MappingRegions)
+ RawCoverageMappingReader(
+ StringRef MappingData, ArrayRef<std::string> &TranslationUnitFilenames,
+ std::vector<StringRef> &Filenames,
+ std::vector<CounterExpression> &Expressions,
+ std::vector<CounterMappingRegion> &MappingRegions,
+ CovMapVersion Version = CovMapVersion::CurrentVersion)
: RawCoverageReader(MappingData),
TranslationUnitFilenames(TranslationUnitFilenames),
Filenames(Filenames), Expressions(Expressions),
- MappingRegions(MappingRegions) {}
+ MappingRegions(MappingRegions), Version(Version) {}
RawCoverageMappingReader(const RawCoverageMappingReader &) = delete;
RawCoverageMappingReader &
operator=(const RawCoverageMappingReader &) = delete;
diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc
b/llvm/include/llvm/ProfileData/InstrProfData.inc
index 8c092b5e0868b..be01da0b99994 100644
--- a/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -756,7 +756,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Indexed profile format version (start from 1). */
#define INSTR_PROF_INDEX_VERSION 13
/* Coverage mapping format version (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 6
+#define INSTR_PROF_COVMAP_VERSION 7
/* Profile version is always of type uint64_t. Reserve the upper 32 bits in the
* version for other variants of profile. We set the 8th most significant bit
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 0d9a5a6758f06..f2d82015b072c 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -766,7 +766,7 @@ struct CountedRegionEmitter {
Files.resize(Region.FileID + 1);
}
Files[Region.FileID].LastIndex = I + 1;
- if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
+ if (Region.isExpansion()) {
if (Region.ExpandedFileID >= Files.size()) {
// Extend (only possible in CoverageMappingTests)
Files.resize(Region.ExpandedFileID + 1);
@@ -799,7 +799,7 @@ struct CountedRegionEmitter {
if (Region.FileID != Idx)
break;
- if (Region.Kind == CounterMappingRegion::ExpansionRegion)
+ if (Region.isExpansion())
if (auto E = walk(Region.ExpandedFileID))
return E;
@@ -1454,7 +1454,7 @@ findMainViewFileID(const FunctionRecord &Function) {
return std::nullopt;
SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
for (const auto &CR : Function.CountedRegions)
- if (CR.Kind == CounterMappingRegion::ExpansionRegion)
+ if (CR.isExpansion())
IsNotExpandedFile[CR.ExpandedFileID] = false;
int I = IsNotExpandedFile.find_first();
if (I == -1)
@@ -1474,7 +1474,7 @@ findMainViewFileID(StringRef SourceFile, const
FunctionRecord &Function) {
}
static bool isExpansion(const CountedRegion &R, unsigned FileID) {
- return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
+ return R.isExpansion() && R.FileID == FileID;
}
CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index e89efe09d49e8..8b5b157225d65 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -275,9 +275,24 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
} else {
// Is it an expansion region?
if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
- Kind = CounterMappingRegion::ExpansionRegion;
- ExpandedFileID = EncodedCounterAndRegion >>
- Counter::EncodingCounterTagAndExpansionRegionTagBits;
+ // Version8+: bit 2 marks expansion, bit 3 distinguishes macro, FileID
+ // at bit 4+ Version < 8: bit 2 marks expansion, FileID at bit 3+
+ if (Version >= CovMapVersion::Version8) {
+ // Check for macro expansion: bit 3 is set for MacroExpansionRegion
+ if (EncodedCounterAndRegion &
+ Counter::EncodingMacroExpansionRegionBit) {
+ Kind = CounterMappingRegion::MacroExpansionRegion;
+ } else {
+ Kind = CounterMappingRegion::ExpansionRegion;
+ }
+ ExpandedFileID =
+ EncodedCounterAndRegion >>
Counter::EncodingTagBitsMacroExpansion;
+ } else {
+ // Pre-Version8: all expansions are ExpansionRegion, FileID at bit 3+
+ Kind = CounterMappingRegion::ExpansionRegion;
+ ExpandedFileID = EncodedCounterAndRegion >>
+
Counter::EncodingCounterTagAndExpansionRegionTagBits;
+ }
if (ExpandedFileID >= NumFileIDs)
return make_error<CoverageMapError>(coveragemap_error::malformed,
"ExpandedFileID is invalid");
@@ -375,8 +390,12 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
<< ColumnStart << " -> " << (LineStart + NumLines) << ":"
<< ColumnEnd << ", ";
- if (Kind == CounterMappingRegion::ExpansionRegion)
- dbgs() << "Expands to file " << ExpandedFileID;
+ if (Kind == CounterMappingRegion::ExpansionRegion ||
+ Kind == CounterMappingRegion::MacroExpansionRegion)
+ dbgs() << "Expands to file " << ExpandedFileID
+ << (Kind == CounterMappingRegion::MacroExpansionRegion
+ ? " (macro)"
+ : "");
else
CounterMappingContext(Expressions).dump(C, dbgs());
dbgs() << "\n";
@@ -446,7 +465,7 @@ Error RawCoverageMappingReader::read() {
FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
for (;;) {
for (auto &R : MappingRegions) {
- if (R.Kind != CounterMappingRegion::ExpansionRegion)
+ if (!R.isExpansion())
continue;
assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
@@ -837,6 +856,7 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>>
CovMapFuncRecordReader::get(
case CovMapVersion::Version5:
case CovMapVersion::Version6:
case CovMapVersion::Version7:
+ case CovMapVersion::Version8:
// Decompress the name data.
if (Error E = P.create(P.getNameData()))
return std::move(E);
@@ -858,6 +878,9 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>>
CovMapFuncRecordReader::get(
else if (Version == CovMapVersion::Version7)
return std::make_unique<VersionedCovMapFuncRecordReader<
CovMapVersion::Version7, IntPtrT, Endian>>(P, R, D, F);
+ else if (Version == CovMapVersion::Version8)
+ return std::make_unique<VersionedCovMapFuncRecordReader<
+ CovMapVersion::Version8, IntPtrT, Endian>>(P, R, D, F);
}
llvm_unreachable("Unsupported version");
}
@@ -1375,7 +1398,7 @@ Error
BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
auto &R = MappingRecords[CurrentRecord];
auto F = ArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize);
RawCoverageMappingReader Reader(R.CoverageMapping, F, FunctionsFilenames,
- Expressions, MappingRegions);
+ Expressions, MappingRegions, R.Version);
if (auto Err = Reader.read())
return Err;
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
index dc97870985145..ca5d7a3627e58 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -225,17 +225,19 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
case CounterMappingRegion::GapRegion:
writeCounter(MinExpressions, Count, OS);
break;
- case CounterMappingRegion::ExpansionRegion: {
+ case CounterMappingRegion::ExpansionRegion:
+ case CounterMappingRegion::MacroExpansionRegion: {
assert(Count.isZero());
- assert(I->ExpandedFileID <=
- (std::numeric_limits<unsigned>::max() >>
- Counter::EncodingCounterTagAndExpansionRegionTagBits));
- // Mark an expansion region with a set bit that follows the counter tag,
- // and pack the expanded file id into the remaining bits.
+ // Both ExpansionRegion and MacroExpansionRegion use the same encoding:
+ // - bit 2: ExpansionRegionBit (set for both types)
+ // - bit 3: MacroExpansionRegionBit (set only for MacroExpansionRegion)
+ // - bit 4+: ExpandedFileID
+ bool IsMacro = I->Kind == CounterMappingRegion::MacroExpansionRegion;
unsigned EncodedTagExpandedFileID =
- (1 << Counter::EncodingTagBits) |
- (I->ExpandedFileID
- << Counter::EncodingCounterTagAndExpansionRegionTagBits);
+ Counter::EncodingExpansionRegionBit |
+ (I->ExpandedFileID << Counter::EncodingTagBitsMacroExpansion);
+ if (IsMacro)
+ EncodedTagExpandedFileID |= Counter::EncodingMacroExpansionRegionBit;
encodeULEB128(EncodedTagExpandedFileID, OS);
break;
}
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.c
b/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.c
new file mode 100644
index 0000000000000..bafc6af355d5f
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.c
@@ -0,0 +1,24 @@
+// Simple test for --ignore-branch-in-macro
+// This file is compiled to generate test input data
+
+#define MY_ABS(x) ((x) >= 0 ? (x) : -(x))
+#define MY_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+int test_function(int val) {
+ // Macro branches - should be filtered with --ignore-branch-in-macro
+ int abs_val = MY_ABS(val);
+ int max_val = MY_MAX(val, 5);
+
+ // Source-level branches - always counted
+ if (val > 0) {
+ return abs_val + max_val;
+ }
+ return 0;
+}
+
+int main() {
+ test_function(1);
+ test_function(-1);
+ test_function(10);
+ return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.o
b/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.o
new file mode 100644
index
0000000000000000000000000000000000000000..2fc016fe8251e602b3479bcdb13508e5ef8102b2
GIT binary patch
literal 3664
zcmbtWeQZ-z6u<YCuI)ylY#<2JJuoOZ`fRs#w20aP9Ys+Ikpxj}-ukgk`Z2mUGKpZ#
zfTS!CLj1sl#27`5Q3F8}{xJ;D5X}%Z5)C8<6N!r>5e-o!OXfMR_jGS>um9*t?mOrF
z&OP^>bMLvgeJQfOUE<uv1abB-<D?k)2Iqtl*2OTJ2QxQCi`R;~Zbb*}2u25nc(kaC
z1G{dq7w1pK2P3zNk?W&Q|4^eY4MwgPBR65TeRrkVBcs))aLr<5WRwj?Mv9Rexcct9
ztX98ii`*zi#zr0IBV(A-U}S9Txs)=qVGnA0zR`i}9$}rj!fC921gD-J2P#R`g!zY}
z1D|`go?|Ee=~}Vm^^G%&VA;H9-O;mw=WP3jzkcJB#^O#J=iJWSFznpLT{YZMUoCk!
zXY1;D9lLWGen904mt4#vyCnw9&1SK~g+jsUX0=k4BvtXfs7c(;+;%>#j@{4MY*sJZ
ztC87R16x$h7PF-g<PPTLY%Y^!S1mFZyNBId%a*cbklXD`2Yzi$yn4k2@;n$wlqY1w
zdEIooRD#*Ff;)gqsi*rdKlIfZcfsdmLko|-y?A@gn+L<5PrK*XKRB5C?cDFz+K(K*
zc6avMw4?U?d*5x@{z%;``OM3|bbPUQ^@5Lw8wO5>PDM|gK6AX`(nnVgJ$3fz{*(Lu
zTJ+hK@%zfXCc;@V+F#mR%Si@snn5;-R6o^jv{}jK-mjhCf4Om;S1CT(c;PYS%i)Xh
z;m3!EZLD2$EMxJsn(dT#B=f!9xvbpOtoRgPXSXIVflnAlS6_z`&t+Dm(>pQ`;K$pO
z&pn@vYYNWtb)@_)iH<<BC6NsJ)j%NO?@)ujrY4`?uf_w-q2>Niu(>6%6!V-dlI1%$
zGT!gu3#L1qhalN{z;PhGi=Va`o_*44ca`)O%qZDbA`Y|`KV|zW-H!F*-9nD%j)dJ_
z17kWWKr>*>gyBJ@0{sN|H1@~1mD$Fq!zNp8%<!lP(?OkMw@xLSo|zSn*-oZ+bk#i>
z6q-%1XsXGkS80XMngYHCNUfnReeVJLP~gXfhrZ_^;~6cK^p{b$920ij_k|MeJcAou
zB0K{m+&T0b!^a3{4uU{td{GH5<8&Xq74QuvoX+~03V6YUQ$G$?z|R_RJY~xNLIwN>
zfn(lynl%6C3ixORoO%@RJMJ6l#1Y4QNS8rI!u`ZS6cz&E$Aw<wo?)|BIbGE(7K`V0
z<dgB(npL4dYfE!$WO;DSnm~J7--M|>&=gwU6l`v54Yr3?`TLlXPo`BxOZICFUxrLF
ztHEr18e%>9R4ks=dX0Kk%_Mu7(wWco^$-qGGpbQb^<}{ZFH0&O(~`Yf41l->FH#xJ
zsNGqnWOG_lS^LB$Z?C4tw=qSJswNWfdUcA#l3lS>9%8bL8qepvsqVCv%zJTBCC-#y
zEw8B^z+cGd9BVNopHMZGw(mdlKf%-L2O=b{$XvWI1~RGaL9iiKWtf9vSm=KXPK^41
z^i~kC2g3viegvBdC@2EX1sQvTUNHK7*#_9u*8)IsA!$DP<LgBClz0I!J%l8KG(i;i
z*aW0Yv>w5g;yW$k<GW6Ai5CE~ihotqy_f<CZjPTPe<n|w>BP+fN|#vqYxb{{zeglU
z=Y{)+5amt$QNS=&n}`RZPW?icg-*;I-vQ26{zrs=m>dN+`%B=g=VFTgjc7>f6U@H`
z2Kf_SseV}$XsjQv1l3KvQvE-Qd?=nszZ{?RO7&m;pY@Me)Q|ruC?BeS3t+ha5|iOO
zL9%!h=)VqGaITTsKtarB1VLUY{JTv!`4c|@c9M-#k6ArR7IVKZVLhhfXYULD&BjGR
zruqrK2m+pEm;mD9{iC|DfABY${AvHr0A^c1oZQ6``8r+-%Hk7Ta(Helx5ah^{!
MSeI}>X4Sv{0)OeM*#H0l
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.proftext
b/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.proftext
new file mode 100644
index 0000000000000..bb9d561b47fb9
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/macro-filter-test.proftext
@@ -0,0 +1,19 @@
+test_function
+# Func Hash:
+242690539886576728
+# Num Counters:
+4
+# Counter Values:
+3
+2
+1
+2
+
+main
+# Func Hash:
+24
+# Num Counters:
+1
+# Counter Values:
+1
+
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.c
b/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.c
new file mode 100644
index 0000000000000..0af3c0ca14fd3
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.c
@@ -0,0 +1,34 @@
+// Test that --ignore-branch-in-macro distinguishes macros from #include
+
+// Header with branch
+static inline int header_func(int x) {
+ if (x > 10) {
+ return x * 2;
+ }
+ return x;
+}
+
+// Macro with branch
+#define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
+
+int test_func(int val) {
+ // Macro branches - should be filtered
+ int clamped = CLAMP(val, 1, 100);
+
+ // #include branch - should be preserved
+ int h = header_func(val);
+
+ // Source branch - always counted
+ if (val > 0) {
+ return clamped + h;
+ }
+ return 0;
+}
+
+int main() {
+ test_func(1);
+ test_func(-1);
+ test_func(50);
+ test_func(150);
+ return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.o
b/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.o
new file mode 100644
index
0000000000000000000000000000000000000000..958f5dcddaff34d2192c0262c2f145a7fe18a0d2
GIT binary patch
literal 4760
zcmbtWeQZ-z6u<9v-59J}H&o`>MloSRW=q?xTSpKJ+uJ%fKEx1-Fw0x}_JLcwbloyF
zgXutRss>0j#PEmFnGhoh8l(K9Off(v7%_qgk_g0)nN6L9n8hr?b6)T1-ro9vgwx!f
zdw%Dfdp_=c_r1MRbG;}CCdNr%>zF`-h8HfH6@2Q{$4bF+n?L@me|XXsADs3l%&71W
zj|%>{IvpOI76yyw<0mjeT$-G4fJJCeI*X8MF+P!*kf!6(ctRQn`-C(Zmu@Bor^h8#
zJq7M;Ps#iM3F)Runu<#^6Io}Z8L(vuX~sYNwXNk;n@WznW&03T^Eb+UVY<v9p9@!U
z<z!|vurMq-XFceLm4}_5+DWW^97CVH1(ck*Q`lQHbB#j2)|OLf3A8LS{_r!$uUvl>
z=G*r*9{I|%!*s*C`?Yn}sV3OJ1%gE|<F7P3ITi`Ig*l>C5LkJ!u$UFXOt4!`f>0)i
z+01IQhzyv8<+DRWLqiKJtU$~Z#Y|y8N}^z9mTV!Xh&2doDO+JPmm)K>mF$sHwwl%B
zUyUuh2w65;%X~$wmepgP|6P3j_o~pFKV`$b5CI^{6Os{x;+#wou+wLEgl@d(Sy=&d
ztOv1KJ3%mK2^nQ(s4Sc1+02-1o|#$MK}^rg^7YArH)Ad8KVw<IMdj&%%a4wIX&JKR
zu+fq$rngV*-`vpg_<MEl_!q7D;=(IGe{;<GZfV8N?{km&C;#5`!kK8jzcbX}K5^~z
zUnQ3gKb9HvI1i5O9e)3Z@ET>LEPOPve{0_4AHpX~%HllE?HKJB?bYpUQI~NC1L_y`
z>JH`%`<aete`s&g*=RBSU0`25aJjtE?uc(LKi|}LZez1!>_>a~rSs>SzFoDk@nX}b
zWB!fJjrNxs+kX>S{F-%w1-s;MyRBb|_I5_XHg|=?>2S7p#%wF$&j+KUuhkKZbg${^
z>hE5SfA*eeWVaHGInc`4+UBYZwR)7wkm7a89#6>CDtn!7x6|d4gPw|-YFCZ7qB69K
zCw(91!t-01Fklsy=435607Vo7jsxi<{9B)EeOauvWQrexMN+pGaUk^|r}XPn`khHN
zdjfe%->mAfPk84c$Mc6Ap8=#C7#0}0C;(Yu<ijXH0SI%xAI1YH7*Gi;n8E(Jl}>F+
zv)lP#FT!t>JE%4Bxrr^Dx6CgpqPgTX7ACa<4Zx=+wW_)Jzp9uw7fjh><@3p;c4IF7
zfhsPZ3v$V%c5J@Nq;@eKzGNOa2}psaZ|a!<>|>5waRY(Wy#|ira#4M&A<Rb9|Kzz@
zF5-?SX$9xiz?Z{KOSG9!=nUZVnF(VCUjjf6a=jie)8TYaxD0T=4#%^H^kkB$6=Ph&
zU(w<8{2VgC$22%rNBLhgz_06Y%KuLT{2|_V>;vXV>)Q?RYL4T&c<RW0y#d~2fNwLv
z>BQoFiG3rPIO5m`l8GaZ`IBseITF@|gUH7xgpYE0mky`%m}kl_Se%iWmAx>>lFI^t
zV5C2)1Ot-0u6BddBe|<3Z&kgkzHe4lx1q*URasFbReS5|JoW1}Dz~@7<8{@$t13Mk
zYQ42peasP6x@1R88Hh2wl)II13|7KhInWbr3k1WlUacIKyOmz%XpctvdI*P%x@E1@
z))xjHT<UGXK)2i(W{z+qrZ^flZL{~r<lwW+p{_57Lhy=c=P4*1fwm~Dp7M+-y|Dl+
z6-*)BaxfYR^!Elj!@;h;km3jiIutpiM3ZK!+TP!5PpO%sHx`Y_t-zn_RykIyDK8|)
zWZw6CWllIxsgG*SVxRLXfzBJL`0*o=Jq0tw@XTq+#|2sEK<A8Xx55OU2_FHR_wcLg
zIQK6B9M2xS0#%~#0=yUS9i=BfzXHh~{n3t|YvM-$Q$vV0n9b5r9(QCGQfIUt!A9}7
zq=}F3QHo34DE=1y@X<X@@$NSM_B8SFEk$vO8^s^s@#%eF6#orSBwJ-86P2Ik{ylTh
z+5IEfsDHb7{&Ze&{}7_QiMIiU@l8A)OjYvoLv7<SF@66ea8BpHo%{R9k#oJj51iFp
zbn$Kc`Jr=)`Qx`0`4etbe@~kF(U<BbZdCtao<H@Er=N;XvQhm<@3DSwn)>niyW9GQ
z($tS%eN;Dbqx#2r{uGbu)yqcpPu*kvThi2z-_8`D_P-x6Jbxmy!T&5dd4cr(L>jc!
zQVR%(Ikh0nW$xdp!^xlcXP~FK)^v;-tOe89UQS{?y5rBj<NgCWf2yBg{2oJ79|4?q
z@c#L^jL%OI4DzS`odL|$d@BNM2u6yIbANp1kkB7VU#k}YeeP&?fS<ps+yNPWx9Q{m
E4_<vM7XSbN
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.proftext
b/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.proftext
new file mode 100644
index 0000000000000..9837ff4e8ddce
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/macro-vs-include.proftext
@@ -0,0 +1,28 @@
+test_func
+# Func Hash:
+241846114956444760
+# Num Counters:
+4
+# Counter Values:
+4
+1
+1
+3
+
+macro-vs-include.c:header_func
+# Func Hash:
+11211998296
+# Num Counters:
+2
+# Counter Values:
+4
+2
+
+main
+# Func Hash:
+24
+# Num Counters:
+1
+# Counter Values:
+1
+
diff --git a/llvm/test/tools/llvm-cov/macro-expansion-filter.test
b/llvm/test/tools/llvm-cov/macro-expansion-filter.test
new file mode 100644
index 0000000000000..0f7c1003cb47b
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/macro-expansion-filter.test
@@ -0,0 +1,49 @@
+// Test --ignore-branch-in-macro flag filters macro branches correctly
+//
+// The test binary was compiled with a clang that emits MacroExpansionRegion
+// (Version8 coverage mapping). It contains:
+// - 2 macro calls (MY_ABS, MY_MAX), each producing 2 branches = 4 macro
branches
+// - 1 source-level if statement producing 2 branches = 2 source branches
+// - Total: 6 branches without filter, 2 branches with filter
+
+// Test 1: Verify flag is accepted and changes branch count in report
+// RUN: llvm-profdata merge %S/Inputs/macro-filter-test.proftext -o %t.profdata
+// RUN: llvm-cov report %S/Inputs/macro-filter-test.o -instr-profile
%t.profdata --show-branch-summary -path-equivalence=/tmp,%S/Inputs | FileCheck
%s -check-prefix=WITHOUT-FILTER
+// WITHOUT-FILTER: Branches
+// WITHOUT-FILTER: 6
+
+// RUN: llvm-cov report %S/Inputs/macro-filter-test.o -instr-profile
%t.profdata --show-branch-summary --ignore-branch-in-macro
-path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=WITH-FILTER
+// WITH-FILTER: Branches
+// WITH-FILTER: 2
+
+// Test 2: Verify LCOV export filters macro branches
+// RUN: llvm-cov export --format=lcov %S/Inputs/macro-filter-test.o
-instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %s
-check-prefix=LCOV-WITHOUT
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+
+// RUN: llvm-cov export --format=lcov --ignore-branch-in-macro
%S/Inputs/macro-filter-test.o -instr-profile %t.profdata
-path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=LCOV-WITH
+// LCOV-WITH: BRDA:
+// LCOV-WITH: BRDA:
+// LCOV-WITH-NOT: BRDA:
+
+// Test 3: Verify JSON export filters macro branches
+// RUN: llvm-cov export --format=text %S/Inputs/macro-filter-test.o
-instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %s
-check-prefix=JSON-WITHOUT
+// JSON-WITHOUT: "branches"
+// JSON-WITHOUT: "branches"
+
+// RUN: llvm-cov export --format=text --ignore-branch-in-macro
%S/Inputs/macro-filter-test.o -instr-profile %t.profdata
-path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=JSON-WITH
+// JSON-WITH: "branches"
+
+// Test 4: Verify backward compatibility with old binaries (Version7)
+// The branch-macros.o32l was compiled with an older clang (Version7)
+// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
+// RUN: llvm-cov report --show-branch-summary --ignore-branch-in-macro
%S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions
-path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s
-check-prefix=BACKWARD-COMPAT
+// BACKWARD-COMPAT: Name
+// BACKWARD-COMPAT: _Z4funcii
+// BACKWARD-COMPAT: _Z5func2ii
+// BACKWARD-COMPAT: main
+// BACKWARD-COMPAT: TOTAL
diff --git a/llvm/test/tools/llvm-cov/macro-vs-include.test
b/llvm/test/tools/llvm-cov/macro-vs-include.test
new file mode 100644
index 0000000000000..68440db758468
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/macro-vs-include.test
@@ -0,0 +1,38 @@
+// Test that --ignore-branch-in-macro distinguishes macros from #include
+//
+// The test binary contains:
+// - 1 macro call (CLAMP) producing 2 branches
+// - 1 #include (header_func) producing 2 branches
+// - 1 source-level if producing 2 branches
+// - Total: 8 branches without filter, 4 branches with filter
+//
+// This verifies that macro branches are filtered while #include branches
+// are preserved.
+
+// Test: Verify branch count changes from 8 to 4
+// RUN: llvm-profdata merge %S/Inputs/macro-vs-include.proftext -o %t.profdata
+// RUN: llvm-cov report %S/Inputs/macro-vs-include.o -instr-profile
%t.profdata --show-branch-summary -path-equivalence=/tmp,%S/Inputs | FileCheck
%s -check-prefix=WITHOUT-FILTER
+// WITHOUT-FILTER: Branches
+// WITHOUT-FILTER: 8
+
+// RUN: llvm-cov report %S/Inputs/macro-vs-include.o -instr-profile
%t.profdata --show-branch-summary --ignore-branch-in-macro
-path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=WITH-FILTER
+// WITH-FILTER: Branches
+// WITH-FILTER: 4
+
+// Test: Verify LCOV export preserves #include branches but filters macro
branches
+// RUN: llvm-cov export --format=lcov %S/Inputs/macro-vs-include.o
-instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %s
-check-prefix=LCOV-WITHOUT
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+// LCOV-WITHOUT: BRDA:
+
+// RUN: llvm-cov export --format=lcov --ignore-branch-in-macro
%S/Inputs/macro-vs-include.o -instr-profile %t.profdata
-path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=LCOV-WITH
+// LCOV-WITH: BRDA:
+// LCOV-WITH: BRDA:
+// LCOV-WITH: BRDA:
+// LCOV-WITH: BRDA:
+// LCOV-WITH-NOT: BRDA:
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp
b/llvm/tools/llvm-cov/CodeCoverage.cpp
index e19101ac76045..8a73394b8462f 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -308,6 +308,10 @@ void CodeCoverageTool::attachExpansionSubViews(
if (!ViewOpts.ShowExpandedRegions)
return;
for (const auto &Expansion : Expansions) {
+ // Skip macro expansions if requested.
+ if (ViewOpts.IgnoreBranchesInMacros && Expansion.Region.isMacroExpansion())
+ continue;
+
auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
if (ExpansionCoverage.empty())
continue;
@@ -376,7 +380,15 @@ CodeCoverageTool::createFunctionView(const FunctionRecord
&Function,
if (!SourceBuffer)
return nullptr;
- auto Branches = FunctionCoverage.getBranches();
+ auto AllBranches = FunctionCoverage.getBranches();
+ // Filter out branches from macro expansions if requested.
+ // These branches have a FileID that differs from the main file's FileID.
+ unsigned MainFileID = AllBranches.empty() ? 0 : AllBranches[0].FileID;
+ SmallVector<CountedRegion, 0> Branches;
+ for (const auto &B : AllBranches)
+ if (!ViewOpts.IgnoreBranchesInMacros || B.FileID == MainFileID)
+ Branches.push_back(B);
+
auto Expansions = FunctionCoverage.getExpansions();
auto MCDCRecords = FunctionCoverage.getMCDCRecords();
auto View = SourceCoverageView::create(DC.demangle(Function.Name),
@@ -399,7 +411,15 @@ CodeCoverageTool::createSourceFileView(StringRef
SourceFile,
if (FileCoverage.empty())
return nullptr;
- auto Branches = FileCoverage.getBranches();
+ auto AllBranches = FileCoverage.getBranches();
+ // Filter out branches from macro expansions if requested.
+ // These branches have a FileID that differs from the main file's FileID.
+ unsigned MainFileID = AllBranches.empty() ? 0 : AllBranches[0].FileID;
+ SmallVector<CountedRegion, 0> Branches;
+ for (const auto &B : AllBranches)
+ if (!ViewOpts.IgnoreBranchesInMacros || B.FileID == MainFileID)
+ Branches.push_back(B);
+
auto Expansions = FileCoverage.getExpansions();
auto MCDCRecords = FileCoverage.getMCDCRecords();
auto View = SourceCoverageView::create(SourceFile, SourceBuffer.get(),
@@ -423,8 +443,17 @@ CodeCoverageTool::createSourceFileView(StringRef
SourceFile,
if (Function->ExecutionCount > 0) {
auto SubViewCoverage = Coverage.getCoverageForFunction(*Function);
auto SubViewExpansions = SubViewCoverage.getExpansions();
- auto SubViewBranches = SubViewCoverage.getBranches();
+ auto AllSubViewBranches = SubViewCoverage.getBranches();
auto SubViewMCDCRecords = SubViewCoverage.getMCDCRecords();
+
+ // Filter out branches from macro expansions if requested.
+ unsigned SubMainFileID =
+ AllSubViewBranches.empty() ? 0 : AllSubViewBranches[0].FileID;
+ SmallVector<CountedRegion, 0> SubViewBranches;
+ for (const auto &B : AllSubViewBranches)
+ if (!ViewOpts.IgnoreBranchesInMacros || B.FileID == SubMainFileID)
+ SubViewBranches.push_back(B);
+
SubView = SourceCoverageView::create(
Funcname, SourceBuffer.get(), ViewOpts,
std::move(SubViewCoverage));
attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
@@ -797,6 +826,10 @@ int CodeCoverageTool::run(Command Cmd, int argc, const
char **argv) {
"summary-only", cl::Optional,
cl::desc("Export only summary information for each source file"));
+ cl::opt<bool> IgnoreBranchesInMacros(
+ "ignore-branch-in-macro", cl::Optional,
+ cl::desc("Ignore branches inside macro expansions in branch coverage"));
+
cl::opt<unsigned> NumThreads(
"num-threads", cl::init(0),
cl::desc("Number of merge threads to use (default: autodetect)"));
@@ -978,6 +1011,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const
char **argv) {
ViewOpts.ShowFunctionSummary = FunctionSummary;
ViewOpts.ShowInstantiationSummary = InstantiationSummary;
ViewOpts.ExportSummaryOnly = SummaryOnly;
+ ViewOpts.IgnoreBranchesInMacros = IgnoreBranchesInMacros;
ViewOpts.NumThreads = NumThreads;
ViewOpts.CompilationDirectory = CompilationDirectory;
diff --git a/llvm/tools/llvm-cov/CoverageExporterJson.cpp
b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
index 4dbd6ea64da94..0eaa5130f8744 100644
--- a/llvm/tools/llvm-cov/CoverageExporterJson.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
@@ -231,14 +231,20 @@ void renderMCDCRecords(json::OStream &JOS,
std::vector<llvm::coverage::CountedRegion>
collectNestedBranches(const coverage::CoverageMapping &Coverage,
- ArrayRef<llvm::coverage::ExpansionRecord> Expansions) {
+ ArrayRef<llvm::coverage::ExpansionRecord> Expansions,
+ bool IgnoreBranchesInMacros = false) {
std::vector<llvm::coverage::CountedRegion> Branches;
for (const auto &Expansion : Expansions) {
+ // Skip macro expansions if requested.
+ if (IgnoreBranchesInMacros && Expansion.Region.isMacroExpansion())
+ continue;
+
auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
// Recursively collect branches from nested expansions.
auto NestedExpansions = ExpansionCoverage.getExpansions();
- auto NestedExBranches = collectNestedBranches(Coverage, NestedExpansions);
+ auto NestedExBranches = collectNestedBranches(Coverage, NestedExpansions,
+ IgnoreBranchesInMacros);
append_range(Branches, NestedExBranches);
// Add branches from this level of expansion.
@@ -253,7 +259,8 @@ collectNestedBranches(const coverage::CoverageMapping
&Coverage,
void renderExpansion(json::OStream &JOS,
const coverage::CoverageMapping &Coverage,
- const coverage::ExpansionRecord &Expansion) {
+ const coverage::ExpansionRecord &Expansion,
+ bool IgnoreBranchesInMacros = false) {
std::vector<llvm::coverage::ExpansionRecord> Expansions = {Expansion};
JOS.object([&] {
JOS.attributeArray("filenames", [&] {
@@ -262,7 +269,8 @@ void renderExpansion(json::OStream &JOS,
});
// Enumerate the branch coverage information for the expansion.
JOS.attributeBegin("branches");
- renderBranchRegions(JOS, collectNestedBranches(Coverage, Expansions));
+ renderBranchRegions(JOS, collectNestedBranches(Coverage, Expansions,
+ IgnoreBranchesInMacros));
JOS.attributeEnd();
// Mark the beginning and end of this expansion in the source file.
JOS.attributeBegin("source_region");
@@ -332,14 +340,22 @@ void renderFile(json::OStream &JOS, const
coverage::CoverageMapping &Coverage,
if (!Options.ExportSummaryOnly) {
// Calculate and render detailed coverage information for given file.
auto FileCoverage = Coverage.getCoverageForFile(Filename);
+ // Filter out branches from macro expansions if requested.
+ // These branches have a FileID that differs from the main file's FileID.
+ auto FileBranches = FileCoverage.getBranches();
+ unsigned MainFileID = FileBranches.empty() ? 0 : FileBranches[0].FileID;
JOS.attributeArray("branches", [&] {
- for (const auto &Branch : FileCoverage.getBranches())
- renderBranch(JOS, Branch);
+ for (const auto &Branch : FileBranches)
+ if (!Options.IgnoreBranchesInMacros || Branch.FileID == MainFileID)
+ renderBranch(JOS, Branch);
});
if (!Options.SkipExpansions) {
JOS.attributeArray("expansions", [&] {
for (const auto &Expansion : FileCoverage.getExpansions())
- renderExpansion(JOS, Coverage, Expansion);
+ if (!Options.IgnoreBranchesInMacros ||
+ !Expansion.Region.isMacroExpansion())
+ renderExpansion(JOS, Coverage, Expansion,
+ Options.IgnoreBranchesInMacros);
});
}
JOS.attributeArray("mcdc_records", [&] {
diff --git a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
index 96be9693a7047..90135d2b6a1d7 100644
--- a/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterLcov.cpp
@@ -99,9 +99,13 @@ std::vector<NestedCountedRegion>
collectNestedBranches(const coverage::CoverageMapping &Coverage,
ArrayRef<llvm::coverage::ExpansionRecord> Expansions,
std::vector<LineColPair> &NestedPath,
- unsigned &PositionCounter) {
+ unsigned &PositionCounter,
+ bool IgnoreBranchesInMacros = false) {
std::vector<NestedCountedRegion> Branches;
for (const auto &Expansion : Expansions) {
+ // Skip macro expansions if requested.
+ if (IgnoreBranchesInMacros && Expansion.Region.isMacroExpansion())
+ continue;
auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
// Track the path to the nested expansions.
@@ -109,8 +113,9 @@ collectNestedBranches(const coverage::CoverageMapping
&Coverage,
// Recursively collect branches from nested expansions.
auto NestedExpansions = ExpansionCoverage.getExpansions();
- auto NestedExBranches = collectNestedBranches(Coverage, NestedExpansions,
- NestedPath, PositionCounter);
+ auto NestedExBranches =
+ collectNestedBranches(Coverage, NestedExpansions, NestedPath,
+ PositionCounter, IgnoreBranchesInMacros);
append_range(Branches, NestedExBranches);
// Add branches from this level of expansion.
@@ -127,20 +132,6 @@ collectNestedBranches(const coverage::CoverageMapping
&Coverage,
return Branches;
}
-void appendNestedCountedRegions(const std::vector<CountedRegion> &Src,
- std::vector<NestedCountedRegion> &Dst) {
- auto Unfolded = make_filter_range(Src, [](auto &Region) {
- return !Region.TrueFolded || !Region.FalseFolded;
- });
- Dst.reserve(Dst.size() + Src.size());
- unsigned PositionCounter = Dst.size();
- std::transform(Unfolded.begin(), Unfolded.end(), std::back_inserter(Dst),
- [=, &PositionCounter](auto &Region) {
- return NestedCountedRegion(Region, {Region.startLoc()},
- PositionCounter++);
- });
-}
-
void appendNestedCountedRegions(const std::vector<NestedCountedRegion> &Src,
std::vector<NestedCountedRegion> &Dst) {
auto Unfolded = make_filter_range(Src, [](auto &NestedRegion) {
@@ -181,17 +172,27 @@ void
combineInstanceCounts(std::vector<NestedCountedRegion> &Branches) {
void renderBranchExecutionCounts(raw_ostream &OS,
const coverage::CoverageMapping &Coverage,
const coverage::CoverageData &FileCoverage,
- bool UnifyInstances) {
+ bool UnifyInstances,
+ bool IgnoreBranchesInMacros = false) {
std::vector<NestedCountedRegion> Branches;
- appendNestedCountedRegions(FileCoverage.getBranches(), Branches);
+ // Filter out branches from macro expansions if requested.
+ // These branches have a FileID that differs from the main file's FileID.
+ auto FileBranches = FileCoverage.getBranches();
+ unsigned MainFileID = FileBranches.empty() ? 0 : FileBranches[0].FileID;
+ for (const auto &B : FileBranches) {
+ if (IgnoreBranchesInMacros && B.FileID != MainFileID)
+ continue;
+ Branches.push_back(NestedCountedRegion(B, {B.startLoc()},
Branches.size()));
+ }
// Recursively collect branches for all file expansions.
std::vector<LineColPair> NestedPath;
unsigned PositionCounter = 0;
- std::vector<NestedCountedRegion> ExBranches = collectNestedBranches(
- Coverage, FileCoverage.getExpansions(), NestedPath, PositionCounter);
+ std::vector<NestedCountedRegion> ExBranches =
+ collectNestedBranches(Coverage, FileCoverage.getExpansions(), NestedPath,
+ PositionCounter, IgnoreBranchesInMacros);
// Append Expansion Branches to Source Branches.
appendNestedCountedRegions(ExBranches, Branches);
@@ -250,7 +251,8 @@ void renderBranchSummary(raw_ostream &OS, const
FileCoverageSummary &Summary) {
void renderFile(raw_ostream &OS, const coverage::CoverageMapping &Coverage,
const std::string &Filename,
const FileCoverageSummary &FileReport, bool ExportSummaryOnly,
- bool SkipFunctions, bool SkipBranches, bool UnifyInstances) {
+ bool SkipFunctions, bool SkipBranches, bool UnifyInstances,
+ bool IgnoreBranchesInMacros = false) {
OS << "SF:" << Filename << '\n';
if (!ExportSummaryOnly && !SkipFunctions) {
@@ -263,7 +265,8 @@ void renderFile(raw_ostream &OS, const
coverage::CoverageMapping &Coverage,
auto FileCoverage = Coverage.getCoverageForFile(Filename);
renderLineExecutionCounts(OS, FileCoverage);
if (!SkipBranches)
- renderBranchExecutionCounts(OS, Coverage, FileCoverage, UnifyInstances);
+ renderBranchExecutionCounts(OS, Coverage, FileCoverage, UnifyInstances,
+ IgnoreBranchesInMacros);
}
if (!SkipBranches)
renderBranchSummary(OS, FileReport);
@@ -276,10 +279,11 @@ void renderFiles(raw_ostream &OS, const
coverage::CoverageMapping &Coverage,
ArrayRef<std::string> SourceFiles,
ArrayRef<FileCoverageSummary> FileReports,
bool ExportSummaryOnly, bool SkipFunctions, bool SkipBranches,
- bool UnifyInstances) {
+ bool UnifyInstances, bool IgnoreBranchesInMacros = false) {
for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I)
renderFile(OS, Coverage, SourceFiles[I], FileReports[I], ExportSummaryOnly,
- SkipFunctions, SkipBranches, UnifyInstances);
+ SkipFunctions, SkipBranches, UnifyInstances,
+ IgnoreBranchesInMacros);
}
} // end anonymous namespace
@@ -299,5 +303,6 @@ void CoverageExporterLcov::renderRoot(ArrayRef<std::string>
SourceFiles) {
SourceFiles, Options);
renderFiles(OS, Coverage, SourceFiles, FileReports,
Options.ExportSummaryOnly,
Options.SkipFunctions, Options.SkipBranches,
- Options.UnifyFunctionInstantiations);
+ Options.UnifyFunctionInstantiations,
+ Options.IgnoreBranchesInMacros);
}
diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp
b/llvm/tools/llvm-cov/CoverageReport.cpp
index 9b754d613370c..c43b3f5be9ee2 100644
--- a/llvm/tools/llvm-cov/CoverageReport.cpp
+++ b/llvm/tools/llvm-cov/CoverageReport.cpp
@@ -428,7 +428,8 @@ void
CoverageReport::renderFunctionReports(ArrayRef<std::string> Files,
OS << "\n";
FunctionCoverageSummary Totals("TOTAL");
for (const auto &F : Functions) {
- auto Function = FunctionCoverageSummary::get(Coverage, F);
+ auto Function = FunctionCoverageSummary::get(
+ Coverage, F, Options.IgnoreBranchesInMacros);
++Totals.ExecutionCount;
Totals.RegionCoverage += Function.RegionCoverage;
Totals.LineCoverage += Function.LineCoverage;
@@ -453,7 +454,8 @@ void CoverageReport::prepareSingleFileReport(const
StringRef Filename,
for (const coverage::FunctionRecord *F : Group.getInstantiations()) {
if (!Filters->matches(*Coverage, *F))
continue;
- auto InstantiationSummary = FunctionCoverageSummary::get(*Coverage, *F);
+ auto InstantiationSummary = FunctionCoverageSummary::get(
+ *Coverage, *F, Options.IgnoreBranchesInMacros);
FileReport->addInstantiation(InstantiationSummary);
InstantiationSummaries.push_back(InstantiationSummary);
}
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index be9aef8416e8d..f4b922d4b4f40 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -38,12 +38,17 @@ static auto sumBranches(const ArrayRef<CountedRegion>
&Branches) {
static BranchCoverageInfo
sumBranchExpansions(const CoverageMapping &CM,
- ArrayRef<ExpansionRecord> Expansions) {
+ ArrayRef<ExpansionRecord> Expansions,
+ bool IgnoreBranchesInMacros) {
BranchCoverageInfo BranchCoverage;
for (const auto &Expansion : Expansions) {
+ // Skip macro expansions if requested.
+ if (IgnoreBranchesInMacros && Expansion.Region.isMacroExpansion())
+ continue;
auto CE = CM.getCoverageForExpansion(Expansion);
BranchCoverage += sumBranches(CE.getBranches());
- BranchCoverage += sumBranchExpansions(CM, CE.getExpansions());
+ BranchCoverage +=
+ sumBranchExpansions(CM, CE.getExpansions(), IgnoreBranchesInMacros);
}
return BranchCoverage;
}
@@ -98,7 +103,8 @@ CoverageDataSummary::CoverageDataSummary(const CoverageData
&CD,
FunctionCoverageSummary
FunctionCoverageSummary::get(const CoverageMapping &CM,
- const coverage::FunctionRecord &Function) {
+ const coverage::FunctionRecord &Function,
+ bool IgnoreBranchesInMacros) {
CoverageData CD = CM.getCoverageForFunction(Function);
auto Summary =
@@ -107,7 +113,8 @@ FunctionCoverageSummary::get(const CoverageMapping &CM,
Summary += CoverageDataSummary(CD, Function.CountedRegions);
// Compute the branch coverage, including branches from expansions.
- Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions());
+ Summary.BranchCoverage +=
+ sumBranchExpansions(CM, CD.getExpansions(), IgnoreBranchesInMacros);
return Summary;
}
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index d9210676c41bf..82da6ad7a3943 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -253,7 +253,8 @@ struct FunctionCoverageSummary : CoverageDataSummary {
/// Compute the code coverage summary for the given function coverage
/// mapping record.
static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
- const coverage::FunctionRecord &Function);
+ const coverage::FunctionRecord &Function,
+ bool IgnoreBranchesInMacros = false);
/// Compute the code coverage summary for an instantiation group \p Group,
/// given a list of summaries for each instantiation in \p Summaries.
diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h
b/llvm/tools/llvm-cov/CoverageViewOptions.h
index 4826d4adb53bf..80184f1e31c3d 100644
--- a/llvm/tools/llvm-cov/CoverageViewOptions.h
+++ b/llvm/tools/llvm-cov/CoverageViewOptions.h
@@ -49,6 +49,8 @@ struct CoverageViewOptions {
bool SkipFunctions;
bool SkipBranches;
bool BinaryCounters;
+ /// Ignore branches inside macro expansions when computing branch coverage.
+ bool IgnoreBranchesInMacros = false;
OutputFormat Format;
BranchOutputType ShowBranches;
std::string ShowOutputDirectory;
diff --git a/llvm/unittests/ProfileData/CoverageMappingTest.cpp
b/llvm/unittests/ProfileData/CoverageMappingTest.cpp
index b268aa7cdd057..45d838ccb2452 100644
--- a/llvm/unittests/ProfileData/CoverageMappingTest.cpp
+++ b/llvm/unittests/ProfileData/CoverageMappingTest.cpp
@@ -219,6 +219,13 @@ struct CoverageMappingTest :
::testing::TestWithParam<std::tuple<bool, bool>> {
LS, CS, LE, CE));
}
+ void addMacroExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned
LS,
+ unsigned CS, unsigned LE, unsigned CE) {
+
InputFunctions.back().Regions.push_back(CounterMappingRegion::makeExpansion(
+ getFileIndexForFunction(File), getFileIndexForFunction(ExpandedFile),
+ LS, CS, LE, CE, /*IsMacro=*/true));
+ }
+
void addExpression(CounterExpression CE) {
InputFunctions.back().Expressions.push_back(CE);
}
@@ -1029,6 +1036,113 @@ TEST_P(CoverageMappingTest,
load_coverage_for_expanded_file) {
EXPECT_EQ(CoverageSegment(1, 10, false), Segments[1]);
}
+TEST_P(CoverageMappingTest, macro_expansion_roundtrip) {
+ startFunction("func", 0x1234);
+ // Add code regions that the expansions reference
+ addCMR(Counter::getCounter(0), "main", 1, 1, 20, 1);
+ addCMR(Counter::getCounter(0), "include_file", 1, 1, 5, 10);
+ addCMR(Counter::getCounter(0), "macro_file", 1, 1, 5, 10);
+ // Add a regular expansion (e.g., #include)
+ addExpansionCMR("main", "include_file", 5, 1, 5, 10);
+ // Add a macro expansion
+ addMacroExpansionCMR("main", "macro_file", 10, 1, 10, 15);
+
+ writeAndReadCoverageRegions();
+ ASSERT_EQ(1u, OutputFunctions.size());
+ const OutputFunctionCoverageData &Output = OutputFunctions[0];
+
+ // Find the expansion regions (there should be 5 regions total: 3 code + 2
+ // expansion)
+ ASSERT_EQ(5u, Output.Regions.size());
+
+ // Check each region
+ size_t ExpansionCount = 0;
+ size_t MacroExpansionCount = 0;
+ for (const auto &Region : Output.Regions) {
+ if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
+ ExpansionCount++;
+ EXPECT_TRUE(Region.isExpansion());
+ EXPECT_FALSE(Region.isMacroExpansion());
+ } else if (Region.Kind == CounterMappingRegion::MacroExpansionRegion) {
+ MacroExpansionCount++;
+ EXPECT_TRUE(Region.isExpansion());
+ EXPECT_TRUE(Region.isMacroExpansion());
+ } else {
+ EXPECT_EQ(CounterMappingRegion::CodeRegion, Region.Kind);
+ EXPECT_FALSE(Region.isExpansion());
+ EXPECT_FALSE(Region.isMacroExpansion());
+ }
+ }
+
+ EXPECT_EQ(1u, ExpansionCount);
+ EXPECT_EQ(1u, MacroExpansionCount);
+}
+
+TEST_P(CoverageMappingTest, macro_expansion_coverage_data) {
+ ProfileWriter.addRecord({"func", 0x1234, {5}}, Err);
+
+ startFunction("func", 0x1234);
+ addCMR(Counter::getCounter(0), "main", 1, 1, 10, 1);
+ addMacroExpansionCMR("main", "macro_def", 5, 1, 5, 20);
+ addCMR(Counter::getCounter(0), "macro_def", 1, 1, 1, 10);
+
+ EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
+
+ // Verify main file coverage
+ CoverageData MainData = LoadedCoverage->getCoverageForFile("main");
+ std::vector<CoverageSegment> MainSegments(MainData.begin(), MainData.end());
+ ASSERT_GE(MainSegments.size(), 2u);
+
+ // Verify macro definition file coverage
+ CoverageData MacroData = LoadedCoverage->getCoverageForFile("macro_def");
+ std::vector<CoverageSegment> MacroSegments(MacroData.begin(),
+ MacroData.end());
+ ASSERT_GE(MacroSegments.size(), 1u);
+ EXPECT_EQ(CoverageSegment(1, 1, 5, true), MacroSegments[0]);
+}
+
+TEST_P(CoverageMappingTest, mixed_expansion_types) {
+ startFunction("func", 0x1234);
+ // Add code regions
+ addCMR(Counter::getCounter(0), "main", 1, 1, 15, 1);
+ addCMR(Counter::getCounter(0), "header1", 1, 1, 3, 1);
+ addCMR(Counter::getCounter(0), "macro1", 1, 1, 5, 1);
+ addCMR(Counter::getCounter(0), "header2", 1, 1, 3, 1);
+ addCMR(Counter::getCounter(0), "macro2", 1, 1, 5, 1);
+ // Mix regular expansions and macro expansions
+ addExpansionCMR("main", "header1", 3, 1, 3, 10);
+ addMacroExpansionCMR("main", "macro1", 5, 1, 5, 15);
+ addExpansionCMR("main", "header2", 7, 1, 7, 10);
+ addMacroExpansionCMR("main", "macro2", 9, 1, 9, 15);
+
+ writeAndReadCoverageRegions();
+ ASSERT_EQ(1u, OutputFunctions.size());
+ const OutputFunctionCoverageData &Output = OutputFunctions[0];
+
+ ASSERT_EQ(9u, Output.Regions.size());
+
+ // Count expansion types
+ size_t ExpansionCount = 0;
+ size_t MacroExpansionCount = 0;
+ for (const auto &Region : Output.Regions) {
+ if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
+ ExpansionCount++;
+ EXPECT_FALSE(Region.isMacroExpansion());
+ } else if (Region.Kind == CounterMappingRegion::MacroExpansionRegion) {
+ MacroExpansionCount++;
+ EXPECT_TRUE(Region.isMacroExpansion());
+ }
+ // All expansions should return true for isExpansion()
+ if (Region.isExpansion()) {
+ EXPECT_TRUE(Region.Kind == CounterMappingRegion::ExpansionRegion ||
+ Region.Kind == CounterMappingRegion::MacroExpansionRegion);
+ }
+ }
+
+ EXPECT_EQ(2u, ExpansionCount);
+ EXPECT_EQ(2u, MacroExpansionCount);
+}
+
TEST_P(CoverageMappingTest, skip_duplicate_function_record) {
ProfileWriter.addRecord({"func", 0x1234, {1}}, Err);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits