Skip to content

Commit d46ea46

Browse files
author
iclsrc
committed
Merge from 'main' to 'sycl-web' (126 commits)
2 parents 584c2c8 + 241de80 commit d46ea46

File tree

515 files changed

+138084
-142629
lines changed

Some content is hidden

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

515 files changed

+138084
-142629
lines changed

clang-tools-extra/clang-tidy/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_clang_library(clangTidyLLVMModule STATIC
1111
PreferRegisterOverUnsignedCheck.cpp
1212
PreferStaticOverAnonymousNamespaceCheck.cpp
1313
TwineLocalCheck.cpp
14+
TypeSwitchCaseTypesCheck.cpp
1415
UseNewMLIROpBuilderCheck.cpp
1516
UseRangesCheck.cpp
1617
UseVectorUtilsCheck.cpp

clang-tools-extra/clang-tidy/llvm/LLVMTidyModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "PreferRegisterOverUnsignedCheck.h"
1818
#include "PreferStaticOverAnonymousNamespaceCheck.h"
1919
#include "TwineLocalCheck.h"
20+
#include "TypeSwitchCaseTypesCheck.h"
2021
#include "UseNewMLIROpBuilderCheck.h"
2122
#include "UseRangesCheck.h"
2223
#include "UseVectorUtilsCheck.h"
@@ -43,6 +44,8 @@ class LLVMModule : public ClangTidyModule {
4344
CheckFactories.registerCheck<readability::QualifiedAutoCheck>(
4445
"llvm-qualified-auto");
4546
CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
47+
CheckFactories.registerCheck<TypeSwitchCaseTypesCheck>(
48+
"llvm-type-switch-case-types");
4649
CheckFactories.registerCheck<UseNewMlirOpBuilderCheck>(
4750
"llvm-use-new-mlir-op-builder");
4851
CheckFactories.registerCheck<UseRangesCheck>("llvm-use-ranges");
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "TypeSwitchCaseTypesCheck.h"
10+
#include "clang/AST/ASTContext.h"
11+
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
13+
using namespace clang::ast_matchers;
14+
15+
namespace clang::tidy::llvm_check {
16+
17+
void TypeSwitchCaseTypesCheck::registerMatchers(MatchFinder *Finder) {
18+
// Match calls to `llvm::TypeSwitch::Case` with a lambda expression.
19+
// Explicit template arguments and their count are checked in `check()`.
20+
Finder->addMatcher(
21+
cxxMemberCallExpr(
22+
argumentCountIs(1),
23+
callee(memberExpr(member(cxxMethodDecl(hasName("Case"),
24+
ofClass(cxxRecordDecl(hasName(
25+
"::llvm::TypeSwitch"))))))
26+
.bind("member")),
27+
hasArgument(0, lambdaExpr().bind("lambda")))
28+
.bind("call"),
29+
this);
30+
}
31+
32+
void TypeSwitchCaseTypesCheck::check(const MatchFinder::MatchResult &Result) {
33+
const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call");
34+
assert(Call);
35+
const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("lambda");
36+
assert(Lambda);
37+
const auto *MemExpr = Result.Nodes.getNodeAs<MemberExpr>("member");
38+
assert(MemExpr);
39+
40+
// Only handle `Case<T>` with exactly one explicit template argument.
41+
if (!MemExpr->hasExplicitTemplateArgs() || MemExpr->getNumTemplateArgs() != 1)
42+
return;
43+
44+
const TemplateArgumentLoc &TemplateArg = MemExpr->getTemplateArgs()[0];
45+
if (TemplateArg.getArgument().getKind() != TemplateArgument::Type)
46+
return;
47+
48+
// Get the lambda's call operator to examine its parameter.
49+
const CXXMethodDecl *CallOp = Lambda->getCallOperator();
50+
if (!CallOp || CallOp->getNumParams() != 1)
51+
return;
52+
53+
const ParmVarDecl *LambdaParam = CallOp->getParamDecl(0);
54+
const QualType ParamType = LambdaParam->getType();
55+
56+
// Check if the parameter uses `auto`.
57+
QualType ParamBaseType = ParamType.getNonReferenceType();
58+
while (ParamBaseType->isPointerType())
59+
ParamBaseType = ParamBaseType->getPointeeType();
60+
const bool ParamIsAuto = ParamBaseType->getUnqualifiedDesugaredType()
61+
->getAs<TemplateTypeParmType>() != nullptr;
62+
63+
if (ParamIsAuto) {
64+
// Warn about `.Case<T>([](auto x) {...})` -- prefer explicit lambda
65+
// parameter type. We only emit a warning without a fixit because we cannot
66+
// reliably determine the deduced type of `auto`. The actual type depends on
67+
// how `dyn_cast<CaseT>` behaves for the `TypeSwitch` value type, which
68+
// varies (e.g., pointer types return pointers, but MLIR handle types may
69+
// return by value).
70+
diag(Call->getExprLoc(),
71+
"lambda parameter needlessly uses 'auto', use explicit type instead");
72+
diag(LambdaParam->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
73+
"replace 'auto' with explicit type", DiagnosticIDs::Note);
74+
diag(TemplateArg.getLocation(),
75+
"type from template argument can be inferred and removed",
76+
DiagnosticIDs::Note);
77+
return;
78+
}
79+
80+
// Handle `.Case<T>([](T x) {...})` -> `.Case([](T x) {...})`.
81+
// Only warn if the types match (otherwise it might be intentional or a bug).
82+
const QualType CaseType = TemplateArg.getArgument().getAsType();
83+
if (CaseType->getCanonicalTypeUnqualified() !=
84+
ParamBaseType->getCanonicalTypeUnqualified())
85+
return;
86+
87+
auto Diag = diag(Call->getExprLoc(), "redundant explicit template argument");
88+
89+
// Skip fixit if template argument involves macros.
90+
const SourceLocation LAngleLoc = MemExpr->getLAngleLoc();
91+
const SourceLocation RAngleLoc = MemExpr->getRAngleLoc();
92+
if (LAngleLoc.isInvalid() || RAngleLoc.isInvalid() || LAngleLoc.isMacroID() ||
93+
RAngleLoc.isMacroID())
94+
return;
95+
96+
Diag << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
97+
98+
// Also remove `template` keyword, if present.
99+
if (MemExpr->hasTemplateKeyword())
100+
Diag << FixItHint::CreateRemoval(MemExpr->getTemplateKeywordLoc());
101+
}
102+
103+
} // namespace clang::tidy::llvm_check
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_TYPESWITCHCASETYPESCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_TYPESWITCHCASETYPESCHECK_H
11+
12+
#include "../ClangTidyCheck.h"
13+
14+
namespace clang::tidy::llvm_check {
15+
16+
/// Simplifies llvm::TypeSwitch Case calls by removing redundant explicit
17+
/// template arguments or replacing 'auto' lambda parameters with explicit
18+
/// types.
19+
///
20+
/// For the user-facing documentation see:
21+
/// https://clang.llvm.org/extra/clang-tidy/checks/llvm/type-switch-case-types.html
22+
class TypeSwitchCaseTypesCheck : public ClangTidyCheck {
23+
public:
24+
using ClangTidyCheck::ClangTidyCheck;
25+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
26+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
27+
28+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
29+
return LangOpts.CPlusPlus;
30+
}
31+
};
32+
33+
} // namespace clang::tidy::llvm_check
34+
35+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_TYPESWITCHCASETYPESCHECK_H

clang-tools-extra/clang-tidy/performance/EnumSizeCheck.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ namespace {
2525

2626
AST_MATCHER(EnumDecl, hasEnumerators) { return !Node.enumerators().empty(); }
2727

28+
AST_MATCHER(EnumDecl, isExternC) {
29+
return Node.getDeclContext()->isExternCContext();
30+
}
31+
32+
AST_MATCHER_P(EnumDecl, hasTypedefNameForAnonDecl,
33+
ast_matchers::internal::Matcher<NamedDecl>, InnerMatcher) {
34+
if (const TypedefNameDecl *TD = Node.getTypedefNameForAnonDecl())
35+
return InnerMatcher.matches(*TD, Finder, Builder);
36+
return false;
37+
}
38+
2839
const std::uint64_t Min8 =
2940
std::imaxabs(std::numeric_limits<std::int8_t>::min());
3041
const std::uint64_t Max8 = std::numeric_limits<std::int8_t>::max();
@@ -90,8 +101,11 @@ bool EnumSizeCheck::isLanguageVersionSupported(
90101
void EnumSizeCheck::registerMatchers(MatchFinder *Finder) {
91102
Finder->addMatcher(
92103
enumDecl(unless(isExpansionInSystemHeader()), isDefinition(),
93-
hasEnumerators(),
94-
unless(matchers::matchesAnyListedRegexName(EnumIgnoreList)))
104+
hasEnumerators(), unless(isExternC()),
105+
unless(anyOf(
106+
matchers::matchesAnyListedRegexName(EnumIgnoreList),
107+
hasTypedefNameForAnonDecl(
108+
matchers::matchesAnyListedRegexName(EnumIgnoreList)))))
95109
.bind("e"),
96110
this);
97111
}

clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) {
2626
Finder->addMatcher(declRefExpr().bind("Ref"), this);
2727

2828
// Analyse parameter usage in function.
29-
Finder->addMatcher(stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")),
30-
binaryOperator(), callExpr(), returnStmt(),
31-
cxxConstructExpr()))
32-
.bind("Mark"),
33-
this);
29+
Finder->addMatcher(
30+
stmt(anyOf(unaryOperator(hasAnyOperatorName("++", "--")),
31+
binaryOperator(), callExpr(), returnStmt(), cxxConstructExpr(),
32+
cxxUnresolvedConstructExpr()))
33+
.bind("Mark"),
34+
this);
3435
Finder->addMatcher(varDecl(hasInitializer(anything())).bind("Mark"), this);
3536
}
3637

