Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / IR / DebugTypeODRUniquingTest.cpp
blobe3a7facb8575b94c1eb906cb93533ae695f8fc48
1 //===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/BinaryFormat/Dwarf.h"
10 #include "llvm/IR/DebugInfoMetadata.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "gtest/gtest.h"
13 using namespace llvm;
15 namespace {
17 TEST(DebugTypeODRUniquingTest, enableDebugTypeODRUniquing) {
18 LLVMContext Context;
19 EXPECT_FALSE(Context.isODRUniquingDebugTypes());
20 Context.enableDebugTypeODRUniquing();
21 EXPECT_TRUE(Context.isODRUniquingDebugTypes());
22 Context.disableDebugTypeODRUniquing();
23 EXPECT_FALSE(Context.isODRUniquingDebugTypes());
26 TEST(DebugTypeODRUniquingTest, getODRType) {
27 LLVMContext Context;
28 MDString &UUID = *MDString::get(Context, "string");
30 // Without a type map, this should return null.
31 EXPECT_FALSE(DICompositeType::getODRType(
32 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
33 nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
34 nullptr, nullptr, nullptr, nullptr, nullptr));
36 // Enable the mapping. There still shouldn't be a type.
37 Context.enableDebugTypeODRUniquing();
38 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
40 // Create some ODR-uniqued type.
41 auto &CT = *DICompositeType::getODRType(
42 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
43 nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
44 nullptr, nullptr, nullptr, nullptr, nullptr);
45 EXPECT_EQ(UUID.getString(), CT.getIdentifier());
47 // Check that we get it back, even if we change a field.
48 EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
49 EXPECT_EQ(&CT,
50 DICompositeType::getODRType(
51 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,
52 nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
53 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
54 nullptr));
55 EXPECT_EQ(&CT, DICompositeType::getODRType(
56 Context, UUID, dwarf::DW_TAG_class_type,
57 MDString::get(Context, "name"), nullptr, 0, nullptr,
58 nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr,
59 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
60 nullptr));
62 // Check that it's discarded with the type map.
63 Context.disableDebugTypeODRUniquing();
64 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
66 // And it shouldn't magically reappear...
67 Context.enableDebugTypeODRUniquing();
68 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
71 TEST(DebugTypeODRUniquingTest, buildODRType) {
72 LLVMContext Context;
73 Context.enableDebugTypeODRUniquing();
75 // Build an ODR type that's a forward decl.
76 MDString &UUID = *MDString::get(Context, "Type");
77 auto &CT = *DICompositeType::buildODRType(
78 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
79 nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
80 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
81 EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
82 EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
84 // Update with another forward decl. This should be a no-op.
85 EXPECT_EQ(&CT, DICompositeType::buildODRType(
86 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
87 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,
88 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
89 nullptr, nullptr));
91 EXPECT_FALSE(DICompositeType::buildODRType(
92 Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
93 nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
94 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
96 // Update with a definition. This time we should see a change.
97 EXPECT_EQ(&CT, DICompositeType::buildODRType(
98 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
99 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
100 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
101 nullptr, nullptr));
102 EXPECT_FALSE(CT.isForwardDecl());
104 // Further updates should be ignored.
105 EXPECT_EQ(&CT, DICompositeType::buildODRType(
106 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
107 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,
108 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
109 nullptr, nullptr));
110 EXPECT_FALSE(CT.isForwardDecl());
111 EXPECT_EQ(&CT, DICompositeType::buildODRType(
112 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
113 111u, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr,
114 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
115 nullptr, nullptr));
116 EXPECT_NE(111u, CT.getLine());
119 TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
120 LLVMContext Context;
121 Context.enableDebugTypeODRUniquing();
123 // Build an ODR type that's a forward decl with no other fields set.
124 MDString &UUID = *MDString::get(Context, "UUID");
125 auto &CT = *DICompositeType::buildODRType(
126 Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
127 DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr,
128 nullptr, nullptr, nullptr, nullptr);
130 // Create macros for running through all the fields except Identifier and Flags.
131 #define FOR_EACH_MDFIELD() \
132 DO_FOR_FIELD(Name) \
133 DO_FOR_FIELD(File) \
134 DO_FOR_FIELD(Scope) \
135 DO_FOR_FIELD(BaseType) \
136 DO_FOR_FIELD(Elements) \
137 DO_FOR_FIELD(VTableHolder) \
138 DO_FOR_FIELD(TemplateParams)
139 #define FOR_EACH_INLINEFIELD() \
140 DO_FOR_FIELD(Line) \
141 DO_FOR_FIELD(SizeInBits) \
142 DO_FOR_FIELD(AlignInBits) \
143 DO_FOR_FIELD(OffsetInBits) \
144 DO_FOR_FIELD(RuntimeLang)
146 // Create all the fields.
147 #define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X);
148 FOR_EACH_MDFIELD();
149 #undef DO_FOR_FIELD
150 unsigned NonZeroInit = 0;
151 #define DO_FOR_FIELD(X) auto X = ++NonZeroInit;
152 FOR_EACH_INLINEFIELD();
153 #undef DO_FOR_FIELD
155 // Replace all the fields with new values that are distinct from each other.
156 EXPECT_EQ(&CT,
157 DICompositeType::buildODRType(
158 Context, UUID, 0, Name, File, Line, Scope, BaseType, SizeInBits,
159 AlignInBits, OffsetInBits, DINode::FlagArtificial, Elements,
160 RuntimeLang, VTableHolder, TemplateParams, nullptr, nullptr,
161 nullptr, nullptr, nullptr, nullptr));
163 // Confirm that all the right fields got updated.
164 #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
165 FOR_EACH_MDFIELD();
166 #undef DO_FOR_FIELD
167 #undef FOR_EACH_MDFIELD
168 #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X());
169 FOR_EACH_INLINEFIELD();
170 #undef DO_FOR_FIELD
171 #undef FOR_EACH_INLINEFIELD
172 EXPECT_EQ(DINode::FlagArtificial, CT.getFlags());
173 EXPECT_EQ(&UUID, CT.getRawIdentifier());
176 } // end namespace