Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / unittests / IR / MetadataTest.cpp
blob1570631287b2a78c9773baa38452c963475dd0af
1 //===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Metadata.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/DIBuilder.h"
14 #include "llvm/IR/DebugInfo.h"
15 #include "llvm/IR/DebugInfoMetadata.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/ModuleSlotTracker.h"
21 #include "llvm/IR/Type.h"
22 #include "llvm/IR/Verifier.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include "gtest/gtest.h"
25 #include <optional>
26 using namespace llvm;
28 namespace {
30 TEST(ContextAndReplaceableUsesTest, FromContext) {
31 LLVMContext Context;
32 ContextAndReplaceableUses CRU(Context);
33 EXPECT_EQ(&Context, &CRU.getContext());
34 EXPECT_FALSE(CRU.hasReplaceableUses());
35 EXPECT_FALSE(CRU.getReplaceableUses());
38 TEST(ContextAndReplaceableUsesTest, FromReplaceableUses) {
39 LLVMContext Context;
40 ContextAndReplaceableUses CRU(std::make_unique<ReplaceableMetadataImpl>(Context));
41 EXPECT_EQ(&Context, &CRU.getContext());
42 EXPECT_TRUE(CRU.hasReplaceableUses());
43 EXPECT_TRUE(CRU.getReplaceableUses());
46 TEST(ContextAndReplaceableUsesTest, makeReplaceable) {
47 LLVMContext Context;
48 ContextAndReplaceableUses CRU(Context);
49 CRU.makeReplaceable(std::make_unique<ReplaceableMetadataImpl>(Context));
50 EXPECT_EQ(&Context, &CRU.getContext());
51 EXPECT_TRUE(CRU.hasReplaceableUses());
52 EXPECT_TRUE(CRU.getReplaceableUses());
55 TEST(ContextAndReplaceableUsesTest, takeReplaceableUses) {
56 LLVMContext Context;
57 auto ReplaceableUses = std::make_unique<ReplaceableMetadataImpl>(Context);
58 auto *Ptr = ReplaceableUses.get();
59 ContextAndReplaceableUses CRU(std::move(ReplaceableUses));
60 ReplaceableUses = CRU.takeReplaceableUses();
61 EXPECT_EQ(&Context, &CRU.getContext());
62 EXPECT_FALSE(CRU.hasReplaceableUses());
63 EXPECT_FALSE(CRU.getReplaceableUses());
64 EXPECT_EQ(Ptr, ReplaceableUses.get());
67 class MetadataTest : public testing::Test {
68 public:
69 MetadataTest() : M("test", Context), Counter(0) {}
71 protected:
72 LLVMContext Context;
73 Module M;
74 int Counter;
76 MDNode *getNode() { return MDNode::get(Context, std::nullopt); }
77 MDNode *getNode(Metadata *MD) { return MDNode::get(Context, MD); }
78 MDNode *getNode(Metadata *MD1, Metadata *MD2) {
79 Metadata *MDs[] = {MD1, MD2};
80 return MDNode::get(Context, MDs);
83 MDTuple *getTuple() { return MDTuple::getDistinct(Context, std::nullopt); }
84 DISubroutineType *getSubroutineType() {
85 return DISubroutineType::getDistinct(Context, DINode::FlagZero, 0,
86 getNode(nullptr));
88 DISubprogram *getSubprogram() {
89 return DISubprogram::getDistinct(
90 Context, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
91 DINode::FlagZero, DISubprogram::SPFlagZero, nullptr);
93 DIFile *getFile() {
94 return DIFile::getDistinct(Context, "file.c", "/path/to/dir");
96 DICompileUnit *getUnit() {
97 return DICompileUnit::getDistinct(
98 Context, 1, getFile(), "clang", false, "-g", 2, "",
99 DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(),
100 getTuple(), getTuple(), 0, true, false,
101 DICompileUnit::DebugNameTableKind::Default, false, "/", "");
103 DIType *getBasicType(StringRef Name) {
104 return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name);
106 DIType *getDerivedType() {
107 return DIDerivedType::getDistinct(
108 Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr,
109 getBasicType("basictype"), 1, 2, 0, std::nullopt, DINode::FlagZero);
111 Constant *getConstant() {
112 return ConstantInt::get(Type::getInt32Ty(Context), Counter++);
114 ConstantAsMetadata *getConstantAsMetadata() {
115 return ConstantAsMetadata::get(getConstant());
117 DIType *getCompositeType() {
118 return DICompositeType::getDistinct(
119 Context, dwarf::DW_TAG_structure_type, "", nullptr, 0, nullptr, nullptr,
120 32, 32, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, "");
122 Function *getFunction(StringRef Name) {
123 return Function::Create(
124 FunctionType::get(Type::getVoidTy(Context), std::nullopt, false),
125 Function::ExternalLinkage, Name, M);
128 typedef MetadataTest MDStringTest;
130 // Test that construction of MDString with different value produces different
131 // MDString objects, even with the same string pointer and nulls in the string.
132 TEST_F(MDStringTest, CreateDifferent) {
133 char x[3] = { 'f', 0, 'A' };
134 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
135 x[2] = 'B';
136 MDString *s2 = MDString::get(Context, StringRef(&x[0], 3));
137 EXPECT_NE(s1, s2);
140 // Test that creation of MDStrings with the same string contents produces the
141 // same MDString object, even with different pointers.
142 TEST_F(MDStringTest, CreateSame) {
143 char x[4] = { 'a', 'b', 'c', 'X' };
144 char y[4] = { 'a', 'b', 'c', 'Y' };
146 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
147 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3));
148 EXPECT_EQ(s1, s2);
151 // Test that MDString prints out the string we fed it.
152 TEST_F(MDStringTest, PrintingSimple) {
153 char str[14] = "testing 1 2 3";
154 MDString *s = MDString::get(Context, StringRef(&str[0], 13));
155 strncpy(str, "aaaaaaaaaaaaa", 14);
157 std::string Str;
158 raw_string_ostream oss(Str);
159 s->print(oss);
160 EXPECT_STREQ("!\"testing 1 2 3\"", oss.str().c_str());
163 // Test printing of MDString with non-printable characters.
164 TEST_F(MDStringTest, PrintingComplex) {
165 char str[5] = {0, '\n', '"', '\\', (char)-1};
166 MDString *s = MDString::get(Context, StringRef(str+0, 5));
167 std::string Str;
168 raw_string_ostream oss(Str);
169 s->print(oss);
170 EXPECT_STREQ("!\"\\00\\0A\\22\\\\\\FF\"", oss.str().c_str());
173 typedef MetadataTest MDNodeTest;
175 // Test the two constructors, and containing other Constants.
176 TEST_F(MDNodeTest, Simple) {
177 char x[3] = { 'a', 'b', 'c' };
178 char y[3] = { '1', '2', '3' };
180 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
181 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3));
182 ConstantAsMetadata *CI =
183 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)));
185 std::vector<Metadata *> V;
186 V.push_back(s1);
187 V.push_back(CI);
188 V.push_back(s2);
190 MDNode *n1 = MDNode::get(Context, V);
191 Metadata *const c1 = n1;
192 MDNode *n2 = MDNode::get(Context, c1);
193 Metadata *const c2 = n2;
194 MDNode *n3 = MDNode::get(Context, V);
195 MDNode *n4 = MDNode::getIfExists(Context, V);
196 MDNode *n5 = MDNode::getIfExists(Context, c1);
197 MDNode *n6 = MDNode::getIfExists(Context, c2);
198 EXPECT_NE(n1, n2);
199 EXPECT_EQ(n1, n3);
200 EXPECT_EQ(n4, n1);
201 EXPECT_EQ(n5, n2);
202 EXPECT_EQ(n6, (Metadata *)nullptr);
204 EXPECT_EQ(3u, n1->getNumOperands());
205 EXPECT_EQ(s1, n1->getOperand(0));
206 EXPECT_EQ(CI, n1->getOperand(1));
207 EXPECT_EQ(s2, n1->getOperand(2));
209 EXPECT_EQ(1u, n2->getNumOperands());
210 EXPECT_EQ(n1, n2->getOperand(0));
213 TEST_F(MDNodeTest, Delete) {
214 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 1);
215 Instruction *I = new BitCastInst(C, Type::getInt32Ty(Context));
217 Metadata *const V = LocalAsMetadata::get(I);
218 MDNode *n = MDNode::get(Context, V);
219 TrackingMDRef wvh(n);
221 EXPECT_EQ(n, wvh);
223 I->deleteValue();
226 TEST_F(MDNodeTest, SelfReference) {
227 // !0 = !{!0}
228 // !1 = !{!0}
230 auto Temp = MDNode::getTemporary(Context, std::nullopt);
231 Metadata *Args[] = {Temp.get()};
232 MDNode *Self = MDNode::get(Context, Args);
233 Self->replaceOperandWith(0, Self);
234 ASSERT_EQ(Self, Self->getOperand(0));
236 // Self-references should be distinct, so MDNode::get() should grab a
237 // uniqued node that references Self, not Self.
238 Args[0] = Self;
239 MDNode *Ref1 = MDNode::get(Context, Args);
240 MDNode *Ref2 = MDNode::get(Context, Args);
241 EXPECT_NE(Self, Ref1);
242 EXPECT_EQ(Ref1, Ref2);
245 // !0 = !{!0, !{}}
246 // !1 = !{!0, !{}}
248 auto Temp = MDNode::getTemporary(Context, std::nullopt);
249 Metadata *Args[] = {Temp.get(), MDNode::get(Context, std::nullopt)};
250 MDNode *Self = MDNode::get(Context, Args);
251 Self->replaceOperandWith(0, Self);
252 ASSERT_EQ(Self, Self->getOperand(0));
254 // Self-references should be distinct, so MDNode::get() should grab a
255 // uniqued node that references Self, not Self itself.
256 Args[0] = Self;
257 MDNode *Ref1 = MDNode::get(Context, Args);
258 MDNode *Ref2 = MDNode::get(Context, Args);
259 EXPECT_NE(Self, Ref1);
260 EXPECT_EQ(Ref1, Ref2);
264 TEST_F(MDNodeTest, Print) {
265 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7);
266 MDString *S = MDString::get(Context, "foo");
267 MDNode *N0 = getNode();
268 MDNode *N1 = getNode(N0);
269 MDNode *N2 = getNode(N0, N1);
271 Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2};
272 MDNode *N = MDNode::get(Context, Args);
274 std::string Expected;
276 raw_string_ostream OS(Expected);
277 OS << "<" << (void *)N << "> = !{";
278 C->printAsOperand(OS);
279 OS << ", ";
280 S->printAsOperand(OS);
281 OS << ", null";
282 MDNode *Nodes[] = {N0, N1, N2};
283 for (auto *Node : Nodes)
284 OS << ", <" << (void *)Node << ">";
285 OS << "}";
288 std::string Actual;
290 raw_string_ostream OS(Actual);
291 N->print(OS);
294 EXPECT_EQ(Expected, Actual);
297 #define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \
298 do { \
299 std::string Actual_; \
300 raw_string_ostream OS(Actual_); \
301 PRINT; \
302 OS.flush(); \
303 std::string Expected_(EXPECTED); \
304 EXPECT_EQ(Expected_, Actual_); \
305 } while (false)
307 TEST_F(MDNodeTest, PrintTemporary) {
308 MDNode *Arg = getNode();
309 TempMDNode Temp = MDNode::getTemporary(Context, Arg);
310 MDNode *N = getNode(Temp.get());
311 Module M("test", Context);
312 NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
313 NMD->addOperand(N);
315 EXPECT_PRINTER_EQ("!0 = !{!1}", N->print(OS, &M));
316 EXPECT_PRINTER_EQ("!1 = <temporary!> !{!2}", Temp->print(OS, &M));
317 EXPECT_PRINTER_EQ("!2 = !{}", Arg->print(OS, &M));
319 // Cleanup.
320 Temp->replaceAllUsesWith(Arg);
323 TEST_F(MDNodeTest, PrintFromModule) {
324 Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7);
325 MDString *S = MDString::get(Context, "foo");
326 MDNode *N0 = getNode();
327 MDNode *N1 = getNode(N0);
328 MDNode *N2 = getNode(N0, N1);
330 Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2};
331 MDNode *N = MDNode::get(Context, Args);
332 Module M("test", Context);
333 NamedMDNode *NMD = M.getOrInsertNamedMetadata("named");
334 NMD->addOperand(N);
336 std::string Expected;
338 raw_string_ostream OS(Expected);
339 OS << "!0 = !{";
340 C->printAsOperand(OS);
341 OS << ", ";
342 S->printAsOperand(OS);
343 OS << ", null, !1, !2, !3}";
346 EXPECT_PRINTER_EQ(Expected, N->print(OS, &M));
349 TEST_F(MDNodeTest, PrintFromFunction) {
350 Module M("test", Context);
351 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
352 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
353 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
354 auto *BB0 = BasicBlock::Create(Context, "entry", F0);
355 auto *BB1 = BasicBlock::Create(Context, "entry", F1);
356 auto *R0 = ReturnInst::Create(Context, BB0);
357 auto *R1 = ReturnInst::Create(Context, BB1);
358 auto *N0 = MDNode::getDistinct(Context, std::nullopt);
359 auto *N1 = MDNode::getDistinct(Context, std::nullopt);
360 R0->setMetadata("md", N0);
361 R1->setMetadata("md", N1);
363 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, &M));
364 EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, &M));
366 ModuleSlotTracker MST(&M);
367 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, MST));
368 EXPECT_PRINTER_EQ("!1 = distinct !{}", N1->print(OS, MST));
371 TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
372 Module M("test", Context);
374 auto *Intrinsic =
375 Function::Create(FunctionType::get(Type::getVoidTy(Context),
376 Type::getMetadataTy(Context), false),
377 GlobalValue::ExternalLinkage, "llvm.intrinsic", &M);
379 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
380 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
381 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
382 auto *BB0 = BasicBlock::Create(Context, "entry", F0);
383 auto *BB1 = BasicBlock::Create(Context, "entry", F1);
384 auto *N0 = MDNode::getDistinct(Context, std::nullopt);
385 auto *N1 = MDNode::getDistinct(Context, std::nullopt);
386 auto *MAV0 = MetadataAsValue::get(Context, N0);
387 auto *MAV1 = MetadataAsValue::get(Context, N1);
388 CallInst::Create(Intrinsic, MAV0, "", BB0);
389 CallInst::Create(Intrinsic, MAV1, "", BB1);
391 EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS));
392 EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS));
393 EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false));
394 EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false));
395 EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true));
396 EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true));
398 ModuleSlotTracker MST(&M);
399 EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS, MST));
400 EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS, MST));
401 EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false, MST));
402 EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false, MST));
403 EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true, MST));
404 EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true, MST));
407 TEST_F(MDNodeTest, PrintWithDroppedCallOperand) {
408 Module M("test", Context);
410 auto *FTy = FunctionType::get(Type::getVoidTy(Context), false);
411 auto *F0 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F0", &M);
412 auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "F1", &M);
413 auto *BB0 = BasicBlock::Create(Context, "entry", F0);
415 CallInst *CI0 = CallInst::Create(F1, "", BB0);
416 CI0->dropAllReferences();
418 auto *R0 = ReturnInst::Create(Context, BB0);
419 auto *N0 = MDNode::getDistinct(Context, std::nullopt);
420 R0->setMetadata("md", N0);
422 // Printing the metadata node would previously result in a failed assertion
423 // due to the call instruction's dropped function operand.
424 ModuleSlotTracker MST(&M);
425 EXPECT_PRINTER_EQ("!0 = distinct !{}", N0->print(OS, MST));
428 TEST_F(MDNodeTest, PrintTree) {
429 DILocalScope *Scope = getSubprogram();
430 DIFile *File = getFile();
431 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
433 DIType *Type = getDerivedType();
434 auto *Var = DILocalVariable::get(Context, Scope, "foo", File,
435 /*LineNo=*/8, Type, /*ArgNo=*/2, Flags,
436 /*Align=*/8, nullptr);
437 std::string Expected;
439 raw_string_ostream SS(Expected);
440 Var->print(SS);
441 // indent level 1
442 Scope->print((SS << "\n").indent(2));
443 File->print((SS << "\n").indent(2));
444 Type->print((SS << "\n").indent(2));
445 // indent level 2
446 auto *BaseType = cast<DIDerivedType>(Type)->getBaseType();
447 BaseType->print((SS << "\n").indent(4));
450 EXPECT_PRINTER_EQ(Expected, Var->printTree(OS));
454 // Test if printTree works correctly when there is
455 // a cycle in the MDNode and its dependencies.
457 // We're trying to create type like this:
458 // struct LinkedList {
459 // LinkedList *Head;
460 // };
461 auto *StructTy = cast<DICompositeType>(getCompositeType());
462 DIType *PointerTy = DIDerivedType::getDistinct(
463 Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr, StructTy,
464 1, 2, 0, std::nullopt, DINode::FlagZero);
465 StructTy->replaceElements(MDTuple::get(Context, PointerTy));
467 auto *Var = DILocalVariable::get(Context, Scope, "foo", File,
468 /*LineNo=*/8, StructTy, /*ArgNo=*/2, Flags,
469 /*Align=*/8, nullptr);
470 std::string Expected;
472 raw_string_ostream SS(Expected);
473 Var->print(SS);
474 // indent level 1
475 Scope->print((SS << "\n").indent(2));
476 File->print((SS << "\n").indent(2));
477 StructTy->print((SS << "\n").indent(2));
478 // indent level 2
479 StructTy->getRawElements()->print((SS << "\n").indent(4));
480 // indent level 3
481 auto Elements = StructTy->getElements();
482 Elements[0]->print((SS << "\n").indent(6));
485 EXPECT_PRINTER_EQ(Expected, Var->printTree(OS));
488 #undef EXPECT_PRINTER_EQ
490 TEST_F(MDNodeTest, NullOperand) {
491 // metadata !{}
492 MDNode *Empty = MDNode::get(Context, std::nullopt);
494 // metadata !{metadata !{}}
495 Metadata *Ops[] = {Empty};
496 MDNode *N = MDNode::get(Context, Ops);
497 ASSERT_EQ(Empty, N->getOperand(0));
499 // metadata !{metadata !{}} => metadata !{null}
500 N->replaceOperandWith(0, nullptr);
501 ASSERT_EQ(nullptr, N->getOperand(0));
503 // metadata !{null}
504 Ops[0] = nullptr;
505 MDNode *NullOp = MDNode::get(Context, Ops);
506 ASSERT_EQ(nullptr, NullOp->getOperand(0));
507 EXPECT_EQ(N, NullOp);
510 TEST_F(MDNodeTest, DistinctOnUniquingCollision) {
511 // !{}
512 MDNode *Empty = MDNode::get(Context, std::nullopt);
513 ASSERT_TRUE(Empty->isResolved());
514 EXPECT_FALSE(Empty->isDistinct());
516 // !{!{}}
517 Metadata *Wrapped1Ops[] = {Empty};
518 MDNode *Wrapped1 = MDNode::get(Context, Wrapped1Ops);
519 ASSERT_EQ(Empty, Wrapped1->getOperand(0));
520 ASSERT_TRUE(Wrapped1->isResolved());
521 EXPECT_FALSE(Wrapped1->isDistinct());
523 // !{!{!{}}}
524 Metadata *Wrapped2Ops[] = {Wrapped1};
525 MDNode *Wrapped2 = MDNode::get(Context, Wrapped2Ops);
526 ASSERT_EQ(Wrapped1, Wrapped2->getOperand(0));
527 ASSERT_TRUE(Wrapped2->isResolved());
528 EXPECT_FALSE(Wrapped2->isDistinct());
530 // !{!{!{}}} => !{!{}}
531 Wrapped2->replaceOperandWith(0, Empty);
532 ASSERT_EQ(Empty, Wrapped2->getOperand(0));
533 EXPECT_TRUE(Wrapped2->isDistinct());
534 EXPECT_FALSE(Wrapped1->isDistinct());
537 TEST_F(MDNodeTest, UniquedOnDeletedOperand) {
538 // temp !{}
539 TempMDTuple T = MDTuple::getTemporary(Context, std::nullopt);
541 // !{temp !{}}
542 Metadata *Ops[] = {T.get()};
543 MDTuple *N = MDTuple::get(Context, Ops);
545 // !{temp !{}} => !{null}
546 T.reset();
547 ASSERT_TRUE(N->isUniqued());
548 Metadata *NullOps[] = {nullptr};
549 ASSERT_EQ(N, MDTuple::get(Context, NullOps));
552 TEST_F(MDNodeTest, DistinctOnDeletedValueOperand) {
553 // i1* @GV
554 Type *Ty = PointerType::getUnqual(Context);
555 std::unique_ptr<GlobalVariable> GV(
556 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
557 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get());
559 // !{i1* @GV}
560 Metadata *Ops[] = {Op};
561 MDTuple *N = MDTuple::get(Context, Ops);
563 // !{i1* @GV} => !{null}
564 GV.reset();
565 ASSERT_TRUE(N->isDistinct());
566 ASSERT_EQ(nullptr, N->getOperand(0));
567 Metadata *NullOps[] = {nullptr};
568 ASSERT_NE(N, MDTuple::get(Context, NullOps));
571 TEST_F(MDNodeTest, getDistinct) {
572 // !{}
573 MDNode *Empty = MDNode::get(Context, std::nullopt);
574 ASSERT_TRUE(Empty->isResolved());
575 ASSERT_FALSE(Empty->isDistinct());
576 ASSERT_EQ(Empty, MDNode::get(Context, std::nullopt));
578 // distinct !{}
579 MDNode *Distinct1 = MDNode::getDistinct(Context, std::nullopt);
580 MDNode *Distinct2 = MDNode::getDistinct(Context, std::nullopt);
581 EXPECT_TRUE(Distinct1->isResolved());
582 EXPECT_TRUE(Distinct2->isDistinct());
583 EXPECT_NE(Empty, Distinct1);
584 EXPECT_NE(Empty, Distinct2);
585 EXPECT_NE(Distinct1, Distinct2);
587 // !{}
588 ASSERT_EQ(Empty, MDNode::get(Context, std::nullopt));
591 TEST_F(MDNodeTest, isUniqued) {
592 MDNode *U = MDTuple::get(Context, std::nullopt);
593 MDNode *D = MDTuple::getDistinct(Context, std::nullopt);
594 auto T = MDTuple::getTemporary(Context, std::nullopt);
595 EXPECT_TRUE(U->isUniqued());
596 EXPECT_FALSE(D->isUniqued());
597 EXPECT_FALSE(T->isUniqued());
600 TEST_F(MDNodeTest, isDistinct) {
601 MDNode *U = MDTuple::get(Context, std::nullopt);
602 MDNode *D = MDTuple::getDistinct(Context, std::nullopt);
603 auto T = MDTuple::getTemporary(Context, std::nullopt);
604 EXPECT_FALSE(U->isDistinct());
605 EXPECT_TRUE(D->isDistinct());
606 EXPECT_FALSE(T->isDistinct());
609 TEST_F(MDNodeTest, isTemporary) {
610 MDNode *U = MDTuple::get(Context, std::nullopt);
611 MDNode *D = MDTuple::getDistinct(Context, std::nullopt);
612 auto T = MDTuple::getTemporary(Context, std::nullopt);
613 EXPECT_FALSE(U->isTemporary());
614 EXPECT_FALSE(D->isTemporary());
615 EXPECT_TRUE(T->isTemporary());
618 TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) {
619 // temporary !{}
620 auto Temp = MDTuple::getTemporary(Context, std::nullopt);
621 ASSERT_FALSE(Temp->isResolved());
623 // distinct !{temporary !{}}
624 Metadata *Ops[] = {Temp.get()};
625 MDNode *Distinct = MDNode::getDistinct(Context, Ops);
626 EXPECT_TRUE(Distinct->isResolved());
627 EXPECT_EQ(Temp.get(), Distinct->getOperand(0));
629 // temporary !{} => !{}
630 MDNode *Empty = MDNode::get(Context, std::nullopt);
631 Temp->replaceAllUsesWith(Empty);
632 EXPECT_EQ(Empty, Distinct->getOperand(0));
635 TEST_F(MDNodeTest, handleChangedOperandRecursion) {
636 // !0 = !{}
637 MDNode *N0 = MDNode::get(Context, std::nullopt);
639 // !1 = !{!3, null}
640 auto Temp3 = MDTuple::getTemporary(Context, std::nullopt);
641 Metadata *Ops1[] = {Temp3.get(), nullptr};
642 MDNode *N1 = MDNode::get(Context, Ops1);
644 // !2 = !{!3, !0}
645 Metadata *Ops2[] = {Temp3.get(), N0};
646 MDNode *N2 = MDNode::get(Context, Ops2);
648 // !3 = !{!2}
649 Metadata *Ops3[] = {N2};
650 MDNode *N3 = MDNode::get(Context, Ops3);
651 Temp3->replaceAllUsesWith(N3);
653 // !4 = !{!1}
654 Metadata *Ops4[] = {N1};
655 MDNode *N4 = MDNode::get(Context, Ops4);
657 // Confirm that the cycle prevented RAUW from getting dropped.
658 EXPECT_TRUE(N0->isResolved());
659 EXPECT_FALSE(N1->isResolved());
660 EXPECT_FALSE(N2->isResolved());
661 EXPECT_FALSE(N3->isResolved());
662 EXPECT_FALSE(N4->isResolved());
664 // Create a couple of distinct nodes to observe what's going on.
666 // !5 = distinct !{!2}
667 // !6 = distinct !{!3}
668 Metadata *Ops5[] = {N2};
669 MDNode *N5 = MDNode::getDistinct(Context, Ops5);
670 Metadata *Ops6[] = {N3};
671 MDNode *N6 = MDNode::getDistinct(Context, Ops6);
673 // Mutate !2 to look like !1, causing a uniquing collision (and an RAUW).
674 // This will ripple up, with !3 colliding with !4, and RAUWing. Since !2
675 // references !3, this can cause a re-entry of handleChangedOperand() when !3
676 // is not ready for it.
678 // !2->replaceOperandWith(1, nullptr)
679 // !2: !{!3, !0} => !{!3, null}
680 // !2->replaceAllUsesWith(!1)
681 // !3: !{!2] => !{!1}
682 // !3->replaceAllUsesWith(!4)
683 N2->replaceOperandWith(1, nullptr);
685 // If all has gone well, N2 and N3 will have been RAUW'ed and deleted from
686 // under us. Just check that the other nodes are sane.
688 // !1 = !{!4, null}
689 // !4 = !{!1}
690 // !5 = distinct !{!1}
691 // !6 = distinct !{!4}
692 EXPECT_EQ(N4, N1->getOperand(0));
693 EXPECT_EQ(N1, N4->getOperand(0));
694 EXPECT_EQ(N1, N5->getOperand(0));
695 EXPECT_EQ(N4, N6->getOperand(0));
698 TEST_F(MDNodeTest, replaceResolvedOperand) {
699 // Check code for replacing one resolved operand with another. If doing this
700 // directly (via replaceOperandWith()) becomes illegal, change the operand to
701 // a global value that gets RAUW'ed.
703 // Use a temporary node to keep N from being resolved.
704 auto Temp = MDTuple::getTemporary(Context, std::nullopt);
705 Metadata *Ops[] = {nullptr, Temp.get()};
707 MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>());
708 MDNode *N = MDTuple::get(Context, Ops);
709 EXPECT_EQ(nullptr, N->getOperand(0));
710 ASSERT_FALSE(N->isResolved());
712 // Check code for replacing resolved nodes.
713 N->replaceOperandWith(0, Empty);
714 EXPECT_EQ(Empty, N->getOperand(0));
716 // Check code for adding another unresolved operand.
717 N->replaceOperandWith(0, Temp.get());
718 EXPECT_EQ(Temp.get(), N->getOperand(0));
720 // Remove the references to Temp; required for teardown.
721 Temp->replaceAllUsesWith(nullptr);
724 TEST_F(MDNodeTest, replaceWithUniqued) {
725 auto *Empty = MDTuple::get(Context, std::nullopt);
726 MDTuple *FirstUniqued;
728 Metadata *Ops[] = {Empty};
729 auto Temp = MDTuple::getTemporary(Context, Ops);
730 EXPECT_TRUE(Temp->isTemporary());
732 // Don't expect a collision.
733 auto *Current = Temp.get();
734 FirstUniqued = MDNode::replaceWithUniqued(std::move(Temp));
735 EXPECT_TRUE(FirstUniqued->isUniqued());
736 EXPECT_TRUE(FirstUniqued->isResolved());
737 EXPECT_EQ(Current, FirstUniqued);
740 Metadata *Ops[] = {Empty};
741 auto Temp = MDTuple::getTemporary(Context, Ops);
742 EXPECT_TRUE(Temp->isTemporary());
744 // Should collide with Uniqued above this time.
745 auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp));
746 EXPECT_TRUE(Uniqued->isUniqued());
747 EXPECT_TRUE(Uniqued->isResolved());
748 EXPECT_EQ(FirstUniqued, Uniqued);
751 auto Unresolved = MDTuple::getTemporary(Context, std::nullopt);
752 Metadata *Ops[] = {Unresolved.get()};
753 auto Temp = MDTuple::getTemporary(Context, Ops);
754 EXPECT_TRUE(Temp->isTemporary());
756 // Shouldn't be resolved.
757 auto *Uniqued = MDNode::replaceWithUniqued(std::move(Temp));
758 EXPECT_TRUE(Uniqued->isUniqued());
759 EXPECT_FALSE(Uniqued->isResolved());
761 // Should be a different node.
762 EXPECT_NE(FirstUniqued, Uniqued);
764 // Should resolve when we update its node (note: be careful to avoid a
765 // collision with any other nodes above).
766 Uniqued->replaceOperandWith(0, nullptr);
767 EXPECT_TRUE(Uniqued->isResolved());
771 TEST_F(MDNodeTest, replaceWithUniquedResolvingOperand) {
772 // temp !{}
773 MDTuple *Op = MDTuple::getTemporary(Context, std::nullopt).release();
774 EXPECT_FALSE(Op->isResolved());
776 // temp !{temp !{}}
777 Metadata *Ops[] = {Op};
778 MDTuple *N = MDTuple::getTemporary(Context, Ops).release();
779 EXPECT_FALSE(N->isResolved());
781 // temp !{temp !{}} => !{temp !{}}
782 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N)));
783 EXPECT_FALSE(N->isResolved());
785 // !{temp !{}} => !{!{}}
786 ASSERT_EQ(Op, MDNode::replaceWithUniqued(TempMDTuple(Op)));
787 EXPECT_TRUE(Op->isResolved());
788 EXPECT_TRUE(N->isResolved());
791 TEST_F(MDNodeTest, replaceWithUniquedDeletedOperand) {
792 // i1* @GV
793 Type *Ty = PointerType::getUnqual(Context);
794 std::unique_ptr<GlobalVariable> GV(
795 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
796 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get());
798 // temp !{i1* @GV}
799 Metadata *Ops[] = {Op};
800 MDTuple *N = MDTuple::getTemporary(Context, Ops).release();
802 // temp !{i1* @GV} => !{i1* @GV}
803 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N)));
804 ASSERT_TRUE(N->isUniqued());
806 // !{i1* @GV} => !{null}
807 GV.reset();
808 ASSERT_TRUE(N->isDistinct());
809 ASSERT_EQ(nullptr, N->getOperand(0));
810 Metadata *NullOps[] = {nullptr};
811 ASSERT_NE(N, MDTuple::get(Context, NullOps));
814 TEST_F(MDNodeTest, replaceWithUniquedChangedOperand) {
815 // i1* @GV
816 Type *Ty = PointerType::getUnqual(Context);
817 std::unique_ptr<GlobalVariable> GV(
818 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
819 ConstantAsMetadata *Op = ConstantAsMetadata::get(GV.get());
821 // temp !{i1* @GV}
822 Metadata *Ops[] = {Op};
823 MDTuple *N = MDTuple::getTemporary(Context, Ops).release();
825 // temp !{i1* @GV} => !{i1* @GV}
826 ASSERT_EQ(N, MDNode::replaceWithUniqued(TempMDTuple(N)));
827 ASSERT_TRUE(N->isUniqued());
829 // !{i1* @GV} => !{i1* @GV2}
830 std::unique_ptr<GlobalVariable> GV2(
831 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
832 GV->replaceAllUsesWith(GV2.get());
833 ASSERT_TRUE(N->isUniqued());
834 Metadata *NullOps[] = {ConstantAsMetadata::get(GV2.get())};
835 ASSERT_EQ(N, MDTuple::get(Context, NullOps));
838 TEST_F(MDNodeTest, replaceWithDistinct) {
840 auto *Empty = MDTuple::get(Context, std::nullopt);
841 Metadata *Ops[] = {Empty};
842 auto Temp = MDTuple::getTemporary(Context, Ops);
843 EXPECT_TRUE(Temp->isTemporary());
845 // Don't expect a collision.
846 auto *Current = Temp.get();
847 auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp));
848 EXPECT_TRUE(Distinct->isDistinct());
849 EXPECT_TRUE(Distinct->isResolved());
850 EXPECT_EQ(Current, Distinct);
853 auto Unresolved = MDTuple::getTemporary(Context, std::nullopt);
854 Metadata *Ops[] = {Unresolved.get()};
855 auto Temp = MDTuple::getTemporary(Context, Ops);
856 EXPECT_TRUE(Temp->isTemporary());
858 // Don't expect a collision.
859 auto *Current = Temp.get();
860 auto *Distinct = MDNode::replaceWithDistinct(std::move(Temp));
861 EXPECT_TRUE(Distinct->isDistinct());
862 EXPECT_TRUE(Distinct->isResolved());
863 EXPECT_EQ(Current, Distinct);
865 // Cleanup; required for teardown.
866 Unresolved->replaceAllUsesWith(nullptr);
870 TEST_F(MDNodeTest, replaceWithPermanent) {
871 Metadata *Ops[] = {nullptr};
872 auto Temp = MDTuple::getTemporary(Context, Ops);
873 auto *T = Temp.get();
875 // U is a normal, uniqued node that references T.
876 auto *U = MDTuple::get(Context, T);
877 EXPECT_TRUE(U->isUniqued());
879 // Make Temp self-referencing.
880 Temp->replaceOperandWith(0, T);
882 // Try to uniquify Temp. This should, despite the name in the API, give a
883 // 'distinct' node, since self-references aren't allowed to be uniqued.
885 // Since it's distinct, N should have the same address as when it was a
886 // temporary (i.e., be equal to T not U).
887 auto *N = MDNode::replaceWithPermanent(std::move(Temp));
888 EXPECT_EQ(N, T);
889 EXPECT_TRUE(N->isDistinct());
891 // U should be the canonical unique node with N as the argument.
892 EXPECT_EQ(U, MDTuple::get(Context, N));
893 EXPECT_TRUE(U->isUniqued());
895 // This temporary should collide with U when replaced, but it should still be
896 // uniqued.
897 EXPECT_EQ(U, MDNode::replaceWithPermanent(MDTuple::getTemporary(Context, N)));
898 EXPECT_TRUE(U->isUniqued());
900 // This temporary should become a new uniqued node.
901 auto Temp2 = MDTuple::getTemporary(Context, U);
902 auto *V = Temp2.get();
903 EXPECT_EQ(V, MDNode::replaceWithPermanent(std::move(Temp2)));
904 EXPECT_TRUE(V->isUniqued());
905 EXPECT_EQ(U, V->getOperand(0));
908 TEST_F(MDNodeTest, deleteTemporaryWithTrackingRef) {
909 TrackingMDRef Ref;
910 EXPECT_EQ(nullptr, Ref.get());
912 auto Temp = MDTuple::getTemporary(Context, std::nullopt);
913 Ref.reset(Temp.get());
914 EXPECT_EQ(Temp.get(), Ref.get());
916 EXPECT_EQ(nullptr, Ref.get());
919 typedef MetadataTest DILocationTest;
921 TEST_F(DILocationTest, Merge) {
922 DISubprogram *N = getSubprogram();
923 DIScope *S = DILexicalBlock::get(Context, N, getFile(), 3, 4);
926 // Identical.
927 auto *A = DILocation::get(Context, 2, 7, N);
928 auto *B = DILocation::get(Context, 2, 7, N);
929 auto *M = DILocation::getMergedLocation(A, B);
930 EXPECT_EQ(2u, M->getLine());
931 EXPECT_EQ(7u, M->getColumn());
932 EXPECT_EQ(N, M->getScope());
936 // Identical, different scopes.
937 auto *A = DILocation::get(Context, 2, 7, N);
938 auto *B = DILocation::get(Context, 2, 7, S);
939 auto *M = DILocation::getMergedLocation(A, B);
940 EXPECT_EQ(2u, M->getLine());
941 EXPECT_EQ(7u, M->getColumn());
942 EXPECT_EQ(N, M->getScope());
946 // Same line, different column.
947 auto *A = DILocation::get(Context, 2, 7, N);
948 auto *B = DILocation::get(Context, 2, 10, S);
949 auto *M0 = DILocation::getMergedLocation(A, B);
950 auto *M1 = DILocation::getMergedLocation(B, A);
951 for (auto *M : {M0, M1}) {
952 EXPECT_EQ(2u, M->getLine());
953 EXPECT_EQ(0u, M->getColumn());
954 EXPECT_EQ(N, M->getScope());
959 // Different lines, same scopes.
960 auto *A = DILocation::get(Context, 1, 6, N);
961 auto *B = DILocation::get(Context, 2, 7, N);
962 auto *M = DILocation::getMergedLocation(A, B);
963 EXPECT_EQ(0u, M->getLine());
964 EXPECT_EQ(0u, M->getColumn());
965 EXPECT_EQ(N, M->getScope());
969 // Twisty locations, all different, same function.
970 auto *A = DILocation::get(Context, 1, 6, N);
971 auto *B = DILocation::get(Context, 2, 7, S);
972 auto *M = DILocation::getMergedLocation(A, B);
973 EXPECT_EQ(0u, M->getLine());
974 EXPECT_EQ(0u, M->getColumn());
975 EXPECT_EQ(N, M->getScope());
979 // Different function, same inlined-at.
980 auto *F = getFile();
981 auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr,
982 0, nullptr, 0, 0, DINode::FlagZero,
983 DISubprogram::SPFlagZero, nullptr);
984 auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr,
985 0, nullptr, 0, 0, DINode::FlagZero,
986 DISubprogram::SPFlagZero, nullptr);
988 auto *I = DILocation::get(Context, 2, 7, N);
989 auto *A = DILocation::get(Context, 1, 6, SP1, I);
990 auto *B = DILocation::get(Context, 3, 8, SP2, I);
991 auto *M = DILocation::getMergedLocation(A, B);
992 EXPECT_EQ(2u, M->getLine());
993 EXPECT_EQ(7u, M->getColumn());
994 EXPECT_EQ(N, M->getScope());
995 EXPECT_EQ(nullptr, M->getInlinedAt());
999 // Different function, inlined-at same line, but different column.
1000 auto *F = getFile();
1001 auto *SP1 = DISubprogram::getDistinct(Context, F, "a", "a", F, 0, nullptr,
1002 0, nullptr, 0, 0, DINode::FlagZero,
1003 DISubprogram::SPFlagZero, nullptr);
1004 auto *SP2 = DISubprogram::getDistinct(Context, F, "b", "b", F, 0, nullptr,
1005 0, nullptr, 0, 0, DINode::FlagZero,
1006 DISubprogram::SPFlagZero, nullptr);
1008 auto *IA = DILocation::get(Context, 2, 7, N);
1009 auto *IB = DILocation::get(Context, 2, 8, N);
1010 auto *A = DILocation::get(Context, 1, 6, SP1, IA);
1011 auto *B = DILocation::get(Context, 3, 8, SP2, IB);
1012 auto *M = DILocation::getMergedLocation(A, B);
1013 EXPECT_EQ(2u, M->getLine());
1014 EXPECT_EQ(0u, M->getColumn());
1015 EXPECT_EQ(N, M->getScope());
1016 EXPECT_EQ(nullptr, M->getInlinedAt());
1020 // Completely different.
1021 auto *I = DILocation::get(Context, 2, 7, N);
1022 auto *A = DILocation::get(Context, 1, 6, S, I);
1023 auto *B = DILocation::get(Context, 2, 7, getSubprogram());
1024 auto *M = DILocation::getMergedLocation(A, B);
1025 EXPECT_EQ(0u, M->getLine());
1026 EXPECT_EQ(0u, M->getColumn());
1027 EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
1028 EXPECT_EQ(S, M->getScope());
1029 EXPECT_EQ(nullptr, M->getInlinedAt());
1032 // Two locations, same line/column different file, inlined at the same place.
1034 auto *FA = getFile();
1035 auto *FB = getFile();
1036 auto *FI = getFile();
1038 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1039 0, nullptr, 0, 0, DINode::FlagZero,
1040 DISubprogram::SPFlagZero, nullptr);
1042 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr,
1043 0, nullptr, 0, 0, DINode::FlagZero,
1044 DISubprogram::SPFlagZero, nullptr);
1046 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr,
1047 0, nullptr, 0, 0, DINode::FlagZero,
1048 DISubprogram::SPFlagZero, nullptr);
1050 auto *I = DILocation::get(Context, 3, 8, SPI);
1051 auto *A = DILocation::get(Context, 2, 7, SPA, I);
1052 auto *B = DILocation::get(Context, 2, 7, SPB, I);
1053 auto *M = DILocation::getMergedLocation(A, B);
1054 EXPECT_EQ(3u, M->getLine());
1055 EXPECT_EQ(8u, M->getColumn());
1056 EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
1057 EXPECT_EQ(SPI, M->getScope());
1058 EXPECT_EQ(nullptr, M->getInlinedAt());
1061 // Two locations, same line/column different file, one location with 2 scopes,
1062 // inlined at the same place.
1064 auto *FA = getFile();
1065 auto *FB = getFile();
1066 auto *FI = getFile();
1068 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1069 0, nullptr, 0, 0, DINode::FlagZero,
1070 DISubprogram::SPFlagZero, nullptr);
1072 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr,
1073 0, nullptr, 0, 0, DINode::FlagZero,
1074 DISubprogram::SPFlagZero, nullptr);
1076 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr,
1077 0, nullptr, 0, 0, DINode::FlagZero,
1078 DISubprogram::SPFlagZero, nullptr);
1080 auto *SPAScope = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9);
1082 auto *I = DILocation::get(Context, 3, 8, SPI);
1083 auto *A = DILocation::get(Context, 2, 7, SPAScope, I);
1084 auto *B = DILocation::get(Context, 2, 7, SPB, I);
1085 auto *M = DILocation::getMergedLocation(A, B);
1086 EXPECT_EQ(3u, M->getLine());
1087 EXPECT_EQ(8u, M->getColumn());
1088 EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
1089 EXPECT_EQ(SPI, M->getScope());
1090 EXPECT_EQ(nullptr, M->getInlinedAt());
1093 // Merge a location in C, which is inlined-at in B that is inlined in A,
1094 // with a location in A that has the same scope, line and column as B's
1095 // inlined-at location.
1097 auto *FA = getFile();
1098 auto *FB = getFile();
1099 auto *FC = getFile();
1101 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1102 0, nullptr, 0, 0, DINode::FlagZero,
1103 DISubprogram::SPFlagZero, nullptr);
1105 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr,
1106 0, nullptr, 0, 0, DINode::FlagZero,
1107 DISubprogram::SPFlagZero, nullptr);
1109 auto *SPC = DISubprogram::getDistinct(Context, FC, "c", "c", FC, 0, nullptr,
1110 0, nullptr, 0, 0, DINode::FlagZero,
1111 DISubprogram::SPFlagZero, nullptr);
1113 auto *A = DILocation::get(Context, 3, 2, SPA);
1114 auto *B = DILocation::get(Context, 2, 4, SPB, A);
1115 auto *C = DILocation::get(Context, 13, 2, SPC, B);
1116 auto *M = DILocation::getMergedLocation(A, C);
1117 EXPECT_EQ(3u, M->getLine());
1118 EXPECT_EQ(2u, M->getColumn());
1119 EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
1120 EXPECT_EQ(SPA, M->getScope());
1121 EXPECT_EQ(nullptr, M->getInlinedAt());
1124 // Two inlined locations with the same scope, line and column
1125 // in the same inlined-at function at different line and column.
1127 auto *FA = getFile();
1128 auto *FB = getFile();
1129 auto *FC = getFile();
1131 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1132 0, nullptr, 0, 0, DINode::FlagZero,
1133 DISubprogram::SPFlagZero, nullptr);
1135 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr,
1136 0, nullptr, 0, 0, DINode::FlagZero,
1137 DISubprogram::SPFlagZero, nullptr);
1139 auto *SPC = DISubprogram::getDistinct(Context, FC, "c", "c", FC, 0, nullptr,
1140 0, nullptr, 0, 0, DINode::FlagZero,
1141 DISubprogram::SPFlagZero, nullptr);
1143 auto *A = DILocation::get(Context, 10, 20, SPA);
1144 auto *B1 = DILocation::get(Context, 3, 2, SPB, A);
1145 auto *B2 = DILocation::get(Context, 4, 5, SPB, A);
1146 auto *C1 = DILocation::get(Context, 2, 4, SPC, B1);
1147 auto *C2 = DILocation::get(Context, 2, 4, SPC, B2);
1149 auto *M = DILocation::getMergedLocation(C1, C2);
1150 EXPECT_EQ(2u, M->getLine());
1151 EXPECT_EQ(4u, M->getColumn());
1152 EXPECT_EQ(SPC, M->getScope());
1153 ASSERT_NE(nullptr, M->getInlinedAt());
1155 auto *I1 = M->getInlinedAt();
1156 EXPECT_EQ(0u, I1->getLine());
1157 EXPECT_EQ(0u, I1->getColumn());
1158 EXPECT_EQ(SPB, I1->getScope());
1159 EXPECT_EQ(A, I1->getInlinedAt());
1162 // Two locations, different line/column and scope in the same subprogram,
1163 // inlined at the same place. This should result in a 0:0 location with
1164 // the nearest common scope in the inlined function.
1166 auto *FA = getFile();
1167 auto *FI = getFile();
1169 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1170 0, nullptr, 0, 0, DINode::FlagZero,
1171 DISubprogram::SPFlagZero, nullptr);
1173 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr,
1174 0, nullptr, 0, 0, DINode::FlagZero,
1175 DISubprogram::SPFlagZero, nullptr);
1177 // Nearest common scope for the two locations in a.
1178 auto *SPAScope1 = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9);
1180 // Scope for the first location in a.
1181 auto *SPAScope2 =
1182 DILexicalBlock::getDistinct(Context, SPAScope1, FA, 10, 12);
1184 // Scope for the second location in a.
1185 auto *SPAScope3 =
1186 DILexicalBlock::getDistinct(Context, SPAScope1, FA, 20, 8);
1187 auto *SPAScope4 =
1188 DILexicalBlock::getDistinct(Context, SPAScope3, FA, 21, 12);
1190 auto *I = DILocation::get(Context, 3, 8, SPI);
1191 auto *A1 = DILocation::get(Context, 12, 7, SPAScope2, I);
1192 auto *A2 = DILocation::get(Context, 21, 15, SPAScope4, I);
1193 auto *M = DILocation::getMergedLocation(A1, A2);
1194 EXPECT_EQ(0u, M->getLine());
1195 EXPECT_EQ(0u, M->getColumn());
1196 EXPECT_TRUE(isa<DILocalScope>(M->getScope()));
1197 EXPECT_EQ(SPAScope1, M->getScope());
1198 EXPECT_EQ(I, M->getInlinedAt());
1201 // Regression test to catch a case where an iterator was invalidated due to
1202 // handling the chain of inlined-at locations after the nearest common
1203 // location for the two arguments were found.
1205 auto *FA = getFile();
1206 auto *FB = getFile();
1207 auto *FI = getFile();
1209 auto *SPA = DISubprogram::getDistinct(Context, FA, "a", "a", FA, 0, nullptr,
1210 0, nullptr, 0, 0, DINode::FlagZero,
1211 DISubprogram::SPFlagZero, nullptr);
1213 auto *SPB = DISubprogram::getDistinct(Context, FB, "b", "b", FB, 0, nullptr,
1214 0, nullptr, 0, 0, DINode::FlagZero,
1215 DISubprogram::SPFlagZero, nullptr);
1217 auto *SPI = DISubprogram::getDistinct(Context, FI, "i", "i", FI, 0, nullptr,
1218 0, nullptr, 0, 0, DINode::FlagZero,
1219 DISubprogram::SPFlagZero, nullptr);
1221 auto *SPAScope1 = DILexicalBlock::getDistinct(Context, SPA, FA, 4, 9);
1222 auto *SPAScope2 = DILexicalBlock::getDistinct(Context, SPA, FA, 8, 3);
1224 DILocation *InlinedAt = nullptr;
1226 // Create a chain of inlined-at locations.
1227 for (int i = 0; i < 256; i++) {
1228 InlinedAt = DILocation::get(Context, 3 + i, 8 + i, SPI, InlinedAt);
1231 auto *A1 = DILocation::get(Context, 5, 9, SPAScope1, InlinedAt);
1232 auto *A2 = DILocation::get(Context, 9, 8, SPAScope2, InlinedAt);
1233 auto *B = DILocation::get(Context, 10, 3, SPB, A1);
1234 auto *M1 = DILocation::getMergedLocation(B, A2);
1235 EXPECT_EQ(0u, M1->getLine());
1236 EXPECT_EQ(0u, M1->getColumn());
1237 EXPECT_TRUE(isa<DILocalScope>(M1->getScope()));
1238 EXPECT_EQ(SPA, M1->getScope());
1239 EXPECT_EQ(InlinedAt, M1->getInlinedAt());
1241 // Test the other argument order for good measure.
1242 auto *M2 = DILocation::getMergedLocation(A2, B);
1243 EXPECT_EQ(M1, M2);
1247 TEST_F(DILocationTest, getDistinct) {
1248 MDNode *N = getSubprogram();
1249 DILocation *L0 = DILocation::getDistinct(Context, 2, 7, N);
1250 EXPECT_TRUE(L0->isDistinct());
1251 DILocation *L1 = DILocation::get(Context, 2, 7, N);
1252 EXPECT_FALSE(L1->isDistinct());
1253 EXPECT_EQ(L1, DILocation::get(Context, 2, 7, N));
1256 TEST_F(DILocationTest, getTemporary) {
1257 MDNode *N = MDNode::get(Context, std::nullopt);
1258 auto L = DILocation::getTemporary(Context, 2, 7, N);
1259 EXPECT_TRUE(L->isTemporary());
1260 EXPECT_FALSE(L->isResolved());
1263 TEST_F(DILocationTest, cloneTemporary) {
1264 MDNode *N = MDNode::get(Context, std::nullopt);
1265 auto L = DILocation::getTemporary(Context, 2, 7, N);
1266 EXPECT_TRUE(L->isTemporary());
1267 auto L2 = L->clone();
1268 EXPECT_TRUE(L2->isTemporary());
1271 TEST_F(DILocationTest, discriminatorEncoding) {
1272 EXPECT_EQ(0U, *DILocation::encodeDiscriminator(0, 0, 0));
1274 // Encode base discriminator as a component: lsb is 0, then the value.
1275 // The other components are all absent, so we leave all the other bits 0.
1276 EXPECT_EQ(2U, *DILocation::encodeDiscriminator(1, 0, 0));
1278 // Base discriminator component is empty, so lsb is 1. Next component is not
1279 // empty, so its lsb is 0, then its value (1). Next component is empty.
1280 // So the bit pattern is 101.
1281 EXPECT_EQ(5U, *DILocation::encodeDiscriminator(0, 1, 0));
1283 // First 2 components are empty, so the bit pattern is 11. Then the
1284 // next component - ending up with 1011.
1285 EXPECT_EQ(0xbU, *DILocation::encodeDiscriminator(0, 0, 1));
1287 // The bit pattern for the first 2 components is 11. The next bit is 0,
1288 // because the last component is not empty. We have 29 bits usable for
1289 // encoding, but we cap it at 12 bits uniformously for all components. We
1290 // encode the last component over 14 bits.
1291 EXPECT_EQ(0xfffbU, *DILocation::encodeDiscriminator(0, 0, 0xfff));
1293 EXPECT_EQ(0x102U, *DILocation::encodeDiscriminator(1, 1, 0));
1295 EXPECT_EQ(0x13eU, *DILocation::encodeDiscriminator(0x1f, 1, 0));
1297 EXPECT_EQ(0x87feU, *DILocation::encodeDiscriminator(0x1ff, 1, 0));
1299 EXPECT_EQ(0x1f3eU, *DILocation::encodeDiscriminator(0x1f, 0x1f, 0));
1301 EXPECT_EQ(0x3ff3eU, *DILocation::encodeDiscriminator(0x1f, 0x1ff, 0));
1303 EXPECT_EQ(0x1ff87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1ff, 0));
1305 EXPECT_EQ(0xfff9f3eU, *DILocation::encodeDiscriminator(0x1f, 0x1f, 0xfff));
1307 EXPECT_EQ(0xffc3ff3eU, *DILocation::encodeDiscriminator(0x1f, 0x1ff, 0x1ff));
1309 EXPECT_EQ(0xffcf87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1f, 0x1ff));
1311 EXPECT_EQ(0xe1ff87feU, *DILocation::encodeDiscriminator(0x1ff, 0x1ff, 7));
1314 TEST_F(DILocationTest, discriminatorEncodingNegativeTests) {
1315 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0, 0x1000));
1316 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0x1000, 0, 0));
1317 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0x1000, 0));
1318 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0, 0, 0x1000));
1319 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(0x1ff, 0x1ff, 8));
1320 EXPECT_EQ(std::nullopt, DILocation::encodeDiscriminator(
1321 std::numeric_limits<uint32_t>::max(),
1322 std::numeric_limits<uint32_t>::max(), 0));
1325 TEST_F(DILocationTest, discriminatorSpecialCases) {
1326 // We don't test getCopyIdentifier here because the only way
1327 // to set it is by constructing an encoded discriminator using
1328 // encodeDiscriminator, which is already tested.
1329 auto L1 = DILocation::get(Context, 1, 2, getSubprogram());
1330 EXPECT_EQ(0U, L1->getBaseDiscriminator());
1331 EXPECT_EQ(1U, L1->getDuplicationFactor());
1333 EXPECT_EQ(L1, *L1->cloneWithBaseDiscriminator(0));
1334 EXPECT_EQ(L1, *L1->cloneByMultiplyingDuplicationFactor(0));
1335 EXPECT_EQ(L1, *L1->cloneByMultiplyingDuplicationFactor(1));
1337 auto L2 = *L1->cloneWithBaseDiscriminator(1);
1338 EXPECT_EQ(0U, L1->getBaseDiscriminator());
1339 EXPECT_EQ(1U, L1->getDuplicationFactor());
1341 EXPECT_EQ(1U, L2->getBaseDiscriminator());
1342 EXPECT_EQ(1U, L2->getDuplicationFactor());
1344 auto L3 = *L2->cloneByMultiplyingDuplicationFactor(2);
1345 EXPECT_EQ(1U, L3->getBaseDiscriminator());
1346 EXPECT_EQ(2U, L3->getDuplicationFactor());
1348 EXPECT_EQ(L2, *L2->cloneByMultiplyingDuplicationFactor(1));
1350 auto L4 = *L3->cloneByMultiplyingDuplicationFactor(4);
1351 EXPECT_EQ(1U, L4->getBaseDiscriminator());
1352 EXPECT_EQ(8U, L4->getDuplicationFactor());
1354 auto L5 = *L4->cloneWithBaseDiscriminator(2);
1355 EXPECT_EQ(2U, L5->getBaseDiscriminator());
1356 EXPECT_EQ(8U, L5->getDuplicationFactor());
1358 // Check extreme cases
1359 auto L6 = *L1->cloneWithBaseDiscriminator(0xfff);
1360 EXPECT_EQ(0xfffU, L6->getBaseDiscriminator());
1361 EXPECT_EQ(0xfffU, (*L6->cloneByMultiplyingDuplicationFactor(0xfff))
1362 ->getDuplicationFactor());
1364 // Check we return std::nullopt for unencodable cases.
1365 EXPECT_EQ(std::nullopt, L4->cloneWithBaseDiscriminator(0x1000));
1366 EXPECT_EQ(std::nullopt, L4->cloneByMultiplyingDuplicationFactor(0x1000));
1370 typedef MetadataTest GenericDINodeTest;
1372 TEST_F(GenericDINodeTest, get) {
1373 StringRef Header = "header";
1374 auto *Empty = MDNode::get(Context, std::nullopt);
1375 Metadata *Ops1[] = {Empty};
1376 auto *N = GenericDINode::get(Context, 15, Header, Ops1);
1377 EXPECT_EQ(15u, N->getTag());
1378 EXPECT_EQ(2u, N->getNumOperands());
1379 EXPECT_EQ(Header, N->getHeader());
1380 EXPECT_EQ(MDString::get(Context, Header), N->getOperand(0));
1381 EXPECT_EQ(1u, N->getNumDwarfOperands());
1382 EXPECT_EQ(Empty, N->getDwarfOperand(0));
1383 EXPECT_EQ(Empty, N->getOperand(1));
1384 ASSERT_TRUE(N->isUniqued());
1386 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1));
1388 N->replaceOperandWith(1, nullptr);
1389 EXPECT_EQ(15u, N->getTag());
1390 EXPECT_EQ(Header, N->getHeader());
1391 EXPECT_EQ(nullptr, N->getDwarfOperand(0));
1392 ASSERT_TRUE(N->isUniqued());
1394 Metadata *Ops2[] = {nullptr};
1395 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops2));
1397 N->replaceDwarfOperandWith(0, Empty);
1398 EXPECT_EQ(15u, N->getTag());
1399 EXPECT_EQ(Header, N->getHeader());
1400 EXPECT_EQ(Empty, N->getDwarfOperand(0));
1401 ASSERT_TRUE(N->isUniqued());
1402 EXPECT_EQ(N, GenericDINode::get(Context, 15, Header, Ops1));
1404 TempGenericDINode Temp = N->clone();
1405 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1408 TEST_F(GenericDINodeTest, getEmptyHeader) {
1409 // Canonicalize !"" to null.
1410 auto *N = GenericDINode::get(Context, 15, StringRef(), std::nullopt);
1411 EXPECT_EQ(StringRef(), N->getHeader());
1412 EXPECT_EQ(nullptr, N->getOperand(0));
1415 typedef MetadataTest DISubrangeTest;
1417 TEST_F(DISubrangeTest, get) {
1418 auto *N = DISubrange::get(Context, 5, 7);
1419 auto Count = N->getCount();
1420 auto Lower = N->getLowerBound();
1421 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
1422 ASSERT_TRUE(Count);
1423 ASSERT_TRUE(isa<ConstantInt *>(Count));
1424 EXPECT_EQ(5, cast<ConstantInt *>(Count)->getSExtValue());
1425 EXPECT_EQ(7, cast<ConstantInt *>(Lower)->getSExtValue());
1426 EXPECT_EQ(N, DISubrange::get(Context, 5, 7));
1427 EXPECT_EQ(DISubrange::get(Context, 5, 0), DISubrange::get(Context, 5));
1429 TempDISubrange Temp = N->clone();
1430 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1433 TEST_F(DISubrangeTest, getEmptyArray) {
1434 auto *N = DISubrange::get(Context, -1, 0);
1435 auto Count = N->getCount();
1436 auto Lower = N->getLowerBound();
1437 EXPECT_EQ(dwarf::DW_TAG_subrange_type, N->getTag());
1438 ASSERT_TRUE(Count);
1439 ASSERT_TRUE(isa<ConstantInt *>(Count));
1440 EXPECT_EQ(-1, cast<ConstantInt *>(Count)->getSExtValue());
1441 EXPECT_EQ(0, cast<ConstantInt *>(Lower)->getSExtValue());
1442 EXPECT_EQ(N, DISubrange::get(Context, -1, 0));
1445 TEST_F(DISubrangeTest, getVariableCount) {
1446 DILocalScope *Scope = getSubprogram();
1447 DIFile *File = getFile();
1448 DIType *Type = getDerivedType();
1449 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1450 auto *VlaExpr = DILocalVariable::get(Context, Scope, "vla_expr", File, 8,
1451 Type, 2, Flags, 8, nullptr);
1453 auto *N = DISubrange::get(Context, VlaExpr, 0);
1454 auto Count = N->getCount();
1455 auto Lower = N->getLowerBound();
1456 ASSERT_TRUE(Count);
1457 ASSERT_TRUE(isa<DIVariable *>(Count));
1458 EXPECT_EQ(VlaExpr, cast<DIVariable *>(Count));
1459 ASSERT_TRUE(isa<DIVariable>(N->getRawCountNode()));
1460 EXPECT_EQ(0, cast<ConstantInt *>(Lower)->getSExtValue());
1461 EXPECT_EQ("vla_expr", cast<DIVariable *>(Count)->getName());
1462 EXPECT_EQ(N, DISubrange::get(Context, VlaExpr, 0));
1465 TEST_F(DISubrangeTest, fortranAllocatableInt) {
1466 DILocalScope *Scope = getSubprogram();
1467 DIFile *File = getFile();
1468 DIType *Type = getDerivedType();
1469 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1470 auto *LI = ConstantAsMetadata::get(
1471 ConstantInt::getSigned(Type::getInt64Ty(Context), -10));
1472 auto *UI = ConstantAsMetadata::get(
1473 ConstantInt::getSigned(Type::getInt64Ty(Context), 10));
1474 auto *SI = ConstantAsMetadata::get(
1475 ConstantInt::getSigned(Type::getInt64Ty(Context), 4));
1476 auto *UIother = ConstantAsMetadata::get(
1477 ConstantInt::getSigned(Type::getInt64Ty(Context), 20));
1478 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type,
1479 2, Flags, 8, nullptr);
1480 auto *UEother = DIExpression::get(Context, {5, 6});
1481 auto *LIZero = ConstantAsMetadata::get(
1482 ConstantInt::getSigned(Type::getInt64Ty(Context), 0));
1483 auto *UIZero = ConstantAsMetadata::get(
1484 ConstantInt::getSigned(Type::getInt64Ty(Context), 0));
1486 auto *N = DISubrange::get(Context, nullptr, LI, UI, SI);
1488 auto Lower = N->getLowerBound();
1489 ASSERT_TRUE(Lower);
1490 ASSERT_TRUE(isa<ConstantInt *>(Lower));
1491 EXPECT_EQ(cast<ConstantInt>(LI->getValue()), cast<ConstantInt *>(Lower));
1493 auto Upper = N->getUpperBound();
1494 ASSERT_TRUE(Upper);
1495 ASSERT_TRUE(isa<ConstantInt *>(Upper));
1496 EXPECT_EQ(cast<ConstantInt>(UI->getValue()), cast<ConstantInt *>(Upper));
1498 auto Stride = N->getStride();
1499 ASSERT_TRUE(Stride);
1500 ASSERT_TRUE(isa<ConstantInt *>(Stride));
1501 EXPECT_EQ(cast<ConstantInt>(SI->getValue()), cast<ConstantInt *>(Stride));
1503 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LI, UI, SI));
1505 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UIother, SI));
1506 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UEother, SI));
1507 EXPECT_NE(N, DISubrange::get(Context, nullptr, LI, UVother, SI));
1509 auto *NZeroLower = DISubrange::get(Context, nullptr, LIZero, UI, SI);
1510 EXPECT_NE(NZeroLower, DISubrange::get(Context, nullptr, nullptr, UI, SI));
1512 auto *NZeroUpper = DISubrange::get(Context, nullptr, LI, UIZero, SI);
1513 EXPECT_NE(NZeroUpper, DISubrange::get(Context, nullptr, LI, nullptr, SI));
1516 TEST_F(DISubrangeTest, fortranAllocatableVar) {
1517 DILocalScope *Scope = getSubprogram();
1518 DIFile *File = getFile();
1519 DIType *Type = getDerivedType();
1520 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1521 auto *LV =
1522 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8,
1523 nullptr);
1524 auto *UV =
1525 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8,
1526 nullptr);
1527 auto *SV =
1528 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8,
1529 nullptr);
1530 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type,
1531 2, Flags, 8, nullptr);
1532 auto *SIother = ConstantAsMetadata::get(
1533 ConstantInt::getSigned(Type::getInt64Ty(Context), 20));
1534 auto *SEother = DIExpression::get(Context, {5, 6});
1536 auto *N = DISubrange::get(Context, nullptr, LV, UV, SV);
1538 auto Lower = N->getLowerBound();
1539 ASSERT_TRUE(Lower);
1540 ASSERT_TRUE(isa<DIVariable *>(Lower));
1541 EXPECT_EQ(LV, cast<DIVariable *>(Lower));
1543 auto Upper = N->getUpperBound();
1544 ASSERT_TRUE(Upper);
1545 ASSERT_TRUE(isa<DIVariable *>(Upper));
1546 EXPECT_EQ(UV, cast<DIVariable *>(Upper));
1548 auto Stride = N->getStride();
1549 ASSERT_TRUE(Stride);
1550 ASSERT_TRUE(isa<DIVariable *>(Stride));
1551 EXPECT_EQ(SV, cast<DIVariable *>(Stride));
1553 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LV, UV, SV));
1555 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SVother));
1556 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SEother));
1557 EXPECT_NE(N, DISubrange::get(Context, nullptr, LV, UV, SIother));
1560 TEST_F(DISubrangeTest, fortranAllocatableExpr) {
1561 DILocalScope *Scope = getSubprogram();
1562 DIFile *File = getFile();
1563 DIType *Type = getDerivedType();
1564 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1565 auto *LE = DIExpression::get(Context, {1, 2});
1566 auto *UE = DIExpression::get(Context, {2, 3});
1567 auto *SE = DIExpression::get(Context, {3, 4});
1568 auto *LEother = DIExpression::get(Context, {5, 6});
1569 auto *LIother = ConstantAsMetadata::get(
1570 ConstantInt::getSigned(Type::getInt64Ty(Context), 20));
1571 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type,
1572 2, Flags, 8, nullptr);
1574 auto *N = DISubrange::get(Context, nullptr, LE, UE, SE);
1576 auto Lower = N->getLowerBound();
1577 ASSERT_TRUE(Lower);
1578 ASSERT_TRUE(isa<DIExpression *>(Lower));
1579 EXPECT_EQ(LE, cast<DIExpression *>(Lower));
1581 auto Upper = N->getUpperBound();
1582 ASSERT_TRUE(Upper);
1583 ASSERT_TRUE(isa<DIExpression *>(Upper));
1584 EXPECT_EQ(UE, cast<DIExpression *>(Upper));
1586 auto Stride = N->getStride();
1587 ASSERT_TRUE(Stride);
1588 ASSERT_TRUE(isa<DIExpression *>(Stride));
1589 EXPECT_EQ(SE, cast<DIExpression *>(Stride));
1591 EXPECT_EQ(N, DISubrange::get(Context, nullptr, LE, UE, SE));
1593 EXPECT_NE(N, DISubrange::get(Context, nullptr, LEother, UE, SE));
1594 EXPECT_NE(N, DISubrange::get(Context, nullptr, LIother, UE, SE));
1595 EXPECT_NE(N, DISubrange::get(Context, nullptr, LVother, UE, SE));
1598 typedef MetadataTest DIGenericSubrangeTest;
1600 TEST_F(DIGenericSubrangeTest, fortranAssumedRankInt) {
1601 DILocalScope *Scope = getSubprogram();
1602 DIFile *File = getFile();
1603 DIType *Type = getDerivedType();
1604 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1605 auto *LI = DIExpression::get(
1606 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-10)});
1607 auto *UI = DIExpression::get(Context, {dwarf::DW_OP_consts, 10});
1608 auto *SI = DIExpression::get(Context, {dwarf::DW_OP_consts, 4});
1609 auto *UIother = DIExpression::get(Context, {dwarf::DW_OP_consts, 20});
1610 auto *UVother = DILocalVariable::get(Context, Scope, "ubother", File, 8, Type,
1611 2, Flags, 8, nullptr);
1612 auto *UEother = DIExpression::get(Context, {5, 6});
1613 auto *LIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0});
1614 auto *UIZero = DIExpression::get(Context, {dwarf::DW_OP_consts, 0});
1616 auto *N = DIGenericSubrange::get(Context, nullptr, LI, UI, SI);
1618 auto Lower = N->getLowerBound();
1619 ASSERT_TRUE(Lower);
1620 ASSERT_TRUE(isa<DIExpression *>(Lower));
1621 EXPECT_EQ(dyn_cast_or_null<DIExpression>(LI), cast<DIExpression *>(Lower));
1623 auto Upper = N->getUpperBound();
1624 ASSERT_TRUE(Upper);
1625 ASSERT_TRUE(isa<DIExpression *>(Upper));
1626 EXPECT_EQ(dyn_cast_or_null<DIExpression>(UI), cast<DIExpression *>(Upper));
1628 auto Stride = N->getStride();
1629 ASSERT_TRUE(Stride);
1630 ASSERT_TRUE(isa<DIExpression *>(Stride));
1631 EXPECT_EQ(dyn_cast_or_null<DIExpression>(SI), cast<DIExpression *>(Stride));
1633 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LI, UI, SI));
1635 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UIother, SI));
1636 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UEother, SI));
1637 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LI, UVother, SI));
1639 auto *NZeroLower = DIGenericSubrange::get(Context, nullptr, LIZero, UI, SI);
1640 EXPECT_NE(NZeroLower,
1641 DIGenericSubrange::get(Context, nullptr, nullptr, UI, SI));
1643 auto *NZeroUpper = DIGenericSubrange::get(Context, nullptr, LI, UIZero, SI);
1644 EXPECT_NE(NZeroUpper,
1645 DIGenericSubrange::get(Context, nullptr, LI, nullptr, SI));
1648 TEST_F(DIGenericSubrangeTest, fortranAssumedRankVar) {
1649 DILocalScope *Scope = getSubprogram();
1650 DIFile *File = getFile();
1651 DIType *Type = getDerivedType();
1652 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1653 auto *LV =
1654 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8,
1655 nullptr);
1656 auto *UV =
1657 DILocalVariable::get(Context, Scope, "ub", File, 8, Type, 2, Flags, 8,
1658 nullptr);
1659 auto *SV =
1660 DILocalVariable::get(Context, Scope, "st", File, 8, Type, 2, Flags, 8,
1661 nullptr);
1662 auto *SVother = DILocalVariable::get(Context, Scope, "stother", File, 8, Type,
1663 2, Flags, 8, nullptr);
1664 auto *SIother = DIExpression::get(
1665 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)});
1666 auto *SEother = DIExpression::get(Context, {5, 6});
1668 auto *N = DIGenericSubrange::get(Context, nullptr, LV, UV, SV);
1670 auto Lower = N->getLowerBound();
1671 ASSERT_TRUE(Lower);
1672 ASSERT_TRUE(isa<DIVariable *>(Lower));
1673 EXPECT_EQ(LV, cast<DIVariable *>(Lower));
1675 auto Upper = N->getUpperBound();
1676 ASSERT_TRUE(Upper);
1677 ASSERT_TRUE(isa<DIVariable *>(Upper));
1678 EXPECT_EQ(UV, cast<DIVariable *>(Upper));
1680 auto Stride = N->getStride();
1681 ASSERT_TRUE(Stride);
1682 ASSERT_TRUE(isa<DIVariable *>(Stride));
1683 EXPECT_EQ(SV, cast<DIVariable *>(Stride));
1685 EXPECT_EQ(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SV));
1687 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SVother));
1688 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SEother));
1689 EXPECT_NE(N, DIGenericSubrange::get(Context, nullptr, LV, UV, SIother));
1692 TEST_F(DIGenericSubrangeTest, useDIBuilder) {
1693 DILocalScope *Scope = getSubprogram();
1694 DIFile *File = getFile();
1695 DIType *Type = getDerivedType();
1696 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
1697 auto *LV =
1698 DILocalVariable::get(Context, Scope, "lb", File, 8, Type, 2, Flags, 8, nullptr);
1699 auto *UE = DIExpression::get(Context, {2, 3});
1700 auto *SE = DIExpression::get(Context, {3, 4});
1702 auto *LVother = DILocalVariable::get(Context, Scope, "lbother", File, 8, Type,
1703 2, Flags, 8, nullptr);
1704 auto *LIother = DIExpression::get(
1705 Context, {dwarf::DW_OP_consts, static_cast<uint64_t>(-1)});
1707 Module M("M", Context);
1708 DIBuilder DIB(M);
1710 auto *N = DIB.getOrCreateGenericSubrange(
1711 DIGenericSubrange::BoundType(nullptr), DIGenericSubrange::BoundType(LV),
1712 DIGenericSubrange::BoundType(UE), DIGenericSubrange::BoundType(SE));
1714 auto Lower = N->getLowerBound();
1715 ASSERT_TRUE(Lower);
1716 ASSERT_TRUE(isa<DIVariable *>(Lower));
1717 EXPECT_EQ(LV, cast<DIVariable *>(Lower));
1719 auto Upper = N->getUpperBound();
1720 ASSERT_TRUE(Upper);
1721 ASSERT_TRUE(isa<DIExpression *>(Upper));
1722 EXPECT_EQ(UE, cast<DIExpression *>(Upper));
1724 auto Stride = N->getStride();
1725 ASSERT_TRUE(Stride);
1726 ASSERT_TRUE(isa<DIExpression *>(Stride));
1727 EXPECT_EQ(SE, cast<DIExpression *>(Stride));
1729 EXPECT_EQ(
1730 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr),
1731 DIGenericSubrange::BoundType(LV),
1732 DIGenericSubrange::BoundType(UE),
1733 DIGenericSubrange::BoundType(SE)));
1735 EXPECT_NE(
1736 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr),
1737 DIGenericSubrange::BoundType(LVother),
1738 DIGenericSubrange::BoundType(UE),
1739 DIGenericSubrange::BoundType(SE)));
1740 EXPECT_NE(
1741 N, DIB.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr),
1742 DIGenericSubrange::BoundType(LIother),
1743 DIGenericSubrange::BoundType(UE),
1744 DIGenericSubrange::BoundType(SE)));
1746 typedef MetadataTest DIEnumeratorTest;
1748 TEST_F(DIEnumeratorTest, get) {
1749 auto *N = DIEnumerator::get(Context, 7, false, "name");
1750 EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag());
1751 EXPECT_EQ(7, N->getValue().getSExtValue());
1752 EXPECT_FALSE(N->isUnsigned());
1753 EXPECT_EQ("name", N->getName());
1754 EXPECT_EQ(N, DIEnumerator::get(Context, 7, false, "name"));
1756 EXPECT_NE(N, DIEnumerator::get(Context, 7, true, "name"));
1757 EXPECT_NE(N, DIEnumerator::get(Context, 8, false, "name"));
1758 EXPECT_NE(N, DIEnumerator::get(Context, 7, false, "nam"));
1760 TempDIEnumerator Temp = N->clone();
1761 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1764 TEST_F(DIEnumeratorTest, getWithLargeValues) {
1765 auto *N = DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val");
1766 EXPECT_EQ(128U, N->getValue().popcount());
1767 EXPECT_EQ(N,
1768 DIEnumerator::get(Context, APInt::getMaxValue(128), false, "val"));
1769 EXPECT_NE(N,
1770 DIEnumerator::get(Context, APInt::getMinValue(128), false, "val"));
1773 typedef MetadataTest DIBasicTypeTest;
1775 TEST_F(DIBasicTypeTest, get) {
1776 auto *N =
1777 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7,
1778 DINode::FlagZero);
1779 EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag());
1780 EXPECT_EQ("special", N->getName());
1781 EXPECT_EQ(33u, N->getSizeInBits());
1782 EXPECT_EQ(26u, N->getAlignInBits());
1783 EXPECT_EQ(7u, N->getEncoding());
1784 EXPECT_EQ(0u, N->getLine());
1785 EXPECT_EQ(DINode::FlagZero, N->getFlags());
1786 EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1787 26, 7, DINode::FlagZero));
1789 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
1790 "special", 33, 26, 7, DINode::FlagZero));
1791 EXPECT_NE(N,
1792 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7,
1793 DINode::FlagZero));
1794 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
1795 26, 7, DINode::FlagZero));
1796 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1797 25, 7, DINode::FlagZero));
1798 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1799 26, 6, DINode::FlagZero));
1800 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1801 26, 7, DINode::FlagBigEndian));
1802 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1803 26, 7, DINode::FlagLittleEndian));
1805 TempDIBasicType Temp = N->clone();
1806 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1809 TEST_F(DIBasicTypeTest, getWithLargeValues) {
1810 auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special",
1811 UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero);
1812 EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
1813 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits());
1816 TEST_F(DIBasicTypeTest, getUnspecified) {
1817 auto *N =
1818 DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, "unspecified");
1819 EXPECT_EQ(dwarf::DW_TAG_unspecified_type, N->getTag());
1820 EXPECT_EQ("unspecified", N->getName());
1821 EXPECT_EQ(0u, N->getSizeInBits());
1822 EXPECT_EQ(0u, N->getAlignInBits());
1823 EXPECT_EQ(0u, N->getEncoding());
1824 EXPECT_EQ(0u, N->getLine());
1825 EXPECT_EQ(DINode::FlagZero, N->getFlags());
1828 typedef MetadataTest DITypeTest;
1830 TEST_F(DITypeTest, clone) {
1831 // Check that DIType has a specialized clone that returns TempDIType.
1832 DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32,
1833 dwarf::DW_ATE_signed, DINode::FlagZero);
1835 TempDIType Temp = N->clone();
1836 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1839 TEST_F(DITypeTest, cloneWithFlags) {
1840 // void (void)
1841 Metadata *TypesOps[] = {nullptr};
1842 Metadata *Types = MDTuple::get(Context, TypesOps);
1844 DIType *D =
1845 DISubroutineType::getDistinct(Context, DINode::FlagZero, 0, Types);
1846 EXPECT_EQ(DINode::FlagZero, D->getFlags());
1847 TempDIType D2 = D->cloneWithFlags(DINode::FlagRValueReference);
1848 EXPECT_EQ(DINode::FlagRValueReference, D2->getFlags());
1849 EXPECT_EQ(DINode::FlagZero, D->getFlags());
1851 TempDIType T =
1852 DISubroutineType::getTemporary(Context, DINode::FlagZero, 0, Types);
1853 EXPECT_EQ(DINode::FlagZero, T->getFlags());
1854 TempDIType T2 = T->cloneWithFlags(DINode::FlagRValueReference);
1855 EXPECT_EQ(DINode::FlagRValueReference, T2->getFlags());
1856 EXPECT_EQ(DINode::FlagZero, T->getFlags());
1859 typedef MetadataTest DIDerivedTypeTest;
1861 TEST_F(DIDerivedTypeTest, get) {
1862 DIFile *File = getFile();
1863 DIScope *Scope = getSubprogram();
1864 DIType *BaseType = getBasicType("basic");
1865 MDTuple *ExtraData = getTuple();
1866 unsigned DWARFAddressSpace = 8;
1867 DINode::DIFlags Flags5 = static_cast<DINode::DIFlags>(5);
1868 DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(4);
1870 auto *N =
1871 DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File,
1872 1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5,
1873 ExtraData);
1874 EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag());
1875 EXPECT_EQ("something", N->getName());
1876 EXPECT_EQ(File, N->getFile());
1877 EXPECT_EQ(1u, N->getLine());
1878 EXPECT_EQ(Scope, N->getScope());
1879 EXPECT_EQ(BaseType, N->getBaseType());
1880 EXPECT_EQ(2u, N->getSizeInBits());
1881 EXPECT_EQ(3u, N->getAlignInBits());
1882 EXPECT_EQ(4u, N->getOffsetInBits());
1883 EXPECT_EQ(DWARFAddressSpace, *N->getDWARFAddressSpace());
1884 EXPECT_EQ(5u, N->getFlags());
1885 EXPECT_EQ(ExtraData, N->getExtraData());
1886 EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1887 "something", File, 1, Scope, BaseType, 2, 3,
1888 4, DWARFAddressSpace, Flags5, ExtraData));
1890 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type,
1891 "something", File, 1, Scope, BaseType, 2, 3,
1892 4, DWARFAddressSpace, Flags5, ExtraData));
1893 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else",
1894 File, 1, Scope, BaseType, 2, 3,
1895 4, DWARFAddressSpace, Flags5, ExtraData));
1896 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1897 "something", getFile(), 1, Scope, BaseType, 2,
1898 3, 4, DWARFAddressSpace, Flags5, ExtraData));
1899 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1900 "something", File, 2, Scope, BaseType, 2, 3,
1901 4, DWARFAddressSpace, Flags5, ExtraData));
1902 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1903 "something", File, 1, getSubprogram(),
1904 BaseType, 2, 3, 4, DWARFAddressSpace, Flags5,
1905 ExtraData));
1906 EXPECT_NE(N, DIDerivedType::get(
1907 Context, dwarf::DW_TAG_pointer_type, "something", File, 1,
1908 Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace,
1909 Flags5, ExtraData));
1910 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1911 "something", File, 1, Scope, BaseType, 3, 3,
1912 4, DWARFAddressSpace, Flags5, ExtraData));
1913 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1914 "something", File, 1, Scope, BaseType, 2, 2,
1915 4, DWARFAddressSpace, Flags5, ExtraData));
1916 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1917 "something", File, 1, Scope, BaseType, 2, 3,
1918 5, DWARFAddressSpace, Flags5, ExtraData));
1919 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1920 "something", File, 1, Scope, BaseType, 2, 3,
1921 4, DWARFAddressSpace + 1, Flags5, ExtraData));
1922 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1923 "something", File, 1, Scope, BaseType, 2, 3,
1924 4, DWARFAddressSpace, Flags4, ExtraData));
1925 EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
1926 "something", File, 1, Scope, BaseType, 2, 3,
1927 4, DWARFAddressSpace, Flags5, getTuple()));
1929 TempDIDerivedType Temp = N->clone();
1930 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
1933 TEST_F(DIDerivedTypeTest, getWithLargeValues) {
1934 DIFile *File = getFile();
1935 DIScope *Scope = getSubprogram();
1936 DIType *BaseType = getBasicType("basic");
1937 MDTuple *ExtraData = getTuple();
1938 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
1940 auto *N = DIDerivedType::get(
1941 Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope,
1942 BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3,
1943 Flags, ExtraData);
1944 EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
1945 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits());
1946 EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits());
1947 EXPECT_EQ(UINT32_MAX - 3, *N->getDWARFAddressSpace());
1950 typedef MetadataTest DICompositeTypeTest;
1952 TEST_F(DICompositeTypeTest, get) {
1953 unsigned Tag = dwarf::DW_TAG_structure_type;
1954 StringRef Name = "some name";
1955 DIFile *File = getFile();
1956 unsigned Line = 1;
1957 DIScope *Scope = getSubprogram();
1958 DIType *BaseType = getCompositeType();
1959 uint64_t SizeInBits = 2;
1960 uint32_t AlignInBits = 3;
1961 uint64_t OffsetInBits = 4;
1962 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
1963 MDTuple *Elements = getTuple();
1964 unsigned RuntimeLang = 6;
1965 DIType *VTableHolder = getCompositeType();
1966 MDTuple *TemplateParams = getTuple();
1967 StringRef Identifier = "some id";
1969 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope,
1970 BaseType, SizeInBits, AlignInBits,
1971 OffsetInBits, Flags, Elements, RuntimeLang,
1972 VTableHolder, TemplateParams, Identifier);
1973 EXPECT_EQ(Tag, N->getTag());
1974 EXPECT_EQ(Name, N->getName());
1975 EXPECT_EQ(File, N->getFile());
1976 EXPECT_EQ(Line, N->getLine());
1977 EXPECT_EQ(Scope, N->getScope());
1978 EXPECT_EQ(BaseType, N->getBaseType());
1979 EXPECT_EQ(SizeInBits, N->getSizeInBits());
1980 EXPECT_EQ(AlignInBits, N->getAlignInBits());
1981 EXPECT_EQ(OffsetInBits, N->getOffsetInBits());
1982 EXPECT_EQ(Flags, N->getFlags());
1983 EXPECT_EQ(Elements, N->getElements().get());
1984 EXPECT_EQ(RuntimeLang, N->getRuntimeLang());
1985 EXPECT_EQ(VTableHolder, N->getVTableHolder());
1986 EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
1987 EXPECT_EQ(Identifier, N->getIdentifier());
1989 EXPECT_EQ(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
1990 BaseType, SizeInBits, AlignInBits,
1991 OffsetInBits, Flags, Elements, RuntimeLang,
1992 VTableHolder, TemplateParams, Identifier));
1994 EXPECT_NE(N, DICompositeType::get(Context, Tag + 1, Name, File, Line, Scope,
1995 BaseType, SizeInBits, AlignInBits,
1996 OffsetInBits, Flags, Elements, RuntimeLang,
1997 VTableHolder, TemplateParams, Identifier));
1998 EXPECT_NE(N, DICompositeType::get(Context, Tag, "abc", File, Line, Scope,
1999 BaseType, SizeInBits, AlignInBits,
2000 OffsetInBits, Flags, Elements, RuntimeLang,
2001 VTableHolder, TemplateParams, Identifier));
2002 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, getFile(), Line, Scope,
2003 BaseType, SizeInBits, AlignInBits,
2004 OffsetInBits, Flags, Elements, RuntimeLang,
2005 VTableHolder, TemplateParams, Identifier));
2006 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line + 1, Scope,
2007 BaseType, SizeInBits, AlignInBits,
2008 OffsetInBits, Flags, Elements, RuntimeLang,
2009 VTableHolder, TemplateParams, Identifier));
2010 EXPECT_NE(N, DICompositeType::get(
2011 Context, Tag, Name, File, Line, getSubprogram(), BaseType,
2012 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
2013 RuntimeLang, VTableHolder, TemplateParams, Identifier));
2014 EXPECT_NE(N, DICompositeType::get(
2015 Context, Tag, Name, File, Line, Scope, getBasicType("other"),
2016 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
2017 RuntimeLang, VTableHolder, TemplateParams, Identifier));
2018 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2019 BaseType, SizeInBits + 1, AlignInBits,
2020 OffsetInBits, Flags, Elements, RuntimeLang,
2021 VTableHolder, TemplateParams, Identifier));
2022 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2023 BaseType, SizeInBits, AlignInBits + 1,
2024 OffsetInBits, Flags, Elements, RuntimeLang,
2025 VTableHolder, TemplateParams, Identifier));
2026 EXPECT_NE(N, DICompositeType::get(
2027 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
2028 AlignInBits, OffsetInBits + 1, Flags, Elements, RuntimeLang,
2029 VTableHolder, TemplateParams, Identifier));
2030 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1);
2031 EXPECT_NE(N, DICompositeType::get(
2032 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
2033 AlignInBits, OffsetInBits, FlagsPOne, Elements, RuntimeLang,
2034 VTableHolder, TemplateParams, Identifier));
2035 EXPECT_NE(N, DICompositeType::get(
2036 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
2037 AlignInBits, OffsetInBits, Flags, getTuple(), RuntimeLang,
2038 VTableHolder, TemplateParams, Identifier));
2039 EXPECT_NE(N, DICompositeType::get(
2040 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
2041 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang + 1,
2042 VTableHolder, TemplateParams, Identifier));
2043 EXPECT_NE(N, DICompositeType::get(
2044 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
2045 AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
2046 getCompositeType(), TemplateParams, Identifier));
2047 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2048 BaseType, SizeInBits, AlignInBits,
2049 OffsetInBits, Flags, Elements, RuntimeLang,
2050 VTableHolder, getTuple(), Identifier));
2051 EXPECT_NE(N, DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2052 BaseType, SizeInBits, AlignInBits,
2053 OffsetInBits, Flags, Elements, RuntimeLang,
2054 VTableHolder, TemplateParams, "other"));
2056 // Be sure that missing identifiers get null pointers.
2057 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2058 BaseType, SizeInBits, AlignInBits,
2059 OffsetInBits, Flags, Elements, RuntimeLang,
2060 VTableHolder, TemplateParams, "")
2061 ->getRawIdentifier());
2062 EXPECT_FALSE(DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2063 BaseType, SizeInBits, AlignInBits,
2064 OffsetInBits, Flags, Elements, RuntimeLang,
2065 VTableHolder, TemplateParams)
2066 ->getRawIdentifier());
2068 TempDICompositeType Temp = N->clone();
2069 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2072 TEST_F(DICompositeTypeTest, getWithLargeValues) {
2073 unsigned Tag = dwarf::DW_TAG_structure_type;
2074 StringRef Name = "some name";
2075 DIFile *File = getFile();
2076 unsigned Line = 1;
2077 DIScope *Scope = getSubprogram();
2078 DIType *BaseType = getCompositeType();
2079 uint64_t SizeInBits = UINT64_MAX;
2080 uint32_t AlignInBits = UINT32_MAX - 1;
2081 uint64_t OffsetInBits = UINT64_MAX - 2;
2082 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
2083 MDTuple *Elements = getTuple();
2084 unsigned RuntimeLang = 6;
2085 DIType *VTableHolder = getCompositeType();
2086 MDTuple *TemplateParams = getTuple();
2087 StringRef Identifier = "some id";
2089 auto *N = DICompositeType::get(Context, Tag, Name, File, Line, Scope,
2090 BaseType, SizeInBits, AlignInBits,
2091 OffsetInBits, Flags, Elements, RuntimeLang,
2092 VTableHolder, TemplateParams, Identifier);
2093 EXPECT_EQ(SizeInBits, N->getSizeInBits());
2094 EXPECT_EQ(AlignInBits, N->getAlignInBits());
2095 EXPECT_EQ(OffsetInBits, N->getOffsetInBits());
2098 TEST_F(DICompositeTypeTest, replaceOperands) {
2099 unsigned Tag = dwarf::DW_TAG_structure_type;
2100 StringRef Name = "some name";
2101 DIFile *File = getFile();
2102 unsigned Line = 1;
2103 DIScope *Scope = getSubprogram();
2104 DIType *BaseType = getCompositeType();
2105 uint64_t SizeInBits = 2;
2106 uint32_t AlignInBits = 3;
2107 uint64_t OffsetInBits = 4;
2108 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
2109 unsigned RuntimeLang = 6;
2110 StringRef Identifier = "some id";
2112 auto *N = DICompositeType::get(
2113 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2114 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier);
2116 auto *Elements = MDTuple::getDistinct(Context, std::nullopt);
2117 EXPECT_EQ(nullptr, N->getElements().get());
2118 N->replaceElements(Elements);
2119 EXPECT_EQ(Elements, N->getElements().get());
2120 N->replaceElements(nullptr);
2121 EXPECT_EQ(nullptr, N->getElements().get());
2123 DIType *VTableHolder = getCompositeType();
2124 EXPECT_EQ(nullptr, N->getVTableHolder());
2125 N->replaceVTableHolder(VTableHolder);
2126 EXPECT_EQ(VTableHolder, N->getVTableHolder());
2127 // As an extension, the containing type can be anything. This is
2128 // used by Rust to associate vtables with their concrete type.
2129 DIType *BasicType = getBasicType("basic");
2130 N->replaceVTableHolder(BasicType);
2131 EXPECT_EQ(BasicType, N->getVTableHolder());
2132 N->replaceVTableHolder(nullptr);
2133 EXPECT_EQ(nullptr, N->getVTableHolder());
2135 auto *TemplateParams = MDTuple::getDistinct(Context, std::nullopt);
2136 EXPECT_EQ(nullptr, N->getTemplateParams().get());
2137 N->replaceTemplateParams(TemplateParams);
2138 EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
2139 N->replaceTemplateParams(nullptr);
2140 EXPECT_EQ(nullptr, N->getTemplateParams().get());
2143 TEST_F(DICompositeTypeTest, variant_part) {
2144 unsigned Tag = dwarf::DW_TAG_variant_part;
2145 StringRef Name = "some name";
2146 DIFile *File = getFile();
2147 unsigned Line = 1;
2148 DIScope *Scope = getSubprogram();
2149 DIType *BaseType = getCompositeType();
2150 uint64_t SizeInBits = 2;
2151 uint32_t AlignInBits = 3;
2152 uint64_t OffsetInBits = 4;
2153 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(5);
2154 unsigned RuntimeLang = 6;
2155 StringRef Identifier = "some id";
2156 DIDerivedType *Discriminator = cast<DIDerivedType>(getDerivedType());
2157 DIDerivedType *Discriminator2 = cast<DIDerivedType>(getDerivedType());
2159 EXPECT_NE(Discriminator, Discriminator2);
2161 auto *N = DICompositeType::get(
2162 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2163 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2164 Discriminator);
2166 // Test the hashing.
2167 auto *Same = DICompositeType::get(
2168 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2169 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2170 Discriminator);
2171 auto *Other = DICompositeType::get(
2172 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2173 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2174 Discriminator2);
2175 auto *NoDisc = DICompositeType::get(
2176 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2177 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2178 nullptr);
2180 EXPECT_EQ(N, Same);
2181 EXPECT_NE(Same, Other);
2182 EXPECT_NE(Same, NoDisc);
2183 EXPECT_NE(Other, NoDisc);
2185 EXPECT_EQ(N->getDiscriminator(), Discriminator);
2188 TEST_F(DICompositeTypeTest, dynamicArray) {
2189 unsigned Tag = dwarf::DW_TAG_array_type;
2190 StringRef Name = "some name";
2191 DIFile *File = getFile();
2192 unsigned Line = 1;
2193 DILocalScope *Scope = getSubprogram();
2194 DIType *BaseType = getCompositeType();
2195 uint64_t SizeInBits = 32;
2196 uint32_t AlignInBits = 32;
2197 uint64_t OffsetInBits = 4;
2198 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(3);
2199 unsigned RuntimeLang = 6;
2200 StringRef Identifier = "some id";
2201 DIType *Type = getDerivedType();
2202 Metadata *DlVar1 = DILocalVariable::get(Context, Scope, "dl_var1", File, 8,
2203 Type, 2, Flags, 8, nullptr);
2204 Metadata *DlVar2 = DILocalVariable::get(Context, Scope, "dl_var2", File, 8,
2205 Type, 2, Flags, 8, nullptr);
2206 uint64_t Elements1[] = {dwarf::DW_OP_push_object_address, dwarf::DW_OP_deref};
2207 Metadata *DataLocation1 = DIExpression::get(Context, Elements1);
2209 uint64_t Elements2[] = {dwarf::DW_OP_constu, 0};
2210 Metadata *DataLocation2 = DIExpression::get(Context, Elements2);
2212 uint64_t Elements3[] = {dwarf::DW_OP_constu, 3};
2213 Metadata *Rank1 = DIExpression::get(Context, Elements3);
2215 uint64_t Elements4[] = {dwarf::DW_OP_constu, 4};
2216 Metadata *Rank2 = DIExpression::get(Context, Elements4);
2218 ConstantInt *RankInt1 = ConstantInt::get(Context, APInt(7, 0));
2219 ConstantAsMetadata *RankConst1 = ConstantAsMetadata::get(RankInt1);
2220 ConstantInt *RankInt2 = ConstantInt::get(Context, APInt(6, 0));
2221 ConstantAsMetadata *RankConst2 = ConstantAsMetadata::get(RankInt2);
2222 auto *N1 = DICompositeType::get(
2223 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2224 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2225 nullptr, DlVar1);
2227 auto *Same1 = DICompositeType::get(
2228 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2229 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2230 nullptr, DlVar1);
2232 auto *Other1 = DICompositeType::get(
2233 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2234 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2235 nullptr, DlVar2);
2237 EXPECT_EQ(N1, Same1);
2238 EXPECT_NE(Same1, Other1);
2239 EXPECT_EQ(N1->getDataLocation(), DlVar1);
2241 auto *N2 = DICompositeType::get(
2242 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2243 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2244 nullptr, DataLocation1);
2246 auto *Same2 = DICompositeType::get(
2247 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2248 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2249 nullptr, DataLocation1);
2251 auto *Other2 = DICompositeType::get(
2252 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2253 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2254 nullptr, DataLocation2);
2256 EXPECT_EQ(N2, Same2);
2257 EXPECT_NE(Same2, Other2);
2258 EXPECT_EQ(N2->getDataLocationExp(), DataLocation1);
2260 auto *N3 = DICompositeType::get(
2261 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2262 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2263 nullptr, DataLocation1, nullptr, nullptr, Rank1);
2265 auto *Same3 = DICompositeType::get(
2266 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2267 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2268 nullptr, DataLocation1, nullptr, nullptr, Rank1);
2270 auto *Other3 = DICompositeType::get(
2271 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2272 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2273 nullptr, DataLocation1, nullptr, nullptr, Rank2);
2275 EXPECT_EQ(N3, Same3);
2276 EXPECT_NE(Same3, Other3);
2277 EXPECT_EQ(N3->getRankExp(), Rank1);
2279 auto *N4 = DICompositeType::get(
2280 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2281 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2282 nullptr, DataLocation1, nullptr, nullptr, RankConst1);
2284 auto *Same4 = DICompositeType::get(
2285 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2286 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2287 nullptr, DataLocation1, nullptr, nullptr, RankConst1);
2289 auto *Other4 = DICompositeType::get(
2290 Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
2291 OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
2292 nullptr, DataLocation1, nullptr, nullptr, RankConst2);
2294 EXPECT_EQ(N4, Same4);
2295 EXPECT_NE(Same4, Other4);
2296 EXPECT_EQ(N4->getRankConst(), RankInt1);
2299 typedef MetadataTest DISubroutineTypeTest;
2301 TEST_F(DISubroutineTypeTest, get) {
2302 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(1);
2303 DINode::DIFlags FlagsPOne = static_cast<DINode::DIFlags>(Flags + 1);
2304 MDTuple *TypeArray = getTuple();
2306 auto *N = DISubroutineType::get(Context, Flags, 0, TypeArray);
2307 EXPECT_EQ(dwarf::DW_TAG_subroutine_type, N->getTag());
2308 EXPECT_EQ(Flags, N->getFlags());
2309 EXPECT_EQ(TypeArray, N->getTypeArray().get());
2310 EXPECT_EQ(N, DISubroutineType::get(Context, Flags, 0, TypeArray));
2312 EXPECT_NE(N, DISubroutineType::get(Context, FlagsPOne, 0, TypeArray));
2313 EXPECT_NE(N, DISubroutineType::get(Context, Flags, 0, getTuple()));
2315 // Test the hashing of calling conventions.
2316 auto *Fast = DISubroutineType::get(
2317 Context, Flags, dwarf::DW_CC_BORLAND_msfastcall, TypeArray);
2318 auto *Std = DISubroutineType::get(Context, Flags,
2319 dwarf::DW_CC_BORLAND_stdcall, TypeArray);
2320 EXPECT_EQ(Fast,
2321 DISubroutineType::get(Context, Flags,
2322 dwarf::DW_CC_BORLAND_msfastcall, TypeArray));
2323 EXPECT_EQ(Std, DISubroutineType::get(
2324 Context, Flags, dwarf::DW_CC_BORLAND_stdcall, TypeArray));
2326 EXPECT_NE(N, Fast);
2327 EXPECT_NE(N, Std);
2328 EXPECT_NE(Fast, Std);
2330 TempDISubroutineType Temp = N->clone();
2331 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2333 // Test always-empty operands.
2334 EXPECT_EQ(nullptr, N->getScope());
2335 EXPECT_EQ(nullptr, N->getFile());
2336 EXPECT_EQ("", N->getName());
2339 typedef MetadataTest DIFileTest;
2341 TEST_F(DIFileTest, get) {
2342 StringRef Filename = "file";
2343 StringRef Directory = "dir";
2344 DIFile::ChecksumKind CSKind = DIFile::ChecksumKind::CSK_MD5;
2345 StringRef ChecksumString = "000102030405060708090a0b0c0d0e0f";
2346 DIFile::ChecksumInfo<StringRef> Checksum(CSKind, ChecksumString);
2347 StringRef Source = "source";
2348 auto *N = DIFile::get(Context, Filename, Directory, Checksum, Source);
2350 EXPECT_EQ(dwarf::DW_TAG_file_type, N->getTag());
2351 EXPECT_EQ(Filename, N->getFilename());
2352 EXPECT_EQ(Directory, N->getDirectory());
2353 EXPECT_EQ(Checksum, N->getChecksum());
2354 EXPECT_EQ(Source, N->getSource());
2355 EXPECT_EQ(N, DIFile::get(Context, Filename, Directory, Checksum, Source));
2357 EXPECT_NE(N, DIFile::get(Context, "other", Directory, Checksum, Source));
2358 EXPECT_NE(N, DIFile::get(Context, Filename, "other", Checksum, Source));
2359 DIFile::ChecksumInfo<StringRef> OtherChecksum(DIFile::ChecksumKind::CSK_SHA1, ChecksumString);
2360 EXPECT_NE(
2361 N, DIFile::get(Context, Filename, Directory, OtherChecksum));
2362 StringRef OtherSource = "other";
2363 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum, OtherSource));
2364 EXPECT_NE(N, DIFile::get(Context, Filename, Directory, Checksum));
2365 EXPECT_NE(N, DIFile::get(Context, Filename, Directory));
2367 TempDIFile Temp = N->clone();
2368 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2371 TEST_F(DIFileTest, EmptySource) {
2372 DIFile *N = DIFile::get(Context, "file", "dir");
2373 EXPECT_EQ(std::nullopt, N->getSource());
2375 std::optional<DIFile::ChecksumInfo<StringRef>> Checksum;
2376 std::optional<StringRef> Source;
2377 N = DIFile::get(Context, "file", "dir", Checksum, Source);
2378 EXPECT_EQ(Source, N->getSource());
2380 Source = "";
2381 N = DIFile::get(Context, "file", "dir", Checksum, Source);
2382 EXPECT_EQ(Source, N->getSource());
2385 TEST_F(DIFileTest, ScopeGetFile) {
2386 // Ensure that DIScope::getFile() returns itself.
2387 DIScope *N = DIFile::get(Context, "file", "dir");
2388 EXPECT_EQ(N, N->getFile());
2391 typedef MetadataTest DICompileUnitTest;
2393 TEST_F(DICompileUnitTest, get) {
2394 unsigned SourceLanguage = 1;
2395 DIFile *File = getFile();
2396 StringRef Producer = "some producer";
2397 bool IsOptimized = false;
2398 StringRef Flags = "flag after flag";
2399 unsigned RuntimeVersion = 2;
2400 StringRef SplitDebugFilename = "another/file";
2401 auto EmissionKind = DICompileUnit::FullDebug;
2402 MDTuple *EnumTypes = getTuple();
2403 MDTuple *RetainedTypes = getTuple();
2404 MDTuple *GlobalVariables = getTuple();
2405 MDTuple *ImportedEntities = getTuple();
2406 uint64_t DWOId = 0x10000000c0ffee;
2407 MDTuple *Macros = getTuple();
2408 StringRef SysRoot = "/";
2409 StringRef SDK = "MacOSX.sdk";
2410 auto *N = DICompileUnit::getDistinct(
2411 Context, SourceLanguage, File, Producer, IsOptimized, Flags,
2412 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
2413 RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true,
2414 false, DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK);
2416 EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag());
2417 EXPECT_EQ(SourceLanguage, N->getSourceLanguage());
2418 EXPECT_EQ(File, N->getFile());
2419 EXPECT_EQ(Producer, N->getProducer());
2420 EXPECT_EQ(IsOptimized, N->isOptimized());
2421 EXPECT_EQ(Flags, N->getFlags());
2422 EXPECT_EQ(RuntimeVersion, N->getRuntimeVersion());
2423 EXPECT_EQ(SplitDebugFilename, N->getSplitDebugFilename());
2424 EXPECT_EQ(EmissionKind, N->getEmissionKind());
2425 EXPECT_EQ(EnumTypes, N->getEnumTypes().get());
2426 EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get());
2427 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
2428 EXPECT_EQ(ImportedEntities, N->getImportedEntities().get());
2429 EXPECT_EQ(Macros, N->getMacros().get());
2430 EXPECT_EQ(DWOId, N->getDWOId());
2431 EXPECT_EQ(SysRoot, N->getSysRoot());
2432 EXPECT_EQ(SDK, N->getSDK());
2434 TempDICompileUnit Temp = N->clone();
2435 EXPECT_EQ(dwarf::DW_TAG_compile_unit, Temp->getTag());
2436 EXPECT_EQ(SourceLanguage, Temp->getSourceLanguage());
2437 EXPECT_EQ(File, Temp->getFile());
2438 EXPECT_EQ(Producer, Temp->getProducer());
2439 EXPECT_EQ(IsOptimized, Temp->isOptimized());
2440 EXPECT_EQ(Flags, Temp->getFlags());
2441 EXPECT_EQ(RuntimeVersion, Temp->getRuntimeVersion());
2442 EXPECT_EQ(SplitDebugFilename, Temp->getSplitDebugFilename());
2443 EXPECT_EQ(EmissionKind, Temp->getEmissionKind());
2444 EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get());
2445 EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get());
2446 EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get());
2447 EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get());
2448 EXPECT_EQ(Macros, Temp->getMacros().get());
2449 EXPECT_EQ(SysRoot, Temp->getSysRoot());
2450 EXPECT_EQ(SDK, Temp->getSDK());
2452 auto *TempAddress = Temp.get();
2453 auto *Clone = MDNode::replaceWithPermanent(std::move(Temp));
2454 EXPECT_TRUE(Clone->isDistinct());
2455 EXPECT_EQ(TempAddress, Clone);
2458 TEST_F(DICompileUnitTest, replaceArrays) {
2459 unsigned SourceLanguage = 1;
2460 DIFile *File = getFile();
2461 StringRef Producer = "some producer";
2462 bool IsOptimized = false;
2463 StringRef Flags = "flag after flag";
2464 unsigned RuntimeVersion = 2;
2465 StringRef SplitDebugFilename = "another/file";
2466 auto EmissionKind = DICompileUnit::FullDebug;
2467 MDTuple *EnumTypes = MDTuple::getDistinct(Context, std::nullopt);
2468 MDTuple *RetainedTypes = MDTuple::getDistinct(Context, std::nullopt);
2469 MDTuple *ImportedEntities = MDTuple::getDistinct(Context, std::nullopt);
2470 uint64_t DWOId = 0xc0ffee;
2471 StringRef SysRoot = "/";
2472 StringRef SDK = "MacOSX.sdk";
2473 auto *N = DICompileUnit::getDistinct(
2474 Context, SourceLanguage, File, Producer, IsOptimized, Flags,
2475 RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
2476 RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false,
2477 DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK);
2479 auto *GlobalVariables = MDTuple::getDistinct(Context, std::nullopt);
2480 EXPECT_EQ(nullptr, N->getGlobalVariables().get());
2481 N->replaceGlobalVariables(GlobalVariables);
2482 EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
2483 N->replaceGlobalVariables(nullptr);
2484 EXPECT_EQ(nullptr, N->getGlobalVariables().get());
2486 auto *Macros = MDTuple::getDistinct(Context, std::nullopt);
2487 EXPECT_EQ(nullptr, N->getMacros().get());
2488 N->replaceMacros(Macros);
2489 EXPECT_EQ(Macros, N->getMacros().get());
2490 N->replaceMacros(nullptr);
2491 EXPECT_EQ(nullptr, N->getMacros().get());
2494 typedef MetadataTest DISubprogramTest;
2496 TEST_F(DISubprogramTest, get) {
2497 DIScope *Scope = getCompositeType();
2498 StringRef Name = "name";
2499 StringRef LinkageName = "linkage";
2500 DIFile *File = getFile();
2501 unsigned Line = 2;
2502 DISubroutineType *Type = getSubroutineType();
2503 bool IsLocalToUnit = false;
2504 bool IsDefinition = true;
2505 unsigned ScopeLine = 3;
2506 DIType *ContainingType = getCompositeType();
2507 unsigned Virtuality = 2;
2508 unsigned VirtualIndex = 5;
2509 int ThisAdjustment = -3;
2510 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(6);
2511 bool IsOptimized = false;
2512 MDTuple *TemplateParams = getTuple();
2513 DISubprogram *Declaration = getSubprogram();
2514 MDTuple *RetainedNodes = getTuple();
2515 MDTuple *ThrownTypes = getTuple();
2516 MDTuple *Annotations = getTuple();
2517 StringRef TargetFuncName = "target";
2518 DICompileUnit *Unit = getUnit();
2519 DISubprogram::DISPFlags SPFlags =
2520 static_cast<DISubprogram::DISPFlags>(Virtuality);
2521 assert(!IsLocalToUnit && IsDefinition && !IsOptimized &&
2522 "bools and SPFlags have to match");
2523 SPFlags |= DISubprogram::SPFlagDefinition;
2525 auto *N = DISubprogram::get(
2526 Context, Scope, Name, LinkageName, File, Line, Type, ScopeLine,
2527 ContainingType, VirtualIndex, ThisAdjustment, Flags, SPFlags, Unit,
2528 TemplateParams, Declaration, RetainedNodes, ThrownTypes, Annotations,
2529 TargetFuncName);
2531 EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
2532 EXPECT_EQ(Scope, N->getScope());
2533 EXPECT_EQ(Name, N->getName());
2534 EXPECT_EQ(LinkageName, N->getLinkageName());
2535 EXPECT_EQ(File, N->getFile());
2536 EXPECT_EQ(Line, N->getLine());
2537 EXPECT_EQ(Type, N->getType());
2538 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
2539 EXPECT_EQ(IsDefinition, N->isDefinition());
2540 EXPECT_EQ(ScopeLine, N->getScopeLine());
2541 EXPECT_EQ(ContainingType, N->getContainingType());
2542 EXPECT_EQ(Virtuality, N->getVirtuality());
2543 EXPECT_EQ(VirtualIndex, N->getVirtualIndex());
2544 EXPECT_EQ(ThisAdjustment, N->getThisAdjustment());
2545 EXPECT_EQ(Flags, N->getFlags());
2546 EXPECT_EQ(IsOptimized, N->isOptimized());
2547 EXPECT_EQ(Unit, N->getUnit());
2548 EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
2549 EXPECT_EQ(Declaration, N->getDeclaration());
2550 EXPECT_EQ(RetainedNodes, N->getRetainedNodes().get());
2551 EXPECT_EQ(ThrownTypes, N->getThrownTypes().get());
2552 EXPECT_EQ(Annotations, N->getAnnotations().get());
2553 EXPECT_EQ(TargetFuncName, N->getTargetFuncName());
2554 EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2555 Type, ScopeLine, ContainingType, VirtualIndex,
2556 ThisAdjustment, Flags, SPFlags, Unit,
2557 TemplateParams, Declaration, RetainedNodes,
2558 ThrownTypes, Annotations, TargetFuncName));
2560 EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName,
2561 File, Line, Type, ScopeLine, ContainingType,
2562 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2563 Unit, TemplateParams, Declaration,
2564 RetainedNodes, ThrownTypes, Annotations,
2565 TargetFuncName));
2566 EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File,
2567 Line, Type, ScopeLine, ContainingType,
2568 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2569 Unit, TemplateParams, Declaration,
2570 RetainedNodes, ThrownTypes, Annotations,
2571 TargetFuncName));
2572 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line,
2573 Type, ScopeLine, ContainingType, VirtualIndex,
2574 ThisAdjustment, Flags, SPFlags, Unit,
2575 TemplateParams, Declaration, RetainedNodes,
2576 ThrownTypes, Annotations, TargetFuncName));
2577 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(),
2578 Line, Type, ScopeLine, ContainingType,
2579 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2580 Unit, TemplateParams, Declaration,
2581 RetainedNodes, ThrownTypes, Annotations,
2582 TargetFuncName));
2583 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File,
2584 Line + 1, Type, ScopeLine, ContainingType,
2585 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2586 Unit, TemplateParams, Declaration,
2587 RetainedNodes, ThrownTypes, Annotations,
2588 TargetFuncName));
2589 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2590 getSubroutineType(), ScopeLine, ContainingType,
2591 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2592 Unit, TemplateParams, Declaration,
2593 RetainedNodes, ThrownTypes, Annotations,
2594 TargetFuncName));
2595 EXPECT_NE(N, DISubprogram::get(
2596 Context, Scope, Name, LinkageName, File, Line, Type,
2597 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
2598 Flags, SPFlags ^ DISubprogram::SPFlagLocalToUnit, Unit,
2599 TemplateParams, Declaration, RetainedNodes, ThrownTypes,
2600 Annotations, TargetFuncName));
2601 EXPECT_NE(N, DISubprogram::get(
2602 Context, Scope, Name, LinkageName, File, Line, Type,
2603 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
2604 Flags, SPFlags ^ DISubprogram::SPFlagDefinition, Unit,
2605 TemplateParams, Declaration, RetainedNodes, ThrownTypes,
2606 Annotations, TargetFuncName));
2607 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2608 Type, ScopeLine + 1, ContainingType,
2609 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2610 Unit, TemplateParams, Declaration,
2611 RetainedNodes, ThrownTypes, Annotations,
2612 TargetFuncName));
2613 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2614 Type, ScopeLine, getCompositeType(),
2615 VirtualIndex, ThisAdjustment, Flags, SPFlags,
2616 Unit, TemplateParams, Declaration,
2617 RetainedNodes, ThrownTypes, Annotations,
2618 TargetFuncName));
2619 EXPECT_NE(N, DISubprogram::get(
2620 Context, Scope, Name, LinkageName, File, Line, Type,
2621 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
2622 Flags, SPFlags ^ DISubprogram::SPFlagVirtual, Unit,
2623 TemplateParams, Declaration, RetainedNodes, ThrownTypes,
2624 Annotations, TargetFuncName));
2625 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2626 Type, ScopeLine, ContainingType,
2627 VirtualIndex + 1, ThisAdjustment, Flags,
2628 SPFlags, Unit, TemplateParams, Declaration,
2629 RetainedNodes, ThrownTypes, Annotations,
2630 TargetFuncName));
2631 EXPECT_NE(N, DISubprogram::get(
2632 Context, Scope, Name, LinkageName, File, Line, Type,
2633 ScopeLine, ContainingType, VirtualIndex, ThisAdjustment,
2634 Flags, SPFlags ^ DISubprogram::SPFlagOptimized, Unit,
2635 TemplateParams, Declaration, RetainedNodes, ThrownTypes,
2636 Annotations, TargetFuncName));
2637 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2638 Type, ScopeLine, ContainingType, VirtualIndex,
2639 ThisAdjustment, Flags, SPFlags, nullptr,
2640 TemplateParams, Declaration, RetainedNodes,
2641 ThrownTypes, Annotations, TargetFuncName));
2642 EXPECT_NE(N,
2643 DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2644 Type, ScopeLine, ContainingType, VirtualIndex,
2645 ThisAdjustment, Flags, SPFlags, Unit, getTuple(),
2646 Declaration, RetainedNodes, ThrownTypes,
2647 Annotations, TargetFuncName));
2648 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2649 Type, ScopeLine, ContainingType, VirtualIndex,
2650 ThisAdjustment, Flags, SPFlags, Unit,
2651 TemplateParams, getSubprogram(), RetainedNodes,
2652 ThrownTypes, Annotations, TargetFuncName));
2653 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2654 Type, ScopeLine, ContainingType, VirtualIndex,
2655 ThisAdjustment, Flags, SPFlags, Unit,
2656 TemplateParams, Declaration, getTuple(),
2657 ThrownTypes, Annotations, TargetFuncName));
2658 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2659 Type, ScopeLine, ContainingType, VirtualIndex,
2660 ThisAdjustment, Flags, SPFlags, Unit,
2661 TemplateParams, Declaration, RetainedNodes,
2662 getTuple(), Annotations, TargetFuncName));
2663 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2664 Type, ScopeLine, ContainingType, VirtualIndex,
2665 ThisAdjustment, Flags, SPFlags, Unit,
2666 TemplateParams, Declaration, RetainedNodes,
2667 ThrownTypes, getTuple(), TargetFuncName));
2668 EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
2669 Type, ScopeLine, ContainingType, VirtualIndex,
2670 ThisAdjustment, Flags, SPFlags, Unit,
2671 TemplateParams, Declaration, RetainedNodes,
2672 ThrownTypes, Annotations, "other"));
2674 TempDISubprogram Temp = N->clone();
2675 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2678 typedef MetadataTest DILexicalBlockTest;
2680 TEST_F(DILexicalBlockTest, get) {
2681 DILocalScope *Scope = getSubprogram();
2682 DIFile *File = getFile();
2683 unsigned Line = 5;
2684 unsigned Column = 8;
2686 auto *N = DILexicalBlock::get(Context, Scope, File, Line, Column);
2688 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
2689 EXPECT_EQ(Scope, N->getScope());
2690 EXPECT_EQ(File, N->getFile());
2691 EXPECT_EQ(Line, N->getLine());
2692 EXPECT_EQ(Column, N->getColumn());
2693 EXPECT_EQ(N, DILexicalBlock::get(Context, Scope, File, Line, Column));
2695 EXPECT_NE(N,
2696 DILexicalBlock::get(Context, getSubprogram(), File, Line, Column));
2697 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, getFile(), Line, Column));
2698 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line + 1, Column));
2699 EXPECT_NE(N, DILexicalBlock::get(Context, Scope, File, Line, Column + 1));
2701 TempDILexicalBlock Temp = N->clone();
2702 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2705 TEST_F(DILexicalBlockTest, Overflow) {
2706 DISubprogram *SP = getSubprogram();
2707 DIFile *F = getFile();
2709 auto *LB = DILexicalBlock::get(Context, SP, F, 2, 7);
2710 EXPECT_EQ(2u, LB->getLine());
2711 EXPECT_EQ(7u, LB->getColumn());
2713 unsigned U16 = 1u << 16;
2715 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 - 1);
2716 EXPECT_EQ(UINT32_MAX, LB->getLine());
2717 EXPECT_EQ(U16 - 1, LB->getColumn());
2720 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16);
2721 EXPECT_EQ(UINT32_MAX, LB->getLine());
2722 EXPECT_EQ(0u, LB->getColumn());
2725 auto *LB = DILexicalBlock::get(Context, SP, F, UINT32_MAX, U16 + 1);
2726 EXPECT_EQ(UINT32_MAX, LB->getLine());
2727 EXPECT_EQ(0u, LB->getColumn());
2731 typedef MetadataTest DILexicalBlockFileTest;
2733 TEST_F(DILexicalBlockFileTest, get) {
2734 DILocalScope *Scope = getSubprogram();
2735 DIFile *File = getFile();
2736 unsigned Discriminator = 5;
2738 auto *N = DILexicalBlockFile::get(Context, Scope, File, Discriminator);
2740 EXPECT_EQ(dwarf::DW_TAG_lexical_block, N->getTag());
2741 EXPECT_EQ(Scope, N->getScope());
2742 EXPECT_EQ(File, N->getFile());
2743 EXPECT_EQ(Discriminator, N->getDiscriminator());
2744 EXPECT_EQ(N, DILexicalBlockFile::get(Context, Scope, File, Discriminator));
2746 EXPECT_NE(N, DILexicalBlockFile::get(Context, getSubprogram(), File,
2747 Discriminator));
2748 EXPECT_NE(N,
2749 DILexicalBlockFile::get(Context, Scope, getFile(), Discriminator));
2750 EXPECT_NE(N,
2751 DILexicalBlockFile::get(Context, Scope, File, Discriminator + 1));
2753 TempDILexicalBlockFile Temp = N->clone();
2754 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2757 typedef MetadataTest DINamespaceTest;
2759 TEST_F(DINamespaceTest, get) {
2760 DIScope *Scope = getFile();
2761 StringRef Name = "namespace";
2762 bool ExportSymbols = true;
2764 auto *N = DINamespace::get(Context, Scope, Name, ExportSymbols);
2766 EXPECT_EQ(dwarf::DW_TAG_namespace, N->getTag());
2767 EXPECT_EQ(Scope, N->getScope());
2768 EXPECT_EQ(Name, N->getName());
2769 EXPECT_EQ(N, DINamespace::get(Context, Scope, Name, ExportSymbols));
2770 EXPECT_NE(N, DINamespace::get(Context, getFile(), Name, ExportSymbols));
2771 EXPECT_NE(N, DINamespace::get(Context, Scope, "other", ExportSymbols));
2772 EXPECT_NE(N, DINamespace::get(Context, Scope, Name, !ExportSymbols));
2774 TempDINamespace Temp = N->clone();
2775 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2778 typedef MetadataTest DIModuleTest;
2780 TEST_F(DIModuleTest, get) {
2781 DIFile *File = getFile();
2782 DIScope *Scope = getFile();
2783 StringRef Name = "module";
2784 StringRef ConfigMacro = "-DNDEBUG";
2785 StringRef Includes = "-I.";
2786 StringRef APINotes = "/tmp/m.apinotes";
2787 unsigned LineNo = 4;
2788 bool IsDecl = true;
2790 auto *N = DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes,
2791 APINotes, LineNo, IsDecl);
2793 EXPECT_EQ(dwarf::DW_TAG_module, N->getTag());
2794 EXPECT_EQ(File, N->getFile());
2795 EXPECT_EQ(Scope, N->getScope());
2796 EXPECT_EQ(Name, N->getName());
2797 EXPECT_EQ(ConfigMacro, N->getConfigurationMacros());
2798 EXPECT_EQ(Includes, N->getIncludePath());
2799 EXPECT_EQ(APINotes, N->getAPINotesFile());
2800 EXPECT_EQ(LineNo, N->getLineNo());
2801 EXPECT_EQ(IsDecl, N->getIsDecl());
2802 EXPECT_EQ(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes,
2803 APINotes, LineNo, IsDecl));
2804 EXPECT_NE(N, DIModule::get(Context, getFile(), getFile(), Name, ConfigMacro,
2805 Includes, APINotes, LineNo, IsDecl));
2806 EXPECT_NE(N, DIModule::get(Context, File, Scope, "other", ConfigMacro,
2807 Includes, APINotes, LineNo, IsDecl));
2808 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, "other", Includes,
2809 APINotes, LineNo, IsDecl));
2810 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, "other",
2811 APINotes, LineNo, IsDecl));
2812 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes,
2813 "other", LineNo, IsDecl));
2814 EXPECT_NE(N, DIModule::get(Context, getFile(), Scope, Name, ConfigMacro,
2815 Includes, APINotes, LineNo, IsDecl));
2816 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes,
2817 APINotes, 5, IsDecl));
2818 EXPECT_NE(N, DIModule::get(Context, File, Scope, Name, ConfigMacro, Includes,
2819 APINotes, LineNo, false));
2821 TempDIModule Temp = N->clone();
2822 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2825 typedef MetadataTest DITemplateTypeParameterTest;
2827 TEST_F(DITemplateTypeParameterTest, get) {
2828 StringRef Name = "template";
2829 DIType *Type = getBasicType("basic");
2830 bool defaulted = false;
2832 auto *N = DITemplateTypeParameter::get(Context, Name, Type, defaulted);
2834 EXPECT_EQ(dwarf::DW_TAG_template_type_parameter, N->getTag());
2835 EXPECT_EQ(Name, N->getName());
2836 EXPECT_EQ(Type, N->getType());
2837 EXPECT_EQ(N, DITemplateTypeParameter::get(Context, Name, Type, defaulted));
2839 EXPECT_NE(N, DITemplateTypeParameter::get(Context, "other", Type, defaulted));
2840 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name,
2841 getBasicType("other"), defaulted));
2842 EXPECT_NE(N, DITemplateTypeParameter::get(Context, Name, Type, true));
2844 TempDITemplateTypeParameter Temp = N->clone();
2845 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2848 typedef MetadataTest DITemplateValueParameterTest;
2850 TEST_F(DITemplateValueParameterTest, get) {
2851 unsigned Tag = dwarf::DW_TAG_template_value_parameter;
2852 StringRef Name = "template";
2853 DIType *Type = getBasicType("basic");
2854 bool defaulted = false;
2855 Metadata *Value = getConstantAsMetadata();
2857 auto *N =
2858 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted, Value);
2859 EXPECT_EQ(Tag, N->getTag());
2860 EXPECT_EQ(Name, N->getName());
2861 EXPECT_EQ(Type, N->getType());
2862 EXPECT_EQ(Value, N->getValue());
2863 EXPECT_EQ(N, DITemplateValueParameter::get(Context, Tag, Name, Type,
2864 defaulted, Value));
2866 EXPECT_NE(N, DITemplateValueParameter::get(
2867 Context, dwarf::DW_TAG_GNU_template_template_param, Name,
2868 Type, defaulted, Value));
2869 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, "other", Type,
2870 defaulted, Value));
2871 EXPECT_NE(N, DITemplateValueParameter::get(Context, Tag, Name,
2872 getBasicType("other"), defaulted,
2873 Value));
2874 EXPECT_NE(N,
2875 DITemplateValueParameter::get(Context, Tag, Name, Type, defaulted,
2876 getConstantAsMetadata()));
2877 EXPECT_NE(
2878 N, DITemplateValueParameter::get(Context, Tag, Name, Type, true, Value));
2880 TempDITemplateValueParameter Temp = N->clone();
2881 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2884 typedef MetadataTest DIGlobalVariableTest;
2886 TEST_F(DIGlobalVariableTest, get) {
2887 DIScope *Scope = getSubprogram();
2888 StringRef Name = "name";
2889 StringRef LinkageName = "linkage";
2890 DIFile *File = getFile();
2891 unsigned Line = 5;
2892 DIType *Type = getDerivedType();
2893 bool IsLocalToUnit = false;
2894 bool IsDefinition = true;
2895 MDTuple *templateParams = getTuple();
2896 DIDerivedType *StaticDataMemberDeclaration =
2897 cast<DIDerivedType>(getDerivedType());
2899 uint32_t AlignInBits = 8;
2901 auto *N = DIGlobalVariable::get(
2902 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
2903 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
2904 nullptr);
2906 EXPECT_EQ(dwarf::DW_TAG_variable, N->getTag());
2907 EXPECT_EQ(Scope, N->getScope());
2908 EXPECT_EQ(Name, N->getName());
2909 EXPECT_EQ(LinkageName, N->getLinkageName());
2910 EXPECT_EQ(File, N->getFile());
2911 EXPECT_EQ(Line, N->getLine());
2912 EXPECT_EQ(Type, N->getType());
2913 EXPECT_EQ(IsLocalToUnit, N->isLocalToUnit());
2914 EXPECT_EQ(IsDefinition, N->isDefinition());
2915 EXPECT_EQ(StaticDataMemberDeclaration, N->getStaticDataMemberDeclaration());
2916 EXPECT_EQ(templateParams, N->getTemplateParams());
2917 EXPECT_EQ(AlignInBits, N->getAlignInBits());
2918 EXPECT_EQ(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2919 Line, Type, IsLocalToUnit, IsDefinition,
2920 StaticDataMemberDeclaration,
2921 templateParams, AlignInBits, nullptr));
2923 EXPECT_NE(N, DIGlobalVariable::get(
2924 Context, getSubprogram(), Name, LinkageName, File, Line,
2925 Type, IsLocalToUnit, IsDefinition,
2926 StaticDataMemberDeclaration, templateParams, AlignInBits,
2927 nullptr));
2928 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, "other", LinkageName, File,
2929 Line, Type, IsLocalToUnit, IsDefinition,
2930 StaticDataMemberDeclaration,
2931 templateParams, AlignInBits, nullptr));
2932 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, "other", File, Line,
2933 Type, IsLocalToUnit, IsDefinition,
2934 StaticDataMemberDeclaration,
2935 templateParams, AlignInBits, nullptr));
2936 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName,
2937 getFile(), Line, Type, IsLocalToUnit,
2938 IsDefinition, StaticDataMemberDeclaration,
2939 templateParams, AlignInBits, nullptr));
2940 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2941 Line + 1, Type, IsLocalToUnit,
2942 IsDefinition, StaticDataMemberDeclaration,
2943 templateParams, AlignInBits, nullptr));
2944 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2945 Line, getDerivedType(), IsLocalToUnit,
2946 IsDefinition, StaticDataMemberDeclaration,
2947 templateParams, AlignInBits, nullptr));
2948 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2949 Line, Type, !IsLocalToUnit, IsDefinition,
2950 StaticDataMemberDeclaration,
2951 templateParams, AlignInBits, nullptr));
2952 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2953 Line, Type, IsLocalToUnit, !IsDefinition,
2954 StaticDataMemberDeclaration,
2955 templateParams, AlignInBits, nullptr));
2956 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2957 Line, Type, IsLocalToUnit, IsDefinition,
2958 cast<DIDerivedType>(getDerivedType()),
2959 templateParams, AlignInBits, nullptr));
2960 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2961 Line, Type, IsLocalToUnit, IsDefinition,
2962 StaticDataMemberDeclaration, nullptr,
2963 AlignInBits, nullptr));
2964 EXPECT_NE(N, DIGlobalVariable::get(Context, Scope, Name, LinkageName, File,
2965 Line, Type, IsLocalToUnit, IsDefinition,
2966 StaticDataMemberDeclaration,
2967 templateParams, (AlignInBits << 1),
2968 nullptr));
2970 TempDIGlobalVariable Temp = N->clone();
2971 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
2974 typedef MetadataTest DIGlobalVariableExpressionTest;
2976 TEST_F(DIGlobalVariableExpressionTest, get) {
2977 DIScope *Scope = getSubprogram();
2978 StringRef Name = "name";
2979 StringRef LinkageName = "linkage";
2980 DIFile *File = getFile();
2981 unsigned Line = 5;
2982 DIType *Type = getDerivedType();
2983 bool IsLocalToUnit = false;
2984 bool IsDefinition = true;
2985 MDTuple *templateParams = getTuple();
2986 auto *Expr = DIExpression::get(Context, {1, 2});
2987 auto *Expr2 = DIExpression::get(Context, {1, 2, 3});
2988 DIDerivedType *StaticDataMemberDeclaration =
2989 cast<DIDerivedType>(getDerivedType());
2990 uint32_t AlignInBits = 8;
2992 auto *Var = DIGlobalVariable::get(
2993 Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
2994 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
2995 nullptr);
2996 auto *Var2 = DIGlobalVariable::get(
2997 Context, Scope, "other", LinkageName, File, Line, Type, IsLocalToUnit,
2998 IsDefinition, StaticDataMemberDeclaration, templateParams, AlignInBits,
2999 nullptr);
3000 auto *N = DIGlobalVariableExpression::get(Context, Var, Expr);
3002 EXPECT_EQ(Var, N->getVariable());
3003 EXPECT_EQ(Expr, N->getExpression());
3004 EXPECT_EQ(N, DIGlobalVariableExpression::get(Context, Var, Expr));
3005 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var2, Expr));
3006 EXPECT_NE(N, DIGlobalVariableExpression::get(Context, Var, Expr2));
3008 TempDIGlobalVariableExpression Temp = N->clone();
3009 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
3012 typedef MetadataTest DILocalVariableTest;
3014 TEST_F(DILocalVariableTest, get) {
3015 DILocalScope *Scope = getSubprogram();
3016 StringRef Name = "name";
3017 DIFile *File = getFile();
3018 unsigned Line = 5;
3019 DIType *Type = getDerivedType();
3020 unsigned Arg = 6;
3021 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
3022 uint32_t AlignInBits = 8;
3024 auto *N =
3025 DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg, Flags,
3026 AlignInBits, nullptr);
3027 EXPECT_TRUE(N->isParameter());
3028 EXPECT_EQ(Scope, N->getScope());
3029 EXPECT_EQ(Name, N->getName());
3030 EXPECT_EQ(File, N->getFile());
3031 EXPECT_EQ(Line, N->getLine());
3032 EXPECT_EQ(Type, N->getType());
3033 EXPECT_EQ(Arg, N->getArg());
3034 EXPECT_EQ(Flags, N->getFlags());
3035 EXPECT_EQ(AlignInBits, N->getAlignInBits());
3036 EXPECT_EQ(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type, Arg,
3037 Flags, AlignInBits, nullptr));
3039 EXPECT_FALSE(
3040 DILocalVariable::get(Context, Scope, Name, File, Line, Type, 0, Flags,
3041 AlignInBits, nullptr)->isParameter());
3042 EXPECT_NE(N, DILocalVariable::get(Context, getSubprogram(), Name, File, Line,
3043 Type, Arg, Flags, AlignInBits, nullptr));
3044 EXPECT_NE(N, DILocalVariable::get(Context, Scope, "other", File, Line, Type,
3045 Arg, Flags, AlignInBits, nullptr));
3046 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, getFile(), Line, Type,
3047 Arg, Flags, AlignInBits, nullptr));
3048 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line + 1, Type,
3049 Arg, Flags, AlignInBits, nullptr));
3050 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line,
3051 getDerivedType(), Arg, Flags, AlignInBits,
3052 nullptr));
3053 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type,
3054 Arg + 1, Flags, AlignInBits, nullptr));
3055 EXPECT_NE(N, DILocalVariable::get(Context, Scope, Name, File, Line, Type,
3056 Arg, Flags, (AlignInBits << 1), nullptr));
3058 TempDILocalVariable Temp = N->clone();
3059 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
3062 TEST_F(DILocalVariableTest, getArg256) {
3063 EXPECT_EQ(255u, DILocalVariable::get(Context, getSubprogram(), "", getFile(),
3064 0, nullptr, 255, DINode::FlagZero, 0,
3065 nullptr)
3066 ->getArg());
3067 EXPECT_EQ(256u, DILocalVariable::get(Context, getSubprogram(), "", getFile(),
3068 0, nullptr, 256, DINode::FlagZero, 0,
3069 nullptr)
3070 ->getArg());
3071 EXPECT_EQ(257u, DILocalVariable::get(Context, getSubprogram(), "", getFile(),
3072 0, nullptr, 257, DINode::FlagZero, 0,
3073 nullptr)
3074 ->getArg());
3075 unsigned Max = UINT16_MAX;
3076 EXPECT_EQ(Max, DILocalVariable::get(Context, getSubprogram(), "", getFile(),
3077 0, nullptr, Max, DINode::FlagZero, 0,
3078 nullptr)
3079 ->getArg());
3082 typedef MetadataTest DIExpressionTest;
3084 TEST_F(DIExpressionTest, get) {
3085 uint64_t Elements[] = {2, 6, 9, 78, 0};
3086 auto *N = DIExpression::get(Context, Elements);
3087 EXPECT_EQ(ArrayRef(Elements), N->getElements());
3088 EXPECT_EQ(N, DIExpression::get(Context, Elements));
3090 EXPECT_EQ(5u, N->getNumElements());
3091 EXPECT_EQ(2u, N->getElement(0));
3092 EXPECT_EQ(6u, N->getElement(1));
3093 EXPECT_EQ(9u, N->getElement(2));
3094 EXPECT_EQ(78u, N->getElement(3));
3095 EXPECT_EQ(0u, N->getElement(4));
3097 TempDIExpression Temp = N->clone();
3098 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
3100 // Test DIExpression::prepend().
3101 uint64_t Elts0[] = {dwarf::DW_OP_LLVM_fragment, 0, 32};
3102 auto *N0 = DIExpression::get(Context, Elts0);
3103 uint8_t DIExprFlags = DIExpression::ApplyOffset;
3104 DIExprFlags |= DIExpression::DerefBefore;
3105 DIExprFlags |= DIExpression::DerefAfter;
3106 DIExprFlags |= DIExpression::StackValue;
3107 auto *N0WithPrependedOps = DIExpression::prepend(N0, DIExprFlags, 64);
3108 uint64_t Elts1[] = {dwarf::DW_OP_deref,
3109 dwarf::DW_OP_plus_uconst, 64,
3110 dwarf::DW_OP_deref,
3111 dwarf::DW_OP_stack_value,
3112 dwarf::DW_OP_LLVM_fragment, 0, 32};
3113 auto *N1 = DIExpression::get(Context, Elts1);
3114 EXPECT_EQ(N0WithPrependedOps, N1);
3116 // Test DIExpression::append().
3117 uint64_t Elts2[] = {dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 64,
3118 dwarf::DW_OP_deref, dwarf::DW_OP_stack_value};
3119 auto *N2 = DIExpression::append(N0, Elts2);
3120 EXPECT_EQ(N0WithPrependedOps, N2);
3123 TEST_F(DIExpressionTest, isValid) {
3124 #define EXPECT_VALID(...) \
3125 do { \
3126 uint64_t Elements[] = {__VA_ARGS__}; \
3127 EXPECT_TRUE(DIExpression::get(Context, Elements)->isValid()); \
3128 } while (false)
3129 #define EXPECT_INVALID(...) \
3130 do { \
3131 uint64_t Elements[] = {__VA_ARGS__}; \
3132 EXPECT_FALSE(DIExpression::get(Context, Elements)->isValid()); \
3133 } while (false)
3135 // Empty expression should be valid.
3136 EXPECT_TRUE(DIExpression::get(Context, std::nullopt)->isValid());
3138 // Valid constructions.
3139 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6);
3140 EXPECT_VALID(dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus);
3141 EXPECT_VALID(dwarf::DW_OP_deref);
3142 EXPECT_VALID(dwarf::DW_OP_LLVM_fragment, 3, 7);
3143 EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref);
3144 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6);
3145 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 3, 7);
3146 EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6,
3147 dwarf::DW_OP_LLVM_fragment, 3, 7);
3148 EXPECT_VALID(dwarf::DW_OP_LLVM_entry_value, 1);
3149 EXPECT_VALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_entry_value, 1);
3151 // Invalid constructions.
3152 EXPECT_INVALID(~0u);
3153 EXPECT_INVALID(dwarf::DW_OP_plus, 0);
3154 EXPECT_INVALID(dwarf::DW_OP_plus_uconst);
3155 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment);
3156 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3);
3157 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus_uconst, 3);
3158 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_deref);
3159 EXPECT_INVALID(dwarf::DW_OP_LLVM_entry_value, 2);
3160 EXPECT_INVALID(dwarf::DW_OP_plus_uconst, 5, dwarf::DW_OP_LLVM_entry_value, 1);
3161 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 5,
3162 dwarf::DW_OP_LLVM_entry_value, 1);
3163 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_LLVM_entry_value, 1);
3165 #undef EXPECT_VALID
3166 #undef EXPECT_INVALID
3169 TEST_F(DIExpressionTest, createFragmentExpression) {
3170 #define EXPECT_VALID_FRAGMENT(Offset, Size, ...) \
3171 do { \
3172 uint64_t Elements[] = {__VA_ARGS__}; \
3173 DIExpression *Expression = DIExpression::get(Context, Elements); \
3174 EXPECT_TRUE( \
3175 DIExpression::createFragmentExpression(Expression, Offset, Size) \
3176 .has_value()); \
3177 } while (false)
3178 #define EXPECT_INVALID_FRAGMENT(Offset, Size, ...) \
3179 do { \
3180 uint64_t Elements[] = {__VA_ARGS__}; \
3181 DIExpression *Expression = DIExpression::get(Context, Elements); \
3182 EXPECT_FALSE( \
3183 DIExpression::createFragmentExpression(Expression, Offset, Size) \
3184 .has_value()); \
3185 } while (false)
3187 // createFragmentExpression adds correct ops.
3188 std::optional<DIExpression*> R = DIExpression::createFragmentExpression(
3189 DIExpression::get(Context, {}), 0, 32);
3190 EXPECT_EQ(R.has_value(), true);
3191 EXPECT_EQ(3u, (*R)->getNumElements());
3192 EXPECT_EQ(dwarf::DW_OP_LLVM_fragment, (*R)->getElement(0));
3193 EXPECT_EQ(0u, (*R)->getElement(1));
3194 EXPECT_EQ(32u, (*R)->getElement(2));
3196 // Valid fragment expressions.
3197 EXPECT_VALID_FRAGMENT(0, 32, {});
3198 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_deref);
3199 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_LLVM_fragment, 0, 32);
3200 EXPECT_VALID_FRAGMENT(16, 16, dwarf::DW_OP_LLVM_fragment, 0, 32);
3202 // Invalid fragment expressions (incompatible ops).
3203 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus,
3204 dwarf::DW_OP_stack_value);
3205 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 14, dwarf::DW_OP_minus,
3206 dwarf::DW_OP_stack_value);
3207 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shr,
3208 dwarf::DW_OP_stack_value);
3209 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shl,
3210 dwarf::DW_OP_stack_value);
3211 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 16, dwarf::DW_OP_shra,
3212 dwarf::DW_OP_stack_value);
3213 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3214 dwarf::DW_OP_stack_value);
3216 // Fragments can be created for expressions using DW_OP_plus to compute an
3217 // address.
3218 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_constu, 6, dwarf::DW_OP_plus);
3219 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref);
3220 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_deref,
3221 dwarf::DW_OP_stack_value);
3223 // Check the other deref operations work in the same way.
3224 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3225 dwarf::DW_OP_deref_size, 1);
3226 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3227 dwarf::DW_OP_deref_type, 1, 1);
3228 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3229 dwarf::DW_OP_xderef);
3230 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3231 dwarf::DW_OP_xderef_size, 1);
3232 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst, 6,
3233 dwarf::DW_OP_xderef_type, 1, 1);
3235 // Fragments cannot be created for expressions using DW_OP_plus to compute an
3236 // implicit value (check that this correctly fails even though there is a
3237 // deref in the expression).
3238 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst,
3239 2, dwarf::DW_OP_stack_value);
3241 #undef EXPECT_VALID_FRAGMENT
3242 #undef EXPECT_INVALID_FRAGMENT
3245 TEST_F(DIExpressionTest, convertToUndefExpression) {
3246 #define EXPECT_UNDEF_OPS_EQUAL(TestExpr, Expected) \
3247 do { \
3248 const DIExpression *Undef = \
3249 DIExpression::convertToUndefExpression(TestExpr); \
3250 EXPECT_EQ(Undef, Expected); \
3251 } while (false)
3252 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
3254 // Expressions which are single-location and non-complex should be unchanged.
3255 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(), GET_EXPR());
3256 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 32),
3257 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 32));
3259 // Variadic expressions should become single-location.
3260 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0), GET_EXPR());
3261 EXPECT_UNDEF_OPS_EQUAL(
3262 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_fragment, 32, 32),
3263 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 32, 32));
3264 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3265 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul),
3266 GET_EXPR());
3267 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3268 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul,
3269 dwarf::DW_OP_LLVM_fragment, 64, 32),
3270 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 64, 32));
3272 // Any stack-computing ops should be removed.
3273 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 8), GET_EXPR());
3274 EXPECT_UNDEF_OPS_EQUAL(
3275 GET_EXPR(dwarf::DW_OP_plus_uconst, 8, dwarf::DW_OP_LLVM_fragment, 0, 16),
3276 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 0, 16));
3277 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 24, dwarf::DW_OP_shra),
3278 GET_EXPR());
3279 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 24, dwarf::DW_OP_shra,
3280 dwarf::DW_OP_LLVM_fragment, 8, 16),
3281 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 8, 16));
3282 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_deref), GET_EXPR());
3283 EXPECT_UNDEF_OPS_EQUAL(
3284 GET_EXPR(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 16, 16),
3285 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 16, 16));
3286 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 4, dwarf::DW_OP_minus),
3287 GET_EXPR());
3288 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu, 4, dwarf::DW_OP_minus,
3289 dwarf::DW_OP_LLVM_fragment, 24, 16),
3290 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 24, 16));
3292 // Stack-value operators are also not preserved.
3293 EXPECT_UNDEF_OPS_EQUAL(
3294 GET_EXPR(dwarf::DW_OP_plus_uconst, 8, dwarf::DW_OP_stack_value),
3295 GET_EXPR());
3296 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 8,
3297 dwarf::DW_OP_stack_value,
3298 dwarf::DW_OP_LLVM_fragment, 32, 16),
3299 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 32, 16));
3301 #undef EXPECT_UNDEF_OPS_EQUAL
3302 #undef GET_EXPR
3305 TEST_F(DIExpressionTest, convertToVariadicExpression) {
3306 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \
3307 do { \
3308 const DIExpression *Variadic = \
3309 DIExpression::convertToVariadicExpression(TestExpr); \
3310 EXPECT_EQ(Variadic, TestExpr); \
3311 } while (false)
3312 #define EXPECT_VARIADIC_OPS_EQUAL(TestExpr, Expected) \
3313 do { \
3314 const DIExpression *Variadic = \
3315 DIExpression::convertToVariadicExpression(TestExpr); \
3316 EXPECT_EQ(Variadic, Expected); \
3317 } while (false)
3318 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
3320 // Expressions which are already variadic should be unaffected.
3321 EXPECT_CONVERT_IS_NOOP(
3322 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value));
3323 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3324 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus,
3325 dwarf::DW_OP_stack_value));
3326 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_constu, 5, dwarf::DW_OP_LLVM_arg,
3327 0, dwarf::DW_OP_plus,
3328 dwarf::DW_OP_stack_value));
3329 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3330 dwarf::DW_OP_stack_value,
3331 dwarf::DW_OP_LLVM_fragment, 0, 32));
3333 // Other expressions should receive a leading `LLVM_arg 0`.
3334 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(), GET_EXPR(dwarf::DW_OP_LLVM_arg, 0));
3335 EXPECT_VARIADIC_OPS_EQUAL(
3336 GET_EXPR(dwarf::DW_OP_plus_uconst, 4),
3337 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4));
3338 EXPECT_VARIADIC_OPS_EQUAL(
3339 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value),
3340 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4,
3341 dwarf::DW_OP_stack_value));
3342 EXPECT_VARIADIC_OPS_EQUAL(
3343 GET_EXPR(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_stack_value,
3344 dwarf::DW_OP_LLVM_fragment, 32, 32),
3345 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 6,
3346 dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 32, 32));
3347 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 14,
3348 dwarf::DW_OP_LLVM_fragment, 32, 32),
3349 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3350 dwarf::DW_OP_plus_uconst, 14,
3351 dwarf::DW_OP_LLVM_fragment, 32, 32));
3353 #undef EXPECT_CONVERT_IS_NOOP
3354 #undef EXPECT_VARIADIC_OPS_EQUAL
3355 #undef GET_EXPR
3358 TEST_F(DIExpressionTest, convertToNonVariadicExpression) {
3359 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \
3360 do { \
3361 std::optional<const DIExpression *> NonVariadic = \
3362 DIExpression::convertToNonVariadicExpression(TestExpr); \
3363 EXPECT_TRUE(NonVariadic.has_value()); \
3364 EXPECT_EQ(*NonVariadic, TestExpr); \
3365 } while (false)
3366 #define EXPECT_NON_VARIADIC_OPS_EQUAL(TestExpr, Expected) \
3367 do { \
3368 std::optional<const DIExpression *> NonVariadic = \
3369 DIExpression::convertToNonVariadicExpression(TestExpr); \
3370 EXPECT_TRUE(NonVariadic.has_value()); \
3371 EXPECT_EQ(*NonVariadic, Expected); \
3372 } while (false)
3373 #define EXPECT_INVALID_CONVERSION(TestExpr) \
3374 do { \
3375 std::optional<const DIExpression *> NonVariadic = \
3376 DIExpression::convertToNonVariadicExpression(TestExpr); \
3377 EXPECT_FALSE(NonVariadic.has_value()); \
3378 } while (false)
3379 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
3381 // Expressions which are already non-variadic should be unaffected.
3382 EXPECT_CONVERT_IS_NOOP(GET_EXPR());
3383 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 4));
3384 EXPECT_CONVERT_IS_NOOP(
3385 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value));
3386 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 6,
3387 dwarf::DW_OP_stack_value,
3388 dwarf::DW_OP_LLVM_fragment, 32, 32));
3389 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst, 14,
3390 dwarf::DW_OP_LLVM_fragment, 32, 32));
3392 // Variadic expressions with a single leading `LLVM_arg 0` and no other
3393 // LLVM_args should have the leading arg removed.
3394 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0), GET_EXPR());
3395 EXPECT_NON_VARIADIC_OPS_EQUAL(
3396 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value),
3397 GET_EXPR(dwarf::DW_OP_stack_value));
3398 EXPECT_NON_VARIADIC_OPS_EQUAL(
3399 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_fragment, 16, 32),
3400 GET_EXPR(dwarf::DW_OP_LLVM_fragment, 16, 32));
3401 EXPECT_NON_VARIADIC_OPS_EQUAL(
3402 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value,
3403 dwarf::DW_OP_LLVM_fragment, 24, 32),
3404 GET_EXPR(dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 24, 32));
3405 EXPECT_NON_VARIADIC_OPS_EQUAL(
3406 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4),
3407 GET_EXPR(dwarf::DW_OP_plus_uconst, 4));
3408 EXPECT_NON_VARIADIC_OPS_EQUAL(
3409 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4,
3410 dwarf::DW_OP_stack_value),
3411 GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value));
3412 EXPECT_NON_VARIADIC_OPS_EQUAL(
3413 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 6,
3414 dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 32, 32),
3415 GET_EXPR(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_stack_value,
3416 dwarf::DW_OP_LLVM_fragment, 32, 32));
3417 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3418 dwarf::DW_OP_plus_uconst, 14,
3419 dwarf::DW_OP_LLVM_fragment, 32, 32),
3420 GET_EXPR(dwarf::DW_OP_plus_uconst, 14,
3421 dwarf::DW_OP_LLVM_fragment, 32, 32));
3423 // Variadic expressions that have any LLVM_args other than a leading
3424 // `LLVM_arg 0` cannot be converted and so should return std::nullopt.
3425 EXPECT_INVALID_CONVERSION(GET_EXPR(
3426 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul));
3427 EXPECT_INVALID_CONVERSION(
3428 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1,
3429 dwarf::DW_OP_plus, dwarf::DW_OP_stack_value));
3430 EXPECT_INVALID_CONVERSION(
3431 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 0,
3432 dwarf::DW_OP_minus, dwarf::DW_OP_stack_value));
3433 EXPECT_INVALID_CONVERSION(GET_EXPR(dwarf::DW_OP_constu, 5,
3434 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_div,
3435 dwarf::DW_OP_stack_value));
3437 #undef EXPECT_CONVERT_IS_NOOP
3438 #undef EXPECT_NON_VARIADIC_OPS_EQUAL
3439 #undef EXPECT_INVALID_CONVERSION
3440 #undef GET_EXPR
3443 TEST_F(DIExpressionTest, replaceArg) {
3444 #define EXPECT_REPLACE_ARG_EQ(Expr, OldArg, NewArg, ...) \
3445 do { \
3446 uint64_t Elements[] = {__VA_ARGS__}; \
3447 ArrayRef<uint64_t> Expected = Elements; \
3448 DIExpression *Expression = DIExpression::replaceArg(Expr, OldArg, NewArg); \
3449 EXPECT_EQ(Expression->getElements(), Expected); \
3450 } while (false)
3452 auto N = DIExpression::get(
3453 Context, {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_arg, 1,
3454 dwarf::DW_OP_plus, dwarf::DW_OP_LLVM_arg, 2, dwarf::DW_OP_mul});
3455 EXPECT_REPLACE_ARG_EQ(N, 0, 1, dwarf::DW_OP_LLVM_arg, 0,
3456 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus,
3457 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul);
3458 EXPECT_REPLACE_ARG_EQ(N, 0, 2, dwarf::DW_OP_LLVM_arg, 1,
3459 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus,
3460 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul);
3461 EXPECT_REPLACE_ARG_EQ(N, 2, 0, dwarf::DW_OP_LLVM_arg, 0,
3462 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus,
3463 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_mul);
3464 EXPECT_REPLACE_ARG_EQ(N, 2, 1, dwarf::DW_OP_LLVM_arg, 0,
3465 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus,
3466 dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_mul);
3468 #undef EXPECT_REPLACE_ARG_EQ
3471 TEST_F(DIExpressionTest, isEqualExpression) {
3472 #define EXPECT_EQ_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \
3473 EXPECT_TRUE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB))
3474 #define EXPECT_NE_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \
3475 EXPECT_FALSE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB))
3476 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
3478 EXPECT_EQ_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), false);
3479 EXPECT_NE_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), true);
3480 EXPECT_EQ_DEBUG_VALUE(
3481 GET_EXPR(dwarf::DW_OP_plus_uconst, 32), true,
3482 GET_EXPR(dwarf::DW_OP_plus_uconst, 32, dwarf::DW_OP_deref), false);
3483 EXPECT_NE_DEBUG_VALUE(
3484 GET_EXPR(dwarf::DW_OP_plus_uconst, 16, dwarf::DW_OP_deref), true,
3485 GET_EXPR(dwarf::DW_OP_plus_uconst, 16, dwarf::DW_OP_deref), false);
3486 EXPECT_EQ_DEBUG_VALUE(
3487 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 5), false,
3488 GET_EXPR(dwarf::DW_OP_plus_uconst, 5), false);
3489 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus),
3490 false,
3491 GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
3492 dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus),
3493 false);
3494 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu,
3495 8, dwarf::DW_OP_minus),
3496 false,
3497 GET_EXPR(dwarf::DW_OP_constu, 8, dwarf::DW_OP_LLVM_arg,
3498 0, dwarf::DW_OP_minus),
3499 false);
3500 // These expressions are actually equivalent, but we do not currently identify
3501 // commutative operations with different operand orders as being equivalent.
3502 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_constu,
3503 8, dwarf::DW_OP_plus),
3504 false,
3505 GET_EXPR(dwarf::DW_OP_constu, 8, dwarf::DW_OP_LLVM_arg,
3506 0, dwarf::DW_OP_plus),
3507 false);
3509 #undef EXPECT_EQ_DEBUG_VALUE
3510 #undef EXPECT_NE_DEBUG_VALUE
3511 #undef GET_EXPR
3514 TEST_F(DIExpressionTest, foldConstant) {
3515 const ConstantInt *Int;
3516 const ConstantInt *NewInt;
3517 DIExpression *Expr;
3518 DIExpression *NewExpr;
3520 #define EXPECT_FOLD_CONST(StartWidth, StartValue, EndWidth, EndValue, NumElts) \
3521 Int = ConstantInt::get(Context, APInt(StartWidth, StartValue)); \
3522 std::tie(NewExpr, NewInt) = Expr->constantFold(Int); \
3523 ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u); \
3524 EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue)); \
3525 EXPECT_EQ(NewExpr->getNumElements(), NumElts##u)
3527 // Unfoldable expression should return the original unmodified Int/Expr.
3528 Expr = DIExpression::get(Context, {dwarf::DW_OP_deref});
3529 EXPECT_FOLD_CONST(32, 117, 32, 117, 1);
3530 EXPECT_EQ(NewExpr, Expr);
3531 EXPECT_EQ(NewInt, Int);
3532 EXPECT_TRUE(NewExpr->startsWithDeref());
3534 // One unsigned bit-width conversion.
3535 Expr = DIExpression::get(
3536 Context, {dwarf::DW_OP_LLVM_convert, 72, dwarf::DW_ATE_unsigned});
3537 EXPECT_FOLD_CONST(8, 12, 72, 12, 0);
3539 // Two unsigned bit-width conversions (mask truncation).
3540 Expr = DIExpression::get(
3541 Context, {dwarf::DW_OP_LLVM_convert, 8, dwarf::DW_ATE_unsigned,
3542 dwarf::DW_OP_LLVM_convert, 16, dwarf::DW_ATE_unsigned});
3543 EXPECT_FOLD_CONST(32, -1, 16, 0xff, 0);
3545 // Sign extension.
3546 Expr = DIExpression::get(
3547 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed});
3548 EXPECT_FOLD_CONST(16, -1, 32, -1, 0);
3550 // Get non-foldable operations back in the new Expr.
3551 uint64_t Elements[] = {dwarf::DW_OP_deref, dwarf::DW_OP_stack_value};
3552 ArrayRef<uint64_t> Expected = Elements;
3553 Expr = DIExpression::get(
3554 Context, {dwarf::DW_OP_LLVM_convert, 32, dwarf::DW_ATE_signed});
3555 Expr = DIExpression::append(Expr, Expected);
3556 ASSERT_EQ(Expr->getNumElements(), 5u);
3557 EXPECT_FOLD_CONST(16, -1, 32, -1, 2);
3558 EXPECT_EQ(NewExpr->getElements(), Expected);
3560 #undef EXPECT_FOLD_CONST
3563 typedef MetadataTest DIObjCPropertyTest;
3565 TEST_F(DIObjCPropertyTest, get) {
3566 StringRef Name = "name";
3567 DIFile *File = getFile();
3568 unsigned Line = 5;
3569 StringRef GetterName = "getter";
3570 StringRef SetterName = "setter";
3571 unsigned Attributes = 7;
3572 DIType *Type = getBasicType("basic");
3574 auto *N = DIObjCProperty::get(Context, Name, File, Line, GetterName,
3575 SetterName, Attributes, Type);
3577 EXPECT_EQ(dwarf::DW_TAG_APPLE_property, N->getTag());
3578 EXPECT_EQ(Name, N->getName());
3579 EXPECT_EQ(File, N->getFile());
3580 EXPECT_EQ(Line, N->getLine());
3581 EXPECT_EQ(GetterName, N->getGetterName());
3582 EXPECT_EQ(SetterName, N->getSetterName());
3583 EXPECT_EQ(Attributes, N->getAttributes());
3584 EXPECT_EQ(Type, N->getType());
3585 EXPECT_EQ(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
3586 SetterName, Attributes, Type));
3588 EXPECT_NE(N, DIObjCProperty::get(Context, "other", File, Line, GetterName,
3589 SetterName, Attributes, Type));
3590 EXPECT_NE(N, DIObjCProperty::get(Context, Name, getFile(), Line, GetterName,
3591 SetterName, Attributes, Type));
3592 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line + 1, GetterName,
3593 SetterName, Attributes, Type));
3594 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, "other",
3595 SetterName, Attributes, Type));
3596 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
3597 "other", Attributes, Type));
3598 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
3599 SetterName, Attributes + 1, Type));
3600 EXPECT_NE(N, DIObjCProperty::get(Context, Name, File, Line, GetterName,
3601 SetterName, Attributes,
3602 getBasicType("other")));
3604 TempDIObjCProperty Temp = N->clone();
3605 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
3608 typedef MetadataTest DIImportedEntityTest;
3610 TEST_F(DIImportedEntityTest, get) {
3611 unsigned Tag = dwarf::DW_TAG_imported_module;
3612 DIScope *Scope = getSubprogram();
3613 DINode *Entity = getCompositeType();
3614 DIFile *File = getFile();
3615 unsigned Line = 5;
3616 StringRef Name = "name";
3618 auto *N =
3619 DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name);
3621 EXPECT_EQ(Tag, N->getTag());
3622 EXPECT_EQ(Scope, N->getScope());
3623 EXPECT_EQ(Entity, N->getEntity());
3624 EXPECT_EQ(File, N->getFile());
3625 EXPECT_EQ(Line, N->getLine());
3626 EXPECT_EQ(Name, N->getName());
3627 EXPECT_EQ(
3628 N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name));
3630 EXPECT_NE(N,
3631 DIImportedEntity::get(Context, dwarf::DW_TAG_imported_declaration,
3632 Scope, Entity, File, Line, Name));
3633 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, getSubprogram(), Entity,
3634 File, Line, Name));
3635 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, getCompositeType(),
3636 File, Line, Name));
3637 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, nullptr, Line,
3638 Name));
3639 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File,
3640 Line + 1, Name));
3641 EXPECT_NE(N, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
3642 "other"));
3644 TempDIImportedEntity Temp = N->clone();
3645 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
3647 MDTuple *Elements1 = getTuple();
3648 MDTuple *Elements2 = getTuple();
3649 auto *Ne = DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
3650 Name, Elements1);
3652 EXPECT_EQ(Elements1, Ne->getElements().get());
3654 EXPECT_EQ(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
3655 Name, Elements1));
3656 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
3657 "ModOther", Elements1));
3658 EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
3659 Name, Elements2));
3660 EXPECT_NE(
3661 Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name));
3663 TempDIImportedEntity Tempe = Ne->clone();
3664 EXPECT_EQ(Ne, MDNode::replaceWithUniqued(std::move(Tempe)));
3667 typedef MetadataTest MetadataAsValueTest;
3669 TEST_F(MetadataAsValueTest, MDNode) {
3670 MDNode *N = MDNode::get(Context, std::nullopt);
3671 auto *V = MetadataAsValue::get(Context, N);
3672 EXPECT_TRUE(V->getType()->isMetadataTy());
3673 EXPECT_EQ(N, V->getMetadata());
3675 auto *V2 = MetadataAsValue::get(Context, N);
3676 EXPECT_EQ(V, V2);
3679 TEST_F(MetadataAsValueTest, MDNodeMDNode) {
3680 MDNode *N = MDNode::get(Context, std::nullopt);
3681 Metadata *Ops[] = {N};
3682 MDNode *N2 = MDNode::get(Context, Ops);
3683 auto *V = MetadataAsValue::get(Context, N2);
3684 EXPECT_TRUE(V->getType()->isMetadataTy());
3685 EXPECT_EQ(N2, V->getMetadata());
3687 auto *V2 = MetadataAsValue::get(Context, N2);
3688 EXPECT_EQ(V, V2);
3690 auto *V3 = MetadataAsValue::get(Context, N);
3691 EXPECT_TRUE(V3->getType()->isMetadataTy());
3692 EXPECT_NE(V, V3);
3693 EXPECT_EQ(N, V3->getMetadata());
3696 TEST_F(MetadataAsValueTest, MDNodeConstant) {
3697 auto *C = ConstantInt::getTrue(Context);
3698 auto *MD = ConstantAsMetadata::get(C);
3699 Metadata *Ops[] = {MD};
3700 auto *N = MDNode::get(Context, Ops);
3702 auto *V = MetadataAsValue::get(Context, MD);
3703 EXPECT_TRUE(V->getType()->isMetadataTy());
3704 EXPECT_EQ(MD, V->getMetadata());
3706 auto *V2 = MetadataAsValue::get(Context, N);
3707 EXPECT_EQ(MD, V2->getMetadata());
3708 EXPECT_EQ(V, V2);
3711 typedef MetadataTest ValueAsMetadataTest;
3713 TEST_F(ValueAsMetadataTest, UpdatesOnRAUW) {
3714 Type *Ty = PointerType::getUnqual(Context);
3715 std::unique_ptr<GlobalVariable> GV0(
3716 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3717 auto *MD = ValueAsMetadata::get(GV0.get());
3718 EXPECT_TRUE(MD->getValue() == GV0.get());
3719 ASSERT_TRUE(GV0->use_empty());
3721 std::unique_ptr<GlobalVariable> GV1(
3722 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3723 GV0->replaceAllUsesWith(GV1.get());
3724 EXPECT_TRUE(MD->getValue() == GV1.get());
3727 TEST_F(ValueAsMetadataTest, TempTempReplacement) {
3728 // Create a constant.
3729 ConstantAsMetadata *CI =
3730 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)));
3732 auto Temp1 = MDTuple::getTemporary(Context, std::nullopt);
3733 auto Temp2 = MDTuple::getTemporary(Context, {CI});
3734 auto *N = MDTuple::get(Context, {Temp1.get()});
3736 // Test replacing a temporary node with another temporary node.
3737 Temp1->replaceAllUsesWith(Temp2.get());
3738 EXPECT_EQ(N->getOperand(0), Temp2.get());
3740 // Clean up Temp2 for teardown.
3741 Temp2->replaceAllUsesWith(nullptr);
3744 TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
3745 // Create a constant.
3746 ConstantAsMetadata *CI =
3747 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)));
3749 // Create a temporary to prevent nodes from resolving.
3750 auto Temp = MDTuple::getTemporary(Context, std::nullopt);
3752 // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
3753 Metadata *Ops1[] = {CI, CI, Temp.get()};
3754 Metadata *Ops2[] = {nullptr, CI, Temp.get()};
3756 auto *N1 = MDTuple::get(Context, Ops1);
3757 auto *N2 = MDTuple::get(Context, Ops2);
3758 ASSERT_NE(N1, N2);
3760 // Tell metadata that the constant is getting deleted.
3762 // After this, N1 will be invalid, so don't touch it.
3763 ValueAsMetadata::handleDeletion(CI->getValue());
3764 EXPECT_EQ(nullptr, N2->getOperand(0));
3765 EXPECT_EQ(nullptr, N2->getOperand(1));
3766 EXPECT_EQ(Temp.get(), N2->getOperand(2));
3768 // Clean up Temp for teardown.
3769 Temp->replaceAllUsesWith(nullptr);
3772 typedef MetadataTest DIArgListTest;
3774 TEST_F(DIArgListTest, get) {
3775 SmallVector<ValueAsMetadata *, 2> VMs;
3776 VMs.push_back(
3777 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0))));
3778 VMs.push_back(
3779 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(2, 0))));
3780 DIArgList *DV0 = DIArgList::get(Context, VMs);
3781 DIArgList *DV1 = DIArgList::get(Context, VMs);
3782 EXPECT_EQ(DV0, DV1);
3785 TEST_F(DIArgListTest, UpdatesOnRAUW) {
3786 Type *Ty = PointerType::getUnqual(Context);
3787 ConstantAsMetadata *CI =
3788 ConstantAsMetadata::get(ConstantInt::get(Context, APInt(8, 0)));
3789 std::unique_ptr<GlobalVariable> GV0(
3790 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3791 auto *MD0 = ValueAsMetadata::get(GV0.get());
3793 SmallVector<ValueAsMetadata *, 2> VMs;
3794 VMs.push_back(CI);
3795 VMs.push_back(MD0);
3796 auto *AL = DIArgList::get(Context, VMs);
3797 EXPECT_EQ(AL->getArgs()[0], CI);
3798 EXPECT_EQ(AL->getArgs()[1], MD0);
3800 std::unique_ptr<GlobalVariable> GV1(
3801 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3802 auto *MD1 = ValueAsMetadata::get(GV1.get());
3803 GV0->replaceAllUsesWith(GV1.get());
3804 EXPECT_EQ(AL->getArgs()[0], CI);
3805 EXPECT_EQ(AL->getArgs()[1], MD1);
3808 typedef MetadataTest TrackingMDRefTest;
3810 TEST_F(TrackingMDRefTest, UpdatesOnRAUW) {
3811 Type *Ty = PointerType::getUnqual(Context);
3812 std::unique_ptr<GlobalVariable> GV0(
3813 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3814 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV0.get()));
3815 EXPECT_TRUE(MD->getValue() == GV0.get());
3816 ASSERT_TRUE(GV0->use_empty());
3818 std::unique_ptr<GlobalVariable> GV1(
3819 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3820 GV0->replaceAllUsesWith(GV1.get());
3821 EXPECT_TRUE(MD->getValue() == GV1.get());
3823 // Reset it, so we don't inadvertently test deletion.
3824 MD.reset();
3827 TEST_F(TrackingMDRefTest, UpdatesOnDeletion) {
3828 Type *Ty = PointerType::getUnqual(Context);
3829 std::unique_ptr<GlobalVariable> GV(
3830 new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage));
3831 TypedTrackingMDRef<ValueAsMetadata> MD(ValueAsMetadata::get(GV.get()));
3832 EXPECT_TRUE(MD->getValue() == GV.get());
3833 ASSERT_TRUE(GV->use_empty());
3835 GV.reset();
3836 EXPECT_TRUE(!MD);
3839 TEST(NamedMDNodeTest, Search) {
3840 LLVMContext Context;
3841 ConstantAsMetadata *C =
3842 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1));
3843 ConstantAsMetadata *C2 =
3844 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2));
3846 Metadata *const V = C;
3847 Metadata *const V2 = C2;
3848 MDNode *n = MDNode::get(Context, V);
3849 MDNode *n2 = MDNode::get(Context, V2);
3851 Module M("MyModule", Context);
3852 const char *Name = "llvm.NMD1";
3853 NamedMDNode *NMD = M.getOrInsertNamedMetadata(Name);
3854 NMD->addOperand(n);
3855 NMD->addOperand(n2);
3857 std::string Str;
3858 raw_string_ostream oss(Str);
3859 NMD->print(oss);
3860 EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n",
3861 oss.str().c_str());
3864 typedef MetadataTest FunctionAttachmentTest;
3865 TEST_F(FunctionAttachmentTest, setMetadata) {
3866 Function *F = getFunction("foo");
3867 ASSERT_FALSE(F->hasMetadata());
3868 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
3869 EXPECT_EQ(nullptr, F->getMetadata("dbg"));
3870 EXPECT_EQ(nullptr, F->getMetadata("other"));
3872 DISubprogram *SP1 = getSubprogram();
3873 DISubprogram *SP2 = getSubprogram();
3874 ASSERT_NE(SP1, SP2);
3876 F->setMetadata("dbg", SP1);
3877 EXPECT_TRUE(F->hasMetadata());
3878 EXPECT_EQ(SP1, F->getMetadata(LLVMContext::MD_dbg));
3879 EXPECT_EQ(SP1, F->getMetadata("dbg"));
3880 EXPECT_EQ(nullptr, F->getMetadata("other"));
3882 F->setMetadata(LLVMContext::MD_dbg, SP2);
3883 EXPECT_TRUE(F->hasMetadata());
3884 EXPECT_EQ(SP2, F->getMetadata(LLVMContext::MD_dbg));
3885 EXPECT_EQ(SP2, F->getMetadata("dbg"));
3886 EXPECT_EQ(nullptr, F->getMetadata("other"));
3888 F->setMetadata("dbg", nullptr);
3889 EXPECT_FALSE(F->hasMetadata());
3890 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
3891 EXPECT_EQ(nullptr, F->getMetadata("dbg"));
3892 EXPECT_EQ(nullptr, F->getMetadata("other"));
3894 MDTuple *T1 = getTuple();
3895 MDTuple *T2 = getTuple();
3896 ASSERT_NE(T1, T2);
3898 F->setMetadata("other1", T1);
3899 F->setMetadata("other2", T2);
3900 EXPECT_TRUE(F->hasMetadata());
3901 EXPECT_EQ(T1, F->getMetadata("other1"));
3902 EXPECT_EQ(T2, F->getMetadata("other2"));
3903 EXPECT_EQ(nullptr, F->getMetadata("dbg"));
3905 F->setMetadata("other1", T2);
3906 F->setMetadata("other2", T1);
3907 EXPECT_EQ(T2, F->getMetadata("other1"));
3908 EXPECT_EQ(T1, F->getMetadata("other2"));
3910 F->setMetadata("other1", nullptr);
3911 F->setMetadata("other2", nullptr);
3912 EXPECT_FALSE(F->hasMetadata());
3913 EXPECT_EQ(nullptr, F->getMetadata("other1"));
3914 EXPECT_EQ(nullptr, F->getMetadata("other2"));
3917 TEST_F(FunctionAttachmentTest, getAll) {
3918 Function *F = getFunction("foo");
3920 MDTuple *T1 = getTuple();
3921 MDTuple *T2 = getTuple();
3922 MDTuple *P = getTuple();
3923 DISubprogram *SP = getSubprogram();
3925 F->setMetadata("other1", T2);
3926 F->setMetadata(LLVMContext::MD_dbg, SP);
3927 F->setMetadata("other2", T1);
3928 F->setMetadata(LLVMContext::MD_prof, P);
3929 F->setMetadata("other2", T2);
3930 F->setMetadata("other1", T1);
3932 SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
3933 F->getAllMetadata(MDs);
3934 ASSERT_EQ(4u, MDs.size());
3935 EXPECT_EQ(LLVMContext::MD_dbg, MDs[0].first);
3936 EXPECT_EQ(LLVMContext::MD_prof, MDs[1].first);
3937 EXPECT_EQ(Context.getMDKindID("other1"), MDs[2].first);
3938 EXPECT_EQ(Context.getMDKindID("other2"), MDs[3].first);
3939 EXPECT_EQ(SP, MDs[0].second);
3940 EXPECT_EQ(P, MDs[1].second);
3941 EXPECT_EQ(T1, MDs[2].second);
3942 EXPECT_EQ(T2, MDs[3].second);
3945 TEST_F(FunctionAttachmentTest, Verifier) {
3946 Function *F = getFunction("foo");
3947 F->setMetadata("attach", getTuple());
3948 F->setIsMaterializable(true);
3950 // Confirm this is materializable.
3951 ASSERT_TRUE(F->isMaterializable());
3953 // Materializable functions cannot have metadata attachments.
3954 EXPECT_TRUE(verifyFunction(*F));
3956 // Function declarations can.
3957 F->setIsMaterializable(false);
3958 EXPECT_FALSE(verifyModule(*F->getParent()));
3959 EXPECT_FALSE(verifyFunction(*F));
3961 // So can definitions.
3962 (void)new UnreachableInst(Context, BasicBlock::Create(Context, "bb", F));
3963 EXPECT_FALSE(verifyModule(*F->getParent()));
3964 EXPECT_FALSE(verifyFunction(*F));
3967 TEST_F(FunctionAttachmentTest, RealEntryCount) {
3968 Function *F = getFunction("foo");
3969 EXPECT_FALSE(F->getEntryCount().has_value());
3970 F->setEntryCount(12304, Function::PCT_Real);
3971 auto Count = F->getEntryCount();
3972 EXPECT_TRUE(Count.has_value());
3973 EXPECT_EQ(12304u, Count->getCount());
3974 EXPECT_EQ(Function::PCT_Real, Count->getType());
3977 TEST_F(FunctionAttachmentTest, SyntheticEntryCount) {
3978 Function *F = getFunction("bar");
3979 EXPECT_FALSE(F->getEntryCount().has_value());
3980 F->setEntryCount(123, Function::PCT_Synthetic);
3981 auto Count = F->getEntryCount(true /*allow synthetic*/);
3982 EXPECT_TRUE(Count.has_value());
3983 EXPECT_EQ(123u, Count->getCount());
3984 EXPECT_EQ(Function::PCT_Synthetic, Count->getType());
3987 TEST_F(FunctionAttachmentTest, SubprogramAttachment) {
3988 Function *F = getFunction("foo");
3989 DISubprogram *SP = getSubprogram();
3990 F->setSubprogram(SP);
3992 // Note that the static_cast confirms that F->getSubprogram() actually
3993 // returns an DISubprogram.
3994 EXPECT_EQ(SP, static_cast<DISubprogram *>(F->getSubprogram()));
3995 EXPECT_EQ(SP, F->getMetadata("dbg"));
3996 EXPECT_EQ(SP, F->getMetadata(LLVMContext::MD_dbg));
3999 typedef MetadataTest DistinctMDOperandPlaceholderTest;
4000 TEST_F(DistinctMDOperandPlaceholderTest, getID) {
4001 EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID());
4004 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWith) {
4005 // Set up some placeholders.
4006 DistinctMDOperandPlaceholder PH0(7);
4007 DistinctMDOperandPlaceholder PH1(3);
4008 DistinctMDOperandPlaceholder PH2(0);
4009 Metadata *Ops[] = {&PH0, &PH1, &PH2};
4010 auto *D = MDTuple::getDistinct(Context, Ops);
4011 ASSERT_EQ(&PH0, D->getOperand(0));
4012 ASSERT_EQ(&PH1, D->getOperand(1));
4013 ASSERT_EQ(&PH2, D->getOperand(2));
4015 // Replace them.
4016 auto *N0 = MDTuple::get(Context, std::nullopt);
4017 auto *N1 = MDTuple::get(Context, N0);
4018 PH0.replaceUseWith(N0);
4019 PH1.replaceUseWith(N1);
4020 PH2.replaceUseWith(nullptr);
4021 EXPECT_EQ(N0, D->getOperand(0));
4022 EXPECT_EQ(N1, D->getOperand(1));
4023 EXPECT_EQ(nullptr, D->getOperand(2));
4026 TEST_F(DistinctMDOperandPlaceholderTest, replaceUseWithNoUser) {
4027 // There is no user, but we can still call replace.
4028 DistinctMDOperandPlaceholder(7).replaceUseWith(
4029 MDTuple::get(Context, std::nullopt));
4032 // Test various assertions in metadata tracking. Don't run these tests if gtest
4033 // will use SEH to recover from them. Two of these tests get halfway through
4034 // inserting metadata into DenseMaps for tracking purposes, and then they
4035 // assert, and we attempt to destroy an LLVMContext with broken invariants,
4036 // leading to infinite loops.
4037 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH)
4038 TEST_F(DistinctMDOperandPlaceholderTest, MetadataAsValue) {
4039 // This shouldn't crash.
4040 DistinctMDOperandPlaceholder PH(7);
4041 EXPECT_DEATH(MetadataAsValue::get(Context, &PH),
4042 "Unexpected callback to owner");
4045 TEST_F(DistinctMDOperandPlaceholderTest, UniquedMDNode) {
4046 // This shouldn't crash.
4047 DistinctMDOperandPlaceholder PH(7);
4048 EXPECT_DEATH(MDTuple::get(Context, &PH), "Unexpected callback to owner");
4051 TEST_F(DistinctMDOperandPlaceholderTest, SecondDistinctMDNode) {
4052 // This shouldn't crash.
4053 DistinctMDOperandPlaceholder PH(7);
4054 MDTuple::getDistinct(Context, &PH);
4055 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH),
4056 "Placeholders can only be used once");
4059 TEST_F(DistinctMDOperandPlaceholderTest, TrackingMDRefAndDistinctMDNode) {
4060 // TrackingMDRef doesn't install an owner callback, so it can't be detected
4061 // as an invalid use. However, using a placeholder in a TrackingMDRef *and*
4062 // a distinct node isn't possible and we should assert.
4064 // (There's no positive test for using TrackingMDRef because it's not a
4065 // useful thing to do.)
4067 DistinctMDOperandPlaceholder PH(7);
4068 MDTuple::getDistinct(Context, &PH);
4069 EXPECT_DEATH(TrackingMDRef Ref(&PH), "Placeholders can only be used once");
4072 DistinctMDOperandPlaceholder PH(7);
4073 TrackingMDRef Ref(&PH);
4074 EXPECT_DEATH(MDTuple::getDistinct(Context, &PH),
4075 "Placeholders can only be used once");
4078 #endif
4080 typedef MetadataTest DebugVariableTest;
4081 TEST_F(DebugVariableTest, DenseMap) {
4082 DenseMap<DebugVariable, uint64_t> DebugVariableMap;
4084 DILocalScope *Scope = getSubprogram();
4085 DIFile *File = getFile();
4086 DIType *Type = getDerivedType();
4087 DINode::DIFlags Flags = static_cast<DINode::DIFlags>(7);
4089 DILocation *InlinedLoc = DILocation::get(Context, 2, 7, Scope);
4091 DILocalVariable *VarA =
4092 DILocalVariable::get(Context, Scope, "A", File, 5, Type, 2, Flags, 8, nullptr);
4093 DILocalVariable *VarB =
4094 DILocalVariable::get(Context, Scope, "B", File, 7, Type, 3, Flags, 8, nullptr);
4096 DebugVariable DebugVariableA(VarA, std::nullopt, nullptr);
4097 DebugVariable DebugVariableInlineA(VarA, std::nullopt, InlinedLoc);
4098 DebugVariable DebugVariableB(VarB, std::nullopt, nullptr);
4099 DebugVariable DebugVariableFragB(VarB, {{16, 16}}, nullptr);
4101 DebugVariableMap.insert({DebugVariableA, 2});
4102 DebugVariableMap.insert({DebugVariableInlineA, 3});
4103 DebugVariableMap.insert({DebugVariableB, 6});
4104 DebugVariableMap.insert({DebugVariableFragB, 12});
4106 EXPECT_EQ(DebugVariableMap.count(DebugVariableA), 1u);
4107 EXPECT_EQ(DebugVariableMap.count(DebugVariableInlineA), 1u);
4108 EXPECT_EQ(DebugVariableMap.count(DebugVariableB), 1u);
4109 EXPECT_EQ(DebugVariableMap.count(DebugVariableFragB), 1u);
4111 EXPECT_EQ(DebugVariableMap.find(DebugVariableA)->second, 2u);
4112 EXPECT_EQ(DebugVariableMap.find(DebugVariableInlineA)->second, 3u);
4113 EXPECT_EQ(DebugVariableMap.find(DebugVariableB)->second, 6u);
4114 EXPECT_EQ(DebugVariableMap.find(DebugVariableFragB)->second, 12u);
4117 typedef MetadataTest MDTupleAllocationTest;
4118 TEST_F(MDTupleAllocationTest, Tracking) {
4119 // Make sure that the move constructor and move assignment op
4120 // for MDOperand correctly adjust tracking information.
4121 auto *Value1 = getConstantAsMetadata();
4122 MDTuple *A = MDTuple::getDistinct(Context, {Value1, Value1});
4123 EXPECT_EQ(A->getOperand(0), Value1);
4124 EXPECT_EQ(A->getOperand(1), Value1);
4126 MDNode::op_range Ops = A->operands();
4128 MDOperand NewOps1;
4129 // Move assignment operator.
4130 NewOps1 = std::move(*const_cast<MDOperand *>(Ops.begin()));
4131 // Move constructor.
4132 MDOperand NewOps2(std::move(*const_cast<MDOperand *>(Ops.begin() + 1)));
4134 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value1));
4135 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value1));
4137 auto *Value2 = getConstantAsMetadata();
4138 Value *V1 = Value1->getValue();
4139 Value *V2 = Value2->getValue();
4140 ValueAsMetadata::handleRAUW(V1, V2);
4142 EXPECT_EQ(NewOps1.get(), static_cast<Metadata *>(Value2));
4143 EXPECT_EQ(NewOps2.get(), static_cast<Metadata *>(Value2));
4146 TEST_F(MDTupleAllocationTest, Resize) {
4147 MDTuple *A = getTuple();
4148 Metadata *Value1 = getConstantAsMetadata();
4149 Metadata *Value2 = getConstantAsMetadata();
4150 Metadata *Value3 = getConstantAsMetadata();
4152 EXPECT_EQ(A->getNumOperands(), 0u);
4154 // Add a couple of elements to it, which resizes the node.
4155 A->push_back(Value1);
4156 EXPECT_EQ(A->getNumOperands(), 1u);
4157 EXPECT_EQ(A->getOperand(0), Value1);
4159 A->push_back(Value2);
4160 EXPECT_EQ(A->getNumOperands(), 2u);
4161 EXPECT_EQ(A->getOperand(0), Value1);
4162 EXPECT_EQ(A->getOperand(1), Value2);
4164 // Append another element, which should resize the node
4165 // to a "large" node, though not detectable by the user.
4166 A->push_back(Value3);
4167 EXPECT_EQ(A->getNumOperands(), 3u);
4168 EXPECT_EQ(A->getOperand(0), Value1);
4169 EXPECT_EQ(A->getOperand(1), Value2);
4170 EXPECT_EQ(A->getOperand(2), Value3);
4172 // Remove the last element
4173 A->pop_back();
4174 EXPECT_EQ(A->getNumOperands(), 2u);
4175 EXPECT_EQ(A->getOperand(1), Value2);
4177 // Allocate a node with 4 operands.
4178 Metadata *Value4 = getConstantAsMetadata();
4179 Metadata *Value5 = getConstantAsMetadata();
4181 Metadata *Ops[] = {Value1, Value2, Value3, Value4};
4182 MDTuple *B = MDTuple::getDistinct(Context, Ops);
4184 EXPECT_EQ(B->getNumOperands(), 4u);
4185 B->pop_back();
4186 EXPECT_EQ(B->getNumOperands(), 3u);
4187 B->push_back(Value5);
4188 EXPECT_EQ(B->getNumOperands(), 4u);
4189 EXPECT_EQ(B->getOperand(0), Value1);
4190 EXPECT_EQ(B->getOperand(1), Value2);
4191 EXPECT_EQ(B->getOperand(2), Value3);
4192 EXPECT_EQ(B->getOperand(3), Value5);
4194 // Check that we can resize temporary nodes as well.
4195 auto Temp1 = MDTuple::getTemporary(Context, std::nullopt);
4196 EXPECT_EQ(Temp1->getNumOperands(), 0u);
4198 Temp1->push_back(Value1);
4199 EXPECT_EQ(Temp1->getNumOperands(), 1u);
4200 EXPECT_EQ(Temp1->getOperand(0), Value1);
4202 for (int i = 0; i < 11; i++)
4203 Temp1->push_back(Value2);
4204 EXPECT_EQ(Temp1->getNumOperands(), 12u);
4205 EXPECT_EQ(Temp1->getOperand(2), Value2);
4206 EXPECT_EQ(Temp1->getOperand(11), Value2);
4208 // Allocate a node that starts off as a large one.
4209 Metadata *OpsLarge[] = {Value1, Value2, Value3, Value4,
4210 Value1, Value2, Value3, Value4,
4211 Value1, Value2, Value3, Value4,
4212 Value1, Value2, Value3, Value4,
4213 Value1, Value2, Value3, Value4};
4214 MDTuple *C = MDTuple::getDistinct(Context, OpsLarge);
4215 EXPECT_EQ(C->getNumOperands(), 20u);
4216 EXPECT_EQ(C->getOperand(7), Value4);
4217 EXPECT_EQ(C->getOperand(13), Value2);
4219 C->push_back(Value1);
4220 C->push_back(Value2);
4221 EXPECT_EQ(C->getNumOperands(), 22u);
4222 EXPECT_EQ(C->getOperand(21), Value2);
4223 C->pop_back();
4224 EXPECT_EQ(C->getNumOperands(), 21u);
4225 EXPECT_EQ(C->getOperand(20), Value1);
4228 TEST_F(MDTupleAllocationTest, Tracking2) {
4229 // Resize a tuple and check that we can still RAUW one of its operands.
4230 auto *Value1 = getConstantAsMetadata();
4231 MDTuple *A = getTuple();
4232 A->push_back(Value1);
4233 A->push_back(Value1);
4234 A->push_back(Value1); // Causes a resize to large.
4235 EXPECT_EQ(A->getOperand(0), Value1);
4236 EXPECT_EQ(A->getOperand(1), Value1);
4237 EXPECT_EQ(A->getOperand(2), Value1);
4239 auto *Value2 = getConstantAsMetadata();
4240 Value *V1 = Value1->getValue();
4241 Value *V2 = Value2->getValue();
4242 ValueAsMetadata::handleRAUW(V1, V2);
4244 EXPECT_EQ(A->getOperand(0), Value2);
4245 EXPECT_EQ(A->getOperand(1), Value2);
4246 EXPECT_EQ(A->getOperand(2), Value2);
4249 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH)
4250 typedef MetadataTest MDTupleAllocationDeathTest;
4251 TEST_F(MDTupleAllocationDeathTest, ResizeRejected) {
4252 MDTuple *A = MDTuple::get(Context, None);
4253 auto *Value1 = getConstantAsMetadata();
4254 EXPECT_DEATH(A->push_back(Value1),
4255 "Resizing is not supported for uniqued nodes");
4257 // Check that a node, which has been allocated as a temporary,
4258 // cannot be resized after it has been uniqued.
4259 auto *Value2 = getConstantAsMetadata();
4260 auto B = MDTuple::getTemporary(Context, {Value2});
4261 B->push_back(Value2);
4262 MDTuple *BUniqued = MDNode::replaceWithUniqued(std::move(B));
4263 EXPECT_EQ(BUniqued->getNumOperands(), 2u);
4264 EXPECT_EQ(BUniqued->getOperand(1), Value2);
4265 EXPECT_DEATH(BUniqued->push_back(Value2),
4266 "Resizing is not supported for uniqued nodes");
4268 #endif
4270 } // end namespace