@@ -93,6 +94,9 @@ void NonConstParameterCheck::check(const MatchFinder::MatchResult &Result) {
9394
markCanNotBeConst(Arg->IgnoreParenCasts(), false);
9495
}
9596
}
97+
} else if (const auto *CE = dyn_cast<CXXUnresolvedConstructExpr>(S)) {
98+
for (const auto *Arg : CE->arguments())
99+
markCanNotBeConst(Arg->IgnoreParenCasts(), true);
96100
} else if (const auto *R = dyn_cast<ReturnStmt>(S)) {
97101
markCanNotBeConst(R->getRetValue(), true);
98102
} else if (const auto *U = dyn_cast<UnaryOperator>(S)) {

clang-tools-extra/clangd/index/Background.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,7 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
309309

310310
IndexFileIn Index;
311311
auto Action = createStaticIndexingAction(
312-
IndexOpts, [&](SymbolSlab S) { Index.Symbols = std::move(S); },
313-
[&](RefSlab R) { Index.Refs = std::move(R); },
314-
[&](RelationSlab R) { Index.Relations = std::move(R); },
315-
[&](IncludeGraph IG) { Index.Sources = std::move(IG); });
312+
IndexOpts, [&](IndexFileIn Result) { Index = std::move(Result); });
316313

317314
// We're going to run clang here, and it could potentially crash.
318315
// We could use CrashRecoveryContext to try to make indexing crashes nonfatal,

