Skip to content

Commit 5bcde12

Browse files
authored
Merge branch 'main' into users/el-ev/cleanup-c-fn-noproto
2 parents 02b5829 + 5d136f9 commit 5bcde12

File tree

661 files changed

+132307
-67322
lines changed

Some content is hidden

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

661 files changed

+132307
-67322
lines changed

bolt/lib/Core/MCPlusBuilder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,10 +442,10 @@ void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {
442442
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
443443
Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
444444

445-
for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
446-
if (!Inst.getOperand(I).isReg())
445+
for (const MCOperand &Operand : useOperands(Inst)) {
446+
if (!Operand.isReg())
447447
continue;
448-
Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true);
448+
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
449449
}
450450
}
451451

bolt/unittests/Core/MCPlusBuilder.cpp

Lines changed: 122 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#ifdef AARCH64_AVAILABLE
1010
#include "AArch64Subtarget.h"
11+
#include "MCTargetDesc/AArch64MCTargetDesc.h"
1112
#endif // AARCH64_AVAILABLE
1213

1314
#ifdef X86_AVAILABLE
@@ -19,6 +20,7 @@
1920
#include "bolt/Rewrite/RewriteInstance.h"
2021
#include "llvm/BinaryFormat/ELF.h"
2122
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
23+
#include "llvm/MC/MCInstBuilder.h"
2224
#include "llvm/Support/TargetSelect.h"
2325
#include "gtest/gtest.h"
2426

@@ -70,16 +72,28 @@ struct MCPlusBuilderTester : public testing::TestWithParam<Triple::ArchType> {
7072
BC->MRI.get(), BC->STI.get())));
7173
}
7274

75+
void assertRegMask(const BitVector &RegMask,
76+
std::initializer_list<MCPhysReg> ExpectedRegs) {
77+
ASSERT_EQ(RegMask.count(), ExpectedRegs.size());
78+
for (MCPhysReg Reg : ExpectedRegs)
79+
ASSERT_TRUE(RegMask[Reg]) << "Expected " << BC->MRI->getName(Reg) << ".";
80+
}
81+
82+
void assertRegMask(std::function<void(BitVector &)> FillRegMask,
83+
std::initializer_list<MCPhysReg> ExpectedRegs) {
84+
BitVector RegMask(BC->MRI->getNumRegs());
85+
FillRegMask(RegMask);
86+
assertRegMask(RegMask, ExpectedRegs);
87+
}
88+
7389
void testRegAliases(Triple::ArchType Arch, uint64_t Register,
74-
uint64_t *Aliases, size_t Count,
90+
std::initializer_list<MCPhysReg> ExpectedAliases,
7591
bool OnlySmaller = false) {
7692
if (GetParam() != Arch)
7793
GTEST_SKIP();
7894

7995
const BitVector &BV = BC->MIB->getAliases(Register, OnlySmaller);
80-
ASSERT_EQ(BV.count(), Count);
81-
for (size_t I = 0; I < Count; ++I)
82-
ASSERT_TRUE(BV[Aliases[I]]);
96+
assertRegMask(BV, ExpectedAliases);
8397
}
8498

8599
char ElfBuf[sizeof(typename ELF64LE::Ehdr)] = {};
@@ -94,17 +108,15 @@ INSTANTIATE_TEST_SUITE_P(AArch64, MCPlusBuilderTester,
94108
::testing::Values(Triple::aarch64));
95109

96110
TEST_P(MCPlusBuilderTester, AliasX0) {
97-
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI,
98-
AArch64::X0, AArch64::W0_W1,
99-
AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7};
100-
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
101-
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count);
111+
testRegAliases(Triple::aarch64, AArch64::X0,
112+
{AArch64::W0, AArch64::W0_HI, AArch64::X0, AArch64::W0_W1,
113+
AArch64::X0_X1, AArch64::X0_X1_X2_X3_X4_X5_X6_X7});
102114
}
103115

104116
TEST_P(MCPlusBuilderTester, AliasSmallerX0) {
105-
uint64_t AliasesX0[] = {AArch64::W0, AArch64::W0_HI, AArch64::X0};
106-
size_t AliasesX0Count = sizeof(AliasesX0) / sizeof(*AliasesX0);
107-
testRegAliases(Triple::aarch64, AArch64::X0, AliasesX0, AliasesX0Count, true);
117+
testRegAliases(Triple::aarch64, AArch64::X0,
118+
{AArch64::W0, AArch64::W0_HI, AArch64::X0},
119+
/*OnlySmaller=*/true);
108120
}
109121

