brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 6716796 Raw
186 lines · cpp
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-exception6//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) {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 26TEST(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, nullptr, 0, DINode::FlagZero, nullptr, 0, std::nullopt,34      nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,35      nullptr));36 37  // Enable the mapping.  There still shouldn't be a type.38  Context.enableDebugTypeODRUniquing();39  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));40 41  // Create some ODR-uniqued type.42  auto &CT = *DICompositeType::getODRType(43      Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,44      nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0, std::nullopt,45      nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,46      nullptr);47  EXPECT_EQ(UUID.getString(), CT.getIdentifier());48 49  // Check that we get it back, even if we change a field.50  EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));51  EXPECT_EQ(&CT, DICompositeType::getODRType(52                     Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,53                     0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero,54                     nullptr, 0, std::nullopt, nullptr, nullptr, nullptr,55                     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));56  EXPECT_EQ(&CT, DICompositeType::getODRType(57                     Context, UUID, dwarf::DW_TAG_class_type,58                     MDString::get(Context, "name"), nullptr, 0, nullptr,59                     nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero, nullptr, 0,60                     std::nullopt, nullptr, nullptr, nullptr, nullptr, nullptr,61                     nullptr, nullptr, nullptr, nullptr));62 63  // Check that it's discarded with the type map.64  Context.disableDebugTypeODRUniquing();65  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));66 67  // And it shouldn't magically reappear...68  Context.enableDebugTypeODRUniquing();69  EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID));70}71 72TEST(DebugTypeODRUniquingTest, buildODRType) {73  LLVMContext Context;74  Context.enableDebugTypeODRUniquing();75 76  // Build an ODR type that's a forward decl.77  MDString &UUID = *MDString::get(Context, "Type");78  auto &CT = *DICompositeType::buildODRType(79      Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,80      nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0,81      std::nullopt, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,82      nullptr, nullptr, nullptr);83  EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));84  EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());85 86  // Update with another forward decl.  This should be a no-op.87  EXPECT_EQ(&CT,88            DICompositeType::buildODRType(89                Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,90                nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl,91                nullptr, 0, std::nullopt, nullptr, nullptr, nullptr, nullptr,92                nullptr, nullptr, nullptr, nullptr, nullptr));93 94  EXPECT_FALSE(DICompositeType::buildODRType(95      Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, 0, nullptr,96      nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl, nullptr, 0,97      std::nullopt, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,98      nullptr, nullptr, nullptr));99 100  // Update with a definition.  This time we should see a change.101  EXPECT_EQ(&CT, DICompositeType::buildODRType(102                     Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,103                     0, nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero,104                     nullptr, 0, std::nullopt, nullptr, nullptr, nullptr,105                     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));106  EXPECT_FALSE(CT.isForwardDecl());107 108  // Further updates should be ignored.109  EXPECT_EQ(&CT,110            DICompositeType::buildODRType(111                Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,112                nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagFwdDecl,113                nullptr, 0, std::nullopt, nullptr, nullptr, nullptr, nullptr,114                nullptr, nullptr, nullptr, nullptr, nullptr));115  EXPECT_FALSE(CT.isForwardDecl());116  EXPECT_EQ(&CT,117            DICompositeType::buildODRType(118                Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 111u,119                nullptr, nullptr, 0, 0, 0, nullptr, 0, DINode::FlagZero,120                nullptr, 0, std::nullopt, nullptr, nullptr, nullptr, nullptr,121                nullptr, nullptr, nullptr, nullptr, nullptr));122  EXPECT_NE(111u, CT.getLine());123}124 125TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {126  LLVMContext Context;127  Context.enableDebugTypeODRUniquing();128 129  // Build an ODR type that's a forward decl with no other fields set.130  MDString &UUID = *MDString::get(Context, "UUID");131  auto &CT = *DICompositeType::buildODRType(132      Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, nullptr,133      0, DINode::FlagFwdDecl, nullptr, 0, std::nullopt, nullptr, nullptr,134      nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);135 136// Create macros for running through all the fields except Identifier and Flags.137#define FOR_EACH_MDFIELD()                                                     \138  DO_FOR_FIELD(Name)                                                           \139  DO_FOR_FIELD(File)                                                           \140  DO_FOR_FIELD(Scope)                                                          \141  DO_FOR_FIELD(BaseType)                                                       \142  DO_FOR_FIELD(Elements)                                                       \143  DO_FOR_FIELD(VTableHolder)                                                   \144  DO_FOR_FIELD(TemplateParams)                                                 \145  DO_FOR_FIELD(SizeInBits)                                                     \146  DO_FOR_FIELD(OffsetInBits)147#define FOR_EACH_INLINEFIELD()                                                 \148  DO_FOR_FIELD(Line)                                                           \149  DO_FOR_FIELD(AlignInBits)                                                    \150  DO_FOR_FIELD(NumExtraInhabitants)                                            \151  DO_FOR_FIELD(RuntimeLang)                                                    \152  DO_FOR_FIELD(EnumKind)153 154// Create all the fields.155#define DO_FOR_FIELD(X) auto *X = MDString::get(Context, #X);156  FOR_EACH_MDFIELD();157#undef DO_FOR_FIELD158  unsigned NonZeroInit = 0;159#define DO_FOR_FIELD(X) auto X = ++NonZeroInit;160  FOR_EACH_INLINEFIELD();161#undef DO_FOR_FIELD162 163  // Replace all the fields with new values that are distinct from each other.164  EXPECT_EQ(&CT,165            DICompositeType::buildODRType(166                Context, UUID, 0, Name, File, Line, Scope, BaseType, SizeInBits,167                AlignInBits, OffsetInBits, nullptr, NumExtraInhabitants,168                DINode::FlagArtificial, Elements, RuntimeLang, EnumKind,169                VTableHolder, TemplateParams, nullptr, nullptr, nullptr,170                nullptr, nullptr, nullptr, nullptr));171 172  // Confirm that all the right fields got updated.173#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());174  FOR_EACH_MDFIELD();175#undef DO_FOR_FIELD176#undef FOR_EACH_MDFIELD177#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X());178  FOR_EACH_INLINEFIELD();179#undef DO_FOR_FIELD180#undef FOR_EACH_INLINEFIELD181  EXPECT_EQ(DINode::FlagArtificial, CT.getFlags());182  EXPECT_EQ(&UUID, CT.getRawIdentifier());183}184 185} // end namespace186