clang-tools-extra/clangd/index/IndexAction.cpp

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Headers.h"
1212
#include "clang-include-cleaner/Record.h"
1313
#include "index/Relation.h"
14+
#include "index/Serialization.h"
1415
#include "index/SymbolCollector.h"
1516
#include "index/SymbolOrigin.h"
1617
#include "clang/AST/ASTConsumer.h"
@@ -130,13 +131,8 @@ class IndexAction : public ASTFrontendAction {
130131
IndexAction(std::shared_ptr<SymbolCollector> C,
131132
std::unique_ptr<include_cleaner::PragmaIncludes> PI,
132133
const index::IndexingOptions &Opts,
133-
std::function<void(SymbolSlab)> SymbolsCallback,
134-
std::function<void(RefSlab)> RefsCallback,
135-
std::function<void(RelationSlab)> RelationsCallback,
136-
std::function<void(IncludeGraph)> IncludeGraphCallback)
137-
: SymbolsCallback(SymbolsCallback), RefsCallback(RefsCallback),
138-
RelationsCallback(RelationsCallback),
139-
IncludeGraphCallback(IncludeGraphCallback), Collector(C),
134+
std::function<void(IndexFileIn)> IndexContentsCallback)
135+
: IndexContentsCallback(IndexContentsCallback), Collector(C),
140136
PI(std::move(PI)), Opts(Opts) {
141137
this->Opts.ShouldTraverseDecl = [this](const Decl *D) {
142138
// Many operations performed during indexing is linear in terms of depth
@@ -161,9 +157,8 @@ class IndexAction : public ASTFrontendAction {
161157
std::unique_ptr<ASTConsumer>
162158
CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
163159
PI->record(CI.getPreprocessor());
164-
if (IncludeGraphCallback != nullptr)
165-
CI.getPreprocessor().addPPCallbacks(
166-
std::make_unique<IncludeGraphCollector>(CI.getSourceManager(), IG));
160+
CI.getPreprocessor().addPPCallbacks(
161+
std::make_unique<IncludeGraphCollector>(CI.getSourceManager(), IG));
167162

168163
return index::createIndexingASTConsumer(Collector, Opts,
169164
CI.getPreprocessorPtr());
@@ -185,26 +180,21 @@ class IndexAction : public ASTFrontendAction {
185180
}
186181

187182
void EndSourceFileAction() override {
188-
SymbolsCallback(Collector->takeSymbols());
189-
if (RefsCallback != nullptr)
190-
RefsCallback(Collector->takeRefs());
191-
if (RelationsCallback != nullptr)
192-
RelationsCallback(Collector->takeRelations());
193-
if (IncludeGraphCallback != nullptr) {
183+
IndexFileIn Result;
184+
Result.Symbols = Collector->takeSymbols();
185+
Result.Refs = Collector->takeRefs();
186+
Result.Relations = Collector->takeRelations();
194187
#ifndef NDEBUG
195188
// This checks if all nodes are initialized.
196189
for (const auto &Node : IG)
197190
assert(Node.getKeyData() == Node.getValue().URI.data());
198191
#endif
199-
IncludeGraphCallback(std::move(IG));
200-
}
192+
Result.Sources = std::move(IG);
193+
IndexContentsCallback(std::move(Result));
201194
}
202195

203196
private:
204-
std::function<void(SymbolSlab)> SymbolsCallback;
205-
std::function<void(RefSlab)> RefsCallback;
206-
std::function<void(RelationSlab)> RelationsCallback;
207-
std::function<void(IncludeGraph)> IncludeGraphCallback;
197+
std::function<void(IndexFileIn)> IndexContentsCallback;
208198
std::shared_ptr<SymbolCollector> Collector;
209199
std::unique_ptr<include_cleaner::PragmaIncludes> PI;
210200
index::IndexingOptions Opts;
@@ -215,10 +205,7 @@ class IndexAction : public ASTFrontendAction {
215205

216206
std::unique_ptr<FrontendAction> createStaticIndexingAction(
217207
SymbolCollector::Options Opts,
218-
std::function<void(SymbolSlab)> SymbolsCallback,
219-
std::function<void(RefSlab)> RefsCallback,
220-
std::function<void(RelationSlab)> RelationsCallback,
221-
std::function<void(IncludeGraph)> IncludeGraphCallback) {
208+
std::function<void(IndexFileIn)> IndexContentsCallback) {
222209
index::IndexingOptions IndexOpts;
223210
IndexOpts.SystemSymbolFilter =
224211
index::IndexingOptions::SystemSymbolFilterKind::All;
@@ -231,16 +218,13 @@ std::unique_ptr<FrontendAction> createStaticIndexingAction(
231218
if (Opts.Origin == SymbolOrigin::Unknown)
232219
Opts.Origin = SymbolOrigin::Static;
233220
Opts.StoreAllDocumentation = false;
234-
if (RefsCallback != nullptr) {
235-
Opts.RefFilter = RefKind::All;
236-
Opts.RefsInHeaders = true;
237-
}
221+
Opts.RefFilter = RefKind::All;
222+
Opts.RefsInHeaders = true;
238223
auto PragmaIncludes = std::make_unique<include_cleaner::PragmaIncludes>();
239224
Opts.PragmaIncludes = PragmaIncludes.get();
240225
return std::make_unique<IndexAction>(std::make_shared<SymbolCollector>(Opts),
241226
std::move(PragmaIncludes), IndexOpts,
242-
SymbolsCallback, RefsCallback,
243-
RelationsCallback, IncludeGraphCallback);
227+
IndexContentsCallback);
244228
}
245229

246230
} // namespace clangd

clang-tools-extra/clangd/index/IndexAction.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88

99
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEXACTION_H
1010
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEXACTION_H
11-
#include "Headers.h"
1211
#include "index/SymbolCollector.h"
1312
#include "clang/Frontend/FrontendAction.h"
1413

1514
namespace clang {
1615
namespace clangd {
1716

17+
struct IndexFileIn;
18+
1819
// Creates an action that indexes translation units and delivers the results
19-
// for SymbolsCallback (each slab corresponds to one TU).
20+
// for IndexContentsCallback (each call corresponds to one TU).
2021
//
2122
// Only a subset of SymbolCollector::Options are respected:
2223
// - include paths are always collected, and canonicalized appropriately
@@ -25,10 +26,7 @@ namespace clangd {
2526
// - the symbol origin is set to Static if not specified by caller
2627
std::unique_ptr<FrontendAction> createStaticIndexingAction(
2728
SymbolCollector::Options Opts,
28-
std::function<void(SymbolSlab)> SymbolsCallback,
29-
std::function<void(RefSlab)> RefsCallback,
30-
std::function<void(RelationSlab)> RelationsCallback,
31-
std::function<void(IncludeGraph)> IncludeGraphCallback);
29+
std::function<void(IndexFileIn)> IndexContentsCallback);
3230

3331
} // namespace clangd
3432
} // namespace clang

0 commit comments

Comments
 (0)