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