110122
TEST_P(MCPlusBuilderTester, AArch64_CmpJE) {
@@ -155,6 +167,100 @@ TEST_P(MCPlusBuilderTester, AArch64_CmpJNE) {
155167
ASSERT_EQ(Label, BB->getLabel());
156168
}
157169

170+
TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitDef) {
171+
if (GetParam() != Triple::aarch64)
172+
GTEST_SKIP();
173+
174+
// adds x0, x5, #42
175+
MCInst Inst = MCInstBuilder(AArch64::ADDSXri)
176+
.addReg(AArch64::X0)
177+
.addReg(AArch64::X5)
178+
.addImm(42)
179+
.addImm(0);
180+
181+
assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
182+
{AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI,
183+
AArch64::X0_X1_X2_X3_X4_X5_X6_X7, AArch64::W0_W1,
184+
AArch64::X0_X1});
185+
186+
assertRegMask(
187+
[&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
188+
{AArch64::NZCV, AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5,
189+
AArch64::W0_HI, AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
190+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
191+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
192+
193+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); },
194+
{AArch64::NZCV, AArch64::W0, AArch64::X0, AArch64::W0_HI});
195+
196+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
197+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
198+
199+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
200+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
201+
}
202+
203+
TEST_P(MCPlusBuilderTester, testAccessedRegsImplicitUse) {
204+
if (GetParam() != Triple::aarch64)
205+
GTEST_SKIP();
206+
207+
// b.eq <label>
208+
MCInst Inst =
209+
MCInstBuilder(AArch64::Bcc)
210+
.addImm(AArch64CC::EQ)
211+
.addImm(0); // <label> - should be Expr, but immediate 0 works too.
212+
213+
assertRegMask([&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
214+
{});
215+
216+
assertRegMask([&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
217+
{AArch64::NZCV});
218+
219+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); }, {});
220+
221+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
222+
{AArch64::NZCV});
223+
224+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
225+
{AArch64::NZCV});
226+
}
227+
228+
TEST_P(MCPlusBuilderTester, testAccessedRegsMultipleDefs) {
229+
if (GetParam() != Triple::aarch64)
230+
GTEST_SKIP();
231+
232+
// ldr x0, [x5], #16
233+
MCInst Inst = MCInstBuilder(AArch64::LDRXpost)
234+
.addReg(AArch64::X5)
235+
.addReg(AArch64::X0)
236+
.addReg(AArch64::X5)
237+
.addImm(16);
238+
239+
assertRegMask(
240+
[&](BitVector &BV) { BC->MIB->getClobberedRegs(Inst, BV); },
241+
{AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
242+
AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
243+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
244+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
245+
246+
assertRegMask(
247+
[&](BitVector &BV) { BC->MIB->getTouchedRegs(Inst, BV); },
248+
{AArch64::W0, AArch64::W5, AArch64::X0, AArch64::X5, AArch64::W0_HI,
249+
AArch64::W5_HI, AArch64::X0_X1_X2_X3_X4_X5_X6_X7,
250+
AArch64::X2_X3_X4_X5_X6_X7_X8_X9, AArch64::X4_X5_X6_X7_X8_X9_X10_X11,
251+
AArch64::W0_W1, AArch64::W4_W5, AArch64::X0_X1, AArch64::X4_X5});
252+
253+
assertRegMask([&](BitVector &BV) { BC->MIB->getWrittenRegs(Inst, BV); },
254+
{AArch64::W0, AArch64::X0, AArch64::W0_HI, AArch64::W5,
255+
AArch64::X5, AArch64::W5_HI});
256+
257+
assertRegMask([&](BitVector &BV) { BC->MIB->getUsedRegs(Inst, BV); },
258+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
259+
260+
assertRegMask([&](BitVector &BV) { BC->MIB->getSrcRegs(Inst, BV); },
261+
{AArch64::W5, AArch64::X5, AArch64::W5_HI});
262+
}
263+
158264
#endif // AARCH64_AVAILABLE
159265

160266
#ifdef X86_AVAILABLE
@@ -163,15 +269,13 @@ INSTANTIATE_TEST_SUITE_P(X86, MCPlusBuilderTester,
163269
::testing::Values(Triple::x86_64));
164270

165271
TEST_P(MCPlusBuilderTester, AliasAX) {
166-
uint64_t AliasesAX[] = {X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH};
167-
size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX);
168-
testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount);
272+
testRegAliases(Triple::x86_64, X86::AX,
273+
{X86::RAX, X86::EAX, X86::AX, X86::AL, X86::AH});
169274
}
170275

171276
TEST_P(MCPlusBuilderTester, AliasSmallerAX) {
172-
uint64_t AliasesAX[] = {X86::AX, X86::AL, X86::AH};
173-
size_t AliasesAXCount = sizeof(AliasesAX) / sizeof(*AliasesAX);
174-
testRegAliases(Triple::x86_64, X86::AX, AliasesAX, AliasesAXCount, true);
277+
testRegAliases(Triple::x86_64, X86::AX, {X86::AX, X86::AL, X86::AH},
278+
/*OnlySmaller=*/true);
175279
}
176280

177281
TEST_P(MCPlusBuilderTester, ReplaceRegWithImm) {

clang-tools-extra/clang-doc/Serialize.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,7 @@ static bool isPublic(const clang::AccessSpecifier AS,
261261
const clang::Linkage Link) {
262262
if (AS == clang::AccessSpecifier::AS_private)
263263
return false;
264-
else if ((Link == clang::Linkage::Module) ||
265-
(Link == clang::Linkage::External))
264+
if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
266265
return true;
267266
return false; // otherwise, linkage is some form of internal linkage
268267
}

clang-tools-extra/clangd/XRefs.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,7 +2380,7 @@ outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
23802380
// Initially store the ranges in a map keyed by SymbolID of the callee.
23812381
// This allows us to group different calls to the same function
23822382
// into the same CallHierarchyOutgoingCall.
2383-
llvm::DenseMap<SymbolID, std::vector<Range>> CallsOut;
2383+
llvm::DenseMap<SymbolID, std::vector<Location>> CallsOut;
23842384
// We can populate the ranges based on a refs request only. As we do so, we
23852385
// also accumulate the callee IDs into a lookup request.
23862386
LookupRequest CallsOutLookup;
@@ -2390,8 +2390,8 @@ outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
23902390
elog("outgoingCalls failed to convert location: {0}", Loc.takeError());
23912391
return;
23922392
}
2393-
auto It = CallsOut.try_emplace(R.Symbol, std::vector<Range>{}).first;
2394-
It->second.push_back(Loc->range);
2393+
auto It = CallsOut.try_emplace(R.Symbol, std::vector<Location>{}).first;
2394+
It->second.push_back(*Loc);
23952395

23962396
CallsOutLookup.IDs.insert(R.Symbol);
23972397
});
@@ -2411,9 +2411,22 @@ outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
24112411

