Skip to content

Commit 6312650

Browse files
Merge branch 'main' into ldstpair
2 parents 19a8ab6 + 96c5b8c commit 6312650

File tree

401 files changed

+12537
-5677
lines changed

Some content is hidden

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

401 files changed

+12537
-5677
lines changed

.github/new-prs-labeler.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,30 @@ backend:X86:
822822
- llvm/lib/TargetParser/X86*
823823
- llvm/utils/TableGen/X86*
824824

825+
backend:PowerPC:
826+
- llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC*
827+
- llvm/include/llvm/BinaryFormat/XCOFF.h
828+
- llvm/include/llvm/IR/IntrinsicsPowerPC.td
829+
- llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
830+
- llvm/lib/Target/PowerPC/**
831+
- llvm/test/Analysis/**/PowerPC/**
832+
- llvm/test/CodeGen/PowerPC/**
833+
- llvm/test/CodeGen/MIR/PowerPC/**
834+
- llvm/test/DebugInfo/XCOFF/**
835+
- llvm/test/DebugInfo/PowerPC/**
836+
- llvm/test/LTO/PowerPC/**
837+
- llvm/test/MC/Disassembler/PowerPC/**
838+
- llvm/test/MC/PowerPC/**
839+
- llvm/test/MC/XCOFF/**
840+
- llvm/test/Transforms/**/PowerPC/**
841+
- clang/include/clang/Basic/BuiltinsPPC.*
842+
- clang/lib/Basic/Targets/PPC.*
843+
- clang/lib/CodeGen/Targets/PPC.cpp
844+
- clang/lib/Driver/ToolChains/PPC*
845+
- clang/lib/Driver/ToolChains/AIX*
846+
- clang/lib/Driver/ToolChains/Arch/PPC.*
847+
- clang/test/CodeGen/PowerPC/**
848+
825849
third-party:unittests:
826850
- third-party/unittests/**
827851

bolt/tools/merge-fdata/merge-fdata.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
317317
ThreadPoolStrategy S = optimal_concurrency(
318318
std::max(Filenames.size() / 4, static_cast<size_t>(1)));
319319
ThreadPool Pool(S);
320-
DenseMap<llvm::thread::id, ProfileTy> ParsedProfiles(Pool.getThreadCount());
320+
DenseMap<llvm::thread::id, ProfileTy> ParsedProfiles(
321+
Pool.getMaxConcurrency());
321322
for (const auto &Filename : Filenames)
322323
Pool.async(ParseProfile, std::cref(Filename), std::ref(ParsedProfiles));
323324
Pool.wait();

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,23 @@ std::optional<int64_t> decodeVersion(llvm::StringRef Encoded) {
7373

7474
const llvm::StringLiteral ApplyFixCommand = "clangd.applyFix";
7575
const llvm::StringLiteral ApplyTweakCommand = "clangd.applyTweak";
76+
const llvm::StringLiteral ApplyRenameCommand = "clangd.applyRename";
77+
78+
CodeAction toCodeAction(const ClangdServer::CodeActionResult::Rename &R,
79+
const URIForFile &File) {
80+
CodeAction CA;
81+
CA.title = R.FixMessage;
82+
CA.kind = std::string(CodeAction::REFACTOR_KIND);
83+
CA.command.emplace();
84+
CA.command->title = R.FixMessage;
85+
CA.command->command = std::string(ApplyRenameCommand);
86+
RenameParams Params;
87+
Params.textDocument = TextDocumentIdentifier{File};
88+
Params.position = R.Diag.Range.start;
89+
Params.newName = R.NewName;
90+
CA.command->argument = Params;
91+
return CA;
92+
}
7693

7794
/// Transforms a tweak into a code action that would apply it if executed.
7895
/// EXPECTS: T.prepare() was called and returned true.
@@ -808,6 +825,16 @@ void ClangdLSPServer::onCommandApplyTweak(const TweakArgs &Args,
808825
std::move(Action));
809826
}
810827

828+
void ClangdLSPServer::onCommandApplyRename(const RenameParams &R,
829+
Callback<llvm::json::Value> Reply) {
830+
onRename(R, [this, Reply = std::move(Reply)](
831+
llvm::Expected<WorkspaceEdit> Edit) mutable {
832+
if (!Edit)
833+
Reply(Edit.takeError());
834+
applyEdit(std::move(*Edit), "Rename applied.", std::move(Reply));
835+
});
836+
}
837+
811838
void ClangdLSPServer::applyEdit(WorkspaceEdit WE, llvm::json::Value Success,
812839
Callback<llvm::json::Value> Reply) {
813840
ApplyWorkspaceEditParams Edit;
@@ -1046,6 +1073,10 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params,
10461073
CAs.back().diagnostics = {It->second};
10471074
}
10481075
}
1076+
1077+
for (const auto &R : Fixits->Renames)
1078+
CAs.push_back(toCodeAction(R, File));
1079+
10491080
for (const auto &TR : Fixits->TweakRefs)
10501081
CAs.push_back(toCodeAction(TR, File, Selection));
10511082

@@ -1667,6 +1698,7 @@ void ClangdLSPServer::bindMethods(LSPBinder &Bind,
16671698
Bind.method("textDocument/foldingRange", this, &ClangdLSPServer::onFoldingRange);
16681699
Bind.command(ApplyFixCommand, this, &ClangdLSPServer::onCommandApplyEdit);
16691700
Bind.command(ApplyTweakCommand, this, &ClangdLSPServer::onCommandApplyTweak);
1701+
Bind.command(ApplyRenameCommand, this, &ClangdLSPServer::onCommandApplyRename);
16701702

16711703
ApplyWorkspaceEdit = Bind.outgoingMethod("workspace/applyEdit");
16721704
PublishDiagnostics = Bind.outgoingNotification("textDocument/publishDiagnostics");

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
174174
/// Implement commands.
175175
void onCommandApplyEdit(const WorkspaceEdit &, Callback<llvm::json::Value>);
176176
void onCommandApplyTweak(const TweakArgs &, Callback<llvm::json::Value>);
177+
void onCommandApplyRename(const RenameParams &, Callback<llvm::json::Value>);
177178

178179
/// Outgoing LSP calls.
179180
LSPBinder::OutgoingMethod<ApplyWorkspaceEditParams,

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -625,9 +625,10 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
625625
WorkScheduler->runWithAST("Rename", File, std::move(Action));
626626
}
627627

628+
namespace {
628629
// May generate several candidate selections, due to SelectionTree ambiguity.
629630
// vector of pointers because GCC doesn't like non-copyable Selection.
630-
static llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>>
631+
llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>>
631632
tweakSelection(const Range &Sel, const InputsAndAST &AST,
632633
llvm::vfs::FileSystem *FS) {
633634
auto Begin = positionToOffset(AST.Inputs.Contents, Sel.start);
@@ -648,6 +649,27 @@ tweakSelection(const Range &Sel, const InputsAndAST &AST,
648649
return std::move(Result);
649650
}
650651

652+
// Some fixes may perform local renaming, we want to convert those to clangd
653+
// rename commands, such that we can leverage the index for more accurate
654+
// results.
655+
std::optional<ClangdServer::CodeActionResult::Rename>
656+
tryConvertToRename(const Diag *Diag, const Fix &Fix) {
657+
bool IsClangTidyRename = Diag->Source == Diag::ClangTidy &&
658+
Diag->Name == "readability-identifier-naming" &&
659+
!Fix.Edits.empty();
660+
if (IsClangTidyRename && Diag->InsideMainFile) {
661+
ClangdServer::CodeActionResult::Rename R;
662+
R.NewName = Fix.Edits.front().newText;
663+
R.FixMessage = Fix.Message;
664+
R.Diag = {Diag->Range, Diag->Message};
665+
return R;
666+
}
667+
668+
return std::nullopt;
669+
}
670+
671+
} // namespace
672+
651673
void ClangdServer::codeAction(const CodeActionInputs &Params,
652674
Callback<CodeActionResult> CB) {
653675
auto Action = [Params, CB = std::move(CB),
@@ -668,16 +690,22 @@ void ClangdServer::codeAction(const CodeActionInputs &Params,
668690
CodeActionResult Result;
669691
Result.Version = InpAST->AST.version().str();
670692
if (KindAllowed(CodeAction::QUICKFIX_KIND)) {
671-
auto FindMatchedFixes =
672-
[&InpAST](const DiagRef &DR) -> llvm::ArrayRef<Fix> {
693+
auto FindMatchedDiag = [&InpAST](const DiagRef &DR) -> const Diag * {
673694
for (const auto &Diag : InpAST->AST.getDiagnostics())
674695
if (Diag.Range == DR.Range && Diag.Message == DR.Message)
675-
return Diag.Fixes;
676-
return {};
696+
return &Diag;
697+
return nullptr;
677698
};
678-
for (const auto &Diag : Params.Diagnostics)
679-
for (const auto &Fix : FindMatchedFixes(Diag))
680-
Result.QuickFixes.push_back({Diag, Fix});
699+
for (const auto &DiagRef : Params.Diagnostics) {
700+
if (const auto *Diag = FindMatchedDiag(DiagRef))
701+
for (const auto &Fix : Diag->Fixes) {
702+
if (auto Rename = tryConvertToRename(Diag, Fix)) {
703+
Result.Renames.emplace_back(std::move(*Rename));
704+
} else {
705+
Result.QuickFixes.push_back({DiagRef, Fix});
706+
}
707+
}
708+
}
681709
}
682710

683711
// Collect Tweaks

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,12 @@ class ClangdServer {
380380
};
381381
std::vector<QuickFix> QuickFixes;
382382
std::vector<TweakRef> TweakRefs;
383+
struct Rename {
384+
DiagRef Diag;
385+
std::string FixMessage;
386+
std::string NewName;
387+
};
388+
std::vector<Rename> Renames;
383389
};
384390
/// Surface code actions (quick-fixes for diagnostics, or available code
385391
/// tweaks) for a given range in a file.

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,14 @@ bool fromJSON(const llvm::json::Value &Params, RenameParams &R,
11871187
O.map("position", R.position) && O.map("newName", R.newName);
11881188
}
11891189

1190+
llvm::json::Value toJSON(const RenameParams &R) {
1191+
return llvm::json::Object{
1192+
{"textDocument", R.textDocument},
1193+
{"position", R.position},
1194+
{"newName", R.newName},
1195+
};
1196+
}
1197+
11901198
llvm::json::Value toJSON(const PrepareRenameResult &PRR) {
11911199
if (PRR.placeholder.empty())
11921200
return toJSON(PRR.range);

clang-tools-extra/clangd/Protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,6 +1435,7 @@ struct RenameParams {
14351435
std::string newName;
14361436
};
14371437
bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);
1438+
llvm::json::Value toJSON(const RenameParams &);
14381439

14391440
struct PrepareRenameResult {
14401441
/// Range of the string to rename.

clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,8 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
468468
// Extracting Exprs like a = 1 gives placeholder = a = 1 which isn't useful.
469469
// FIXME: we could still hoist the assignment, and leave the variable there?
470470
ParsedBinaryOperator BinOp;
471-
if (BinOp.parse(*N) && BinaryOperator::isAssignmentOp(BinOp.Kind))
471+
bool IsBinOp = BinOp.parse(*N);
472+
if (IsBinOp && BinaryOperator::isAssignmentOp(BinOp.Kind))
472473
return false;
473474

474475
const SelectionTree::Node &OuterImplicit = N->outerImplicit();
@@ -483,13 +484,48 @@ bool eligibleForExtraction(const SelectionTree::Node *N) {
483484
OuterImplicit.ASTNode.get<Expr>()))
484485
return false;
485486

487+
std::function<bool(const SelectionTree::Node *)> IsFullySelected =
488+
[&](const SelectionTree::Node *N) {
489+
if (N->ASTNode.getSourceRange().isValid() &&
490+
N->Selected != SelectionTree::Complete)
491+
return false;
492+
for (const auto *Child : N->Children) {
493+
if (!IsFullySelected(Child))
494+
return false;
495+
}
496+
return true;
497+
};
498+
auto ExprIsFullySelectedTargetNode = [&](const Expr *E) {
499+
if (E != OuterImplicit.ASTNode.get<Expr>())
500+
return false;
501+
502+
// The above condition is the only relevant one except for binary operators.
503+
// Without the following code, we would fail to offer extraction for e.g.:
504+
// int x = 1 + 2 + [[3 + 4 + 5]];
505+
// See the documentation of ParsedBinaryOperator for further details.
506+
if (!IsBinOp)
507+
return true;
508+
return IsFullySelected(N);
509+
};
510+
486511
// Disable extraction of full RHS on assignment operations, e.g:
487-
// auto x = [[RHS_EXPR]];
512+
// x = [[RHS_EXPR]];
488513
// This would just result in duplicating the code.
489514
if (const auto *BO = Parent->ASTNode.get<BinaryOperator>()) {
490-
if (BO->isAssignmentOp() &&
491-
BO->getRHS() == OuterImplicit.ASTNode.get<Expr>())
515+
if (BO->isAssignmentOp() && ExprIsFullySelectedTargetNode(BO->getRHS()))
516+
return false;
517+
}
518+
519+
// The same logic as for assignments applies to initializations.
520+
// However, we do allow extracting the RHS of an init capture, as it is
521+
// a valid use case to move non-trivial expressions out of the capture clause.
522+
// FIXME: In that case, the extracted variable should be captured directly,
523+
// rather than an explicit copy.
524+
if (const auto *Decl = Parent->ASTNode.get<VarDecl>()) {
525+
if (!Decl->isInitCapture() &&
526+
ExprIsFullySelectedTargetNode(Decl->getInit())) {
492527
return false;
528+
}
493529
}
494530

495531
return true;

clang-tools-extra/clangd/test/initialize-params.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
# CHECK-NEXT: "executeCommandProvider": {
4141
# CHECK-NEXT: "commands": [
4242
# CHECK-NEXT: "clangd.applyFix",
43+
# CHECK-NEXT: "clangd.applyRename"
4344
# CHECK-NEXT: "clangd.applyTweak"
4445
# CHECK-NEXT: ]
4546
# CHECK-NEXT: },

clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,67 @@ TEST_F(LSPTest, RecordsLatencies) {
195195
EXPECT_THAT(Tracer.takeMetric("lsp_latency", MethodName), testing::SizeIs(1));
196196
}
197197

198+
// clang-tidy's renames are converted to clangd's internal rename functionality,
199+
// see clangd#1589 and clangd#741
200+
TEST_F(LSPTest, ClangTidyRename) {
201+
Annotations Header(R"cpp(
202+
void [[foo]]();
203+
)cpp");
204+
Annotations Source(R"cpp(
205+
void [[foo]]() {}
206+
)cpp");
207+
Opts.ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
208+
llvm::StringRef) {
209+
ClangTidyOpts.Checks = {"-*,readability-identifier-naming"};
210+
ClangTidyOpts.CheckOptions["readability-identifier-naming.FunctionCase"] =
211+
"CamelCase";
212+
};
213+
auto &Client = start();
214+
Client.didOpen("foo.hpp", Header.code());
215+
Client.didOpen("foo.cpp", Source.code());
216+
217+
auto RenameDiag = Client.diagnostics("foo.cpp").value().at(0);
218+
219+
auto RenameCommand =
220+
(*Client
221+
.call("textDocument/codeAction",
222+
llvm::json::Object{
223+
{"textDocument", Client.documentID("foo.cpp")},
224+
{"context",
225+
llvm::json::Object{
226+
{"diagnostics", llvm::json::Array{RenameDiag}}}},
227+
{"range", Source.range()}})
228+
.takeValue()
229+
.getAsArray())[0];
230+
231+
ASSERT_EQ((*RenameCommand.getAsObject())["title"], "change 'foo' to 'Foo'");
232+
233+
Client.expectServerCall("workspace/applyEdit");
234+
Client.call("workspace/executeCommand", RenameCommand);
235+
Client.sync();
236+
237+
auto Params = Client.takeCallParams("workspace/applyEdit");
238+
auto Uri = [&](llvm::StringRef Path) {
239+
return Client.uri(Path).getAsString().value().str();
240+
};
241+
llvm::json::Object ExpectedEdit = llvm::json::Object{
242+
{"edit", llvm::json::Object{
243+
{"changes",
244+
llvm::json::Object{
245+
{Uri("foo.hpp"), llvm::json::Array{llvm::json::Object{
246+
{"range", Header.range()},
247+
{"newText", "Foo"},
248+
}}},
249+
250+
{Uri("foo.cpp"), llvm::json::Array{llvm::json::Object{
251+
{"range", Source.range()},
252+
{"newText", "Foo"},
253+
}}}
254+
255+
}}}}};
256+
EXPECT_EQ(Params, std::vector{llvm::json::Value(std::move(ExpectedEdit))});
257+
}
258+
198259
TEST_F(LSPTest, IncomingCalls) {
199260
Annotations Code(R"cpp(
200261
void calle^e(int);

0 commit comments

Comments
 (0)