1 //===- unittests/IR/MetadataTest.cpp - Metadata unit tests ----------------===//
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
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"
30 TEST(ContextAndReplaceableUsesTest
, FromContext
) {
32 ContextAndReplaceableUses
CRU(Context
);
33 EXPECT_EQ(&Context
, &CRU
.getContext());
34 EXPECT_FALSE(CRU
.hasReplaceableUses());
35 EXPECT_FALSE(CRU
.getReplaceableUses());
38 TEST(ContextAndReplaceableUsesTest
, FromReplaceableUses
) {
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
) {
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
) {
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
{
69 MetadataTest() : M("test", Context
), Counter(0) {}
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,
88 DISubprogram
*getSubprogram() {
89 return DISubprogram::getDistinct(
90 Context
, nullptr, "", "", nullptr, 0, nullptr, 0, nullptr, 0, 0,
91 DINode::FlagZero
, DISubprogram::SPFlagZero
, nullptr);
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));
136 MDString
*s2
= MDString::get(Context
, StringRef(&x
[0], 3));
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));
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);
158 raw_string_ostream
oss(Str
);
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));
168 raw_string_ostream
oss(Str
);
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
;
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
);
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
);
226 TEST_F(MDNodeTest
, SelfReference
) {
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.
239 MDNode
*Ref1
= MDNode::get(Context
, Args
);
240 MDNode
*Ref2
= MDNode::get(Context
, Args
);
241 EXPECT_NE(Self
, Ref1
);
242 EXPECT_EQ(Ref1
, Ref2
);
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.
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
);
280 S
->printAsOperand(OS
);
282 MDNode
*Nodes
[] = {N0
, N1
, N2
};
283 for (auto *Node
: Nodes
)
284 OS
<< ", <" << (void *)Node
<< ">";
290 raw_string_ostream
OS(Actual
);
294 EXPECT_EQ(Expected
, Actual
);
297 #define EXPECT_PRINTER_EQ(EXPECTED, PRINT) \
299 std::string Actual_; \
300 raw_string_ostream OS(Actual_); \
303 std::string Expected_(EXPECTED); \
304 EXPECT_EQ(Expected_, Actual_); \
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");
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
));
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");
336 std::string Expected
;
338 raw_string_ostream
OS(Expected
);
340 C
->printAsOperand(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
);
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
);
442 Scope
->print((SS
<< "\n").indent(2));
443 File
->print((SS
<< "\n").indent(2));
444 Type
->print((SS
<< "\n").indent(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 {
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
);
475 Scope
->print((SS
<< "\n").indent(2));
476 File
->print((SS
<< "\n").indent(2));
477 StructTy
->print((SS
<< "\n").indent(2));
479 StructTy
->getRawElements()->print((SS
<< "\n").indent(4));
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
) {
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));
505 MDNode
*NullOp
= MDNode::get(Context
, Ops
);
506 ASSERT_EQ(nullptr, NullOp
->getOperand(0));
507 EXPECT_EQ(N
, NullOp
);
510 TEST_F(MDNodeTest
, DistinctOnUniquingCollision
) {
512 MDNode
*Empty
= MDNode::get(Context
, std::nullopt
);
513 ASSERT_TRUE(Empty
->isResolved());
514 EXPECT_FALSE(Empty
->isDistinct());
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());
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
) {
539 TempMDTuple T
= MDTuple::getTemporary(Context
, std::nullopt
);
542 Metadata
*Ops
[] = {T
.get()};
543 MDTuple
*N
= MDTuple::get(Context
, Ops
);
545 // !{temp !{}} => !{null}
547 ASSERT_TRUE(N
->isUniqued());
548 Metadata
*NullOps
[] = {nullptr};
549 ASSERT_EQ(N
, MDTuple::get(Context
, NullOps
));
552 TEST_F(MDNodeTest
, DistinctOnDeletedValueOperand
) {
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());
560 Metadata
*Ops
[] = {Op
};
561 MDTuple
*N
= MDTuple::get(Context
, Ops
);
563 // !{i1* @GV} => !{null}
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
) {
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
));
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
);
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
) {
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
) {
637 MDNode
*N0
= MDNode::get(Context
, std::nullopt
);
640 auto Temp3
= MDTuple::getTemporary(Context
, std::nullopt
);
641 Metadata
*Ops1
[] = {Temp3
.get(), nullptr};
642 MDNode
*N1
= MDNode::get(Context
, Ops1
);
645 Metadata
*Ops2
[] = {Temp3
.get(), N0
};
646 MDNode
*N2
= MDNode::get(Context
, Ops2
);
649 Metadata
*Ops3
[] = {N2
};
650 MDNode
*N3
= MDNode::get(Context
, Ops3
);
651 Temp3
->replaceAllUsesWith(N3
);
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.
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
) {
773 MDTuple
*Op
= MDTuple::getTemporary(Context
, std::nullopt
).release();
774 EXPECT_FALSE(Op
->isResolved());
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
) {
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());
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}
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
) {
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());
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
));
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
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
) {
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);
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.
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.
1182 DILexicalBlock::getDistinct(Context
, SPAScope1
, FA
, 10, 12);
1184 // Scope for the second location in a.
1186 DILexicalBlock::getDistinct(Context
, SPAScope1
, FA
, 20, 8);
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
);
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());
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());
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();
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();
1490 ASSERT_TRUE(isa
<ConstantInt
*>(Lower
));
1491 EXPECT_EQ(cast
<ConstantInt
>(LI
->getValue()), cast
<ConstantInt
*>(Lower
));
1493 auto Upper
= N
->getUpperBound();
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);
1522 DILocalVariable::get(Context
, Scope
, "lb", File
, 8, Type
, 2, Flags
, 8,
1525 DILocalVariable::get(Context
, Scope
, "ub", File
, 8, Type
, 2, Flags
, 8,
1528 DILocalVariable::get(Context
, Scope
, "st", File
, 8, Type
, 2, Flags
, 8,
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();
1540 ASSERT_TRUE(isa
<DIVariable
*>(Lower
));
1541 EXPECT_EQ(LV
, cast
<DIVariable
*>(Lower
));
1543 auto Upper
= N
->getUpperBound();
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();
1578 ASSERT_TRUE(isa
<DIExpression
*>(Lower
));
1579 EXPECT_EQ(LE
, cast
<DIExpression
*>(Lower
));
1581 auto Upper
= N
->getUpperBound();
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();
1620 ASSERT_TRUE(isa
<DIExpression
*>(Lower
));
1621 EXPECT_EQ(dyn_cast_or_null
<DIExpression
>(LI
), cast
<DIExpression
*>(Lower
));
1623 auto Upper
= N
->getUpperBound();
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);
1654 DILocalVariable::get(Context
, Scope
, "lb", File
, 8, Type
, 2, Flags
, 8,
1657 DILocalVariable::get(Context
, Scope
, "ub", File
, 8, Type
, 2, Flags
, 8,
1660 DILocalVariable::get(Context
, Scope
, "st", File
, 8, Type
, 2, Flags
, 8,
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();
1672 ASSERT_TRUE(isa
<DIVariable
*>(Lower
));
1673 EXPECT_EQ(LV
, cast
<DIVariable
*>(Lower
));
1675 auto Upper
= N
->getUpperBound();
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);
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
);
1710 auto *N
= DIB
.getOrCreateGenericSubrange(
1711 DIGenericSubrange::BoundType(nullptr), DIGenericSubrange::BoundType(LV
),
1712 DIGenericSubrange::BoundType(UE
), DIGenericSubrange::BoundType(SE
));
1714 auto Lower
= N
->getLowerBound();
1716 ASSERT_TRUE(isa
<DIVariable
*>(Lower
));
1717 EXPECT_EQ(LV
, cast
<DIVariable
*>(Lower
));
1719 auto Upper
= N
->getUpperBound();
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
));
1730 N
, DIB
.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr),
1731 DIGenericSubrange::BoundType(LV
),
1732 DIGenericSubrange::BoundType(UE
),
1733 DIGenericSubrange::BoundType(SE
)));
1736 N
, DIB
.getOrCreateGenericSubrange(DIGenericSubrange::BoundType(nullptr),
1737 DIGenericSubrange::BoundType(LVother
),
1738 DIGenericSubrange::BoundType(UE
),
1739 DIGenericSubrange::BoundType(SE
)));
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());
1768 DIEnumerator::get(Context
, APInt::getMaxValue(128), false, "val"));
1770 DIEnumerator::get(Context
, APInt::getMinValue(128), false, "val"));
1773 typedef MetadataTest DIBasicTypeTest
;
1775 TEST_F(DIBasicTypeTest
, get
) {
1777 DIBasicType::get(Context
, dwarf::DW_TAG_base_type
, "special", 33, 26, 7,
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
));
1792 DIBasicType::get(Context
, dwarf::DW_TAG_base_type
, "s", 33, 26, 7,
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
) {
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
) {
1841 Metadata
*TypesOps
[] = {nullptr};
1842 Metadata
*Types
= MDTuple::get(Context
, TypesOps
);
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());
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 DIDerivedType::PtrAuthData
PtrAuthData(1, false, 1234, true, true);
1868 DIDerivedType::PtrAuthData
PtrAuthData2(1, false, 1234, true, false);
1869 DINode::DIFlags Flags5
= static_cast<DINode::DIFlags
>(5);
1870 DINode::DIFlags Flags4
= static_cast<DINode::DIFlags
>(4);
1872 auto *N
= DIDerivedType::get(
1873 Context
, dwarf::DW_TAG_pointer_type
, "something", File
, 1, Scope
,
1874 BaseType
, 2, 3, 4, DWARFAddressSpace
, std::nullopt
, Flags5
, ExtraData
);
1875 auto *N1
= DIDerivedType::get(Context
, dwarf::DW_TAG_LLVM_ptrauth_type
, "",
1876 File
, 1, Scope
, N
, 2, 3, 4, DWARFAddressSpace
,
1877 PtrAuthData
, Flags5
, ExtraData
);
1878 EXPECT_EQ(dwarf::DW_TAG_pointer_type
, N
->getTag());
1879 EXPECT_EQ("something", N
->getName());
1880 EXPECT_EQ(File
, N
->getFile());
1881 EXPECT_EQ(1u, N
->getLine());
1882 EXPECT_EQ(Scope
, N
->getScope());
1883 EXPECT_EQ(BaseType
, N
->getBaseType());
1884 EXPECT_EQ(2u, N
->getSizeInBits());
1885 EXPECT_EQ(3u, N
->getAlignInBits());
1886 EXPECT_EQ(4u, N
->getOffsetInBits());
1887 EXPECT_EQ(DWARFAddressSpace
, *N
->getDWARFAddressSpace());
1888 EXPECT_EQ(std::nullopt
, N
->getPtrAuthData());
1889 EXPECT_EQ(PtrAuthData
, N1
->getPtrAuthData());
1890 EXPECT_NE(PtrAuthData2
, N1
->getPtrAuthData());
1891 EXPECT_EQ(5u, N
->getFlags());
1892 EXPECT_EQ(ExtraData
, N
->getExtraData());
1893 EXPECT_EQ(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1894 "something", File
, 1, Scope
, BaseType
, 2, 3,
1895 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1898 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_reference_type
,
1899 "something", File
, 1, Scope
, BaseType
, 2, 3,
1900 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1902 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
, "else",
1903 File
, 1, Scope
, BaseType
, 2, 3, 4,
1904 DWARFAddressSpace
, std::nullopt
, Flags5
,
1906 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1907 "something", getFile(), 1, Scope
, BaseType
, 2,
1908 3, 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1910 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1911 "something", File
, 2, Scope
, BaseType
, 2, 3,
1912 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1914 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1915 "something", File
, 1, getSubprogram(),
1916 BaseType
, 2, 3, 4, DWARFAddressSpace
,
1917 std::nullopt
, Flags5
, ExtraData
));
1918 EXPECT_NE(N
, DIDerivedType::get(
1919 Context
, dwarf::DW_TAG_pointer_type
, "something", File
, 1,
1920 Scope
, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace
,
1921 std::nullopt
, Flags5
, ExtraData
));
1922 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1923 "something", File
, 1, Scope
, BaseType
, 3, 3,
1924 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1926 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1927 "something", File
, 1, Scope
, BaseType
, 2, 2,
1928 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1930 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1931 "something", File
, 1, Scope
, BaseType
, 2, 3,
1932 5, DWARFAddressSpace
, std::nullopt
, Flags5
,
1934 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1935 "something", File
, 1, Scope
, BaseType
, 2, 3,
1936 4, DWARFAddressSpace
+ 1, std::nullopt
,
1937 Flags5
, ExtraData
));
1939 DIDerivedType::get(Context
, dwarf::DW_TAG_LLVM_ptrauth_type
, "",
1940 File
, 1, Scope
, N
, 2, 3, 4, DWARFAddressSpace
,
1941 std::nullopt
, Flags5
, ExtraData
));
1942 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1943 "something", File
, 1, Scope
, BaseType
, 2, 3,
1944 4, DWARFAddressSpace
, std::nullopt
, Flags4
,
1946 EXPECT_NE(N
, DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
,
1947 "something", File
, 1, Scope
, BaseType
, 2, 3,
1948 4, DWARFAddressSpace
, std::nullopt
, Flags5
,
1951 TempDIDerivedType Temp
= N
->clone();
1952 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
1953 TempDIDerivedType Temp1
= N1
->clone();
1954 EXPECT_EQ(N1
, MDNode::replaceWithUniqued(std::move(Temp1
)));
1957 TEST_F(DIDerivedTypeTest
, getWithLargeValues
) {
1958 DIFile
*File
= getFile();
1959 DIScope
*Scope
= getSubprogram();
1960 DIType
*BaseType
= getBasicType("basic");
1961 MDTuple
*ExtraData
= getTuple();
1962 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(5);
1964 auto *N
= DIDerivedType::get(Context
, dwarf::DW_TAG_pointer_type
, "something",
1965 File
, 1, Scope
, BaseType
, UINT64_MAX
,
1966 UINT32_MAX
- 1, UINT64_MAX
- 2, UINT32_MAX
- 3,
1967 std::nullopt
, Flags
, ExtraData
);
1968 EXPECT_EQ(UINT64_MAX
, N
->getSizeInBits());
1969 EXPECT_EQ(UINT32_MAX
- 1, N
->getAlignInBits());
1970 EXPECT_EQ(UINT64_MAX
- 2, N
->getOffsetInBits());
1971 EXPECT_EQ(UINT32_MAX
- 3, *N
->getDWARFAddressSpace());
1973 auto *N1
= DIDerivedType::get(
1974 Context
, dwarf::DW_TAG_LLVM_ptrauth_type
, "", File
, 1, Scope
, N
,
1975 UINT64_MAX
, UINT32_MAX
- 1, UINT64_MAX
- 2, UINT32_MAX
- 3,
1976 DIDerivedType::PtrAuthData(7, true, 0xffff, true, false), Flags
,
1978 EXPECT_EQ(7U, N1
->getPtrAuthData()->key());
1979 EXPECT_EQ(true, N1
->getPtrAuthData()->isAddressDiscriminated());
1980 EXPECT_EQ(0xffffU
, N1
->getPtrAuthData()->extraDiscriminator());
1983 typedef MetadataTest DICompositeTypeTest
;
1985 TEST_F(DICompositeTypeTest
, get
) {
1986 unsigned Tag
= dwarf::DW_TAG_structure_type
;
1987 StringRef Name
= "some name";
1988 DIFile
*File
= getFile();
1990 DIScope
*Scope
= getSubprogram();
1991 DIType
*BaseType
= getCompositeType();
1992 uint64_t SizeInBits
= 2;
1993 uint32_t AlignInBits
= 3;
1994 uint64_t OffsetInBits
= 4;
1995 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(5);
1996 MDTuple
*Elements
= getTuple();
1997 unsigned RuntimeLang
= 6;
1998 DIType
*VTableHolder
= getCompositeType();
1999 MDTuple
*TemplateParams
= getTuple();
2000 StringRef Identifier
= "some id";
2002 auto *N
= DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2003 BaseType
, SizeInBits
, AlignInBits
,
2004 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2005 VTableHolder
, TemplateParams
, Identifier
);
2006 EXPECT_EQ(Tag
, N
->getTag());
2007 EXPECT_EQ(Name
, N
->getName());
2008 EXPECT_EQ(File
, N
->getFile());
2009 EXPECT_EQ(Line
, N
->getLine());
2010 EXPECT_EQ(Scope
, N
->getScope());
2011 EXPECT_EQ(BaseType
, N
->getBaseType());
2012 EXPECT_EQ(SizeInBits
, N
->getSizeInBits());
2013 EXPECT_EQ(AlignInBits
, N
->getAlignInBits());
2014 EXPECT_EQ(OffsetInBits
, N
->getOffsetInBits());
2015 EXPECT_EQ(Flags
, N
->getFlags());
2016 EXPECT_EQ(Elements
, N
->getElements().get());
2017 EXPECT_EQ(RuntimeLang
, N
->getRuntimeLang());
2018 EXPECT_EQ(VTableHolder
, N
->getVTableHolder());
2019 EXPECT_EQ(TemplateParams
, N
->getTemplateParams().get());
2020 EXPECT_EQ(Identifier
, N
->getIdentifier());
2022 EXPECT_EQ(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2023 BaseType
, SizeInBits
, AlignInBits
,
2024 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2025 VTableHolder
, TemplateParams
, Identifier
));
2027 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
+ 1, Name
, File
, Line
, Scope
,
2028 BaseType
, SizeInBits
, AlignInBits
,
2029 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2030 VTableHolder
, TemplateParams
, Identifier
));
2031 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, "abc", File
, Line
, Scope
,
2032 BaseType
, SizeInBits
, AlignInBits
,
2033 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2034 VTableHolder
, TemplateParams
, Identifier
));
2035 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, getFile(), Line
, Scope
,
2036 BaseType
, SizeInBits
, AlignInBits
,
2037 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2038 VTableHolder
, TemplateParams
, Identifier
));
2039 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
+ 1, Scope
,
2040 BaseType
, SizeInBits
, AlignInBits
,
2041 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2042 VTableHolder
, TemplateParams
, Identifier
));
2043 EXPECT_NE(N
, DICompositeType::get(
2044 Context
, Tag
, Name
, File
, Line
, getSubprogram(), BaseType
,
2045 SizeInBits
, AlignInBits
, OffsetInBits
, Flags
, Elements
,
2046 RuntimeLang
, VTableHolder
, TemplateParams
, Identifier
));
2047 EXPECT_NE(N
, DICompositeType::get(
2048 Context
, Tag
, Name
, File
, Line
, Scope
, getBasicType("other"),
2049 SizeInBits
, AlignInBits
, OffsetInBits
, Flags
, Elements
,
2050 RuntimeLang
, VTableHolder
, TemplateParams
, Identifier
));
2051 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2052 BaseType
, SizeInBits
+ 1, AlignInBits
,
2053 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2054 VTableHolder
, TemplateParams
, Identifier
));
2055 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2056 BaseType
, SizeInBits
, AlignInBits
+ 1,
2057 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2058 VTableHolder
, TemplateParams
, Identifier
));
2059 EXPECT_NE(N
, DICompositeType::get(
2060 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
,
2061 AlignInBits
, OffsetInBits
+ 1, Flags
, Elements
, RuntimeLang
,
2062 VTableHolder
, TemplateParams
, Identifier
));
2063 DINode::DIFlags FlagsPOne
= static_cast<DINode::DIFlags
>(Flags
+ 1);
2064 EXPECT_NE(N
, DICompositeType::get(
2065 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
,
2066 AlignInBits
, OffsetInBits
, FlagsPOne
, Elements
, RuntimeLang
,
2067 VTableHolder
, TemplateParams
, Identifier
));
2068 EXPECT_NE(N
, DICompositeType::get(
2069 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
,
2070 AlignInBits
, OffsetInBits
, Flags
, getTuple(), RuntimeLang
,
2071 VTableHolder
, TemplateParams
, Identifier
));
2072 EXPECT_NE(N
, DICompositeType::get(
2073 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
,
2074 AlignInBits
, OffsetInBits
, Flags
, Elements
, RuntimeLang
+ 1,
2075 VTableHolder
, TemplateParams
, Identifier
));
2076 EXPECT_NE(N
, DICompositeType::get(
2077 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
,
2078 AlignInBits
, OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2079 getCompositeType(), TemplateParams
, Identifier
));
2080 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2081 BaseType
, SizeInBits
, AlignInBits
,
2082 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2083 VTableHolder
, getTuple(), Identifier
));
2084 EXPECT_NE(N
, DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2085 BaseType
, SizeInBits
, AlignInBits
,
2086 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2087 VTableHolder
, TemplateParams
, "other"));
2089 // Be sure that missing identifiers get null pointers.
2090 EXPECT_FALSE(DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2091 BaseType
, SizeInBits
, AlignInBits
,
2092 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2093 VTableHolder
, TemplateParams
, "")
2094 ->getRawIdentifier());
2095 EXPECT_FALSE(DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2096 BaseType
, SizeInBits
, AlignInBits
,
2097 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2098 VTableHolder
, TemplateParams
)
2099 ->getRawIdentifier());
2101 TempDICompositeType Temp
= N
->clone();
2102 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2105 TEST_F(DICompositeTypeTest
, getWithLargeValues
) {
2106 unsigned Tag
= dwarf::DW_TAG_structure_type
;
2107 StringRef Name
= "some name";
2108 DIFile
*File
= getFile();
2110 DIScope
*Scope
= getSubprogram();
2111 DIType
*BaseType
= getCompositeType();
2112 uint64_t SizeInBits
= UINT64_MAX
;
2113 uint32_t AlignInBits
= UINT32_MAX
- 1;
2114 uint64_t OffsetInBits
= UINT64_MAX
- 2;
2115 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(5);
2116 MDTuple
*Elements
= getTuple();
2117 unsigned RuntimeLang
= 6;
2118 DIType
*VTableHolder
= getCompositeType();
2119 MDTuple
*TemplateParams
= getTuple();
2120 StringRef Identifier
= "some id";
2122 auto *N
= DICompositeType::get(Context
, Tag
, Name
, File
, Line
, Scope
,
2123 BaseType
, SizeInBits
, AlignInBits
,
2124 OffsetInBits
, Flags
, Elements
, RuntimeLang
,
2125 VTableHolder
, TemplateParams
, Identifier
);
2126 EXPECT_EQ(SizeInBits
, N
->getSizeInBits());
2127 EXPECT_EQ(AlignInBits
, N
->getAlignInBits());
2128 EXPECT_EQ(OffsetInBits
, N
->getOffsetInBits());
2131 TEST_F(DICompositeTypeTest
, replaceOperands
) {
2132 unsigned Tag
= dwarf::DW_TAG_structure_type
;
2133 StringRef Name
= "some name";
2134 DIFile
*File
= getFile();
2136 DIScope
*Scope
= getSubprogram();
2137 DIType
*BaseType
= getCompositeType();
2138 uint64_t SizeInBits
= 2;
2139 uint32_t AlignInBits
= 3;
2140 uint64_t OffsetInBits
= 4;
2141 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(5);
2142 unsigned RuntimeLang
= 6;
2143 StringRef Identifier
= "some id";
2145 auto *N
= DICompositeType::get(
2146 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2147 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
);
2149 auto *Elements
= MDTuple::getDistinct(Context
, std::nullopt
);
2150 EXPECT_EQ(nullptr, N
->getElements().get());
2151 N
->replaceElements(Elements
);
2152 EXPECT_EQ(Elements
, N
->getElements().get());
2153 N
->replaceElements(nullptr);
2154 EXPECT_EQ(nullptr, N
->getElements().get());
2156 DIType
*VTableHolder
= getCompositeType();
2157 EXPECT_EQ(nullptr, N
->getVTableHolder());
2158 N
->replaceVTableHolder(VTableHolder
);
2159 EXPECT_EQ(VTableHolder
, N
->getVTableHolder());
2160 // As an extension, the containing type can be anything. This is
2161 // used by Rust to associate vtables with their concrete type.
2162 DIType
*BasicType
= getBasicType("basic");
2163 N
->replaceVTableHolder(BasicType
);
2164 EXPECT_EQ(BasicType
, N
->getVTableHolder());
2165 N
->replaceVTableHolder(nullptr);
2166 EXPECT_EQ(nullptr, N
->getVTableHolder());
2168 auto *TemplateParams
= MDTuple::getDistinct(Context
, std::nullopt
);
2169 EXPECT_EQ(nullptr, N
->getTemplateParams().get());
2170 N
->replaceTemplateParams(TemplateParams
);
2171 EXPECT_EQ(TemplateParams
, N
->getTemplateParams().get());
2172 N
->replaceTemplateParams(nullptr);
2173 EXPECT_EQ(nullptr, N
->getTemplateParams().get());
2176 TEST_F(DICompositeTypeTest
, variant_part
) {
2177 unsigned Tag
= dwarf::DW_TAG_variant_part
;
2178 StringRef Name
= "some name";
2179 DIFile
*File
= getFile();
2181 DIScope
*Scope
= getSubprogram();
2182 DIType
*BaseType
= getCompositeType();
2183 uint64_t SizeInBits
= 2;
2184 uint32_t AlignInBits
= 3;
2185 uint64_t OffsetInBits
= 4;
2186 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(5);
2187 unsigned RuntimeLang
= 6;
2188 StringRef Identifier
= "some id";
2189 DIDerivedType
*Discriminator
= cast
<DIDerivedType
>(getDerivedType());
2190 DIDerivedType
*Discriminator2
= cast
<DIDerivedType
>(getDerivedType());
2192 EXPECT_NE(Discriminator
, Discriminator2
);
2194 auto *N
= DICompositeType::get(
2195 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2196 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2199 // Test the hashing.
2200 auto *Same
= DICompositeType::get(
2201 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2202 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2204 auto *Other
= DICompositeType::get(
2205 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2206 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2208 auto *NoDisc
= DICompositeType::get(
2209 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2210 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2214 EXPECT_NE(Same
, Other
);
2215 EXPECT_NE(Same
, NoDisc
);
2216 EXPECT_NE(Other
, NoDisc
);
2218 EXPECT_EQ(N
->getDiscriminator(), Discriminator
);
2221 TEST_F(DICompositeTypeTest
, dynamicArray
) {
2222 unsigned Tag
= dwarf::DW_TAG_array_type
;
2223 StringRef Name
= "some name";
2224 DIFile
*File
= getFile();
2226 DILocalScope
*Scope
= getSubprogram();
2227 DIType
*BaseType
= getCompositeType();
2228 uint64_t SizeInBits
= 32;
2229 uint32_t AlignInBits
= 32;
2230 uint64_t OffsetInBits
= 4;
2231 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(3);
2232 unsigned RuntimeLang
= 6;
2233 StringRef Identifier
= "some id";
2234 DIType
*Type
= getDerivedType();
2235 Metadata
*DlVar1
= DILocalVariable::get(Context
, Scope
, "dl_var1", File
, 8,
2236 Type
, 2, Flags
, 8, nullptr);
2237 Metadata
*DlVar2
= DILocalVariable::get(Context
, Scope
, "dl_var2", File
, 8,
2238 Type
, 2, Flags
, 8, nullptr);
2239 uint64_t Elements1
[] = {dwarf::DW_OP_push_object_address
, dwarf::DW_OP_deref
};
2240 Metadata
*DataLocation1
= DIExpression::get(Context
, Elements1
);
2242 uint64_t Elements2
[] = {dwarf::DW_OP_constu
, 0};
2243 Metadata
*DataLocation2
= DIExpression::get(Context
, Elements2
);
2245 uint64_t Elements3
[] = {dwarf::DW_OP_constu
, 3};
2246 Metadata
*Rank1
= DIExpression::get(Context
, Elements3
);
2248 uint64_t Elements4
[] = {dwarf::DW_OP_constu
, 4};
2249 Metadata
*Rank2
= DIExpression::get(Context
, Elements4
);
2251 ConstantInt
*RankInt1
= ConstantInt::get(Context
, APInt(7, 0));
2252 ConstantAsMetadata
*RankConst1
= ConstantAsMetadata::get(RankInt1
);
2253 ConstantInt
*RankInt2
= ConstantInt::get(Context
, APInt(6, 0));
2254 ConstantAsMetadata
*RankConst2
= ConstantAsMetadata::get(RankInt2
);
2255 auto *N1
= DICompositeType::get(
2256 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2257 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2260 auto *Same1
= DICompositeType::get(
2261 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2262 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2265 auto *Other1
= DICompositeType::get(
2266 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2267 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2270 EXPECT_EQ(N1
, Same1
);
2271 EXPECT_NE(Same1
, Other1
);
2272 EXPECT_EQ(N1
->getDataLocation(), DlVar1
);
2274 auto *N2
= DICompositeType::get(
2275 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2276 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2277 nullptr, DataLocation1
);
2279 auto *Same2
= DICompositeType::get(
2280 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2281 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2282 nullptr, DataLocation1
);
2284 auto *Other2
= DICompositeType::get(
2285 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2286 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2287 nullptr, DataLocation2
);
2289 EXPECT_EQ(N2
, Same2
);
2290 EXPECT_NE(Same2
, Other2
);
2291 EXPECT_EQ(N2
->getDataLocationExp(), DataLocation1
);
2293 auto *N3
= DICompositeType::get(
2294 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2295 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2296 nullptr, DataLocation1
, nullptr, nullptr, Rank1
);
2298 auto *Same3
= DICompositeType::get(
2299 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2300 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2301 nullptr, DataLocation1
, nullptr, nullptr, Rank1
);
2303 auto *Other3
= DICompositeType::get(
2304 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2305 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2306 nullptr, DataLocation1
, nullptr, nullptr, Rank2
);
2308 EXPECT_EQ(N3
, Same3
);
2309 EXPECT_NE(Same3
, Other3
);
2310 EXPECT_EQ(N3
->getRankExp(), Rank1
);
2312 auto *N4
= DICompositeType::get(
2313 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2314 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2315 nullptr, DataLocation1
, nullptr, nullptr, RankConst1
);
2317 auto *Same4
= DICompositeType::get(
2318 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2319 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2320 nullptr, DataLocation1
, nullptr, nullptr, RankConst1
);
2322 auto *Other4
= DICompositeType::get(
2323 Context
, Tag
, Name
, File
, Line
, Scope
, BaseType
, SizeInBits
, AlignInBits
,
2324 OffsetInBits
, Flags
, nullptr, RuntimeLang
, nullptr, nullptr, Identifier
,
2325 nullptr, DataLocation1
, nullptr, nullptr, RankConst2
);
2327 EXPECT_EQ(N4
, Same4
);
2328 EXPECT_NE(Same4
, Other4
);
2329 EXPECT_EQ(N4
->getRankConst(), RankInt1
);
2332 typedef MetadataTest DISubroutineTypeTest
;
2334 TEST_F(DISubroutineTypeTest
, get
) {
2335 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(1);
2336 DINode::DIFlags FlagsPOne
= static_cast<DINode::DIFlags
>(Flags
+ 1);
2337 MDTuple
*TypeArray
= getTuple();
2339 auto *N
= DISubroutineType::get(Context
, Flags
, 0, TypeArray
);
2340 EXPECT_EQ(dwarf::DW_TAG_subroutine_type
, N
->getTag());
2341 EXPECT_EQ(Flags
, N
->getFlags());
2342 EXPECT_EQ(TypeArray
, N
->getTypeArray().get());
2343 EXPECT_EQ(N
, DISubroutineType::get(Context
, Flags
, 0, TypeArray
));
2345 EXPECT_NE(N
, DISubroutineType::get(Context
, FlagsPOne
, 0, TypeArray
));
2346 EXPECT_NE(N
, DISubroutineType::get(Context
, Flags
, 0, getTuple()));
2348 // Test the hashing of calling conventions.
2349 auto *Fast
= DISubroutineType::get(
2350 Context
, Flags
, dwarf::DW_CC_BORLAND_msfastcall
, TypeArray
);
2351 auto *Std
= DISubroutineType::get(Context
, Flags
,
2352 dwarf::DW_CC_BORLAND_stdcall
, TypeArray
);
2354 DISubroutineType::get(Context
, Flags
,
2355 dwarf::DW_CC_BORLAND_msfastcall
, TypeArray
));
2356 EXPECT_EQ(Std
, DISubroutineType::get(
2357 Context
, Flags
, dwarf::DW_CC_BORLAND_stdcall
, TypeArray
));
2361 EXPECT_NE(Fast
, Std
);
2363 TempDISubroutineType Temp
= N
->clone();
2364 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2366 // Test always-empty operands.
2367 EXPECT_EQ(nullptr, N
->getScope());
2368 EXPECT_EQ(nullptr, N
->getFile());
2369 EXPECT_EQ("", N
->getName());
2372 typedef MetadataTest DIFileTest
;
2374 TEST_F(DIFileTest
, get
) {
2375 StringRef Filename
= "file";
2376 StringRef Directory
= "dir";
2377 DIFile::ChecksumKind CSKind
= DIFile::ChecksumKind::CSK_MD5
;
2378 StringRef ChecksumString
= "000102030405060708090a0b0c0d0e0f";
2379 DIFile::ChecksumInfo
<StringRef
> Checksum(CSKind
, ChecksumString
);
2380 StringRef Source
= "source";
2381 auto *N
= DIFile::get(Context
, Filename
, Directory
, Checksum
, Source
);
2383 EXPECT_EQ(dwarf::DW_TAG_file_type
, N
->getTag());
2384 EXPECT_EQ(Filename
, N
->getFilename());
2385 EXPECT_EQ(Directory
, N
->getDirectory());
2386 EXPECT_EQ(Checksum
, N
->getChecksum());
2387 EXPECT_EQ(Source
, N
->getSource());
2388 EXPECT_EQ(N
, DIFile::get(Context
, Filename
, Directory
, Checksum
, Source
));
2390 EXPECT_NE(N
, DIFile::get(Context
, "other", Directory
, Checksum
, Source
));
2391 EXPECT_NE(N
, DIFile::get(Context
, Filename
, "other", Checksum
, Source
));
2392 DIFile::ChecksumInfo
<StringRef
> OtherChecksum(DIFile::ChecksumKind::CSK_SHA1
, ChecksumString
);
2394 N
, DIFile::get(Context
, Filename
, Directory
, OtherChecksum
));
2395 StringRef OtherSource
= "other";
2396 EXPECT_NE(N
, DIFile::get(Context
, Filename
, Directory
, Checksum
, OtherSource
));
2397 EXPECT_NE(N
, DIFile::get(Context
, Filename
, Directory
, Checksum
));
2398 EXPECT_NE(N
, DIFile::get(Context
, Filename
, Directory
));
2400 TempDIFile Temp
= N
->clone();
2401 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2404 TEST_F(DIFileTest
, EmptySource
) {
2405 DIFile
*N
= DIFile::get(Context
, "file", "dir");
2406 EXPECT_EQ(std::nullopt
, N
->getSource());
2408 std::optional
<DIFile::ChecksumInfo
<StringRef
>> Checksum
;
2409 std::optional
<StringRef
> Source
;
2410 N
= DIFile::get(Context
, "file", "dir", Checksum
, Source
);
2411 EXPECT_EQ(Source
, N
->getSource());
2414 N
= DIFile::get(Context
, "file", "dir", Checksum
, Source
);
2415 EXPECT_EQ(Source
, N
->getSource());
2418 TEST_F(DIFileTest
, ScopeGetFile
) {
2419 // Ensure that DIScope::getFile() returns itself.
2420 DIScope
*N
= DIFile::get(Context
, "file", "dir");
2421 EXPECT_EQ(N
, N
->getFile());
2424 typedef MetadataTest DICompileUnitTest
;
2426 TEST_F(DICompileUnitTest
, get
) {
2427 unsigned SourceLanguage
= 1;
2428 DIFile
*File
= getFile();
2429 StringRef Producer
= "some producer";
2430 bool IsOptimized
= false;
2431 StringRef Flags
= "flag after flag";
2432 unsigned RuntimeVersion
= 2;
2433 StringRef SplitDebugFilename
= "another/file";
2434 auto EmissionKind
= DICompileUnit::FullDebug
;
2435 MDTuple
*EnumTypes
= getTuple();
2436 MDTuple
*RetainedTypes
= getTuple();
2437 MDTuple
*GlobalVariables
= getTuple();
2438 MDTuple
*ImportedEntities
= getTuple();
2439 uint64_t DWOId
= 0x10000000c0ffee;
2440 MDTuple
*Macros
= getTuple();
2441 StringRef SysRoot
= "/";
2442 StringRef SDK
= "MacOSX.sdk";
2443 auto *N
= DICompileUnit::getDistinct(
2444 Context
, SourceLanguage
, File
, Producer
, IsOptimized
, Flags
,
2445 RuntimeVersion
, SplitDebugFilename
, EmissionKind
, EnumTypes
,
2446 RetainedTypes
, GlobalVariables
, ImportedEntities
, Macros
, DWOId
, true,
2447 false, DICompileUnit::DebugNameTableKind::Default
, false, SysRoot
, SDK
);
2449 EXPECT_EQ(dwarf::DW_TAG_compile_unit
, N
->getTag());
2450 EXPECT_EQ(SourceLanguage
, N
->getSourceLanguage());
2451 EXPECT_EQ(File
, N
->getFile());
2452 EXPECT_EQ(Producer
, N
->getProducer());
2453 EXPECT_EQ(IsOptimized
, N
->isOptimized());
2454 EXPECT_EQ(Flags
, N
->getFlags());
2455 EXPECT_EQ(RuntimeVersion
, N
->getRuntimeVersion());
2456 EXPECT_EQ(SplitDebugFilename
, N
->getSplitDebugFilename());
2457 EXPECT_EQ(EmissionKind
, N
->getEmissionKind());
2458 EXPECT_EQ(EnumTypes
, N
->getEnumTypes().get());
2459 EXPECT_EQ(RetainedTypes
, N
->getRetainedTypes().get());
2460 EXPECT_EQ(GlobalVariables
, N
->getGlobalVariables().get());
2461 EXPECT_EQ(ImportedEntities
, N
->getImportedEntities().get());
2462 EXPECT_EQ(Macros
, N
->getMacros().get());
2463 EXPECT_EQ(DWOId
, N
->getDWOId());
2464 EXPECT_EQ(SysRoot
, N
->getSysRoot());
2465 EXPECT_EQ(SDK
, N
->getSDK());
2467 TempDICompileUnit Temp
= N
->clone();
2468 EXPECT_EQ(dwarf::DW_TAG_compile_unit
, Temp
->getTag());
2469 EXPECT_EQ(SourceLanguage
, Temp
->getSourceLanguage());
2470 EXPECT_EQ(File
, Temp
->getFile());
2471 EXPECT_EQ(Producer
, Temp
->getProducer());
2472 EXPECT_EQ(IsOptimized
, Temp
->isOptimized());
2473 EXPECT_EQ(Flags
, Temp
->getFlags());
2474 EXPECT_EQ(RuntimeVersion
, Temp
->getRuntimeVersion());
2475 EXPECT_EQ(SplitDebugFilename
, Temp
->getSplitDebugFilename());
2476 EXPECT_EQ(EmissionKind
, Temp
->getEmissionKind());
2477 EXPECT_EQ(EnumTypes
, Temp
->getEnumTypes().get());
2478 EXPECT_EQ(RetainedTypes
, Temp
->getRetainedTypes().get());
2479 EXPECT_EQ(GlobalVariables
, Temp
->getGlobalVariables().get());
2480 EXPECT_EQ(ImportedEntities
, Temp
->getImportedEntities().get());
2481 EXPECT_EQ(Macros
, Temp
->getMacros().get());
2482 EXPECT_EQ(SysRoot
, Temp
->getSysRoot());
2483 EXPECT_EQ(SDK
, Temp
->getSDK());
2485 auto *TempAddress
= Temp
.get();
2486 auto *Clone
= MDNode::replaceWithPermanent(std::move(Temp
));
2487 EXPECT_TRUE(Clone
->isDistinct());
2488 EXPECT_EQ(TempAddress
, Clone
);
2491 TEST_F(DICompileUnitTest
, replaceArrays
) {
2492 unsigned SourceLanguage
= 1;
2493 DIFile
*File
= getFile();
2494 StringRef Producer
= "some producer";
2495 bool IsOptimized
= false;
2496 StringRef Flags
= "flag after flag";
2497 unsigned RuntimeVersion
= 2;
2498 StringRef SplitDebugFilename
= "another/file";
2499 auto EmissionKind
= DICompileUnit::FullDebug
;
2500 MDTuple
*EnumTypes
= MDTuple::getDistinct(Context
, std::nullopt
);
2501 MDTuple
*RetainedTypes
= MDTuple::getDistinct(Context
, std::nullopt
);
2502 MDTuple
*ImportedEntities
= MDTuple::getDistinct(Context
, std::nullopt
);
2503 uint64_t DWOId
= 0xc0ffee;
2504 StringRef SysRoot
= "/";
2505 StringRef SDK
= "MacOSX.sdk";
2506 auto *N
= DICompileUnit::getDistinct(
2507 Context
, SourceLanguage
, File
, Producer
, IsOptimized
, Flags
,
2508 RuntimeVersion
, SplitDebugFilename
, EmissionKind
, EnumTypes
,
2509 RetainedTypes
, nullptr, ImportedEntities
, nullptr, DWOId
, true, false,
2510 DICompileUnit::DebugNameTableKind::Default
, false, SysRoot
, SDK
);
2512 auto *GlobalVariables
= MDTuple::getDistinct(Context
, std::nullopt
);
2513 EXPECT_EQ(nullptr, N
->getGlobalVariables().get());
2514 N
->replaceGlobalVariables(GlobalVariables
);
2515 EXPECT_EQ(GlobalVariables
, N
->getGlobalVariables().get());
2516 N
->replaceGlobalVariables(nullptr);
2517 EXPECT_EQ(nullptr, N
->getGlobalVariables().get());
2519 auto *Macros
= MDTuple::getDistinct(Context
, std::nullopt
);
2520 EXPECT_EQ(nullptr, N
->getMacros().get());
2521 N
->replaceMacros(Macros
);
2522 EXPECT_EQ(Macros
, N
->getMacros().get());
2523 N
->replaceMacros(nullptr);
2524 EXPECT_EQ(nullptr, N
->getMacros().get());
2527 typedef MetadataTest DISubprogramTest
;
2529 TEST_F(DISubprogramTest
, get
) {
2530 DIScope
*Scope
= getCompositeType();
2531 StringRef Name
= "name";
2532 StringRef LinkageName
= "linkage";
2533 DIFile
*File
= getFile();
2535 DISubroutineType
*Type
= getSubroutineType();
2536 bool IsLocalToUnit
= false;
2537 bool IsDefinition
= true;
2538 unsigned ScopeLine
= 3;
2539 DIType
*ContainingType
= getCompositeType();
2540 unsigned Virtuality
= 2;
2541 unsigned VirtualIndex
= 5;
2542 int ThisAdjustment
= -3;
2543 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(6);
2544 bool IsOptimized
= false;
2545 MDTuple
*TemplateParams
= getTuple();
2546 DISubprogram
*Declaration
= getSubprogram();
2547 MDTuple
*RetainedNodes
= getTuple();
2548 MDTuple
*ThrownTypes
= getTuple();
2549 MDTuple
*Annotations
= getTuple();
2550 StringRef TargetFuncName
= "target";
2551 DICompileUnit
*Unit
= getUnit();
2552 DISubprogram::DISPFlags SPFlags
=
2553 static_cast<DISubprogram::DISPFlags
>(Virtuality
);
2554 assert(!IsLocalToUnit
&& IsDefinition
&& !IsOptimized
&&
2555 "bools and SPFlags have to match");
2556 SPFlags
|= DISubprogram::SPFlagDefinition
;
2558 auto *N
= DISubprogram::get(
2559 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
, ScopeLine
,
2560 ContainingType
, VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
, Unit
,
2561 TemplateParams
, Declaration
, RetainedNodes
, ThrownTypes
, Annotations
,
2564 EXPECT_EQ(dwarf::DW_TAG_subprogram
, N
->getTag());
2565 EXPECT_EQ(Scope
, N
->getScope());
2566 EXPECT_EQ(Name
, N
->getName());
2567 EXPECT_EQ(LinkageName
, N
->getLinkageName());
2568 EXPECT_EQ(File
, N
->getFile());
2569 EXPECT_EQ(Line
, N
->getLine());
2570 EXPECT_EQ(Type
, N
->getType());
2571 EXPECT_EQ(IsLocalToUnit
, N
->isLocalToUnit());
2572 EXPECT_EQ(IsDefinition
, N
->isDefinition());
2573 EXPECT_EQ(ScopeLine
, N
->getScopeLine());
2574 EXPECT_EQ(ContainingType
, N
->getContainingType());
2575 EXPECT_EQ(Virtuality
, N
->getVirtuality());
2576 EXPECT_EQ(VirtualIndex
, N
->getVirtualIndex());
2577 EXPECT_EQ(ThisAdjustment
, N
->getThisAdjustment());
2578 EXPECT_EQ(Flags
, N
->getFlags());
2579 EXPECT_EQ(IsOptimized
, N
->isOptimized());
2580 EXPECT_EQ(Unit
, N
->getUnit());
2581 EXPECT_EQ(TemplateParams
, N
->getTemplateParams().get());
2582 EXPECT_EQ(Declaration
, N
->getDeclaration());
2583 EXPECT_EQ(RetainedNodes
, N
->getRetainedNodes().get());
2584 EXPECT_EQ(ThrownTypes
, N
->getThrownTypes().get());
2585 EXPECT_EQ(Annotations
, N
->getAnnotations().get());
2586 EXPECT_EQ(TargetFuncName
, N
->getTargetFuncName());
2587 EXPECT_EQ(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2588 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2589 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2590 TemplateParams
, Declaration
, RetainedNodes
,
2591 ThrownTypes
, Annotations
, TargetFuncName
));
2593 EXPECT_NE(N
, DISubprogram::get(Context
, getCompositeType(), Name
, LinkageName
,
2594 File
, Line
, Type
, ScopeLine
, ContainingType
,
2595 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2596 Unit
, TemplateParams
, Declaration
,
2597 RetainedNodes
, ThrownTypes
, Annotations
,
2599 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, "other", LinkageName
, File
,
2600 Line
, Type
, ScopeLine
, ContainingType
,
2601 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2602 Unit
, TemplateParams
, Declaration
,
2603 RetainedNodes
, ThrownTypes
, Annotations
,
2605 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, "other", File
, Line
,
2606 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2607 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2608 TemplateParams
, Declaration
, RetainedNodes
,
2609 ThrownTypes
, Annotations
, TargetFuncName
));
2610 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, getFile(),
2611 Line
, Type
, ScopeLine
, ContainingType
,
2612 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2613 Unit
, TemplateParams
, Declaration
,
2614 RetainedNodes
, ThrownTypes
, Annotations
,
2616 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
,
2617 Line
+ 1, Type
, ScopeLine
, ContainingType
,
2618 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2619 Unit
, TemplateParams
, Declaration
,
2620 RetainedNodes
, ThrownTypes
, Annotations
,
2622 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2623 getSubroutineType(), ScopeLine
, ContainingType
,
2624 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2625 Unit
, TemplateParams
, Declaration
,
2626 RetainedNodes
, ThrownTypes
, Annotations
,
2628 EXPECT_NE(N
, DISubprogram::get(
2629 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
,
2630 ScopeLine
, ContainingType
, VirtualIndex
, ThisAdjustment
,
2631 Flags
, SPFlags
^ DISubprogram::SPFlagLocalToUnit
, Unit
,
2632 TemplateParams
, Declaration
, RetainedNodes
, ThrownTypes
,
2633 Annotations
, TargetFuncName
));
2634 EXPECT_NE(N
, DISubprogram::get(
2635 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
,
2636 ScopeLine
, ContainingType
, VirtualIndex
, ThisAdjustment
,
2637 Flags
, SPFlags
^ DISubprogram::SPFlagDefinition
, Unit
,
2638 TemplateParams
, Declaration
, RetainedNodes
, ThrownTypes
,
2639 Annotations
, TargetFuncName
));
2640 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2641 Type
, ScopeLine
+ 1, ContainingType
,
2642 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2643 Unit
, TemplateParams
, Declaration
,
2644 RetainedNodes
, ThrownTypes
, Annotations
,
2646 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2647 Type
, ScopeLine
, getCompositeType(),
2648 VirtualIndex
, ThisAdjustment
, Flags
, SPFlags
,
2649 Unit
, TemplateParams
, Declaration
,
2650 RetainedNodes
, ThrownTypes
, Annotations
,
2652 EXPECT_NE(N
, DISubprogram::get(
2653 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
,
2654 ScopeLine
, ContainingType
, VirtualIndex
, ThisAdjustment
,
2655 Flags
, SPFlags
^ DISubprogram::SPFlagVirtual
, Unit
,
2656 TemplateParams
, Declaration
, RetainedNodes
, ThrownTypes
,
2657 Annotations
, TargetFuncName
));
2658 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2659 Type
, ScopeLine
, ContainingType
,
2660 VirtualIndex
+ 1, ThisAdjustment
, Flags
,
2661 SPFlags
, Unit
, TemplateParams
, Declaration
,
2662 RetainedNodes
, ThrownTypes
, Annotations
,
2664 EXPECT_NE(N
, DISubprogram::get(
2665 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
,
2666 ScopeLine
, ContainingType
, VirtualIndex
, ThisAdjustment
,
2667 Flags
, SPFlags
^ DISubprogram::SPFlagOptimized
, Unit
,
2668 TemplateParams
, Declaration
, RetainedNodes
, ThrownTypes
,
2669 Annotations
, TargetFuncName
));
2670 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2671 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2672 ThisAdjustment
, Flags
, SPFlags
, nullptr,
2673 TemplateParams
, Declaration
, RetainedNodes
,
2674 ThrownTypes
, Annotations
, TargetFuncName
));
2676 DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2677 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2678 ThisAdjustment
, Flags
, SPFlags
, Unit
, getTuple(),
2679 Declaration
, RetainedNodes
, ThrownTypes
,
2680 Annotations
, TargetFuncName
));
2681 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2682 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2683 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2684 TemplateParams
, getSubprogram(), RetainedNodes
,
2685 ThrownTypes
, Annotations
, TargetFuncName
));
2686 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2687 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2688 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2689 TemplateParams
, Declaration
, getTuple(),
2690 ThrownTypes
, Annotations
, TargetFuncName
));
2691 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2692 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2693 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2694 TemplateParams
, Declaration
, RetainedNodes
,
2695 getTuple(), Annotations
, TargetFuncName
));
2696 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2697 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2698 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2699 TemplateParams
, Declaration
, RetainedNodes
,
2700 ThrownTypes
, getTuple(), TargetFuncName
));
2701 EXPECT_NE(N
, DISubprogram::get(Context
, Scope
, Name
, LinkageName
, File
, Line
,
2702 Type
, ScopeLine
, ContainingType
, VirtualIndex
,
2703 ThisAdjustment
, Flags
, SPFlags
, Unit
,
2704 TemplateParams
, Declaration
, RetainedNodes
,
2705 ThrownTypes
, Annotations
, "other"));
2707 TempDISubprogram Temp
= N
->clone();
2708 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2711 typedef MetadataTest DILexicalBlockTest
;
2713 TEST_F(DILexicalBlockTest
, get
) {
2714 DILocalScope
*Scope
= getSubprogram();
2715 DIFile
*File
= getFile();
2717 unsigned Column
= 8;
2719 auto *N
= DILexicalBlock::get(Context
, Scope
, File
, Line
, Column
);
2721 EXPECT_EQ(dwarf::DW_TAG_lexical_block
, N
->getTag());
2722 EXPECT_EQ(Scope
, N
->getScope());
2723 EXPECT_EQ(File
, N
->getFile());
2724 EXPECT_EQ(Line
, N
->getLine());
2725 EXPECT_EQ(Column
, N
->getColumn());
2726 EXPECT_EQ(N
, DILexicalBlock::get(Context
, Scope
, File
, Line
, Column
));
2729 DILexicalBlock::get(Context
, getSubprogram(), File
, Line
, Column
));
2730 EXPECT_NE(N
, DILexicalBlock::get(Context
, Scope
, getFile(), Line
, Column
));
2731 EXPECT_NE(N
, DILexicalBlock::get(Context
, Scope
, File
, Line
+ 1, Column
));
2732 EXPECT_NE(N
, DILexicalBlock::get(Context
, Scope
, File
, Line
, Column
+ 1));
2734 TempDILexicalBlock Temp
= N
->clone();
2735 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2738 TEST_F(DILexicalBlockTest
, Overflow
) {
2739 DISubprogram
*SP
= getSubprogram();
2740 DIFile
*F
= getFile();
2742 auto *LB
= DILexicalBlock::get(Context
, SP
, F
, 2, 7);
2743 EXPECT_EQ(2u, LB
->getLine());
2744 EXPECT_EQ(7u, LB
->getColumn());
2746 unsigned U16
= 1u << 16;
2748 auto *LB
= DILexicalBlock::get(Context
, SP
, F
, UINT32_MAX
, U16
- 1);
2749 EXPECT_EQ(UINT32_MAX
, LB
->getLine());
2750 EXPECT_EQ(U16
- 1, LB
->getColumn());
2753 auto *LB
= DILexicalBlock::get(Context
, SP
, F
, UINT32_MAX
, U16
);
2754 EXPECT_EQ(UINT32_MAX
, LB
->getLine());
2755 EXPECT_EQ(0u, LB
->getColumn());
2758 auto *LB
= DILexicalBlock::get(Context
, SP
, F
, UINT32_MAX
, U16
+ 1);
2759 EXPECT_EQ(UINT32_MAX
, LB
->getLine());
2760 EXPECT_EQ(0u, LB
->getColumn());
2764 typedef MetadataTest DILexicalBlockFileTest
;
2766 TEST_F(DILexicalBlockFileTest
, get
) {
2767 DILocalScope
*Scope
= getSubprogram();
2768 DIFile
*File
= getFile();
2769 unsigned Discriminator
= 5;
2771 auto *N
= DILexicalBlockFile::get(Context
, Scope
, File
, Discriminator
);
2773 EXPECT_EQ(dwarf::DW_TAG_lexical_block
, N
->getTag());
2774 EXPECT_EQ(Scope
, N
->getScope());
2775 EXPECT_EQ(File
, N
->getFile());
2776 EXPECT_EQ(Discriminator
, N
->getDiscriminator());
2777 EXPECT_EQ(N
, DILexicalBlockFile::get(Context
, Scope
, File
, Discriminator
));
2779 EXPECT_NE(N
, DILexicalBlockFile::get(Context
, getSubprogram(), File
,
2782 DILexicalBlockFile::get(Context
, Scope
, getFile(), Discriminator
));
2784 DILexicalBlockFile::get(Context
, Scope
, File
, Discriminator
+ 1));
2786 TempDILexicalBlockFile Temp
= N
->clone();
2787 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2790 typedef MetadataTest DINamespaceTest
;
2792 TEST_F(DINamespaceTest
, get
) {
2793 DIScope
*Scope
= getFile();
2794 StringRef Name
= "namespace";
2795 bool ExportSymbols
= true;
2797 auto *N
= DINamespace::get(Context
, Scope
, Name
, ExportSymbols
);
2799 EXPECT_EQ(dwarf::DW_TAG_namespace
, N
->getTag());
2800 EXPECT_EQ(Scope
, N
->getScope());
2801 EXPECT_EQ(Name
, N
->getName());
2802 EXPECT_EQ(N
, DINamespace::get(Context
, Scope
, Name
, ExportSymbols
));
2803 EXPECT_NE(N
, DINamespace::get(Context
, getFile(), Name
, ExportSymbols
));
2804 EXPECT_NE(N
, DINamespace::get(Context
, Scope
, "other", ExportSymbols
));
2805 EXPECT_NE(N
, DINamespace::get(Context
, Scope
, Name
, !ExportSymbols
));
2807 TempDINamespace Temp
= N
->clone();
2808 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2811 typedef MetadataTest DIModuleTest
;
2813 TEST_F(DIModuleTest
, get
) {
2814 DIFile
*File
= getFile();
2815 DIScope
*Scope
= getFile();
2816 StringRef Name
= "module";
2817 StringRef ConfigMacro
= "-DNDEBUG";
2818 StringRef Includes
= "-I.";
2819 StringRef APINotes
= "/tmp/m.apinotes";
2820 unsigned LineNo
= 4;
2823 auto *N
= DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, Includes
,
2824 APINotes
, LineNo
, IsDecl
);
2826 EXPECT_EQ(dwarf::DW_TAG_module
, N
->getTag());
2827 EXPECT_EQ(File
, N
->getFile());
2828 EXPECT_EQ(Scope
, N
->getScope());
2829 EXPECT_EQ(Name
, N
->getName());
2830 EXPECT_EQ(ConfigMacro
, N
->getConfigurationMacros());
2831 EXPECT_EQ(Includes
, N
->getIncludePath());
2832 EXPECT_EQ(APINotes
, N
->getAPINotesFile());
2833 EXPECT_EQ(LineNo
, N
->getLineNo());
2834 EXPECT_EQ(IsDecl
, N
->getIsDecl());
2835 EXPECT_EQ(N
, DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, Includes
,
2836 APINotes
, LineNo
, IsDecl
));
2837 EXPECT_NE(N
, DIModule::get(Context
, getFile(), getFile(), Name
, ConfigMacro
,
2838 Includes
, APINotes
, LineNo
, IsDecl
));
2839 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, "other", ConfigMacro
,
2840 Includes
, APINotes
, LineNo
, IsDecl
));
2841 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, Name
, "other", Includes
,
2842 APINotes
, LineNo
, IsDecl
));
2843 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, "other",
2844 APINotes
, LineNo
, IsDecl
));
2845 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, Includes
,
2846 "other", LineNo
, IsDecl
));
2847 EXPECT_NE(N
, DIModule::get(Context
, getFile(), Scope
, Name
, ConfigMacro
,
2848 Includes
, APINotes
, LineNo
, IsDecl
));
2849 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, Includes
,
2850 APINotes
, 5, IsDecl
));
2851 EXPECT_NE(N
, DIModule::get(Context
, File
, Scope
, Name
, ConfigMacro
, Includes
,
2852 APINotes
, LineNo
, false));
2854 TempDIModule Temp
= N
->clone();
2855 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2858 typedef MetadataTest DITemplateTypeParameterTest
;
2860 TEST_F(DITemplateTypeParameterTest
, get
) {
2861 StringRef Name
= "template";
2862 DIType
*Type
= getBasicType("basic");
2863 bool defaulted
= false;
2865 auto *N
= DITemplateTypeParameter::get(Context
, Name
, Type
, defaulted
);
2867 EXPECT_EQ(dwarf::DW_TAG_template_type_parameter
, N
->getTag());
2868 EXPECT_EQ(Name
, N
->getName());
2869 EXPECT_EQ(Type
, N
->getType());
2870 EXPECT_EQ(N
, DITemplateTypeParameter::get(Context
, Name
, Type
, defaulted
));
2872 EXPECT_NE(N
, DITemplateTypeParameter::get(Context
, "other", Type
, defaulted
));
2873 EXPECT_NE(N
, DITemplateTypeParameter::get(Context
, Name
,
2874 getBasicType("other"), defaulted
));
2875 EXPECT_NE(N
, DITemplateTypeParameter::get(Context
, Name
, Type
, true));
2877 TempDITemplateTypeParameter Temp
= N
->clone();
2878 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2881 typedef MetadataTest DITemplateValueParameterTest
;
2883 TEST_F(DITemplateValueParameterTest
, get
) {
2884 unsigned Tag
= dwarf::DW_TAG_template_value_parameter
;
2885 StringRef Name
= "template";
2886 DIType
*Type
= getBasicType("basic");
2887 bool defaulted
= false;
2888 Metadata
*Value
= getConstantAsMetadata();
2891 DITemplateValueParameter::get(Context
, Tag
, Name
, Type
, defaulted
, Value
);
2892 EXPECT_EQ(Tag
, N
->getTag());
2893 EXPECT_EQ(Name
, N
->getName());
2894 EXPECT_EQ(Type
, N
->getType());
2895 EXPECT_EQ(Value
, N
->getValue());
2896 EXPECT_EQ(N
, DITemplateValueParameter::get(Context
, Tag
, Name
, Type
,
2899 EXPECT_NE(N
, DITemplateValueParameter::get(
2900 Context
, dwarf::DW_TAG_GNU_template_template_param
, Name
,
2901 Type
, defaulted
, Value
));
2902 EXPECT_NE(N
, DITemplateValueParameter::get(Context
, Tag
, "other", Type
,
2904 EXPECT_NE(N
, DITemplateValueParameter::get(Context
, Tag
, Name
,
2905 getBasicType("other"), defaulted
,
2908 DITemplateValueParameter::get(Context
, Tag
, Name
, Type
, defaulted
,
2909 getConstantAsMetadata()));
2911 N
, DITemplateValueParameter::get(Context
, Tag
, Name
, Type
, true, Value
));
2913 TempDITemplateValueParameter Temp
= N
->clone();
2914 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
2917 typedef MetadataTest DIGlobalVariableTest
;
2919 TEST_F(DIGlobalVariableTest
, get
) {
2920 DIScope
*Scope
= getSubprogram();
2921 StringRef Name
= "name";
2922 StringRef LinkageName
= "linkage";
2923 DIFile
*File
= getFile();
2925 DIType
*Type
= getDerivedType();
2926 bool IsLocalToUnit
= false;
2927 bool IsDefinition
= true;
2928 MDTuple
*templateParams
= getTuple();
2929 DIDerivedType
*StaticDataMemberDeclaration
=
2930 cast
<DIDerivedType
>(getDerivedType());
2932 uint32_t AlignInBits
= 8;
2934 auto *N
= DIGlobalVariable::get(
2935 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
, IsLocalToUnit
,
2936 IsDefinition
, StaticDataMemberDeclaration
, templateParams
, AlignInBits
,
2939 EXPECT_EQ(dwarf::DW_TAG_variable
, N
->getTag());
2940 EXPECT_EQ(Scope
, N
->getScope());
2941 EXPECT_EQ(Name
, N
->getName());
2942 EXPECT_EQ(LinkageName
, N
->getLinkageName());
2943 EXPECT_EQ(File
, N
->getFile());
2944 EXPECT_EQ(Line
, N
->getLine());
2945 EXPECT_EQ(Type
, N
->getType());
2946 EXPECT_EQ(IsLocalToUnit
, N
->isLocalToUnit());
2947 EXPECT_EQ(IsDefinition
, N
->isDefinition());
2948 EXPECT_EQ(StaticDataMemberDeclaration
, N
->getStaticDataMemberDeclaration());
2949 EXPECT_EQ(templateParams
, N
->getTemplateParams());
2950 EXPECT_EQ(AlignInBits
, N
->getAlignInBits());
2951 EXPECT_EQ(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2952 Line
, Type
, IsLocalToUnit
, IsDefinition
,
2953 StaticDataMemberDeclaration
,
2954 templateParams
, AlignInBits
, nullptr));
2956 EXPECT_NE(N
, DIGlobalVariable::get(
2957 Context
, getSubprogram(), Name
, LinkageName
, File
, Line
,
2958 Type
, IsLocalToUnit
, IsDefinition
,
2959 StaticDataMemberDeclaration
, templateParams
, AlignInBits
,
2961 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, "other", LinkageName
, File
,
2962 Line
, Type
, IsLocalToUnit
, IsDefinition
,
2963 StaticDataMemberDeclaration
,
2964 templateParams
, AlignInBits
, nullptr));
2965 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, "other", File
, Line
,
2966 Type
, IsLocalToUnit
, IsDefinition
,
2967 StaticDataMemberDeclaration
,
2968 templateParams
, AlignInBits
, nullptr));
2969 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
,
2970 getFile(), Line
, Type
, IsLocalToUnit
,
2971 IsDefinition
, StaticDataMemberDeclaration
,
2972 templateParams
, AlignInBits
, nullptr));
2973 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2974 Line
+ 1, Type
, IsLocalToUnit
,
2975 IsDefinition
, StaticDataMemberDeclaration
,
2976 templateParams
, AlignInBits
, nullptr));
2977 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2978 Line
, getDerivedType(), IsLocalToUnit
,
2979 IsDefinition
, StaticDataMemberDeclaration
,
2980 templateParams
, AlignInBits
, nullptr));
2981 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2982 Line
, Type
, !IsLocalToUnit
, IsDefinition
,
2983 StaticDataMemberDeclaration
,
2984 templateParams
, AlignInBits
, nullptr));
2985 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2986 Line
, Type
, IsLocalToUnit
, !IsDefinition
,
2987 StaticDataMemberDeclaration
,
2988 templateParams
, AlignInBits
, nullptr));
2989 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2990 Line
, Type
, IsLocalToUnit
, IsDefinition
,
2991 cast
<DIDerivedType
>(getDerivedType()),
2992 templateParams
, AlignInBits
, nullptr));
2993 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2994 Line
, Type
, IsLocalToUnit
, IsDefinition
,
2995 StaticDataMemberDeclaration
, nullptr,
2996 AlignInBits
, nullptr));
2997 EXPECT_NE(N
, DIGlobalVariable::get(Context
, Scope
, Name
, LinkageName
, File
,
2998 Line
, Type
, IsLocalToUnit
, IsDefinition
,
2999 StaticDataMemberDeclaration
,
3000 templateParams
, (AlignInBits
<< 1),
3003 TempDIGlobalVariable Temp
= N
->clone();
3004 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
3007 typedef MetadataTest DIGlobalVariableExpressionTest
;
3009 TEST_F(DIGlobalVariableExpressionTest
, get
) {
3010 DIScope
*Scope
= getSubprogram();
3011 StringRef Name
= "name";
3012 StringRef LinkageName
= "linkage";
3013 DIFile
*File
= getFile();
3015 DIType
*Type
= getDerivedType();
3016 bool IsLocalToUnit
= false;
3017 bool IsDefinition
= true;
3018 MDTuple
*templateParams
= getTuple();
3019 auto *Expr
= DIExpression::get(Context
, {1, 2});
3020 auto *Expr2
= DIExpression::get(Context
, {1, 2, 3});
3021 DIDerivedType
*StaticDataMemberDeclaration
=
3022 cast
<DIDerivedType
>(getDerivedType());
3023 uint32_t AlignInBits
= 8;
3025 auto *Var
= DIGlobalVariable::get(
3026 Context
, Scope
, Name
, LinkageName
, File
, Line
, Type
, IsLocalToUnit
,
3027 IsDefinition
, StaticDataMemberDeclaration
, templateParams
, AlignInBits
,
3029 auto *Var2
= DIGlobalVariable::get(
3030 Context
, Scope
, "other", LinkageName
, File
, Line
, Type
, IsLocalToUnit
,
3031 IsDefinition
, StaticDataMemberDeclaration
, templateParams
, AlignInBits
,
3033 auto *N
= DIGlobalVariableExpression::get(Context
, Var
, Expr
);
3035 EXPECT_EQ(Var
, N
->getVariable());
3036 EXPECT_EQ(Expr
, N
->getExpression());
3037 EXPECT_EQ(N
, DIGlobalVariableExpression::get(Context
, Var
, Expr
));
3038 EXPECT_NE(N
, DIGlobalVariableExpression::get(Context
, Var2
, Expr
));
3039 EXPECT_NE(N
, DIGlobalVariableExpression::get(Context
, Var
, Expr2
));
3041 TempDIGlobalVariableExpression Temp
= N
->clone();
3042 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
3045 typedef MetadataTest DILocalVariableTest
;
3047 TEST_F(DILocalVariableTest
, get
) {
3048 DILocalScope
*Scope
= getSubprogram();
3049 StringRef Name
= "name";
3050 DIFile
*File
= getFile();
3052 DIType
*Type
= getDerivedType();
3054 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(7);
3055 uint32_t AlignInBits
= 8;
3058 DILocalVariable::get(Context
, Scope
, Name
, File
, Line
, Type
, Arg
, Flags
,
3059 AlignInBits
, nullptr);
3060 EXPECT_TRUE(N
->isParameter());
3061 EXPECT_EQ(Scope
, N
->getScope());
3062 EXPECT_EQ(Name
, N
->getName());
3063 EXPECT_EQ(File
, N
->getFile());
3064 EXPECT_EQ(Line
, N
->getLine());
3065 EXPECT_EQ(Type
, N
->getType());
3066 EXPECT_EQ(Arg
, N
->getArg());
3067 EXPECT_EQ(Flags
, N
->getFlags());
3068 EXPECT_EQ(AlignInBits
, N
->getAlignInBits());
3069 EXPECT_EQ(N
, DILocalVariable::get(Context
, Scope
, Name
, File
, Line
, Type
, Arg
,
3070 Flags
, AlignInBits
, nullptr));
3073 DILocalVariable::get(Context
, Scope
, Name
, File
, Line
, Type
, 0, Flags
,
3074 AlignInBits
, nullptr)->isParameter());
3075 EXPECT_NE(N
, DILocalVariable::get(Context
, getSubprogram(), Name
, File
, Line
,
3076 Type
, Arg
, Flags
, AlignInBits
, nullptr));
3077 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, "other", File
, Line
, Type
,
3078 Arg
, Flags
, AlignInBits
, nullptr));
3079 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, Name
, getFile(), Line
, Type
,
3080 Arg
, Flags
, AlignInBits
, nullptr));
3081 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, Name
, File
, Line
+ 1, Type
,
3082 Arg
, Flags
, AlignInBits
, nullptr));
3083 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, Name
, File
, Line
,
3084 getDerivedType(), Arg
, Flags
, AlignInBits
,
3086 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, Name
, File
, Line
, Type
,
3087 Arg
+ 1, Flags
, AlignInBits
, nullptr));
3088 EXPECT_NE(N
, DILocalVariable::get(Context
, Scope
, Name
, File
, Line
, Type
,
3089 Arg
, Flags
, (AlignInBits
<< 1), nullptr));
3091 TempDILocalVariable Temp
= N
->clone();
3092 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
3095 TEST_F(DILocalVariableTest
, getArg256
) {
3096 EXPECT_EQ(255u, DILocalVariable::get(Context
, getSubprogram(), "", getFile(),
3097 0, nullptr, 255, DINode::FlagZero
, 0,
3100 EXPECT_EQ(256u, DILocalVariable::get(Context
, getSubprogram(), "", getFile(),
3101 0, nullptr, 256, DINode::FlagZero
, 0,
3104 EXPECT_EQ(257u, DILocalVariable::get(Context
, getSubprogram(), "", getFile(),
3105 0, nullptr, 257, DINode::FlagZero
, 0,
3108 unsigned Max
= UINT16_MAX
;
3109 EXPECT_EQ(Max
, DILocalVariable::get(Context
, getSubprogram(), "", getFile(),
3110 0, nullptr, Max
, DINode::FlagZero
, 0,
3115 typedef MetadataTest DIExpressionTest
;
3117 TEST_F(DIExpressionTest
, get
) {
3118 uint64_t Elements
[] = {2, 6, 9, 78, 0};
3119 auto *N
= DIExpression::get(Context
, Elements
);
3120 EXPECT_EQ(ArrayRef(Elements
), N
->getElements());
3121 EXPECT_EQ(N
, DIExpression::get(Context
, Elements
));
3123 EXPECT_EQ(5u, N
->getNumElements());
3124 EXPECT_EQ(2u, N
->getElement(0));
3125 EXPECT_EQ(6u, N
->getElement(1));
3126 EXPECT_EQ(9u, N
->getElement(2));
3127 EXPECT_EQ(78u, N
->getElement(3));
3128 EXPECT_EQ(0u, N
->getElement(4));
3130 TempDIExpression Temp
= N
->clone();
3131 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
3133 // Test DIExpression::prepend().
3134 uint64_t Elts0
[] = {dwarf::DW_OP_LLVM_fragment
, 0, 32};
3135 auto *N0
= DIExpression::get(Context
, Elts0
);
3136 uint8_t DIExprFlags
= DIExpression::ApplyOffset
;
3137 DIExprFlags
|= DIExpression::DerefBefore
;
3138 DIExprFlags
|= DIExpression::DerefAfter
;
3139 DIExprFlags
|= DIExpression::StackValue
;
3140 auto *N0WithPrependedOps
= DIExpression::prepend(N0
, DIExprFlags
, 64);
3141 uint64_t Elts1
[] = {dwarf::DW_OP_deref
,
3142 dwarf::DW_OP_plus_uconst
, 64,
3144 dwarf::DW_OP_stack_value
,
3145 dwarf::DW_OP_LLVM_fragment
, 0, 32};
3146 auto *N1
= DIExpression::get(Context
, Elts1
);
3147 EXPECT_EQ(N0WithPrependedOps
, N1
);
3149 // Test DIExpression::append().
3150 uint64_t Elts2
[] = {dwarf::DW_OP_deref
, dwarf::DW_OP_plus_uconst
, 64,
3151 dwarf::DW_OP_deref
, dwarf::DW_OP_stack_value
};
3152 auto *N2
= DIExpression::append(N0
, Elts2
);
3153 EXPECT_EQ(N0WithPrependedOps
, N2
);
3156 TEST_F(DIExpressionTest
, Fold
) {
3158 // Remove a No-op DW_OP_plus_uconst from an expression.
3159 SmallVector
<uint64_t, 8> Ops
= {dwarf::DW_OP_plus_uconst
, 0};
3160 auto *Expr
= DIExpression::get(Context
, Ops
);
3161 auto *E
= Expr
->foldConstantMath();
3162 SmallVector
<uint64_t, 8> ResOps
;
3163 auto *EmptyExpr
= DIExpression::get(Context
, ResOps
);
3164 EXPECT_EQ(E
, EmptyExpr
);
3166 // Remove a No-op add from an expression.
3168 Ops
.push_back(dwarf::DW_OP_constu
);
3170 Ops
.push_back(dwarf::DW_OP_plus
);
3171 Expr
= DIExpression::get(Context
, Ops
);
3172 E
= Expr
->foldConstantMath();
3173 EXPECT_EQ(E
, EmptyExpr
);
3175 // Remove a No-op subtract from an expression.
3177 Ops
.push_back(dwarf::DW_OP_constu
);
3179 Ops
.push_back(dwarf::DW_OP_minus
);
3180 Expr
= DIExpression::get(Context
, Ops
);
3181 E
= Expr
->foldConstantMath();
3182 EXPECT_EQ(E
, EmptyExpr
);
3184 // Remove a No-op shift left from an expression.
3186 Ops
.push_back(dwarf::DW_OP_constu
);
3188 Ops
.push_back(dwarf::DW_OP_shl
);
3189 Expr
= DIExpression::get(Context
, Ops
);
3190 E
= Expr
->foldConstantMath();
3191 EXPECT_EQ(E
, EmptyExpr
);
3193 // Remove a No-op shift right from an expression.
3195 Ops
.push_back(dwarf::DW_OP_constu
);
3197 Ops
.push_back(dwarf::DW_OP_shr
);
3198 Expr
= DIExpression::get(Context
, Ops
);
3199 E
= Expr
->foldConstantMath();
3200 EXPECT_EQ(E
, EmptyExpr
);
3202 // Remove a No-op multiply from an expression.
3204 Ops
.push_back(dwarf::DW_OP_constu
);
3206 Ops
.push_back(dwarf::DW_OP_mul
);
3207 Expr
= DIExpression::get(Context
, Ops
);
3208 E
= Expr
->foldConstantMath();
3209 EXPECT_EQ(E
, EmptyExpr
);
3211 // Remove a No-op divide from an expression.
3213 Ops
.push_back(dwarf::DW_OP_constu
);
3215 Ops
.push_back(dwarf::DW_OP_div
);
3216 Expr
= DIExpression::get(Context
, Ops
);
3217 E
= Expr
->foldConstantMath();
3218 EXPECT_EQ(E
, EmptyExpr
);
3220 // Test fold {DW_OP_plus_uconst, Const1, DW_OP_plus_uconst, Const2} ->
3221 // {DW_OP_plus_uconst, Const1 + Const2}
3223 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3225 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3227 Expr
= DIExpression::get(Context
, Ops
);
3228 E
= Expr
->foldConstantMath();
3229 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3230 ResOps
.push_back(5);
3231 auto *ResExpr
= DIExpression::get(Context
, ResOps
);
3232 EXPECT_EQ(E
, ResExpr
);
3234 // Test {DW_OP_constu, Const1, DW_OP_plus_uconst, Const2} -> {DW_OP_constu,
3237 Ops
.push_back(dwarf::DW_OP_constu
);
3239 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3241 Expr
= DIExpression::get(Context
, Ops
);
3242 E
= Expr
->foldConstantMath();
3244 ResOps
.push_back(dwarf::DW_OP_constu
);
3245 ResOps
.push_back(5);
3246 ResExpr
= DIExpression::get(Context
, ResOps
);
3247 EXPECT_EQ(E
, ResExpr
);
3249 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_plus} ->
3250 // {DW_OP_constu, Const1 + Const2}
3252 Ops
.push_back(dwarf::DW_OP_constu
);
3254 Ops
.push_back(dwarf::DW_OP_constu
);
3256 Ops
.push_back(dwarf::DW_OP_plus
);
3257 Expr
= DIExpression::get(Context
, Ops
);
3258 E
= Expr
->foldConstantMath();
3260 ResOps
.push_back(dwarf::DW_OP_constu
);
3261 ResOps
.push_back(10);
3262 ResExpr
= DIExpression::get(Context
, ResOps
);
3263 EXPECT_EQ(E
, ResExpr
);
3265 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_minus} ->
3266 // {DW_OP_constu, Const1 - Const2}
3268 Ops
.push_back(dwarf::DW_OP_constu
);
3270 Ops
.push_back(dwarf::DW_OP_constu
);
3272 Ops
.push_back(dwarf::DW_OP_minus
);
3273 Expr
= DIExpression::get(Context
, Ops
);
3274 E
= Expr
->foldConstantMath();
3276 ResOps
.push_back(dwarf::DW_OP_constu
);
3277 ResOps
.push_back(6);
3278 ResExpr
= DIExpression::get(Context
, ResOps
);
3279 EXPECT_EQ(E
, ResExpr
);
3281 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_mul} ->
3282 // {DW_OP_constu, Const1 * Const2}
3284 Ops
.push_back(dwarf::DW_OP_constu
);
3286 Ops
.push_back(dwarf::DW_OP_constu
);
3288 Ops
.push_back(dwarf::DW_OP_mul
);
3289 Expr
= DIExpression::get(Context
, Ops
);
3290 E
= Expr
->foldConstantMath();
3292 ResOps
.push_back(dwarf::DW_OP_constu
);
3293 ResOps
.push_back(16);
3294 ResExpr
= DIExpression::get(Context
, ResOps
);
3295 EXPECT_EQ(E
, ResExpr
);
3297 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_div} ->
3298 // {DW_OP_constu, Const1 / Const2}
3300 Ops
.push_back(dwarf::DW_OP_constu
);
3302 Ops
.push_back(dwarf::DW_OP_constu
);
3304 Ops
.push_back(dwarf::DW_OP_div
);
3305 Expr
= DIExpression::get(Context
, Ops
);
3306 E
= Expr
->foldConstantMath();
3308 ResOps
.push_back(dwarf::DW_OP_constu
);
3309 ResOps
.push_back(4);
3310 ResExpr
= DIExpression::get(Context
, ResOps
);
3311 EXPECT_EQ(E
, ResExpr
);
3313 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_shl} ->
3314 // {DW_OP_constu, Const1 << Const2}
3316 Ops
.push_back(dwarf::DW_OP_constu
);
3318 Ops
.push_back(dwarf::DW_OP_constu
);
3320 Ops
.push_back(dwarf::DW_OP_shl
);
3321 Expr
= DIExpression::get(Context
, Ops
);
3322 E
= Expr
->foldConstantMath();
3324 ResOps
.push_back(dwarf::DW_OP_constu
);
3325 ResOps
.push_back(32);
3326 ResExpr
= DIExpression::get(Context
, ResOps
);
3327 EXPECT_EQ(E
, ResExpr
);
3329 // Test {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_shr} ->
3330 // {DW_OP_constu, Const1 >> Const2}
3332 Ops
.push_back(dwarf::DW_OP_constu
);
3334 Ops
.push_back(dwarf::DW_OP_constu
);
3336 Ops
.push_back(dwarf::DW_OP_shr
);
3337 Expr
= DIExpression::get(Context
, Ops
);
3338 E
= Expr
->foldConstantMath();
3340 ResOps
.push_back(dwarf::DW_OP_constu
);
3341 ResOps
.push_back(2);
3342 ResExpr
= DIExpression::get(Context
, ResOps
);
3343 EXPECT_EQ(E
, ResExpr
);
3345 // Test {DW_OP_plus_uconst, Const1, DW_OP_constu, Const2, DW_OP_plus} ->
3346 // {DW_OP_plus_uconst, Const1 + Const2}
3348 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3350 Ops
.push_back(dwarf::DW_OP_constu
);
3352 Ops
.push_back(dwarf::DW_OP_plus
);
3353 Expr
= DIExpression::get(Context
, Ops
);
3354 E
= Expr
->foldConstantMath();
3356 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3357 ResOps
.push_back(10);
3358 ResExpr
= DIExpression::get(Context
, ResOps
);
3359 EXPECT_EQ(E
, ResExpr
);
3361 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_plus_uconst, Const2} ->
3362 // {DW_OP_plus_uconst, Const1 + Const2}
3364 Ops
.push_back(dwarf::DW_OP_constu
);
3366 Ops
.push_back(dwarf::DW_OP_plus
);
3367 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3369 Expr
= DIExpression::get(Context
, Ops
);
3370 E
= Expr
->foldConstantMath();
3372 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3373 ResOps
.push_back(10);
3374 ResExpr
= DIExpression::get(Context
, ResOps
);
3375 EXPECT_EQ(E
, ResExpr
);
3377 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_constu, Const2, DW_OP_plus}
3378 // -> {DW_OP_plus_uconst, Const1 + Const2}
3380 Ops
.push_back(dwarf::DW_OP_constu
);
3382 Ops
.push_back(dwarf::DW_OP_plus
);
3383 Ops
.push_back(dwarf::DW_OP_constu
);
3385 Ops
.push_back(dwarf::DW_OP_plus
);
3386 Expr
= DIExpression::get(Context
, Ops
);
3387 E
= Expr
->foldConstantMath();
3389 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3390 ResOps
.push_back(10);
3391 ResExpr
= DIExpression::get(Context
, ResOps
);
3392 EXPECT_EQ(E
, ResExpr
);
3394 // Test {DW_OP_constu, Const1, DW_OP_mul, DW_OP_constu, Const2, DW_OP_mul} ->
3395 // {DW_OP_constu, Const1 * Const2, DW_OP_mul}
3397 Ops
.push_back(dwarf::DW_OP_constu
);
3399 Ops
.push_back(dwarf::DW_OP_mul
);
3400 Ops
.push_back(dwarf::DW_OP_constu
);
3402 Ops
.push_back(dwarf::DW_OP_mul
);
3403 Expr
= DIExpression::get(Context
, Ops
);
3404 E
= Expr
->foldConstantMath();
3406 ResOps
.push_back(dwarf::DW_OP_constu
);
3407 ResOps
.push_back(16);
3408 ResOps
.push_back(dwarf::DW_OP_mul
);
3409 ResExpr
= DIExpression::get(Context
, ResOps
);
3410 EXPECT_EQ(E
, ResExpr
);
3412 // Test {DW_OP_plus_uconst, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg,
3413 // DW_OP_plus, DW_OP_constu, Const2, DW_OP_plus} -> {DW_OP_plus_uconst, Const1
3414 // + Const2, DW_OP_LLVM_arg, Arg, DW_OP_plus}
3416 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3418 Ops
.push_back(dwarf::DW_OP_LLVM_arg
);
3420 Ops
.push_back(dwarf::DW_OP_plus
);
3421 Ops
.push_back(dwarf::DW_OP_constu
);
3423 Ops
.push_back(dwarf::DW_OP_plus
);
3424 Expr
= DIExpression::get(Context
, Ops
);
3425 E
= Expr
->foldConstantMath();
3427 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3428 ResOps
.push_back(10);
3429 ResOps
.push_back(dwarf::DW_OP_LLVM_arg
);
3430 ResOps
.push_back(0);
3431 ResOps
.push_back(dwarf::DW_OP_plus
);
3432 ResExpr
= DIExpression::get(Context
, ResOps
);
3433 EXPECT_EQ(E
, ResExpr
);
3435 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus,
3436 // DW_OP_plus_uconst, Const2} -> {DW_OP_constu, Const1 + Const2, DW_OP_plus,
3437 // DW_OP_LLVM_arg, Arg, DW_OP_plus}
3439 Ops
.push_back(dwarf::DW_OP_constu
);
3441 Ops
.push_back(dwarf::DW_OP_plus
);
3442 Ops
.push_back(dwarf::DW_OP_LLVM_arg
);
3444 Ops
.push_back(dwarf::DW_OP_plus
);
3445 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3447 Expr
= DIExpression::get(Context
, Ops
);
3448 E
= Expr
->foldConstantMath();
3450 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3451 ResOps
.push_back(10);
3452 ResOps
.push_back(dwarf::DW_OP_LLVM_arg
);
3453 ResOps
.push_back(0);
3454 ResOps
.push_back(dwarf::DW_OP_plus
);
3455 ResExpr
= DIExpression::get(Context
, ResOps
);
3456 EXPECT_EQ(E
, ResExpr
);
3458 // Test {DW_OP_constu, Const1, DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus,
3459 // DW_OP_constu, Const2, DW_OP_plus} -> {DW_OP_constu, Const1 + Const2,
3460 // DW_OP_plus, DW_OP_LLVM_arg, Arg, DW_OP_plus}
3462 Ops
.push_back(dwarf::DW_OP_constu
);
3464 Ops
.push_back(dwarf::DW_OP_plus
);
3465 Ops
.push_back(dwarf::DW_OP_LLVM_arg
);
3467 Ops
.push_back(dwarf::DW_OP_plus
);
3468 Ops
.push_back(dwarf::DW_OP_constu
);
3470 Ops
.push_back(dwarf::DW_OP_plus
);
3471 Expr
= DIExpression::get(Context
, Ops
);
3472 E
= Expr
->foldConstantMath();
3474 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3475 ResOps
.push_back(10);
3476 ResOps
.push_back(dwarf::DW_OP_LLVM_arg
);
3477 ResOps
.push_back(0);
3478 ResOps
.push_back(dwarf::DW_OP_plus
);
3479 ResExpr
= DIExpression::get(Context
, ResOps
);
3480 EXPECT_EQ(E
, ResExpr
);
3482 // Test {DW_OP_constu, Const1, DW_OP_mul, DW_OP_LLVM_arg, Arg, DW_OP_mul,
3483 // DW_OP_constu, Const2, DW_OP_mul} -> {DW_OP_constu, Const1 * Const2,
3484 // DW_OP_mul, DW_OP_LLVM_arg, Arg, DW_OP_mul}
3486 Ops
.push_back(dwarf::DW_OP_constu
);
3488 Ops
.push_back(dwarf::DW_OP_mul
);
3489 Ops
.push_back(dwarf::DW_OP_LLVM_arg
);
3491 Ops
.push_back(dwarf::DW_OP_mul
);
3492 Ops
.push_back(dwarf::DW_OP_constu
);
3494 Ops
.push_back(dwarf::DW_OP_mul
);
3495 Expr
= DIExpression::get(Context
, Ops
);
3496 E
= Expr
->foldConstantMath();
3498 ResOps
.push_back(dwarf::DW_OP_constu
);
3499 ResOps
.push_back(16);
3500 ResOps
.push_back(dwarf::DW_OP_mul
);
3501 ResOps
.push_back(dwarf::DW_OP_LLVM_arg
);
3502 ResOps
.push_back(0);
3503 ResOps
.push_back(dwarf::DW_OP_mul
);
3504 ResExpr
= DIExpression::get(Context
, ResOps
);
3505 EXPECT_EQ(E
, ResExpr
);
3507 // Test an overflow addition.
3509 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3510 Ops
.push_back(UINT64_MAX
);
3511 Ops
.push_back(dwarf::DW_OP_plus_uconst
);
3513 Expr
= DIExpression::get(Context
, Ops
);
3514 E
= Expr
->foldConstantMath();
3516 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3517 ResOps
.push_back(UINT64_MAX
);
3518 ResOps
.push_back(dwarf::DW_OP_plus_uconst
);
3519 ResOps
.push_back(2);
3520 ResExpr
= DIExpression::get(Context
, ResOps
);
3521 EXPECT_EQ(E
, ResExpr
);
3523 // Test an underflow subtraction.
3525 Ops
.push_back(dwarf::DW_OP_constu
);
3527 Ops
.push_back(dwarf::DW_OP_constu
);
3529 Ops
.push_back(dwarf::DW_OP_minus
);
3530 Expr
= DIExpression::get(Context
, Ops
);
3531 E
= Expr
->foldConstantMath();
3533 ResOps
.push_back(dwarf::DW_OP_constu
);
3534 ResOps
.push_back(1);
3535 ResOps
.push_back(dwarf::DW_OP_constu
);
3536 ResOps
.push_back(2);
3537 ResOps
.push_back(dwarf::DW_OP_minus
);
3538 ResExpr
= DIExpression::get(Context
, ResOps
);
3539 EXPECT_EQ(E
, ResExpr
);
3541 // Test a left shift greater than 64.
3543 Ops
.push_back(dwarf::DW_OP_constu
);
3545 Ops
.push_back(dwarf::DW_OP_constu
);
3547 Ops
.push_back(dwarf::DW_OP_shl
);
3548 Expr
= DIExpression::get(Context
, Ops
);
3549 E
= Expr
->foldConstantMath();
3551 ResOps
.push_back(dwarf::DW_OP_constu
);
3552 ResOps
.push_back(1);
3553 ResOps
.push_back(dwarf::DW_OP_constu
);
3554 ResOps
.push_back(65);
3555 ResOps
.push_back(dwarf::DW_OP_shl
);
3556 ResExpr
= DIExpression::get(Context
, ResOps
);
3557 EXPECT_EQ(E
, ResExpr
);
3559 // Test a right shift greater than 64.
3561 Ops
.push_back(dwarf::DW_OP_constu
);
3563 Ops
.push_back(dwarf::DW_OP_constu
);
3565 Ops
.push_back(dwarf::DW_OP_shr
);
3566 Expr
= DIExpression::get(Context
, Ops
);
3567 E
= Expr
->foldConstantMath();
3569 ResOps
.push_back(dwarf::DW_OP_constu
);
3570 ResOps
.push_back(1);
3571 ResOps
.push_back(dwarf::DW_OP_constu
);
3572 ResOps
.push_back(65);
3573 ResOps
.push_back(dwarf::DW_OP_shr
);
3574 ResExpr
= DIExpression::get(Context
, ResOps
);
3575 EXPECT_EQ(E
, ResExpr
);
3577 // Test an overflow multiplication.
3579 Ops
.push_back(dwarf::DW_OP_constu
);
3580 Ops
.push_back(UINT64_MAX
);
3581 Ops
.push_back(dwarf::DW_OP_constu
);
3583 Ops
.push_back(dwarf::DW_OP_mul
);
3584 Expr
= DIExpression::get(Context
, Ops
);
3585 E
= Expr
->foldConstantMath();
3587 ResOps
.push_back(dwarf::DW_OP_constu
);
3588 ResOps
.push_back(UINT64_MAX
);
3589 ResOps
.push_back(dwarf::DW_OP_constu
);
3590 ResOps
.push_back(2);
3591 ResOps
.push_back(dwarf::DW_OP_mul
);
3592 ResExpr
= DIExpression::get(Context
, ResOps
);
3593 EXPECT_EQ(E
, ResExpr
);
3595 // Test a divide by 0.
3597 Ops
.push_back(dwarf::DW_OP_constu
);
3599 Ops
.push_back(dwarf::DW_OP_constu
);
3601 Ops
.push_back(dwarf::DW_OP_div
);
3602 Expr
= DIExpression::get(Context
, Ops
);
3603 E
= Expr
->foldConstantMath();
3605 ResOps
.push_back(dwarf::DW_OP_constu
);
3606 ResOps
.push_back(2);
3607 ResOps
.push_back(dwarf::DW_OP_lit0
);
3608 ResOps
.push_back(dwarf::DW_OP_div
);
3609 ResExpr
= DIExpression::get(Context
, ResOps
);
3610 EXPECT_EQ(E
, ResExpr
);
3613 TEST_F(DIExpressionTest
, Append
) {
3614 // Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_plus} to a DW_OP_plus
3616 SmallVector
<uint64_t, 8> Ops
= {dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_constu
,
3617 2, dwarf::DW_OP_plus
};
3618 auto *Expr
= DIExpression::get(Context
, Ops
);
3619 SmallVector
<uint64_t, 8> AppendOps
= {dwarf::DW_OP_constu
, 3,
3621 auto *AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3622 SmallVector
<uint64_t, 8> OpsRes
= {dwarf::DW_OP_LLVM_arg
, 0,
3623 dwarf::DW_OP_plus_uconst
, 5};
3624 auto *ResExpr
= DIExpression::get(Context
, OpsRes
);
3625 EXPECT_EQ(ResExpr
, AppendExpr
);
3627 // Test appending a {dwarf::DW_OP_plus_uconst, <const>} to a DW_OP_plus
3628 // expression uint64_t PlusUConstOps[] = {dwarf::DW_OP_plus_uconst, 3};
3630 AppendOps
.push_back(dwarf::DW_OP_plus_uconst
);
3631 AppendOps
.push_back(3);
3632 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3634 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3635 OpsRes
.push_back(0);
3636 OpsRes
.push_back(dwarf::DW_OP_plus_uconst
);
3637 OpsRes
.push_back(5);
3638 ResExpr
= DIExpression::get(Context
, OpsRes
);
3639 EXPECT_EQ(ResExpr
, AppendExpr
);
3641 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_plus} to an expression
3643 AppendOps
.push_back(dwarf::DW_OP_constu
);
3644 AppendOps
.push_back(0);
3645 AppendOps
.push_back(dwarf::DW_OP_plus
);
3646 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3648 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3649 OpsRes
.push_back(0);
3650 OpsRes
.push_back(dwarf::DW_OP_plus_uconst
);
3651 OpsRes
.push_back(2);
3652 ResExpr
= DIExpression::get(Context
, OpsRes
);
3653 EXPECT_EQ(ResExpr
, AppendExpr
);
3655 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_minus} to an expression
3657 AppendOps
.push_back(dwarf::DW_OP_constu
);
3658 AppendOps
.push_back(0);
3659 AppendOps
.push_back(dwarf::DW_OP_minus
);
3660 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3662 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3663 OpsRes
.push_back(0);
3664 OpsRes
.push_back(dwarf::DW_OP_plus_uconst
);
3665 OpsRes
.push_back(2);
3666 ResExpr
= DIExpression::get(Context
, OpsRes
);
3667 EXPECT_EQ(ResExpr
, AppendExpr
);
3669 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shl} to an expression
3671 AppendOps
.push_back(dwarf::DW_OP_constu
);
3672 AppendOps
.push_back(0);
3673 AppendOps
.push_back(dwarf::DW_OP_shl
);
3674 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3676 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3677 OpsRes
.push_back(0);
3678 OpsRes
.push_back(dwarf::DW_OP_plus_uconst
);
3679 OpsRes
.push_back(2);
3680 ResExpr
= DIExpression::get(Context
, OpsRes
);
3681 EXPECT_EQ(ResExpr
, AppendExpr
);
3683 // Test appending a {dwarf::DW_OP_constu, 0, DW_OP_shr} to an expression
3685 AppendOps
.push_back(dwarf::DW_OP_constu
);
3686 AppendOps
.push_back(0);
3687 AppendOps
.push_back(dwarf::DW_OP_shr
);
3688 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3690 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3691 OpsRes
.push_back(0);
3692 OpsRes
.push_back(dwarf::DW_OP_plus_uconst
);
3693 OpsRes
.push_back(2);
3694 ResExpr
= DIExpression::get(Context
, OpsRes
);
3695 EXPECT_EQ(ResExpr
, AppendExpr
);
3697 // Test appending a {dwarf::DW_OP_constu, <const>, DW_OP_mul} to a DW_OP_mul
3700 Ops
.push_back(dwarf::DW_OP_LLVM_arg
);
3702 Ops
.push_back(dwarf::DW_OP_constu
);
3704 Ops
.push_back(dwarf::DW_OP_mul
);
3705 Expr
= DIExpression::get(Context
, Ops
);
3707 AppendOps
.push_back(dwarf::DW_OP_constu
);
3708 AppendOps
.push_back(3);
3709 AppendOps
.push_back(dwarf::DW_OP_mul
);
3710 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3712 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3713 OpsRes
.push_back(0);
3714 OpsRes
.push_back(dwarf::DW_OP_constu
);
3715 OpsRes
.push_back(6);
3716 OpsRes
.push_back(dwarf::DW_OP_mul
);
3717 ResExpr
= DIExpression::get(Context
, OpsRes
);
3718 EXPECT_EQ(ResExpr
, AppendExpr
);
3720 // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_mul} to an expression
3722 AppendOps
.push_back(dwarf::DW_OP_constu
);
3723 AppendOps
.push_back(1);
3724 AppendOps
.push_back(dwarf::DW_OP_mul
);
3725 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3727 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3728 OpsRes
.push_back(0);
3729 OpsRes
.push_back(dwarf::DW_OP_constu
);
3730 OpsRes
.push_back(2);
3731 OpsRes
.push_back(dwarf::DW_OP_mul
);
3732 ResExpr
= DIExpression::get(Context
, OpsRes
);
3733 EXPECT_EQ(ResExpr
, AppendExpr
);
3735 // Test appending a {dwarf::DW_OP_constu, 1, DW_OP_div} to an expression
3737 AppendOps
.push_back(dwarf::DW_OP_constu
);
3738 AppendOps
.push_back(1);
3739 AppendOps
.push_back(dwarf::DW_OP_div
);
3740 AppendExpr
= DIExpression::append(Expr
, AppendOps
);
3742 OpsRes
.push_back(dwarf::DW_OP_LLVM_arg
);
3743 OpsRes
.push_back(0);
3744 OpsRes
.push_back(dwarf::DW_OP_constu
);
3745 OpsRes
.push_back(2);
3746 OpsRes
.push_back(dwarf::DW_OP_mul
);
3747 ResExpr
= DIExpression::get(Context
, OpsRes
);
3748 EXPECT_EQ(ResExpr
, AppendExpr
);
3751 TEST_F(DIExpressionTest
, isValid
) {
3752 #define EXPECT_VALID(...) \
3754 uint64_t Elements[] = {__VA_ARGS__}; \
3755 EXPECT_TRUE(DIExpression::get(Context, Elements)->isValid()); \
3757 #define EXPECT_INVALID(...) \
3759 uint64_t Elements[] = {__VA_ARGS__}; \
3760 EXPECT_FALSE(DIExpression::get(Context, Elements)->isValid()); \
3763 // Empty expression should be valid.
3764 EXPECT_TRUE(DIExpression::get(Context
, std::nullopt
)->isValid());
3766 // Valid constructions.
3767 EXPECT_VALID(dwarf::DW_OP_plus_uconst
, 6);
3768 EXPECT_VALID(dwarf::DW_OP_constu
, 6, dwarf::DW_OP_plus
);
3769 EXPECT_VALID(dwarf::DW_OP_deref
);
3770 EXPECT_VALID(dwarf::DW_OP_LLVM_fragment
, 3, 7);
3771 EXPECT_VALID(dwarf::DW_OP_plus_uconst
, 6, dwarf::DW_OP_deref
);
3772 EXPECT_VALID(dwarf::DW_OP_deref
, dwarf::DW_OP_plus_uconst
, 6);
3773 EXPECT_VALID(dwarf::DW_OP_deref
, dwarf::DW_OP_LLVM_fragment
, 3, 7);
3774 EXPECT_VALID(dwarf::DW_OP_deref
, dwarf::DW_OP_plus_uconst
, 6,
3775 dwarf::DW_OP_LLVM_fragment
, 3, 7);
3776 EXPECT_VALID(dwarf::DW_OP_LLVM_entry_value
, 1);
3777 EXPECT_VALID(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_entry_value
, 1);
3779 // Invalid constructions.
3780 EXPECT_INVALID(~0u);
3781 EXPECT_INVALID(dwarf::DW_OP_plus
, 0);
3782 EXPECT_INVALID(dwarf::DW_OP_plus_uconst
);
3783 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment
);
3784 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment
, 3);
3785 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment
, 3, 7, dwarf::DW_OP_plus_uconst
, 3);
3786 EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment
, 3, 7, dwarf::DW_OP_deref
);
3787 EXPECT_INVALID(dwarf::DW_OP_LLVM_entry_value
, 2);
3788 EXPECT_INVALID(dwarf::DW_OP_plus_uconst
, 5, dwarf::DW_OP_LLVM_entry_value
, 1);
3789 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 5,
3790 dwarf::DW_OP_LLVM_entry_value
, 1);
3791 EXPECT_INVALID(dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_LLVM_entry_value
, 1);
3794 #undef EXPECT_INVALID
3797 TEST_F(DIExpressionTest
, createFragmentExpression
) {
3798 #define EXPECT_VALID_FRAGMENT(Offset, Size, ...) \
3800 uint64_t Elements[] = {__VA_ARGS__}; \
3801 DIExpression *Expression = DIExpression::get(Context, Elements); \
3803 DIExpression::createFragmentExpression(Expression, Offset, Size) \
3806 #define EXPECT_INVALID_FRAGMENT(Offset, Size, ...) \
3808 uint64_t Elements[] = {__VA_ARGS__}; \
3809 DIExpression *Expression = DIExpression::get(Context, Elements); \
3811 DIExpression::createFragmentExpression(Expression, Offset, Size) \
3815 // createFragmentExpression adds correct ops.
3816 std::optional
<DIExpression
*> R
= DIExpression::createFragmentExpression(
3817 DIExpression::get(Context
, {}), 0, 32);
3818 EXPECT_EQ(R
.has_value(), true);
3819 EXPECT_EQ(3u, (*R
)->getNumElements());
3820 EXPECT_EQ(dwarf::DW_OP_LLVM_fragment
, (*R
)->getElement(0));
3821 EXPECT_EQ(0u, (*R
)->getElement(1));
3822 EXPECT_EQ(32u, (*R
)->getElement(2));
3824 // Valid fragment expressions.
3825 EXPECT_VALID_FRAGMENT(0, 32, {});
3826 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_deref
);
3827 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_LLVM_fragment
, 0, 32);
3828 EXPECT_VALID_FRAGMENT(16, 16, dwarf::DW_OP_LLVM_fragment
, 0, 32);
3830 // Invalid fragment expressions (incompatible ops).
3831 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 6, dwarf::DW_OP_plus
,
3832 dwarf::DW_OP_stack_value
);
3833 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 14, dwarf::DW_OP_minus
,
3834 dwarf::DW_OP_stack_value
);
3835 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 16, dwarf::DW_OP_shr
,
3836 dwarf::DW_OP_stack_value
);
3837 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 16, dwarf::DW_OP_shl
,
3838 dwarf::DW_OP_stack_value
);
3839 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 16, dwarf::DW_OP_shra
,
3840 dwarf::DW_OP_stack_value
);
3841 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3842 dwarf::DW_OP_stack_value
);
3844 // Fragments can be created for expressions using DW_OP_plus to compute an
3846 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_constu
, 6, dwarf::DW_OP_plus
);
3847 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6, dwarf::DW_OP_deref
);
3848 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6, dwarf::DW_OP_deref
,
3849 dwarf::DW_OP_stack_value
);
3851 // Check the other deref operations work in the same way.
3852 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3853 dwarf::DW_OP_deref_size
, 1);
3854 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3855 dwarf::DW_OP_deref_type
, 1, 1);
3856 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3857 dwarf::DW_OP_xderef
);
3858 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3859 dwarf::DW_OP_xderef_size
, 1);
3860 EXPECT_VALID_FRAGMENT(0, 32, dwarf::DW_OP_plus_uconst
, 6,
3861 dwarf::DW_OP_xderef_type
, 1, 1);
3863 // Fragments cannot be created for expressions using DW_OP_plus to compute an
3864 // implicit value (check that this correctly fails even though there is a
3865 // deref in the expression).
3866 EXPECT_INVALID_FRAGMENT(0, 32, dwarf::DW_OP_deref
, dwarf::DW_OP_plus_uconst
,
3867 2, dwarf::DW_OP_stack_value
);
3869 #undef EXPECT_VALID_FRAGMENT
3870 #undef EXPECT_INVALID_FRAGMENT
3873 TEST_F(DIExpressionTest
, extractLeadingOffset
) {
3875 SmallVector
<uint64_t> Remaining
;
3876 using namespace dwarf
;
3877 #define OPS(...) SmallVector<uint64_t>(ArrayRef<uint64_t>{__VA_ARGS__})
3878 #define EXTRACT_FROM(...) \
3879 DIExpression::get(Context, {__VA_ARGS__}) \
3880 ->extractLeadingOffset(Offset, Remaining)
3881 // Test the number of expression inputs
3882 // ------------------------------------
3884 // Single location expressions are permitted.
3885 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst
, 2));
3886 EXPECT_EQ(Offset
, 2);
3887 EXPECT_EQ(Remaining
.size(), 0u);
3888 // This is also a single-location.
3889 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_arg
, 0, DW_OP_plus_uconst
, 2));
3890 EXPECT_EQ(Offset
, 2);
3891 EXPECT_EQ(Remaining
.size(), 0u);
3892 // Variadic locations are not permitted. A non-zero arg is assumed to
3893 // indicate multiple inputs.
3894 EXPECT_FALSE(EXTRACT_FROM(DW_OP_LLVM_arg
, 1));
3895 EXPECT_FALSE(EXTRACT_FROM(DW_OP_LLVM_arg
, 0, DW_OP_LLVM_arg
, 1, DW_OP_plus
));
3897 // Test offsets expressions
3898 // ------------------------
3899 EXPECT_TRUE(EXTRACT_FROM());
3900 EXPECT_EQ(Offset
, 0);
3901 EXPECT_EQ(Remaining
.size(), 0u);
3903 EXPECT_TRUE(EXTRACT_FROM(DW_OP_constu
, 4, DW_OP_plus
));
3904 EXPECT_EQ(Offset
, 4);
3905 EXPECT_EQ(Remaining
.size(), 0u);
3907 EXPECT_TRUE(EXTRACT_FROM(DW_OP_constu
, 2, DW_OP_minus
));
3908 EXPECT_EQ(Offset
, -2);
3909 EXPECT_EQ(Remaining
.size(), 0u);
3911 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst
, 8));
3912 EXPECT_EQ(Offset
, 8);
3913 EXPECT_EQ(Remaining
.size(), 0u);
3915 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst
, 4, DW_OP_constu
, 2, DW_OP_minus
));
3916 EXPECT_EQ(Offset
, 2);
3917 EXPECT_EQ(Remaining
.size(), 0u);
3919 // Not all operations are permitted for simplicity. Can be added
3920 // if needed in future.
3921 EXPECT_FALSE(EXTRACT_FROM(DW_OP_constu
, 2, DW_OP_mul
));
3923 // Test "remaining ops"
3924 // --------------------
3925 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst
, 4, DW_OP_constu
, 8, DW_OP_minus
,
3926 DW_OP_LLVM_fragment
, 0, 32));
3927 EXPECT_EQ(Remaining
, OPS(DW_OP_LLVM_fragment
, 0, 32));
3928 EXPECT_EQ(Offset
, -4);
3930 EXPECT_TRUE(EXTRACT_FROM(DW_OP_deref
));
3931 EXPECT_EQ(Remaining
, OPS(DW_OP_deref
));
3932 EXPECT_EQ(Offset
, 0);
3934 // Check things after the non-offset ops are added too.
3935 EXPECT_TRUE(EXTRACT_FROM(DW_OP_plus_uconst
, 2, DW_OP_deref_size
, 4,
3936 DW_OP_stack_value
));
3937 EXPECT_EQ(Remaining
, OPS(DW_OP_deref_size
, 4, DW_OP_stack_value
));
3938 EXPECT_EQ(Offset
, 2);
3940 // DW_OP_deref_type isn't supported in LLVM so this currently fails.
3941 EXPECT_FALSE(EXTRACT_FROM(DW_OP_deref_type
, 0));
3943 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_extract_bits_zext
, 0, 8));
3944 EXPECT_EQ(Remaining
, OPS(DW_OP_LLVM_extract_bits_zext
, 0, 8));
3946 EXPECT_TRUE(EXTRACT_FROM(DW_OP_LLVM_extract_bits_sext
, 4, 4));
3947 EXPECT_EQ(Remaining
, OPS(DW_OP_LLVM_extract_bits_sext
, 4, 4));
3952 TEST_F(DIExpressionTest
, convertToUndefExpression
) {
3953 #define EXPECT_UNDEF_OPS_EQUAL(TestExpr, Expected) \
3955 const DIExpression *Undef = \
3956 DIExpression::convertToUndefExpression(TestExpr); \
3957 EXPECT_EQ(Undef, Expected); \
3959 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
3961 // Expressions which are single-location and non-complex should be unchanged.
3962 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(), GET_EXPR());
3963 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 0, 32),
3964 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 0, 32));
3966 // Variadic expressions should become single-location.
3967 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0), GET_EXPR());
3968 EXPECT_UNDEF_OPS_EQUAL(
3969 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_fragment
, 32, 32),
3970 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 32, 32));
3971 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
3972 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
),
3974 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
3975 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
,
3976 dwarf::DW_OP_LLVM_fragment
, 64, 32),
3977 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 64, 32));
3979 // Any stack-computing ops should be removed.
3980 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst
, 8), GET_EXPR());
3981 EXPECT_UNDEF_OPS_EQUAL(
3982 GET_EXPR(dwarf::DW_OP_plus_uconst
, 8, dwarf::DW_OP_LLVM_fragment
, 0, 16),
3983 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 0, 16));
3984 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu
, 24, dwarf::DW_OP_shra
),
3986 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu
, 24, dwarf::DW_OP_shra
,
3987 dwarf::DW_OP_LLVM_fragment
, 8, 16),
3988 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 8, 16));
3989 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_deref
), GET_EXPR());
3990 EXPECT_UNDEF_OPS_EQUAL(
3991 GET_EXPR(dwarf::DW_OP_deref
, dwarf::DW_OP_LLVM_fragment
, 16, 16),
3992 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 16, 16));
3993 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu
, 4, dwarf::DW_OP_minus
),
3995 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_constu
, 4, dwarf::DW_OP_minus
,
3996 dwarf::DW_OP_LLVM_fragment
, 24, 16),
3997 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 24, 16));
3999 // Stack-value operators are also not preserved.
4000 EXPECT_UNDEF_OPS_EQUAL(
4001 GET_EXPR(dwarf::DW_OP_plus_uconst
, 8, dwarf::DW_OP_stack_value
),
4003 EXPECT_UNDEF_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst
, 8,
4004 dwarf::DW_OP_stack_value
,
4005 dwarf::DW_OP_LLVM_fragment
, 32, 16),
4006 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 32, 16));
4008 #undef EXPECT_UNDEF_OPS_EQUAL
4012 TEST_F(DIExpressionTest
, convertToVariadicExpression
) {
4013 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \
4015 const DIExpression *Variadic = \
4016 DIExpression::convertToVariadicExpression(TestExpr); \
4017 EXPECT_EQ(Variadic, TestExpr); \
4019 #define EXPECT_VARIADIC_OPS_EQUAL(TestExpr, Expected) \
4021 const DIExpression *Variadic = \
4022 DIExpression::convertToVariadicExpression(TestExpr); \
4023 EXPECT_EQ(Variadic, Expected); \
4025 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
4027 // Expressions which are already variadic should be unaffected.
4028 EXPECT_CONVERT_IS_NOOP(
4029 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_stack_value
));
4030 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
4031 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_plus
,
4032 dwarf::DW_OP_stack_value
));
4033 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_constu
, 5, dwarf::DW_OP_LLVM_arg
,
4034 0, dwarf::DW_OP_plus
,
4035 dwarf::DW_OP_stack_value
));
4036 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
4037 dwarf::DW_OP_stack_value
,
4038 dwarf::DW_OP_LLVM_fragment
, 0, 32));
4040 // Other expressions should receive a leading `LLVM_arg 0`.
4041 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(), GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0));
4042 EXPECT_VARIADIC_OPS_EQUAL(
4043 GET_EXPR(dwarf::DW_OP_plus_uconst
, 4),
4044 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 4));
4045 EXPECT_VARIADIC_OPS_EQUAL(
4046 GET_EXPR(dwarf::DW_OP_plus_uconst
, 4, dwarf::DW_OP_stack_value
),
4047 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 4,
4048 dwarf::DW_OP_stack_value
));
4049 EXPECT_VARIADIC_OPS_EQUAL(
4050 GET_EXPR(dwarf::DW_OP_plus_uconst
, 6, dwarf::DW_OP_stack_value
,
4051 dwarf::DW_OP_LLVM_fragment
, 32, 32),
4052 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 6,
4053 dwarf::DW_OP_stack_value
, dwarf::DW_OP_LLVM_fragment
, 32, 32));
4054 EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst
, 14,
4055 dwarf::DW_OP_LLVM_fragment
, 32, 32),
4056 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
4057 dwarf::DW_OP_plus_uconst
, 14,
4058 dwarf::DW_OP_LLVM_fragment
, 32, 32));
4060 #undef EXPECT_CONVERT_IS_NOOP
4061 #undef EXPECT_VARIADIC_OPS_EQUAL
4065 TEST_F(DIExpressionTest
, convertToNonVariadicExpression
) {
4066 #define EXPECT_CONVERT_IS_NOOP(TestExpr) \
4068 std::optional<const DIExpression *> NonVariadic = \
4069 DIExpression::convertToNonVariadicExpression(TestExpr); \
4070 EXPECT_TRUE(NonVariadic.has_value()); \
4071 EXPECT_EQ(*NonVariadic, TestExpr); \
4073 #define EXPECT_NON_VARIADIC_OPS_EQUAL(TestExpr, Expected) \
4075 std::optional<const DIExpression *> NonVariadic = \
4076 DIExpression::convertToNonVariadicExpression(TestExpr); \
4077 EXPECT_TRUE(NonVariadic.has_value()); \
4078 EXPECT_EQ(*NonVariadic, Expected); \
4080 #define EXPECT_INVALID_CONVERSION(TestExpr) \
4082 std::optional<const DIExpression *> NonVariadic = \
4083 DIExpression::convertToNonVariadicExpression(TestExpr); \
4084 EXPECT_FALSE(NonVariadic.has_value()); \
4086 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
4088 // Expressions which are already non-variadic should be unaffected.
4089 EXPECT_CONVERT_IS_NOOP(GET_EXPR());
4090 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst
, 4));
4091 EXPECT_CONVERT_IS_NOOP(
4092 GET_EXPR(dwarf::DW_OP_plus_uconst
, 4, dwarf::DW_OP_stack_value
));
4093 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst
, 6,
4094 dwarf::DW_OP_stack_value
,
4095 dwarf::DW_OP_LLVM_fragment
, 32, 32));
4096 EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_plus_uconst
, 14,
4097 dwarf::DW_OP_LLVM_fragment
, 32, 32));
4099 // Variadic expressions with a single leading `LLVM_arg 0` and no other
4100 // LLVM_args should have the leading arg removed.
4101 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0), GET_EXPR());
4102 EXPECT_NON_VARIADIC_OPS_EQUAL(
4103 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_stack_value
),
4104 GET_EXPR(dwarf::DW_OP_stack_value
));
4105 EXPECT_NON_VARIADIC_OPS_EQUAL(
4106 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_fragment
, 16, 32),
4107 GET_EXPR(dwarf::DW_OP_LLVM_fragment
, 16, 32));
4108 EXPECT_NON_VARIADIC_OPS_EQUAL(
4109 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_stack_value
,
4110 dwarf::DW_OP_LLVM_fragment
, 24, 32),
4111 GET_EXPR(dwarf::DW_OP_stack_value
, dwarf::DW_OP_LLVM_fragment
, 24, 32));
4112 EXPECT_NON_VARIADIC_OPS_EQUAL(
4113 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 4),
4114 GET_EXPR(dwarf::DW_OP_plus_uconst
, 4));
4115 EXPECT_NON_VARIADIC_OPS_EQUAL(
4116 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 4,
4117 dwarf::DW_OP_stack_value
),
4118 GET_EXPR(dwarf::DW_OP_plus_uconst
, 4, dwarf::DW_OP_stack_value
));
4119 EXPECT_NON_VARIADIC_OPS_EQUAL(
4120 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 6,
4121 dwarf::DW_OP_stack_value
, dwarf::DW_OP_LLVM_fragment
, 32, 32),
4122 GET_EXPR(dwarf::DW_OP_plus_uconst
, 6, dwarf::DW_OP_stack_value
,
4123 dwarf::DW_OP_LLVM_fragment
, 32, 32));
4124 EXPECT_NON_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
4125 dwarf::DW_OP_plus_uconst
, 14,
4126 dwarf::DW_OP_LLVM_fragment
, 32, 32),
4127 GET_EXPR(dwarf::DW_OP_plus_uconst
, 14,
4128 dwarf::DW_OP_LLVM_fragment
, 32, 32));
4130 // Variadic expressions that have any LLVM_args other than a leading
4131 // `LLVM_arg 0` cannot be converted and so should return std::nullopt.
4132 EXPECT_INVALID_CONVERSION(GET_EXPR(
4133 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
));
4134 EXPECT_INVALID_CONVERSION(
4135 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_arg
, 1,
4136 dwarf::DW_OP_plus
, dwarf::DW_OP_stack_value
));
4137 EXPECT_INVALID_CONVERSION(
4138 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_arg
, 0,
4139 dwarf::DW_OP_minus
, dwarf::DW_OP_stack_value
));
4140 EXPECT_INVALID_CONVERSION(GET_EXPR(dwarf::DW_OP_constu
, 5,
4141 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_div
,
4142 dwarf::DW_OP_stack_value
));
4144 #undef EXPECT_CONVERT_IS_NOOP
4145 #undef EXPECT_NON_VARIADIC_OPS_EQUAL
4146 #undef EXPECT_INVALID_CONVERSION
4150 TEST_F(DIExpressionTest
, replaceArg
) {
4151 #define EXPECT_REPLACE_ARG_EQ(Expr, OldArg, NewArg, ...) \
4153 uint64_t Elements[] = {__VA_ARGS__}; \
4154 ArrayRef<uint64_t> Expected = Elements; \
4155 DIExpression *Expression = DIExpression::replaceArg(Expr, OldArg, NewArg); \
4156 EXPECT_EQ(Expression->getElements(), Expected); \
4159 auto N
= DIExpression::get(
4160 Context
, {dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_LLVM_arg
, 1,
4161 dwarf::DW_OP_plus
, dwarf::DW_OP_LLVM_arg
, 2, dwarf::DW_OP_mul
});
4162 EXPECT_REPLACE_ARG_EQ(N
, 0, 1, dwarf::DW_OP_LLVM_arg
, 0,
4163 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus
,
4164 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
);
4165 EXPECT_REPLACE_ARG_EQ(N
, 0, 2, dwarf::DW_OP_LLVM_arg
, 1,
4166 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus
,
4167 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
);
4168 EXPECT_REPLACE_ARG_EQ(N
, 2, 0, dwarf::DW_OP_LLVM_arg
, 0,
4169 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_plus
,
4170 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_mul
);
4171 EXPECT_REPLACE_ARG_EQ(N
, 2, 1, dwarf::DW_OP_LLVM_arg
, 0,
4172 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_plus
,
4173 dwarf::DW_OP_LLVM_arg
, 1, dwarf::DW_OP_mul
);
4175 #undef EXPECT_REPLACE_ARG_EQ
4178 TEST_F(DIExpressionTest
, isEqualExpression
) {
4179 #define EXPECT_EQ_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \
4180 EXPECT_TRUE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB))
4181 #define EXPECT_NE_DEBUG_VALUE(ExprA, DirectA, ExprB, DirectB) \
4182 EXPECT_FALSE(DIExpression::isEqualExpression(ExprA, DirectA, ExprB, DirectB))
4183 #define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
4185 EXPECT_EQ_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), false);
4186 EXPECT_NE_DEBUG_VALUE(GET_EXPR(), false, GET_EXPR(), true);
4187 EXPECT_EQ_DEBUG_VALUE(
4188 GET_EXPR(dwarf::DW_OP_plus_uconst
, 32), true,
4189 GET_EXPR(dwarf::DW_OP_plus_uconst
, 32, dwarf::DW_OP_deref
), false);
4190 EXPECT_NE_DEBUG_VALUE(
4191 GET_EXPR(dwarf::DW_OP_plus_uconst
, 16, dwarf::DW_OP_deref
), true,
4192 GET_EXPR(dwarf::DW_OP_plus_uconst
, 16, dwarf::DW_OP_deref
), false);
4193 EXPECT_EQ_DEBUG_VALUE(
4194 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus_uconst
, 5), false,
4195 GET_EXPR(dwarf::DW_OP_plus_uconst
, 5), false);
4196 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus
),
4198 GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0,
4199 dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_plus
),
4201 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_constu
,
4202 8, dwarf::DW_OP_minus
),
4204 GET_EXPR(dwarf::DW_OP_constu
, 8, dwarf::DW_OP_LLVM_arg
,
4205 0, dwarf::DW_OP_minus
),
4207 // These expressions are actually equivalent, but we do not currently identify
4208 // commutative operations with different operand orders as being equivalent.
4209 EXPECT_NE_DEBUG_VALUE(GET_EXPR(dwarf::DW_OP_LLVM_arg
, 0, dwarf::DW_OP_constu
,
4210 8, dwarf::DW_OP_plus
),
4212 GET_EXPR(dwarf::DW_OP_constu
, 8, dwarf::DW_OP_LLVM_arg
,
4213 0, dwarf::DW_OP_plus
),
4216 #undef EXPECT_EQ_DEBUG_VALUE
4217 #undef EXPECT_NE_DEBUG_VALUE
4221 TEST_F(DIExpressionTest
, foldConstant
) {
4222 const ConstantInt
*Int
;
4223 const ConstantInt
*NewInt
;
4225 DIExpression
*NewExpr
;
4227 #define EXPECT_FOLD_CONST(StartWidth, StartValue, EndWidth, EndValue, NumElts) \
4228 Int = ConstantInt::get(Context, APInt(StartWidth, StartValue)); \
4229 std::tie(NewExpr, NewInt) = Expr->constantFold(Int); \
4230 ASSERT_EQ(NewInt->getBitWidth(), EndWidth##u); \
4231 EXPECT_EQ(NewInt->getValue(), APInt(EndWidth, EndValue)); \
4232 EXPECT_EQ(NewExpr->getNumElements(), NumElts##u)
4234 // Unfoldable expression should return the original unmodified Int/Expr.
4235 Expr
= DIExpression::get(Context
, {dwarf::DW_OP_deref
});
4236 EXPECT_FOLD_CONST(32, 117, 32, 117, 1);
4237 EXPECT_EQ(NewExpr
, Expr
);
4238 EXPECT_EQ(NewInt
, Int
);
4239 EXPECT_TRUE(NewExpr
->startsWithDeref());
4241 // One unsigned bit-width conversion.
4242 Expr
= DIExpression::get(
4243 Context
, {dwarf::DW_OP_LLVM_convert
, 72, dwarf::DW_ATE_unsigned
});
4244 EXPECT_FOLD_CONST(8, 12, 72, 12, 0);
4246 // Two unsigned bit-width conversions (mask truncation).
4247 Expr
= DIExpression::get(
4248 Context
, {dwarf::DW_OP_LLVM_convert
, 8, dwarf::DW_ATE_unsigned
,
4249 dwarf::DW_OP_LLVM_convert
, 16, dwarf::DW_ATE_unsigned
});
4250 EXPECT_FOLD_CONST(32, -1, 16, 0xff, 0);
4253 Expr
= DIExpression::get(
4254 Context
, {dwarf::DW_OP_LLVM_convert
, 32, dwarf::DW_ATE_signed
});
4255 EXPECT_FOLD_CONST(16, -1, 32, -1, 0);
4257 // Get non-foldable operations back in the new Expr.
4258 uint64_t Elements
[] = {dwarf::DW_OP_deref
, dwarf::DW_OP_stack_value
};
4259 ArrayRef
<uint64_t> Expected
= Elements
;
4260 Expr
= DIExpression::get(
4261 Context
, {dwarf::DW_OP_LLVM_convert
, 32, dwarf::DW_ATE_signed
});
4262 Expr
= DIExpression::append(Expr
, Expected
);
4263 ASSERT_EQ(Expr
->getNumElements(), 5u);
4264 EXPECT_FOLD_CONST(16, -1, 32, -1, 2);
4265 EXPECT_EQ(NewExpr
->getElements(), Expected
);
4267 #undef EXPECT_FOLD_CONST
4270 TEST_F(DIExpressionTest
, appendToStackAssert
) {
4271 DIExpression
*Expr
= DIExpression::get(Context
, {});
4273 // Verify that the DW_OP_LLVM_convert operands, which have the same values as
4274 // DW_OP_stack_value and DW_OP_LLVM_fragment, do not get interpreted as such
4275 // operations. This previously triggered an assert.
4276 uint64_t FromSize
= dwarf::DW_OP_stack_value
;
4277 uint64_t ToSize
= dwarf::DW_OP_LLVM_fragment
;
4279 dwarf::DW_OP_LLVM_convert
, FromSize
, dwarf::DW_ATE_signed
,
4280 dwarf::DW_OP_LLVM_convert
, ToSize
, dwarf::DW_ATE_signed
,
4282 Expr
= DIExpression::appendToStack(Expr
, Ops
);
4284 uint64_t Expected
[] = {
4285 dwarf::DW_OP_LLVM_convert
, FromSize
, dwarf::DW_ATE_signed
,
4286 dwarf::DW_OP_LLVM_convert
, ToSize
, dwarf::DW_ATE_signed
,
4287 dwarf::DW_OP_stack_value
};
4288 EXPECT_EQ(Expr
->getElements(), ArrayRef
<uint64_t>(Expected
));
4291 typedef MetadataTest DIObjCPropertyTest
;
4293 TEST_F(DIObjCPropertyTest
, get
) {
4294 StringRef Name
= "name";
4295 DIFile
*File
= getFile();
4297 StringRef GetterName
= "getter";
4298 StringRef SetterName
= "setter";
4299 unsigned Attributes
= 7;
4300 DIType
*Type
= getBasicType("basic");
4302 auto *N
= DIObjCProperty::get(Context
, Name
, File
, Line
, GetterName
,
4303 SetterName
, Attributes
, Type
);
4305 EXPECT_EQ(dwarf::DW_TAG_APPLE_property
, N
->getTag());
4306 EXPECT_EQ(Name
, N
->getName());
4307 EXPECT_EQ(File
, N
->getFile());
4308 EXPECT_EQ(Line
, N
->getLine());
4309 EXPECT_EQ(GetterName
, N
->getGetterName());
4310 EXPECT_EQ(SetterName
, N
->getSetterName());
4311 EXPECT_EQ(Attributes
, N
->getAttributes());
4312 EXPECT_EQ(Type
, N
->getType());
4313 EXPECT_EQ(N
, DIObjCProperty::get(Context
, Name
, File
, Line
, GetterName
,
4314 SetterName
, Attributes
, Type
));
4316 EXPECT_NE(N
, DIObjCProperty::get(Context
, "other", File
, Line
, GetterName
,
4317 SetterName
, Attributes
, Type
));
4318 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, getFile(), Line
, GetterName
,
4319 SetterName
, Attributes
, Type
));
4320 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, File
, Line
+ 1, GetterName
,
4321 SetterName
, Attributes
, Type
));
4322 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, File
, Line
, "other",
4323 SetterName
, Attributes
, Type
));
4324 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, File
, Line
, GetterName
,
4325 "other", Attributes
, Type
));
4326 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, File
, Line
, GetterName
,
4327 SetterName
, Attributes
+ 1, Type
));
4328 EXPECT_NE(N
, DIObjCProperty::get(Context
, Name
, File
, Line
, GetterName
,
4329 SetterName
, Attributes
,
4330 getBasicType("other")));
4332 TempDIObjCProperty Temp
= N
->clone();
4333 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
4336 typedef MetadataTest DIImportedEntityTest
;
4338 TEST_F(DIImportedEntityTest
, get
) {
4339 unsigned Tag
= dwarf::DW_TAG_imported_module
;
4340 DIScope
*Scope
= getSubprogram();
4341 DINode
*Entity
= getCompositeType();
4342 DIFile
*File
= getFile();
4344 StringRef Name
= "name";
4347 DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
, Name
);
4349 EXPECT_EQ(Tag
, N
->getTag());
4350 EXPECT_EQ(Scope
, N
->getScope());
4351 EXPECT_EQ(Entity
, N
->getEntity());
4352 EXPECT_EQ(File
, N
->getFile());
4353 EXPECT_EQ(Line
, N
->getLine());
4354 EXPECT_EQ(Name
, N
->getName());
4356 N
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
, Name
));
4359 DIImportedEntity::get(Context
, dwarf::DW_TAG_imported_declaration
,
4360 Scope
, Entity
, File
, Line
, Name
));
4361 EXPECT_NE(N
, DIImportedEntity::get(Context
, Tag
, getSubprogram(), Entity
,
4363 EXPECT_NE(N
, DIImportedEntity::get(Context
, Tag
, Scope
, getCompositeType(),
4365 EXPECT_NE(N
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, nullptr, Line
,
4367 EXPECT_NE(N
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
,
4369 EXPECT_NE(N
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
,
4372 TempDIImportedEntity Temp
= N
->clone();
4373 EXPECT_EQ(N
, MDNode::replaceWithUniqued(std::move(Temp
)));
4375 MDTuple
*Elements1
= getTuple();
4376 MDTuple
*Elements2
= getTuple();
4377 auto *Ne
= DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
,
4380 EXPECT_EQ(Elements1
, Ne
->getElements().get());
4382 EXPECT_EQ(Ne
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
,
4384 EXPECT_NE(Ne
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
,
4385 "ModOther", Elements1
));
4386 EXPECT_NE(Ne
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
,
4389 Ne
, DIImportedEntity::get(Context
, Tag
, Scope
, Entity
, File
, Line
, Name
));
4391 TempDIImportedEntity Tempe
= Ne
->clone();
4392 EXPECT_EQ(Ne
, MDNode::replaceWithUniqued(std::move(Tempe
)));
4395 typedef MetadataTest MetadataAsValueTest
;
4397 TEST_F(MetadataAsValueTest
, MDNode
) {
4398 MDNode
*N
= MDNode::get(Context
, std::nullopt
);
4399 auto *V
= MetadataAsValue::get(Context
, N
);
4400 EXPECT_TRUE(V
->getType()->isMetadataTy());
4401 EXPECT_EQ(N
, V
->getMetadata());
4403 auto *V2
= MetadataAsValue::get(Context
, N
);
4407 TEST_F(MetadataAsValueTest
, MDNodeMDNode
) {
4408 MDNode
*N
= MDNode::get(Context
, std::nullopt
);
4409 Metadata
*Ops
[] = {N
};
4410 MDNode
*N2
= MDNode::get(Context
, Ops
);
4411 auto *V
= MetadataAsValue::get(Context
, N2
);
4412 EXPECT_TRUE(V
->getType()->isMetadataTy());
4413 EXPECT_EQ(N2
, V
->getMetadata());
4415 auto *V2
= MetadataAsValue::get(Context
, N2
);
4418 auto *V3
= MetadataAsValue::get(Context
, N
);
4419 EXPECT_TRUE(V3
->getType()->isMetadataTy());
4421 EXPECT_EQ(N
, V3
->getMetadata());
4424 TEST_F(MetadataAsValueTest
, MDNodeConstant
) {
4425 auto *C
= ConstantInt::getTrue(Context
);
4426 auto *MD
= ConstantAsMetadata::get(C
);
4427 Metadata
*Ops
[] = {MD
};
4428 auto *N
= MDNode::get(Context
, Ops
);
4430 auto *V
= MetadataAsValue::get(Context
, MD
);
4431 EXPECT_TRUE(V
->getType()->isMetadataTy());
4432 EXPECT_EQ(MD
, V
->getMetadata());
4434 auto *V2
= MetadataAsValue::get(Context
, N
);
4435 EXPECT_EQ(MD
, V2
->getMetadata());
4439 typedef MetadataTest ValueAsMetadataTest
;
4441 TEST_F(ValueAsMetadataTest
, UpdatesOnRAUW
) {
4442 Type
*Ty
= PointerType::getUnqual(Context
);
4443 std::unique_ptr
<GlobalVariable
> GV0(
4444 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4445 auto *MD
= ValueAsMetadata::get(GV0
.get());
4446 EXPECT_TRUE(MD
->getValue() == GV0
.get());
4447 ASSERT_TRUE(GV0
->use_empty());
4449 std::unique_ptr
<GlobalVariable
> GV1(
4450 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4451 GV0
->replaceAllUsesWith(GV1
.get());
4452 EXPECT_TRUE(MD
->getValue() == GV1
.get());
4455 TEST_F(ValueAsMetadataTest
, handleRAUWWithTypeChange
) {
4456 // Test that handleRAUW supports type changes.
4457 // This is helpful in cases where poison values are used to encode
4458 // types in metadata, e.g. in type annotations.
4459 // Changing the type stored in metadata requires to change the type of
4460 // the stored poison value.
4461 auto *I32Poison
= PoisonValue::get(Type::getInt32Ty(Context
));
4462 auto *I64Poison
= PoisonValue::get(Type::getInt64Ty(Context
));
4463 auto *MD
= ConstantAsMetadata::get(I32Poison
);
4465 EXPECT_EQ(MD
->getValue(), I32Poison
);
4466 EXPECT_NE(MD
->getValue(), I64Poison
);
4468 ValueAsMetadata::handleRAUW(I32Poison
, I64Poison
);
4470 EXPECT_NE(MD
->getValue(), I32Poison
);
4471 EXPECT_EQ(MD
->getValue(), I64Poison
);
4474 TEST_F(ValueAsMetadataTest
, TempTempReplacement
) {
4475 // Create a constant.
4476 ConstantAsMetadata
*CI
=
4477 ConstantAsMetadata::get(ConstantInt::get(Context
, APInt(8, 0)));
4479 auto Temp1
= MDTuple::getTemporary(Context
, std::nullopt
);
4480 auto Temp2
= MDTuple::getTemporary(Context
, {CI
});
4481 auto *N
= MDTuple::get(Context
, {Temp1
.get()});
4483 // Test replacing a temporary node with another temporary node.
4484 Temp1
->replaceAllUsesWith(Temp2
.get());
4485 EXPECT_EQ(N
->getOperand(0), Temp2
.get());
4487 // Clean up Temp2 for teardown.
4488 Temp2
->replaceAllUsesWith(nullptr);
4491 TEST_F(ValueAsMetadataTest
, CollidingDoubleUpdates
) {
4492 // Create a constant.
4493 ConstantAsMetadata
*CI
=
4494 ConstantAsMetadata::get(ConstantInt::get(Context
, APInt(8, 0)));
4496 // Create a temporary to prevent nodes from resolving.
4497 auto Temp
= MDTuple::getTemporary(Context
, std::nullopt
);
4499 // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
4500 Metadata
*Ops1
[] = {CI
, CI
, Temp
.get()};
4501 Metadata
*Ops2
[] = {nullptr, CI
, Temp
.get()};
4503 auto *N1
= MDTuple::get(Context
, Ops1
);
4504 auto *N2
= MDTuple::get(Context
, Ops2
);
4507 // Tell metadata that the constant is getting deleted.
4509 // After this, N1 will be invalid, so don't touch it.
4510 ValueAsMetadata::handleDeletion(CI
->getValue());
4511 EXPECT_EQ(nullptr, N2
->getOperand(0));
4512 EXPECT_EQ(nullptr, N2
->getOperand(1));
4513 EXPECT_EQ(Temp
.get(), N2
->getOperand(2));
4515 // Clean up Temp for teardown.
4516 Temp
->replaceAllUsesWith(nullptr);
4519 typedef MetadataTest DIArgListTest
;
4521 TEST_F(DIArgListTest
, get
) {
4522 SmallVector
<ValueAsMetadata
*, 2> VMs
;
4524 ConstantAsMetadata::get(ConstantInt::get(Context
, APInt(8, 0))));
4526 ConstantAsMetadata::get(ConstantInt::get(Context
, APInt(2, 0))));
4527 DIArgList
*DV0
= DIArgList::get(Context
, VMs
);
4528 DIArgList
*DV1
= DIArgList::get(Context
, VMs
);
4529 EXPECT_EQ(DV0
, DV1
);
4532 TEST_F(DIArgListTest
, UpdatesOnRAUW
) {
4533 Type
*Ty
= PointerType::getUnqual(Context
);
4534 ConstantAsMetadata
*CI
=
4535 ConstantAsMetadata::get(ConstantInt::get(Context
, APInt(8, 0)));
4536 std::unique_ptr
<GlobalVariable
> GV0(
4537 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4538 auto *MD0
= ValueAsMetadata::get(GV0
.get());
4540 SmallVector
<ValueAsMetadata
*, 2> VMs
;
4543 auto *AL
= DIArgList::get(Context
, VMs
);
4544 EXPECT_EQ(AL
->getArgs()[0], CI
);
4545 EXPECT_EQ(AL
->getArgs()[1], MD0
);
4547 std::unique_ptr
<GlobalVariable
> GV1(
4548 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4549 auto *MD1
= ValueAsMetadata::get(GV1
.get());
4550 GV0
->replaceAllUsesWith(GV1
.get());
4551 EXPECT_EQ(AL
->getArgs()[0], CI
);
4552 EXPECT_EQ(AL
->getArgs()[1], MD1
);
4555 typedef MetadataTest TrackingMDRefTest
;
4557 TEST_F(TrackingMDRefTest
, UpdatesOnRAUW
) {
4558 Type
*Ty
= PointerType::getUnqual(Context
);
4559 std::unique_ptr
<GlobalVariable
> GV0(
4560 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4561 TypedTrackingMDRef
<ValueAsMetadata
> MD(ValueAsMetadata::get(GV0
.get()));
4562 EXPECT_TRUE(MD
->getValue() == GV0
.get());
4563 ASSERT_TRUE(GV0
->use_empty());
4565 std::unique_ptr
<GlobalVariable
> GV1(
4566 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4567 GV0
->replaceAllUsesWith(GV1
.get());
4568 EXPECT_TRUE(MD
->getValue() == GV1
.get());
4570 // Reset it, so we don't inadvertently test deletion.
4574 TEST_F(TrackingMDRefTest
, UpdatesOnDeletion
) {
4575 Type
*Ty
= PointerType::getUnqual(Context
);
4576 std::unique_ptr
<GlobalVariable
> GV(
4577 new GlobalVariable(Ty
, false, GlobalValue::ExternalLinkage
));
4578 TypedTrackingMDRef
<ValueAsMetadata
> MD(ValueAsMetadata::get(GV
.get()));
4579 EXPECT_TRUE(MD
->getValue() == GV
.get());
4580 ASSERT_TRUE(GV
->use_empty());
4586 TEST(NamedMDNodeTest
, Search
) {
4587 LLVMContext Context
;
4588 ConstantAsMetadata
*C
=
4589 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context
), 1));
4590 ConstantAsMetadata
*C2
=
4591 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context
), 2));
4593 Metadata
*const V
= C
;
4594 Metadata
*const V2
= C2
;
4595 MDNode
*n
= MDNode::get(Context
, V
);
4596 MDNode
*n2
= MDNode::get(Context
, V2
);
4598 Module
M("MyModule", Context
);
4599 const char *Name
= "llvm.NMD1";
4600 NamedMDNode
*NMD
= M
.getOrInsertNamedMetadata(Name
);
4602 NMD
->addOperand(n2
);
4605 raw_string_ostream
oss(Str
);
4607 EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n",
4611 typedef MetadataTest FunctionAttachmentTest
;
4612 TEST_F(FunctionAttachmentTest
, setMetadata
) {
4613 Function
*F
= getFunction("foo");
4614 ASSERT_FALSE(F
->hasMetadata());
4615 EXPECT_EQ(nullptr, F
->getMetadata(LLVMContext::MD_dbg
));
4616 EXPECT_EQ(nullptr, F
->getMetadata("dbg"));
4617 EXPECT_EQ(nullptr, F
->getMetadata("other"));
4619 DISubprogram
*SP1
= getSubprogram();
4620 DISubprogram
*SP2
= getSubprogram();
4621 ASSERT_NE(SP1
, SP2
);
4623 F
->setMetadata("dbg", SP1
);
4624 EXPECT_TRUE(F
->hasMetadata());
4625 EXPECT_EQ(SP1
, F
->getMetadata(LLVMContext::MD_dbg
));
4626 EXPECT_EQ(SP1
, F
->getMetadata("dbg"));
4627 EXPECT_EQ(nullptr, F
->getMetadata("other"));
4629 F
->setMetadata(LLVMContext::MD_dbg
, SP2
);
4630 EXPECT_TRUE(F
->hasMetadata());
4631 EXPECT_EQ(SP2
, F
->getMetadata(LLVMContext::MD_dbg
));
4632 EXPECT_EQ(SP2
, F
->getMetadata("dbg"));
4633 EXPECT_EQ(nullptr, F
->getMetadata("other"));
4635 F
->setMetadata("dbg", nullptr);
4636 EXPECT_FALSE(F
->hasMetadata());
4637 EXPECT_EQ(nullptr, F
->getMetadata(LLVMContext::MD_dbg
));
4638 EXPECT_EQ(nullptr, F
->getMetadata("dbg"));
4639 EXPECT_EQ(nullptr, F
->getMetadata("other"));
4641 MDTuple
*T1
= getTuple();
4642 MDTuple
*T2
= getTuple();
4645 F
->setMetadata("other1", T1
);
4646 F
->setMetadata("other2", T2
);
4647 EXPECT_TRUE(F
->hasMetadata());
4648 EXPECT_EQ(T1
, F
->getMetadata("other1"));
4649 EXPECT_EQ(T2
, F
->getMetadata("other2"));
4650 EXPECT_EQ(nullptr, F
->getMetadata("dbg"));
4652 F
->setMetadata("other1", T2
);
4653 F
->setMetadata("other2", T1
);
4654 EXPECT_EQ(T2
, F
->getMetadata("other1"));
4655 EXPECT_EQ(T1
, F
->getMetadata("other2"));
4657 F
->setMetadata("other1", nullptr);
4658 F
->setMetadata("other2", nullptr);
4659 EXPECT_FALSE(F
->hasMetadata());
4660 EXPECT_EQ(nullptr, F
->getMetadata("other1"));
4661 EXPECT_EQ(nullptr, F
->getMetadata("other2"));
4664 TEST_F(FunctionAttachmentTest
, getAll
) {
4665 Function
*F
= getFunction("foo");
4667 MDTuple
*T1
= getTuple();
4668 MDTuple
*T2
= getTuple();
4669 MDTuple
*P
= getTuple();
4670 DISubprogram
*SP
= getSubprogram();
4672 F
->setMetadata("other1", T2
);
4673 F
->setMetadata(LLVMContext::MD_dbg
, SP
);
4674 F
->setMetadata("other2", T1
);
4675 F
->setMetadata(LLVMContext::MD_prof
, P
);
4676 F
->setMetadata("other2", T2
);
4677 F
->setMetadata("other1", T1
);
4679 SmallVector
<std::pair
<unsigned, MDNode
*>, 4> MDs
;
4680 F
->getAllMetadata(MDs
);
4681 ASSERT_EQ(4u, MDs
.size());
4682 EXPECT_EQ(LLVMContext::MD_dbg
, MDs
[0].first
);
4683 EXPECT_EQ(LLVMContext::MD_prof
, MDs
[1].first
);
4684 EXPECT_EQ(Context
.getMDKindID("other1"), MDs
[2].first
);
4685 EXPECT_EQ(Context
.getMDKindID("other2"), MDs
[3].first
);
4686 EXPECT_EQ(SP
, MDs
[0].second
);
4687 EXPECT_EQ(P
, MDs
[1].second
);
4688 EXPECT_EQ(T1
, MDs
[2].second
);
4689 EXPECT_EQ(T2
, MDs
[3].second
);
4692 TEST_F(FunctionAttachmentTest
, Verifier
) {
4693 Function
*F
= getFunction("foo");
4694 F
->setMetadata("attach", getTuple());
4695 F
->setIsMaterializable(true);
4697 // Confirm this is materializable.
4698 ASSERT_TRUE(F
->isMaterializable());
4700 // Materializable functions cannot have metadata attachments.
4701 EXPECT_TRUE(verifyFunction(*F
));
4703 // Function declarations can.
4704 F
->setIsMaterializable(false);
4705 EXPECT_FALSE(verifyModule(*F
->getParent()));
4706 EXPECT_FALSE(verifyFunction(*F
));
4708 // So can definitions.
4709 (void)new UnreachableInst(Context
, BasicBlock::Create(Context
, "bb", F
));
4710 EXPECT_FALSE(verifyModule(*F
->getParent()));
4711 EXPECT_FALSE(verifyFunction(*F
));
4714 TEST_F(FunctionAttachmentTest
, RealEntryCount
) {
4715 Function
*F
= getFunction("foo");
4716 EXPECT_FALSE(F
->getEntryCount().has_value());
4717 F
->setEntryCount(12304, Function::PCT_Real
);
4718 auto Count
= F
->getEntryCount();
4719 EXPECT_TRUE(Count
.has_value());
4720 EXPECT_EQ(12304u, Count
->getCount());
4721 EXPECT_EQ(Function::PCT_Real
, Count
->getType());
4724 TEST_F(FunctionAttachmentTest
, SyntheticEntryCount
) {
4725 Function
*F
= getFunction("bar");
4726 EXPECT_FALSE(F
->getEntryCount().has_value());
4727 F
->setEntryCount(123, Function::PCT_Synthetic
);
4728 auto Count
= F
->getEntryCount(true /*allow synthetic*/);
4729 EXPECT_TRUE(Count
.has_value());
4730 EXPECT_EQ(123u, Count
->getCount());
4731 EXPECT_EQ(Function::PCT_Synthetic
, Count
->getType());
4734 TEST_F(FunctionAttachmentTest
, SubprogramAttachment
) {
4735 Function
*F
= getFunction("foo");
4736 DISubprogram
*SP
= getSubprogram();
4737 F
->setSubprogram(SP
);
4739 // Note that the static_cast confirms that F->getSubprogram() actually
4740 // returns an DISubprogram.
4741 EXPECT_EQ(SP
, static_cast<DISubprogram
*>(F
->getSubprogram()));
4742 EXPECT_EQ(SP
, F
->getMetadata("dbg"));
4743 EXPECT_EQ(SP
, F
->getMetadata(LLVMContext::MD_dbg
));
4746 typedef MetadataTest DistinctMDOperandPlaceholderTest
;
4747 TEST_F(DistinctMDOperandPlaceholderTest
, getID
) {
4748 EXPECT_EQ(7u, DistinctMDOperandPlaceholder(7).getID());
4751 TEST_F(DistinctMDOperandPlaceholderTest
, replaceUseWith
) {
4752 // Set up some placeholders.
4753 DistinctMDOperandPlaceholder
PH0(7);
4754 DistinctMDOperandPlaceholder
PH1(3);
4755 DistinctMDOperandPlaceholder
PH2(0);
4756 Metadata
*Ops
[] = {&PH0
, &PH1
, &PH2
};
4757 auto *D
= MDTuple::getDistinct(Context
, Ops
);
4758 ASSERT_EQ(&PH0
, D
->getOperand(0));
4759 ASSERT_EQ(&PH1
, D
->getOperand(1));
4760 ASSERT_EQ(&PH2
, D
->getOperand(2));
4763 auto *N0
= MDTuple::get(Context
, std::nullopt
);
4764 auto *N1
= MDTuple::get(Context
, N0
);
4765 PH0
.replaceUseWith(N0
);
4766 PH1
.replaceUseWith(N1
);
4767 PH2
.replaceUseWith(nullptr);
4768 EXPECT_EQ(N0
, D
->getOperand(0));
4769 EXPECT_EQ(N1
, D
->getOperand(1));
4770 EXPECT_EQ(nullptr, D
->getOperand(2));
4773 TEST_F(DistinctMDOperandPlaceholderTest
, replaceUseWithNoUser
) {
4774 // There is no user, but we can still call replace.
4775 DistinctMDOperandPlaceholder(7).replaceUseWith(
4776 MDTuple::get(Context
, std::nullopt
));
4779 // Test various assertions in metadata tracking. Don't run these tests if gtest
4780 // will use SEH to recover from them. Two of these tests get halfway through
4781 // inserting metadata into DenseMaps for tracking purposes, and then they
4782 // assert, and we attempt to destroy an LLVMContext with broken invariants,
4783 // leading to infinite loops.
4784 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH)
4785 TEST_F(DistinctMDOperandPlaceholderTest
, MetadataAsValue
) {
4786 // This shouldn't crash.
4787 DistinctMDOperandPlaceholder
PH(7);
4788 EXPECT_DEATH(MetadataAsValue::get(Context
, &PH
),
4789 "Unexpected callback to owner");
4792 TEST_F(DistinctMDOperandPlaceholderTest
, UniquedMDNode
) {
4793 // This shouldn't crash.
4794 DistinctMDOperandPlaceholder
PH(7);
4795 EXPECT_DEATH(MDTuple::get(Context
, &PH
), "Unexpected callback to owner");
4798 TEST_F(DistinctMDOperandPlaceholderTest
, SecondDistinctMDNode
) {
4799 // This shouldn't crash.
4800 DistinctMDOperandPlaceholder
PH(7);
4801 MDTuple::getDistinct(Context
, &PH
);
4802 EXPECT_DEATH(MDTuple::getDistinct(Context
, &PH
),
4803 "Placeholders can only be used once");
4806 TEST_F(DistinctMDOperandPlaceholderTest
, TrackingMDRefAndDistinctMDNode
) {
4807 // TrackingMDRef doesn't install an owner callback, so it can't be detected
4808 // as an invalid use. However, using a placeholder in a TrackingMDRef *and*
4809 // a distinct node isn't possible and we should assert.
4811 // (There's no positive test for using TrackingMDRef because it's not a
4812 // useful thing to do.)
4814 DistinctMDOperandPlaceholder
PH(7);
4815 MDTuple::getDistinct(Context
, &PH
);
4816 EXPECT_DEATH(TrackingMDRef
Ref(&PH
), "Placeholders can only be used once");
4819 DistinctMDOperandPlaceholder
PH(7);
4820 TrackingMDRef
Ref(&PH
);
4821 EXPECT_DEATH(MDTuple::getDistinct(Context
, &PH
),
4822 "Placeholders can only be used once");
4827 typedef MetadataTest DebugVariableTest
;
4828 TEST_F(DebugVariableTest
, DenseMap
) {
4829 DenseMap
<DebugVariable
, uint64_t> DebugVariableMap
;
4831 DILocalScope
*Scope
= getSubprogram();
4832 DIFile
*File
= getFile();
4833 DIType
*Type
= getDerivedType();
4834 DINode::DIFlags Flags
= static_cast<DINode::DIFlags
>(7);
4836 DILocation
*InlinedLoc
= DILocation::get(Context
, 2, 7, Scope
);
4838 DILocalVariable
*VarA
=
4839 DILocalVariable::get(Context
, Scope
, "A", File
, 5, Type
, 2, Flags
, 8, nullptr);
4840 DILocalVariable
*VarB
=
4841 DILocalVariable::get(Context
, Scope
, "B", File
, 7, Type
, 3, Flags
, 8, nullptr);
4843 DebugVariable
DebugVariableA(VarA
, std::nullopt
, nullptr);
4844 DebugVariable
DebugVariableInlineA(VarA
, std::nullopt
, InlinedLoc
);
4845 DebugVariable
DebugVariableB(VarB
, std::nullopt
, nullptr);
4846 DebugVariable
DebugVariableFragB(VarB
, {{16, 16}}, nullptr);
4848 DebugVariableMap
.insert({DebugVariableA
, 2});
4849 DebugVariableMap
.insert({DebugVariableInlineA
, 3});
4850 DebugVariableMap
.insert({DebugVariableB
, 6});
4851 DebugVariableMap
.insert({DebugVariableFragB
, 12});
4853 EXPECT_EQ(DebugVariableMap
.count(DebugVariableA
), 1u);
4854 EXPECT_EQ(DebugVariableMap
.count(DebugVariableInlineA
), 1u);
4855 EXPECT_EQ(DebugVariableMap
.count(DebugVariableB
), 1u);
4856 EXPECT_EQ(DebugVariableMap
.count(DebugVariableFragB
), 1u);
4858 EXPECT_EQ(DebugVariableMap
.find(DebugVariableA
)->second
, 2u);
4859 EXPECT_EQ(DebugVariableMap
.find(DebugVariableInlineA
)->second
, 3u);
4860 EXPECT_EQ(DebugVariableMap
.find(DebugVariableB
)->second
, 6u);
4861 EXPECT_EQ(DebugVariableMap
.find(DebugVariableFragB
)->second
, 12u);
4864 typedef MetadataTest MDTupleAllocationTest
;
4865 TEST_F(MDTupleAllocationTest
, Tracking
) {
4866 // Make sure that the move constructor and move assignment op
4867 // for MDOperand correctly adjust tracking information.
4868 auto *Value1
= getConstantAsMetadata();
4869 MDTuple
*A
= MDTuple::getDistinct(Context
, {Value1
, Value1
});
4870 EXPECT_EQ(A
->getOperand(0), Value1
);
4871 EXPECT_EQ(A
->getOperand(1), Value1
);
4873 MDNode::op_range Ops
= A
->operands();
4876 // Move assignment operator.
4877 NewOps1
= std::move(*const_cast<MDOperand
*>(Ops
.begin()));
4878 // Move constructor.
4879 MDOperand
NewOps2(std::move(*const_cast<MDOperand
*>(Ops
.begin() + 1)));
4881 EXPECT_EQ(NewOps1
.get(), static_cast<Metadata
*>(Value1
));
4882 EXPECT_EQ(NewOps2
.get(), static_cast<Metadata
*>(Value1
));
4884 auto *Value2
= getConstantAsMetadata();
4885 Value
*V1
= Value1
->getValue();
4886 Value
*V2
= Value2
->getValue();
4887 ValueAsMetadata::handleRAUW(V1
, V2
);
4889 EXPECT_EQ(NewOps1
.get(), static_cast<Metadata
*>(Value2
));
4890 EXPECT_EQ(NewOps2
.get(), static_cast<Metadata
*>(Value2
));
4893 TEST_F(MDTupleAllocationTest
, Resize
) {
4894 MDTuple
*A
= getTuple();
4895 Metadata
*Value1
= getConstantAsMetadata();
4896 Metadata
*Value2
= getConstantAsMetadata();
4897 Metadata
*Value3
= getConstantAsMetadata();
4899 EXPECT_EQ(A
->getNumOperands(), 0u);
4901 // Add a couple of elements to it, which resizes the node.
4902 A
->push_back(Value1
);
4903 EXPECT_EQ(A
->getNumOperands(), 1u);
4904 EXPECT_EQ(A
->getOperand(0), Value1
);
4906 A
->push_back(Value2
);
4907 EXPECT_EQ(A
->getNumOperands(), 2u);
4908 EXPECT_EQ(A
->getOperand(0), Value1
);
4909 EXPECT_EQ(A
->getOperand(1), Value2
);
4911 // Append another element, which should resize the node
4912 // to a "large" node, though not detectable by the user.
4913 A
->push_back(Value3
);
4914 EXPECT_EQ(A
->getNumOperands(), 3u);
4915 EXPECT_EQ(A
->getOperand(0), Value1
);
4916 EXPECT_EQ(A
->getOperand(1), Value2
);
4917 EXPECT_EQ(A
->getOperand(2), Value3
);
4919 // Remove the last element
4921 EXPECT_EQ(A
->getNumOperands(), 2u);
4922 EXPECT_EQ(A
->getOperand(1), Value2
);
4924 // Allocate a node with 4 operands.
4925 Metadata
*Value4
= getConstantAsMetadata();
4926 Metadata
*Value5
= getConstantAsMetadata();
4928 Metadata
*Ops
[] = {Value1
, Value2
, Value3
, Value4
};
4929 MDTuple
*B
= MDTuple::getDistinct(Context
, Ops
);
4931 EXPECT_EQ(B
->getNumOperands(), 4u);
4933 EXPECT_EQ(B
->getNumOperands(), 3u);
4934 B
->push_back(Value5
);
4935 EXPECT_EQ(B
->getNumOperands(), 4u);
4936 EXPECT_EQ(B
->getOperand(0), Value1
);
4937 EXPECT_EQ(B
->getOperand(1), Value2
);
4938 EXPECT_EQ(B
->getOperand(2), Value3
);
4939 EXPECT_EQ(B
->getOperand(3), Value5
);
4941 // Check that we can resize temporary nodes as well.
4942 auto Temp1
= MDTuple::getTemporary(Context
, std::nullopt
);
4943 EXPECT_EQ(Temp1
->getNumOperands(), 0u);
4945 Temp1
->push_back(Value1
);
4946 EXPECT_EQ(Temp1
->getNumOperands(), 1u);
4947 EXPECT_EQ(Temp1
->getOperand(0), Value1
);
4949 for (int i
= 0; i
< 11; i
++)
4950 Temp1
->push_back(Value2
);
4951 EXPECT_EQ(Temp1
->getNumOperands(), 12u);
4952 EXPECT_EQ(Temp1
->getOperand(2), Value2
);
4953 EXPECT_EQ(Temp1
->getOperand(11), Value2
);
4955 // Allocate a node that starts off as a large one.
4956 Metadata
*OpsLarge
[] = {Value1
, Value2
, Value3
, Value4
,
4957 Value1
, Value2
, Value3
, Value4
,
4958 Value1
, Value2
, Value3
, Value4
,
4959 Value1
, Value2
, Value3
, Value4
,
4960 Value1
, Value2
, Value3
, Value4
};
4961 MDTuple
*C
= MDTuple::getDistinct(Context
, OpsLarge
);
4962 EXPECT_EQ(C
->getNumOperands(), 20u);
4963 EXPECT_EQ(C
->getOperand(7), Value4
);
4964 EXPECT_EQ(C
->getOperand(13), Value2
);
4966 C
->push_back(Value1
);
4967 C
->push_back(Value2
);
4968 EXPECT_EQ(C
->getNumOperands(), 22u);
4969 EXPECT_EQ(C
->getOperand(21), Value2
);
4971 EXPECT_EQ(C
->getNumOperands(), 21u);
4972 EXPECT_EQ(C
->getOperand(20), Value1
);
4975 TEST_F(MDTupleAllocationTest
, Tracking2
) {
4976 // Resize a tuple and check that we can still RAUW one of its operands.
4977 auto *Value1
= getConstantAsMetadata();
4978 MDTuple
*A
= getTuple();
4979 A
->push_back(Value1
);
4980 A
->push_back(Value1
);
4981 A
->push_back(Value1
); // Causes a resize to large.
4982 EXPECT_EQ(A
->getOperand(0), Value1
);
4983 EXPECT_EQ(A
->getOperand(1), Value1
);
4984 EXPECT_EQ(A
->getOperand(2), Value1
);
4986 auto *Value2
= getConstantAsMetadata();
4987 Value
*V1
= Value1
->getValue();
4988 Value
*V2
= Value2
->getValue();
4989 ValueAsMetadata::handleRAUW(V1
, V2
);
4991 EXPECT_EQ(A
->getOperand(0), Value2
);
4992 EXPECT_EQ(A
->getOperand(1), Value2
);
4993 EXPECT_EQ(A
->getOperand(2), Value2
);
4996 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG) && !defined(GTEST_HAS_SEH)
4997 typedef MetadataTest MDTupleAllocationDeathTest
;
4998 TEST_F(MDTupleAllocationDeathTest
, ResizeRejected
) {
4999 MDTuple
*A
= MDTuple::get(Context
, std::nullopt
);
5000 auto *Value1
= getConstantAsMetadata();
5001 EXPECT_DEATH(A
->push_back(Value1
),
5002 "Resizing is not supported for uniqued nodes");
5004 // Check that a node, which has been allocated as a temporary,
5005 // cannot be resized after it has been uniqued.
5006 auto *Value2
= getConstantAsMetadata();
5007 auto B
= MDTuple::getTemporary(Context
, {Value2
});
5008 B
->push_back(Value2
);
5009 MDTuple
*BUniqued
= MDNode::replaceWithUniqued(std::move(B
));
5010 EXPECT_EQ(BUniqued
->getNumOperands(), 2u);
5011 EXPECT_EQ(BUniqued
->getOperand(1), Value2
);
5012 EXPECT_DEATH(BUniqued
->push_back(Value2
),
5013 "Resizing is not supported for uniqued nodes");