24122412
auto It = CallsOut.find(Callee.ID);
24132413
assert(It != CallsOut.end());
2414-
if (auto CHI = symbolToCallHierarchyItem(Callee, Item.uri.file()))
2414+
if (auto CHI = symbolToCallHierarchyItem(Callee, Item.uri.file())) {
2415+
std::vector<Range> FromRanges;
2416+
for (const Location &L : It->second) {
2417+
if (L.uri != Item.uri) {
2418+
// Call location not in same file as the item that outgoingCalls was
2419+
// requested for. This can happen when Item is a declaration separate
2420+
// from the implementation. There's not much we can do, since the
2421+
// protocol only allows returning ranges interpreted as being in
2422+
// Item's file.
2423+
continue;
2424+
}
2425+
FromRanges.push_back(L.range);
2426+
}
24152427
Results.push_back(
2416-
CallHierarchyOutgoingCall{std::move(*CHI), std::move(It->second)});
2428+
CallHierarchyOutgoingCall{std::move(*CHI), std::move(FromRanges)});
2429+
}
24172430
});
24182431
// Sort results by name of the callee.
24192432
llvm::sort(Results, [](const CallHierarchyOutgoingCall &A,

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ using ::testing::UnorderedElementsAre;
4545
// Helpers for matching call hierarchy data structures.
4646
MATCHER_P(withName, N, "") { return arg.name == N; }
4747
MATCHER_P(withDetail, N, "") { return arg.detail == N; }
48+
MATCHER_P(withFile, N, "") { return arg.uri.file() == N; }
4849
MATCHER_P(withSelectionRange, R, "") { return arg.selectionRange == R; }
4950

5051
template <class ItemMatcher>
@@ -383,18 +384,28 @@ TEST(CallHierarchy, MultiFileCpp) {
383384
EXPECT_THAT(IncomingLevel4, IsEmpty());
384385
};
385386

386-
auto CheckOutgoingCalls = [&](ParsedAST &AST, Position Pos, PathRef TUPath) {
387+
auto CheckOutgoingCalls = [&](ParsedAST &AST, Position Pos, PathRef TUPath,
388+
bool IsDeclaration) {
387389
std::vector<CallHierarchyItem> Items =
388390
prepareCallHierarchy(AST, Pos, TUPath);
389-
ASSERT_THAT(Items, ElementsAre(withName("caller3")));
391+
ASSERT_THAT(
392+
Items,
393+
ElementsAre(AllOf(
394+
withName("caller3"),
395+
withFile(testPath(IsDeclaration ? "caller3.hh" : "caller3.cc")))));
390396
auto OutgoingLevel1 = outgoingCalls(Items[0], Index.get());
391397
ASSERT_THAT(
392398
OutgoingLevel1,
399+
// fromRanges are interpreted in the context of Items[0]'s file.
400+
// If that's the header, we can't get ranges from the implementation
401+
// file!
393402
ElementsAre(
394403
AllOf(to(AllOf(withName("caller1"), withDetail("nsa::caller1"))),
395-
oFromRanges(Caller3C.range("Caller1"))),
404+
IsDeclaration ? oFromRanges()
405+
: oFromRanges(Caller3C.range("Caller1"))),
396406
AllOf(to(AllOf(withName("caller2"), withDetail("nsb::caller2"))),
397-
oFromRanges(Caller3C.range("Caller2")))));
407+
IsDeclaration ? oFromRanges()
408+
: oFromRanges(Caller3C.range("Caller2")))));
398409

