Run clang-query and return (filepath, line_number) tuples.
(
clang_query: str, tu: str, file_regex: str
)
| 91 | |
| 92 | |
| 93 | def _run_clang_query( |
| 94 | clang_query: str, tu: str, file_regex: str |
| 95 | ) -> list[tuple[str, int]]: |
| 96 | """Run clang-query and return (filepath, line_number) tuples.""" |
| 97 | query = ( |
| 98 | f"set output diag\n" |
| 99 | f"match functionDecl(" |
| 100 | f"unless(isNoThrow()), " |
| 101 | f"unless(isDeleted()), " |
| 102 | f"unless(isDefaulted()), " |
| 103 | f"unless(isImplicit()), " |
| 104 | f'isExpansionInFileMatching("{file_regex}"))' |
| 105 | ) |
| 106 | |
| 107 | result = subprocess.run( |
| 108 | [clang_query, tu, "--"] + _COMPILER_ARGS, |
| 109 | input=query, |
| 110 | capture_output=True, |
| 111 | text=True, |
| 112 | cwd=str(PROJECT_ROOT), |
| 113 | timeout=300, |
| 114 | ) |
| 115 | |
| 116 | output = result.stdout + result.stderr |
| 117 | |
| 118 | pattern = re.compile(r"(src[\\/]\S+):(\d+):\d+: note: .root. binds here") |
| 119 | hits: list[tuple[str, int]] = [] |
| 120 | seen: set[tuple[str, int]] = set() |
| 121 | |
| 122 | for m in pattern.finditer(output): |
| 123 | filepath = m.group(1).replace("\\", "/") |
| 124 | line_num = int(m.group(2)) |
| 125 | key = (filepath, line_num) |
| 126 | if key not in seen: |
| 127 | seen.add(key) |
| 128 | hits.append(key) |
| 129 | |
| 130 | return hits |
| 131 | |
| 132 | |
| 133 | # ============================================================================ |