Skip to content

Commit 19860bb

Browse files
authored
merge main into amd-staging (llvm#3922)
2 parents 9745e53 + 989e392 commit 19860bb

File tree

77 files changed

+2963
-1671
lines changed

Some content is hidden

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

77 files changed

+2963
-1671
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ add_clang_library(clangTidyLLVMModule STATIC
1111
PreferRegisterOverUnsignedCheck.cpp
1212
PreferStaticOverAnonymousNamespaceCheck.cpp
1313
TwineLocalCheck.cpp
14+
UseNewMLIROpBuilderCheck.cpp
15+
UseRangesCheck.cpp
1416

1517
LINK_LIBS
1618
clangTidy
1719
clangTidyReadabilityModule
1820
clangTidyUtils
21+
clangTransformer
1922

2023
DEPENDS
2124
omp_gen

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "PreferRegisterOverUnsignedCheck.h"
1919
#include "PreferStaticOverAnonymousNamespaceCheck.h"
2020
#include "TwineLocalCheck.h"
21+
#include "UseNewMLIROpBuilderCheck.h"
22+
#include "UseRangesCheck.h"
2123

2224
namespace clang::tidy {
2325
namespace llvm_check {
@@ -40,6 +42,9 @@ class LLVMModule : public ClangTidyModule {
4042
CheckFactories.registerCheck<readability::QualifiedAutoCheck>(
4143
"llvm-qualified-auto");
4244
CheckFactories.registerCheck<TwineLocalCheck>("llvm-twine-local");
45+
CheckFactories.registerCheck<UseNewMlirOpBuilderCheck>(
46+
"llvm-use-new-mlir-op-builder");
47+
CheckFactories.registerCheck<UseRangesCheck>("llvm-use-ranges");
4348
}
4449

4550
ClangTidyOptions getModuleOptions() override {
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
//===--- UseNewMLIROpBuilderCheck.cpp - clang-tidy ------------------------===//
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 "UseNewMLIROpBuilderCheck.h"
10+
#include "clang/ASTMatchers/ASTMatchers.h"
11+
#include "clang/Basic/LLVM.h"
12+
#include "clang/Lex/Lexer.h"
13+
#include "clang/Tooling/Transformer/RangeSelector.h"
14+
#include "clang/Tooling/Transformer/RewriteRule.h"
15+
#include "clang/Tooling/Transformer/SourceCode.h"
16+
#include "clang/Tooling/Transformer/Stencil.h"
17+
#include "llvm/Support/Error.h"
18+
#include "llvm/Support/FormatVariadic.h"
19+
20+
namespace clang::tidy::llvm_check {
21+
namespace {
22+
23+
using namespace ::clang::ast_matchers;
24+
using namespace ::clang::transformer;
25+
26+
EditGenerator rewrite(RangeSelector Call, RangeSelector Builder,
27+
RangeSelector CallArgs) {
28+
// This is using an EditGenerator rather than ASTEdit as we want to warn even
29+
// if in macro.
30+
return [Call = std::move(Call), Builder = std::move(Builder),
31+
CallArgs =
32+
std::move(CallArgs)](const MatchFinder::MatchResult &Result)
33+
-> Expected<SmallVector<transformer::Edit, 1>> {
34+
Expected<CharSourceRange> CallRange = Call(Result);
35+
if (!CallRange)
36+
return CallRange.takeError();
37+
SourceManager &SM = *Result.SourceManager;
38+
const LangOptions &LangOpts = Result.Context->getLangOpts();
39+
SourceLocation Begin = CallRange->getBegin();
40+
41+
// This will result in just a warning and no edit.
42+
bool InMacro = CallRange->getBegin().isMacroID();
43+
if (InMacro) {
44+
while (SM.isMacroArgExpansion(Begin))
45+
Begin = SM.getImmediateExpansionRange(Begin).getBegin();
46+
Edit WarnOnly;
47+
WarnOnly.Kind = EditKind::Range;
48+
WarnOnly.Range = CharSourceRange::getCharRange(Begin, Begin);
49+
return SmallVector<Edit, 1>({WarnOnly});
50+
}
51+
52+
// This will try to extract the template argument as written so that the
53+
// rewritten code looks closest to original.
54+
auto NextToken = [&](std::optional<Token> CurrentToken) {
55+
if (!CurrentToken)
56+
return CurrentToken;
57+
if (CurrentToken->getEndLoc() >= CallRange->getEnd())
58+
return std::optional<Token>();
59+
return clang::Lexer::findNextToken(CurrentToken->getLocation(), SM,
60+
LangOpts);
61+
};
62+
std::optional<Token> LessToken =
63+
clang::Lexer::findNextToken(Begin, SM, LangOpts);
64+
while (LessToken && LessToken->getKind() != clang::tok::less) {
65+
LessToken = NextToken(LessToken);
66+
}
67+
if (!LessToken) {
68+
return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
69+
"missing '<' token");
70+
}
71+
std::optional<Token> EndToken = NextToken(LessToken);
72+
for (std::optional<Token> GreaterToken = NextToken(EndToken);
73+
GreaterToken && GreaterToken->getKind() != clang::tok::greater;
74+
GreaterToken = NextToken(GreaterToken)) {
75+
EndToken = GreaterToken;
76+
}
77+
if (!EndToken) {
78+
return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
79+
"missing '>' token");
80+
}
81+
82+
Expected<CharSourceRange> BuilderRange = Builder(Result);
83+
if (!BuilderRange)
84+
return BuilderRange.takeError();
85+
Expected<CharSourceRange> CallArgsRange = CallArgs(Result);
86+
if (!CallArgsRange)
87+
return CallArgsRange.takeError();
88+
89+
// Helper for concatting below.
90+
auto GetText = [&](const CharSourceRange &Range) {
91+
return clang::Lexer::getSourceText(Range, SM, LangOpts);
92+
};
93+
94+
Edit Replace;
95+
Replace.Kind = EditKind::Range;
96+
Replace.Range = *CallRange;
97+
std::string CallArgsStr;
98+
// Only emit args if there are any.
99+
if (auto CallArgsText = GetText(*CallArgsRange).ltrim();
100+
!CallArgsText.rtrim().empty()) {
101+
CallArgsStr = llvm::formatv(", {}", CallArgsText);
102+
}
103+
Replace.Replacement =
104+
llvm::formatv("{}::create({}{})",
105+
GetText(CharSourceRange::getTokenRange(
106+
LessToken->getEndLoc(), EndToken->getLastLoc())),
107+
GetText(*BuilderRange), CallArgsStr);
108+
109+
return SmallVector<Edit, 1>({Replace});
110+
};
111+
}
112+
113+
RewriteRuleWith<std::string> useNewMlirOpBuilderCheckRule() {
114+
Stencil message = cat("use 'OpType::create(builder, ...)' instead of "
115+
"'builder.create<OpType>(...)'");
116+
// Match a create call on an OpBuilder.
117+
ast_matchers::internal::Matcher<Stmt> base =
118+
cxxMemberCallExpr(
119+
on(expr(hasType(
120+
cxxRecordDecl(isSameOrDerivedFrom("::mlir::OpBuilder"))))
121+
.bind("builder")),
122+
callee(cxxMethodDecl(hasTemplateArgument(0, templateArgument()))),
123+
callee(cxxMethodDecl(hasName("create"))))
124+
.bind("call");
125+
return applyFirst(
126+
// Attempt rewrite given an lvalue builder, else just warn.
127+
{makeRule(cxxMemberCallExpr(unless(on(cxxTemporaryObjectExpr())), base),
128+
rewrite(node("call"), node("builder"), callArgs("call")),
129+
message),
130+
makeRule(base, noopEdit(node("call")), message)});
131+
}
132+
} // namespace
133+
134+
UseNewMlirOpBuilderCheck::UseNewMlirOpBuilderCheck(StringRef Name,
135+
ClangTidyContext *Context)
136+
: TransformerClangTidyCheck(useNewMlirOpBuilderCheckRule(), Name, Context) {
137+
}
138+
139+
} // namespace clang::tidy::llvm_check
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===--- UseNewMLIROpBuilderCheck.h - clang-tidy ----------------*- C++ -*-===//
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_USENEWMLIROPBUILDERCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USENEWMLIROPBUILDERCHECK_H
11+
12+
#include "../utils/TransformerClangTidyCheck.h"
13+
14+
namespace clang::tidy::llvm_check {
15+
16+
/// Checks for uses of MLIR's old/to be deprecated `OpBuilder::create<T>` form
17+
/// and suggests using `T::create` instead.
18+
class UseNewMlirOpBuilderCheck : public utils::TransformerClangTidyCheck {
19+
public:
20+
UseNewMlirOpBuilderCheck(StringRef Name, ClangTidyContext *Context);
21+
22+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
23+
return getLangOpts().CPlusPlus;
24+
}
25+
};
26+
27+
} // namespace clang::tidy::llvm_check
28+
29+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USENEWMLIROPBUILDERCHECK_H
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//===--- UseRangesCheck.cpp - clang-tidy ----------------------------------===//
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 "UseRangesCheck.h"
10+
11+
namespace clang::tidy::llvm_check {
12+
13+
namespace {
14+
15+
class StdToLLVMReplacer : public utils::UseRangesCheck::Replacer {
16+
public:
17+
explicit StdToLLVMReplacer(
18+
ArrayRef<utils::UseRangesCheck::Signature> Signatures)
19+
: Signatures(Signatures) {}
20+
21+
ArrayRef<utils::UseRangesCheck::Signature>
22+
getReplacementSignatures() const override {
23+
return Signatures;
24+
}
25+
26+
std::optional<std::string>
27+
getReplaceName(const NamedDecl &OriginalName) const override {
28+
return ("llvm::" + OriginalName.getName()).str();
29+
}
30+
31+
std::optional<std::string>
32+
getHeaderInclusion(const NamedDecl &) const override {
33+
return "llvm/ADT/STLExtras.h";
34+
}
35+
36+
private:
37+
ArrayRef<utils::UseRangesCheck::Signature> Signatures;
38+
};
39+
40+
} // namespace
41+
42+
utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const {
43+
ReplacerMap Results;
44+
45+
static const Signature SingleSig = {{0}};
46+
static const Signature TwoSig = {{0}, {2}};
47+
48+
const auto AddStdToLLVM =
49+
[&Results](llvm::IntrusiveRefCntPtr<Replacer> Replacer,
50+
std::initializer_list<StringRef> Names) {
51+
for (const auto &Name : Names) {
52+
Results.try_emplace(("::std::" + Name).str(), Replacer);
53+
}
54+
};
55+
56+
// Single range algorithms
57+
AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(SingleSig),
58+
{"all_of", "any_of",
59+
"none_of", "for_each",
60+
"find", "find_if",
61+
"find_if_not", "fill",
62+
"count", "count_if",
63+
"copy", "copy_if",
64+
"transform", "replace",
65+
"remove_if", "stable_sort",
66+
"partition", "partition_point",
67+
"is_sorted", "min_element",
68+
"max_element", "binary_search",
69+
"lower_bound", "upper_bound",
70+
"unique", "uninitialized_copy"});
71+
72+
// Two range algorithms
73+
AddStdToLLVM(llvm::makeIntrusiveRefCnt<StdToLLVMReplacer>(TwoSig),
74+
{"equal", "mismatch", "includes"});
75+
76+
return Results;
77+
}
78+
79+
UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context)
80+
: utils::UseRangesCheck(Name, Context) {}
81+
82+
DiagnosticBuilder UseRangesCheck::createDiag(const CallExpr &Call) {
83+
return diag(Call.getBeginLoc(), "use an LLVM range-based algorithm");
84+
}
85+
86+
ArrayRef<std::pair<StringRef, StringRef>>
87+
UseRangesCheck::getFreeBeginEndMethods() const {
88+
static constexpr std::pair<StringRef, StringRef> Refs[] = {
89+
{"::std::begin", "::std::end"},
90+
{"::std::cbegin", "::std::cend"},
91+
{"::std::rbegin", "::std::rend"},
92+
{"::std::crbegin", "::std::crend"},
93+
};
94+
return Refs;
95+
}
96+
97+
} // namespace clang::tidy::llvm_check
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===--- UseRangesCheck.h - clang-tidy --------------------------*- C++ -*-===//
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_USERANGESCHECK_H
10+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USERANGESCHECK_H
11+
12+
#include "../utils/UseRangesCheck.h"
13+
14+
namespace clang::tidy::llvm_check {
15+
16+
/// Finds calls to STL iterator algorithms that can be replaced with LLVM
17+
/// range-based algorithms from `llvm/ADT/STLExtras.h`.
18+
///
19+
/// For the user-facing documentation see:
20+
/// http://clang.llvm.org/extra/clang-tidy/checks/llvm/use-ranges.html
21+
class UseRangesCheck : public utils::UseRangesCheck {
22+
public:
23+
UseRangesCheck(StringRef Name, ClangTidyContext *Context);
24+
25+
ReplacerMap getReplacerMap() const override;
26+
DiagnosticBuilder createDiag(const CallExpr &Call) override;
27+
ArrayRef<std::pair<StringRef, StringRef>>
28+
getFreeBeginEndMethods() const override;
29+
};
30+
31+
} // namespace clang::tidy::llvm_check
32+
33+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_LLVM_USERANGESCHECK_H

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ def main():
258258
help="Upgrades clang-tidy warnings to errors. Same format as '-checks'.",
259259
default="",
260260
)
261+
parser.add_argument(
262+
"-hide-progress",
263+
action="store_true",
264+
help="Hide progress",
265+
)
261266

262267
clang_tidy_args = []
263268
argv = sys.argv[1:]
@@ -312,7 +317,8 @@ def main():
312317
if max_task_count == 0:
313318
max_task_count = multiprocessing.cpu_count()
314319
max_task_count = min(len(lines_by_file), max_task_count)
315-
print(f"Running clang-tidy in {max_task_count} threads...")
320+
if not args.hide_progress:
321+
print(f"Running clang-tidy in {max_task_count} threads...")
316322

317323
combine_fixes = False
318324
export_fixes_dir = None
@@ -408,7 +414,8 @@ def main():
408414
return_code = 1
409415

410416
if combine_fixes:
411-
print("Writing fixes to " + args.export_fixes + " ...")
417+
if not args.hide_progress:
418+
print(f"Writing fixes to {args.export_fixes} ...")
412419
try:
413420
merge_replacement_files(export_fixes_dir, args.export_fixes)
414421
except:

0 commit comments

Comments
 (0)