llvm-project

Форк
0
/
DebugTypeODRUniquingTest.cpp 
176 строк · 7.9 Кб
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
//===----------------------------------------------------------------------===//
8

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;
14

15
namespace {
16

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());
24
}
25

26
TEST(DebugTypeODRUniquingTest, getODRType) {
27
  LLVMContext Context;
28
  MDString &UUID = *MDString::get(Context, "string");
29

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));
35

36
  // Enable the mapping.  There still shouldn't be a type.
37
  Context.enableDebugTypeODRUniquing();
38
  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
39

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());
46

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));
61

62
  // Check that it's discarded with the type map.
63
  Context.disableDebugTypeODRUniquing();
64
  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
65

66
  // And it shouldn't magically reappear...
67
  Context.enableDebugTypeODRUniquing();
68
  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));
69
}
70

71
TEST(DebugTypeODRUniquingTest, buildODRType) {
72
  LLVMContext Context;
73
  Context.enableDebugTypeODRUniquing();
74

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());
83

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));
90

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));
95

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());
103

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());
117
}
118

119
TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
120
  LLVMContext Context;
121
  Context.enableDebugTypeODRUniquing();
122

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);
129

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)
145

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
154

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));
162

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());
174
}
175

176
} // end namespace
177

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.