1 //===- DebugTypeODRUniquingTest.cpp - Debug type ODR uniquing tests -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/IR/DebugInfoMetadata.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "gtest/gtest.h"
17 TEST(DebugTypeODRUniquingTest, enableDebugTypeODRUniquing) {
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) {
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));
35 // Enable the mapping. There still shouldn't be a type.
36 Context.enableDebugTypeODRUniquing();
37 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
39 // Create some ODR-uniqued type.
40 auto &CT = *DICompositeType::getODRType(
41 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
42 nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr);
43 EXPECT_EQ(UUID.getString(), CT.getIdentifier());
45 // Check that we get it back, even if we change a field.
46 EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
47 EXPECT_EQ(&CT, DICompositeType::getODRType(
48 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
49 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
52 DICompositeType::getODRType(
53 Context, UUID, dwarf::DW_TAG_class_type,
54 MDString::get(Context, "name"), nullptr, 0, nullptr, nullptr, 0,
55 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr));
57 // Check that it's discarded with the type map.
58 Context.disableDebugTypeODRUniquing();
59 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
61 // And it shouldn't magically reappear...
62 Context.enableDebugTypeODRUniquing();
63 EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
66 TEST(DebugTypeODRUniquingTest, buildODRType) {
68 Context.enableDebugTypeODRUniquing();
70 // Build an ODR type that's a forward decl.
71 MDString &UUID = *MDString::get(Context, "Type");
72 auto &CT = *DICompositeType::buildODRType(
73 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
74 nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
75 EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
76 EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
78 // Update with another forward decl. This should be a no-op.
79 EXPECT_EQ(&CT, DICompositeType::buildODRType(
80 Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,
81 nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
82 EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
84 // Update with a definition. This time we should see a change.
85 EXPECT_EQ(&CT, DICompositeType::buildODRType(
86 Context, UUID, dwarf::DW_TAG_structure_type, nullptr,
87 nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero,
88 nullptr, 0, nullptr, nullptr));
89 EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
91 // Further updates should be ignored.
92 EXPECT_EQ(&CT, DICompositeType::buildODRType(
93 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
94 nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr));
95 EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
96 EXPECT_EQ(&CT, DICompositeType::buildODRType(
97 Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
98 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
100 EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
103 TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
105 Context.enableDebugTypeODRUniquing();
107 // Build an ODR type that's a forward decl with no other fields set.
108 MDString &UUID = *MDString::get(Context, "UUID");
109 auto &CT = *DICompositeType::buildODRType(
110 Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
111 DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr);
113 // Create macros for running through all the fields except Identifier and Flags.
114 #define FOR_EACH_MDFIELD() \
117 DO_FOR_FIELD(Scope) \
118 DO_FOR_FIELD(BaseType) \
119 DO_FOR_FIELD(Elements) \
120 DO_FOR_FIELD(VTableHolder) \
121 DO_FOR_FIELD(TemplateParams)
122 #define FOR_EACH_INLINEFIELD() \
125 DO_FOR_FIELD(SizeInBits) \
126 DO_FOR_FIELD(AlignInBits) \
127 DO_FOR_FIELD(OffsetInBits) \
128 DO_FOR_FIELD(RuntimeLang)
130 // Create all the fields.
131 #define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X);
134 unsigned NonZeroInit = 0;
135 #define DO_FOR_FIELD(X) auto X = ++NonZeroInit;
136 FOR_EACH_INLINEFIELD();
139 // Replace all the fields with new values that are distinct from each other.
141 DICompositeType::buildODRType(
142 Context, UUID, Tag, Name, File, Line, Scope, BaseType,
143 SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
144 Elements, RuntimeLang, VTableHolder, TemplateParams));
146 // Confirm that all the right fields got updated.
147 #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
150 #undef FOR_EACH_MDFIELD
151 #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X());
152 FOR_EACH_INLINEFIELD();
154 #undef FOR_EACH_INLINEFIELD
155 EXPECT_EQ(DINode::FlagArtificial, CT.getFlags());
156 EXPECT_EQ(&UUID, CT.getRawIdentifier());