llvm-project
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"13using namespace llvm;14
15namespace {16
17TEST(DebugTypeODRUniquingTest, enableDebugTypeODRUniquing) {18LLVMContext Context;19EXPECT_FALSE(Context.isODRUniquingDebugTypes());20Context.enableDebugTypeODRUniquing();21EXPECT_TRUE(Context.isODRUniquingDebugTypes());22Context.disableDebugTypeODRUniquing();23EXPECT_FALSE(Context.isODRUniquingDebugTypes());24}
25
26TEST(DebugTypeODRUniquingTest, getODRType) {27LLVMContext Context;28MDString &UUID = *MDString::get(Context, "string");29
30// Without a type map, this should return null.31EXPECT_FALSE(DICompositeType::getODRType(32Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,33nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,34nullptr, nullptr, nullptr, nullptr, nullptr));35
36// Enable the mapping. There still shouldn't be a type.37Context.enableDebugTypeODRUniquing();38EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));39
40// Create some ODR-uniqued type.41auto &CT = *DICompositeType::getODRType(42Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,43nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,44nullptr, nullptr, nullptr, nullptr, nullptr);45EXPECT_EQ(UUID.getString(), CT.getIdentifier());46
47// Check that we get it back, even if we change a field.48EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));49EXPECT_EQ(&CT,50DICompositeType::getODRType(51Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,52nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,53nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,54nullptr));55EXPECT_EQ(&CT, DICompositeType::getODRType(56Context, UUID, dwarf::DW_TAG_class_type,57MDString::get(Context, "name"), nullptr, 0, nullptr,58nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr,59nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,60nullptr));61
62// Check that it's discarded with the type map.63Context.disableDebugTypeODRUniquing();64EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));65
66// And it shouldn't magically reappear...67Context.enableDebugTypeODRUniquing();68EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));69}
70
71TEST(DebugTypeODRUniquingTest, buildODRType) {72LLVMContext Context;73Context.enableDebugTypeODRUniquing();74
75// Build an ODR type that's a forward decl.76MDString &UUID = *MDString::get(Context, "Type");77auto &CT = *DICompositeType::buildODRType(78Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,79nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,80nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);81EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));82EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());83
84// Update with another forward decl. This should be a no-op.85EXPECT_EQ(&CT, DICompositeType::buildODRType(86Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,870, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,880, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,89nullptr, nullptr));90
91EXPECT_FALSE(DICompositeType::buildODRType(92Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,93nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,94nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));95
96// Update with a definition. This time we should see a change.97EXPECT_EQ(&CT, DICompositeType::buildODRType(98Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,990, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,100nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,101nullptr, nullptr));102EXPECT_FALSE(CT.isForwardDecl());103
104// Further updates should be ignored.105EXPECT_EQ(&CT, DICompositeType::buildODRType(106Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,1070, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,1080, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,109nullptr, nullptr));110EXPECT_FALSE(CT.isForwardDecl());111EXPECT_EQ(&CT, DICompositeType::buildODRType(112Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,113111u, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr,1140, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,115nullptr, nullptr));116EXPECT_NE(111u, CT.getLine());117}
118
119TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {120LLVMContext Context;121Context.enableDebugTypeODRUniquing();122
123// Build an ODR type that's a forward decl with no other fields set.124MDString &UUID = *MDString::get(Context, "UUID");125auto &CT = *DICompositeType::buildODRType(126Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,127DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr,128nullptr, nullptr, nullptr, nullptr);129
130// Create macros for running through all the fields except Identifier and Flags.
131#define FOR_EACH_MDFIELD() \132DO_FOR_FIELD(Name) \133DO_FOR_FIELD(File) \134DO_FOR_FIELD(Scope) \135DO_FOR_FIELD(BaseType) \136DO_FOR_FIELD(Elements) \137DO_FOR_FIELD(VTableHolder) \138DO_FOR_FIELD(TemplateParams)139#define FOR_EACH_INLINEFIELD() \140DO_FOR_FIELD(Line) \141DO_FOR_FIELD(SizeInBits) \142DO_FOR_FIELD(AlignInBits) \143DO_FOR_FIELD(OffsetInBits) \144DO_FOR_FIELD(RuntimeLang)145
146// Create all the fields.
147#define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X);148FOR_EACH_MDFIELD();149#undef DO_FOR_FIELD150unsigned NonZeroInit = 0;151#define DO_FOR_FIELD(X) auto X = ++NonZeroInit;152FOR_EACH_INLINEFIELD();153#undef DO_FOR_FIELD154
155// Replace all the fields with new values that are distinct from each other.156EXPECT_EQ(&CT,157DICompositeType::buildODRType(158Context, UUID, 0, Name, File, Line, Scope, BaseType, SizeInBits,159AlignInBits, OffsetInBits, DINode::FlagArtificial, Elements,160RuntimeLang, VTableHolder, TemplateParams, nullptr, nullptr,161nullptr, 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());165FOR_EACH_MDFIELD();166#undef DO_FOR_FIELD167#undef FOR_EACH_MDFIELD168#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X());169FOR_EACH_INLINEFIELD();170#undef DO_FOR_FIELD171#undef FOR_EACH_INLINEFIELD172EXPECT_EQ(DINode::FlagArtificial, CT.getFlags());173EXPECT_EQ(&UUID, CT.getRawIdentifier());174}
175
176} // end namespace177