399410
auto OutgoingLevel2 = outgoingCalls(OutgoingLevel1[1].to, Index.get());
400411
ASSERT_THAT(OutgoingLevel2,
@@ -423,15 +434,15 @@ TEST(CallHierarchy, MultiFileCpp) {
423434
CheckIncomingCalls(*AST, CalleeH.point(), testPath("callee.hh"));
424435
AST = Workspace.openFile("caller3.hh");
425436
ASSERT_TRUE(bool(AST));
426-
CheckOutgoingCalls(*AST, Caller3H.point(), testPath("caller3.hh"));
437+
CheckOutgoingCalls(*AST, Caller3H.point(), testPath("caller3.hh"), true);
427438

428439
// Check that invoking from the definition site works.
429440
AST = Workspace.openFile("callee.cc");
430441
ASSERT_TRUE(bool(AST));
431442
CheckIncomingCalls(*AST, CalleeC.point(), testPath("callee.cc"));
432443
AST = Workspace.openFile("caller3.cc");
433444
ASSERT_TRUE(bool(AST));
434-
CheckOutgoingCalls(*AST, Caller3C.point(), testPath("caller3.cc"));
445+
CheckOutgoingCalls(*AST, Caller3C.point(), testPath("caller3.cc"), false);
435446
}
436447

437448
TEST(CallHierarchy, IncomingMultiFileObjC) {

clang/bindings/python/clang/cindex.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,14 @@ def __str__(self):
34993499
def __repr__(self):
35003500
return "<File: %s>" % (self.name)
35013501

3502+
def __eq__(self, other) -> bool:
3503+
return isinstance(other, File) and bool(
3504+
conf.lib.clang_File_isEqual(self, other)
3505+
)
3506+
3507+
def __ne__(self, other) -> bool:
3508+
return not self.__eq__(other)
3509+
35023510
@staticmethod
35033511
def from_result(res, arg):
35043512
assert isinstance(res, c_object_p)
@@ -3986,6 +3994,7 @@ def set_property(self, property, value):
39863994
("clang_getFile", [TranslationUnit, c_interop_string], c_object_p),
39873995
("clang_getFileName", [File], _CXString),
39883996
("clang_getFileTime", [File], c_uint),
3997+
("clang_File_isEqual", [File, File], bool),
39893998
("clang_getIBOutletCollectionType", [Cursor], Type),
39903999
("clang_getIncludedFile", [Cursor], c_object_p),
39914000
(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1, 2, 3
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1, 2, 3
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int a[] = {
2+
#include "a.inc"
3+
};
4+
int b[] = {
5+
#include "b.inc"
6+
};

0 commit comments

Comments
 (0)