Skip to content

Commit c3767dd

Browse files
committed
Merge 57b0843 into cheriot-upstream
2 parents 1304303 + 57b0843 commit c3767dd

File tree

350 files changed

+15006
-4802
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

350 files changed

+15006
-4802
lines changed

clang-tools-extra/clang-tidy/.clang-tidy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ Checks: >
1616
-modernize-use-trailing-return-type,
1717
performance-*,
1818
-performance-enum-size,
19-
-performance-move-const-arg,
2019
-performance-no-int-to-ptr,
2120
-performance-type-promotion-in-math-fn,
2221
-performance-unnecessary-value-param,
@@ -38,3 +37,7 @@ Checks: >
3837
-readability-static-definition-in-anonymous-namespace,
3938
-readability-suspicious-call-argument,
4039
-readability-use-anyofallof
40+
41+
CheckOptions:
42+
- key: performance-move-const-arg.CheckTriviallyCopyableMove
43+
value: false

clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ bool isCompleteAndHasNoZeroValue(const EnumDecl *D) {
2222
const EnumDecl *Definition = D->getDefinition();
2323
return Definition && Definition->isComplete() &&
2424
!Definition->enumerators().empty() &&
25-
std::none_of(Definition->enumerator_begin(),
26-
Definition->enumerator_end(),
27-
[](const EnumConstantDecl *Value) {
28-
return Value->getInitVal().isZero();
29-
});
25+
llvm::none_of(Definition->enumerators(),
26+
[](const EnumConstantDecl *Value) {
27+
return Value->getInitVal().isZero();
28+
});
3029
}
3130

3231
AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) {

clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@ namespace {
2222
AST_MATCHER(EnumDecl, isCompleteAndHasNoZeroValue) {
2323
const EnumDecl *Definition = Node.getDefinition();
2424
return Definition && Node.isComplete() &&
25-
std::none_of(Definition->enumerator_begin(),
26-
Definition->enumerator_end(),
27-
[](const EnumConstantDecl *Value) {
28-
return Value->getInitVal().isZero();
29-
});
25+
llvm::none_of(Definition->enumerators(),
26+
[](const EnumConstantDecl *Value) {
27+
return Value->getInitVal().isZero();
28+
});
3029
}
3130

3231
} // namespace

clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,15 @@ void TaggedUnionMemberCountCheck::storeOptions(
105105

106106
void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) {
107107

108-
auto UnionField = fieldDecl(hasType(qualType(
109-
hasCanonicalType(recordType(hasDeclaration(recordDecl(isUnion())))))));
108+
auto NotFromSystemHeaderOrStdNamespace =
109+
unless(anyOf(isExpansionInSystemHeader(), isInStdNamespace()));
110110

111-
auto EnumField = fieldDecl(hasType(
112-
qualType(hasCanonicalType(enumType(hasDeclaration(enumDecl()))))));
111+
auto UnionField =
112+
fieldDecl(hasType(qualType(hasCanonicalType(recordType(hasDeclaration(
113+
recordDecl(isUnion(), NotFromSystemHeaderOrStdNamespace)))))));
114+
115+
auto EnumField = fieldDecl(hasType(qualType(hasCanonicalType(
116+
enumType(hasDeclaration(enumDecl(NotFromSystemHeaderOrStdNamespace)))))));
113117

114118
auto HasOneUnionField = fieldCountOfKindIsOne(UnionField, UnionMatchBindName);
115119
auto HasOneEnumField = fieldCountOfKindIsOne(EnumField, TagMatchBindName);

clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,7 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) {
132132
hasAncestor(functionDecl().bind("func")),
133133
hasAncestor(functionDecl(
134134
isDefinition(), equalsBoundNode("func"), ToParam,
135-
unless(anyOf(isDeleted(),
136-
hasDescendant(std::move(ForwardCallMatcher))))))),
135+
unless(anyOf(isDeleted(), hasDescendant(ForwardCallMatcher)))))),
137136
this);
138137
}
139138

clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) {
6767
hasParent(fieldDecl(
6868
hasParent(recordDecl(isExternCContext())))),
6969
hasAncestor(functionDecl(isExternC())))),
70-
std::move(IgnoreStringArrayIfNeededMatcher))
70+
IgnoreStringArrayIfNeededMatcher)
7171
.bind("typeloc"),
7272
this);
7373
}

clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
319319

320320
Finder->addMatcher(
321321
expr(
322-
anyOfExhaustive(std::move(ConstantMatchers)),
322+
anyOfExhaustive(ConstantMatchers),
323323
unless(hasParent(explicitCastExpr(hasDestinationType(isFloating())))),
324324
hasType(qualType(hasCanonicalTypeUnqualified(
325325
anyOf(qualType(asString("float")).bind("float"),

clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
import time
5050
import traceback
5151
from types import ModuleType
52-
from typing import Any, Awaitable, Callable, List, Optional, TypeVar
52+
from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, TypeVar
5353

5454

5555
yaml: Optional[ModuleType] = None
@@ -105,6 +105,7 @@ def get_tidy_invocation(
105105
warnings_as_errors: Optional[str],
106106
exclude_header_filter: Optional[str],
107107
allow_no_checks: bool,
108+
store_check_profile: Optional[str],
108109
) -> List[str]:
109110
"""Gets a command line for clang-tidy."""
110111
start = [clang_tidy_binary]
@@ -147,6 +148,9 @@ def get_tidy_invocation(
147148
start.append(f"--warnings-as-errors={warnings_as_errors}")
148149
if allow_no_checks:
149150
start.append("--allow-no-checks")
151+
if store_check_profile:
152+
start.append("--enable-check-profile")
153+
start.append(f"--store-check-profile={store_check_profile}")
150154
if f:
151155
start.append(f)
152156
return start
@@ -178,6 +182,124 @@ def merge_replacement_files(tmpdir: str, mergefile: str) -> None:
178182
open(mergefile, "w").close()
179183

180184

185+
def aggregate_profiles(profile_dir: str) -> Dict[str, float]:
186+
"""Aggregate timing data from multiple profile JSON files"""
187+
aggregated: Dict[str, float] = {}
188+
189+
for profile_file in glob.iglob(os.path.join(profile_dir, "*.json")):
190+
try:
191+
with open(profile_file, "r", encoding="utf-8") as f:
192+
data = json.load(f)
193+
profile_data: Dict[str, float] = data.get("profile", {})
194+
195+
for key, value in profile_data.items():
196+
if key.startswith("time.clang-tidy."):
197+
if key in aggregated:
198+
aggregated[key] += value
199+
else:
200+
aggregated[key] = value
201+
except (json.JSONDecodeError, KeyError, IOError) as e:
202+
print(f"Error: invalid json file {profile_file}: {e}", file=sys.stderr)
203+
continue
204+
205+
return aggregated
206+
207+
208+
def print_profile_data(aggregated_data: Dict[str, float]) -> None:
209+
"""Print aggregated checks profile data in the same format as clang-tidy"""
210+
if not aggregated_data:
211+
return
212+
213+
# Extract checker names and their timing data
214+
checkers: Dict[str, Dict[str, float]] = {}
215+
for key, value in aggregated_data.items():
216+
parts = key.split(".")
217+
if len(parts) >= 4 and parts[0] == "time" and parts[1] == "clang-tidy":
218+
checker_name = ".".join(
219+
parts[2:-1]
220+
) # Everything between "clang-tidy" and the timing type
221+
timing_type = parts[-1] # wall, user, or sys
222+
223+
if checker_name not in checkers:
224+
checkers[checker_name] = {"wall": 0.0, "user": 0.0, "sys": 0.0}
225+
226+
checkers[checker_name][timing_type] = value
227+
228+
if not checkers:
229+
return
230+
231+
total_user = sum(data["user"] for data in checkers.values())
232+
total_sys = sum(data["sys"] for data in checkers.values())
233+
total_wall = sum(data["wall"] for data in checkers.values())
234+
235+
sorted_checkers: List[Tuple[str, Dict[str, float]]] = sorted(
236+
checkers.items(), key=lambda x: x[1]["user"] + x[1]["sys"], reverse=True
237+
)
238+
239+
def print_stderr(*args: Any, **kwargs: Any) -> None:
240+
print(*args, file=sys.stderr, **kwargs)
241+
242+
print_stderr(
243+
"===-------------------------------------------------------------------------==="
244+
)
245+
print_stderr(" clang-tidy checks profiling")
246+
print_stderr(
247+
"===-------------------------------------------------------------------------==="
248+
)
249+
print_stderr(
250+
f" Total Execution Time: {total_user + total_sys:.4f} seconds ({total_wall:.4f} wall clock)\n"
251+
)
252+
253+
# Calculate field widths based on the Total line which has the largest values
254+
total_combined = total_user + total_sys
255+
user_width = len(f"{total_user:.4f}")
256+
sys_width = len(f"{total_sys:.4f}")
257+
combined_width = len(f"{total_combined:.4f}")
258+
wall_width = len(f"{total_wall:.4f}")
259+
260+
# Header with proper alignment
261+
additional_width = 9 # for " (100.0%)"
262+
user_header = "---User Time---".center(user_width + additional_width)
263+
sys_header = "--System Time--".center(sys_width + additional_width)
264+
combined_header = "--User+System--".center(combined_width + additional_width)
265+
wall_header = "---Wall Time---".center(wall_width + additional_width)
266+
267+
print_stderr(
268+
f" {user_header} {sys_header} {combined_header} {wall_header} --- Name ---"
269+
)
270+
271+
for checker_name, data in sorted_checkers:
272+
user_time = data["user"]
273+
sys_time = data["sys"]
274+
wall_time = data["wall"]
275+
combined_time = user_time + sys_time
276+
277+
user_percent = (user_time / total_user * 100) if total_user > 0 else 0
278+
sys_percent = (sys_time / total_sys * 100) if total_sys > 0 else 0
279+
combined_percent = (
280+
(combined_time / total_combined * 100) if total_combined > 0 else 0
281+
)
282+
wall_percent = (wall_time / total_wall * 100) if total_wall > 0 else 0
283+
284+
user_str = f"{user_time:{user_width}.4f} ({user_percent:5.1f}%)"
285+
sys_str = f"{sys_time:{sys_width}.4f} ({sys_percent:5.1f}%)"
286+
combined_str = f"{combined_time:{combined_width}.4f} ({combined_percent:5.1f}%)"
287+
wall_str = f"{wall_time:{wall_width}.4f} ({wall_percent:5.1f}%)"
288+
289+
print_stderr(
290+
f" {user_str} {sys_str} {combined_str} {wall_str} {checker_name}"
291+
)
292+
293+
user_total_str = f"{total_user:{user_width}.4f} (100.0%)"
294+
sys_total_str = f"{total_sys:{sys_width}.4f} (100.0%)"
295+
combined_total_str = f"{total_combined:{combined_width}.4f} (100.0%)"
296+
wall_total_str = f"{total_wall:{wall_width}.4f} (100.0%)"
297+
298+
print_stderr(
299+
f" {user_total_str} {sys_total_str} {combined_total_str} {wall_total_str} Total"
300+
)
301+
302+
181303
def find_binary(arg: str, name: str, build_path: str) -> str:
182304
"""Get the path for a binary or exit"""
183305
if arg:
@@ -240,6 +362,7 @@ async def run_tidy(
240362
clang_tidy_binary: str,
241363
tmpdir: str,
242364
build_path: str,
365+
store_check_profile: Optional[str],
243366
) -> ClangTidyResult:
244367
"""
245368
Runs clang-tidy on a single file and returns the result.
@@ -263,6 +386,7 @@ async def run_tidy(
263386
args.warnings_as_errors,
264387
args.exclude_header_filter,
265388
args.allow_no_checks,
389+
store_check_profile,
266390
)
267391

268392
try:
@@ -447,6 +571,11 @@ async def main() -> None:
447571
action="store_true",
448572
help="Allow empty enabled checks.",
449573
)
574+
parser.add_argument(
575+
"-enable-check-profile",
576+
action="store_true",
577+
help="Enable per-check timing profiles, and print a report",
578+
)
450579
args = parser.parse_args()
451580

452581
db_path = "compile_commands.json"
@@ -489,6 +618,10 @@ async def main() -> None:
489618
export_fixes_dir = tempfile.mkdtemp()
490619
delete_fixes_dir = True
491620

621+
profile_dir: Optional[str] = None
622+
if args.enable_check_profile:
623+
profile_dir = tempfile.mkdtemp()
624+
492625
try:
493626
invocation = get_tidy_invocation(
494627
None,
@@ -509,6 +642,7 @@ async def main() -> None:
509642
args.warnings_as_errors,
510643
args.exclude_header_filter,
511644
args.allow_no_checks,
645+
None, # No profiling for the list-checks invocation
512646
)
513647
invocation.append("-list-checks")
514648
invocation.append("-")
@@ -567,6 +701,7 @@ async def main() -> None:
567701
clang_tidy_binary,
568702
export_fixes_dir,
569703
build_path,
704+
profile_dir,
570705
)
571706
)
572707
for f in files
@@ -593,8 +728,19 @@ async def main() -> None:
593728
if delete_fixes_dir:
594729
assert export_fixes_dir
595730
shutil.rmtree(export_fixes_dir)
731+
if profile_dir:
732+
shutil.rmtree(profile_dir)
596733
return
597734

735+
if args.enable_check_profile and profile_dir:
736+
# Ensure all clang-tidy stdout is flushed before printing profiling
737+
sys.stdout.flush()
738+
aggregated_data = aggregate_profiles(profile_dir)
739+
if aggregated_data:
740+
print_profile_data(aggregated_data)
741+
else:
742+
print("No profiling data found.")
743+
598744
if combine_fixes:
599745
print(f"Writing fixes to {args.export_fixes} ...")
600746
try:
@@ -618,6 +764,8 @@ async def main() -> None:
618764
if delete_fixes_dir:
619765
assert export_fixes_dir
620766
shutil.rmtree(export_fixes_dir)
767+
if profile_dir:
768+
shutil.rmtree(profile_dir)
621769
sys.exit(returncode)
622770

623771

clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,10 @@ RenamerClangTidyCheck::addUsage(
432432
if (FixLocation.isInvalid())
433433
return {NamingCheckFailures.end(), false};
434434

435+
// Skip if in system system header
436+
if (SourceMgr.isInSystemHeader(FixLocation))
437+
return {NamingCheckFailures.end(), false};
438+
435439
auto EmplaceResult = NamingCheckFailures.try_emplace(FailureId);
436440
NamingCheckFailure &Failure = EmplaceResult.first->second;
437441

@@ -455,6 +459,9 @@ RenamerClangTidyCheck::addUsage(
455459
void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl,
456460
SourceRange UsageRange,
457461
const SourceManager &SourceMgr) {
462+
if (SourceMgr.isInSystemHeader(Decl->getLocation()))
463+
return;
464+
458465
if (hasNoName(Decl))
459466
return;
460467

clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ void UseRangesCheck::registerMatchers(MatchFinder *Finder) {
149149
}
150150
Finder->addMatcher(
151151
callExpr(
152-
callee(functionDecl(hasAnyName(std::move(Names)))
152+
callee(functionDecl(hasAnyName(Names))
153153
.bind((FuncDecl + Twine(Replacers.size() - 1).str()))),
154154
ast_matchers::internal::DynTypedMatcher::constructVariadic(
155155
ast_matchers::internal::DynTypedMatcher::VO_AnyOf,

0 commit comments

Comments
 (0)