Changeset View
Changeset View
Standalone View
Standalone View
llvm/unittests/IR/DebugTypeODRUniquingTest.cpp
Show All 24 Lines | |||||
TEST(DebugTypeODRUniquingTest, getODRType) { | TEST(DebugTypeODRUniquingTest, getODRType) { | ||||
LLVMContext Context; | LLVMContext Context; | ||||
MDString &UUID = *MDString::get(Context, "string"); | MDString &UUID = *MDString::get(Context, "string"); | ||||
// Without a type map, this should return null. | // Without a type map, this should return null. | ||||
EXPECT_FALSE(DICompositeType::getODRType( | EXPECT_FALSE(DICompositeType::getODRType( | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | ||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, | nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, | ||||
nullptr, nullptr, nullptr)); | nullptr, nullptr, nullptr, nullptr)); | ||||
// Enable the mapping. There still shouldn't be a type. | // Enable the mapping. There still shouldn't be a type. | ||||
Context.enableDebugTypeODRUniquing(); | Context.enableDebugTypeODRUniquing(); | ||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | ||||
// Create some ODR-uniqued type. | // Create some ODR-uniqued type. | ||||
auto &CT = *DICompositeType::getODRType( | auto &CT = *DICompositeType::getODRType( | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | ||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, | nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr, | ||||
nullptr, nullptr, nullptr); | nullptr, nullptr, nullptr, nullptr); | ||||
EXPECT_EQ(UUID.getString(), CT.getIdentifier()); | EXPECT_EQ(UUID.getString(), CT.getIdentifier()); | ||||
// Check that we get it back, even if we change a field. | // Check that we get it back, even if we change a field. | ||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); | EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); | ||||
EXPECT_EQ(&CT, DICompositeType::getODRType( | EXPECT_EQ(&CT, | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, | DICompositeType::getODRType( | ||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | |||||
EXPECT_EQ(&CT, DICompositeType::getODRType( | EXPECT_EQ(&CT, DICompositeType::getODRType( | ||||
Context, UUID, dwarf::DW_TAG_class_type, | Context, UUID, dwarf::DW_TAG_class_type, | ||||
MDString::get(Context, "name"), nullptr, 0, nullptr, | MDString::get(Context, "name"), nullptr, 0, nullptr, | ||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, | nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | ||||
// Check that it's discarded with the type map. | // Check that it's discarded with the type map. | ||||
Context.disableDebugTypeODRUniquing(); | Context.disableDebugTypeODRUniquing(); | ||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | ||||
// And it shouldn't magically reappear... | // And it shouldn't magically reappear... | ||||
Context.enableDebugTypeODRUniquing(); | Context.enableDebugTypeODRUniquing(); | ||||
EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | EXPECT_FALSE(DICompositeType::getODRTypeIfExists(Context, UUID)); | ||||
} | } | ||||
TEST(DebugTypeODRUniquingTest, buildODRType) { | TEST(DebugTypeODRUniquingTest, buildODRType) { | ||||
LLVMContext Context; | LLVMContext Context; | ||||
Context.enableDebugTypeODRUniquing(); | Context.enableDebugTypeODRUniquing(); | ||||
// Build an ODR type that's a forward decl. | // Build an ODR type that's a forward decl. | ||||
MDString &UUID = *MDString::get(Context, "Type"); | MDString &UUID = *MDString::get(Context, "Type"); | ||||
auto &CT = *DICompositeType::buildODRType( | auto &CT = *DICompositeType::buildODRType( | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr, | ||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, | nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, | ||||
nullptr, nullptr, nullptr, nullptr); | nullptr, nullptr, nullptr, nullptr, nullptr); | ||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); | EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID)); | ||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); | EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); | ||||
// Update with another forward decl. This should be a no-op. | // Update with another forward decl. This should be a no-op. | ||||
EXPECT_EQ(&CT, | EXPECT_EQ(&CT, | ||||
DICompositeType::buildODRType( | DICompositeType::buildODRType( | ||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, | Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, | ||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, | 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | ||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); | EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag()); | ||||
// Update with a definition. This time we should see a change. | // Update with a definition. This time we should see a change. | ||||
EXPECT_EQ(&CT, | EXPECT_EQ(&CT, | ||||
DICompositeType::buildODRType( | DICompositeType::buildODRType( | ||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, | Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr, | ||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | ||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | ||||
// Further updates should be ignored. | // Further updates should be ignored. | ||||
EXPECT_EQ(&CT, DICompositeType::buildODRType( | EXPECT_EQ(&CT, | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, | DICompositeType::buildODRType( | ||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, | ||||
0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | |||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | ||||
EXPECT_EQ(&CT, DICompositeType::buildODRType( | EXPECT_EQ(&CT, | ||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, | DICompositeType::buildODRType( | ||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, | ||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); | |||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag()); | ||||
} | } | ||||
TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { | TEST(DebugTypeODRUniquingTest, buildODRTypeFields) { | ||||
LLVMContext Context; | LLVMContext Context; | ||||
Context.enableDebugTypeODRUniquing(); | Context.enableDebugTypeODRUniquing(); | ||||
// Build an ODR type that's a forward decl with no other fields set. | // Build an ODR type that's a forward decl with no other fields set. | ||||
MDString &UUID = *MDString::get(Context, "UUID"); | MDString &UUID = *MDString::get(Context, "UUID"); | ||||
auto &CT = *DICompositeType::buildODRType( | auto &CT = *DICompositeType::buildODRType( | ||||
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, | Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0, | ||||
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, | DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr, | ||||
nullptr, nullptr); | nullptr, nullptr, nullptr); | ||||
// Create macros for running through all the fields except Identifier and Flags. | // Create macros for running through all the fields except Identifier and Flags. | ||||
#define FOR_EACH_MDFIELD() \ | #define FOR_EACH_MDFIELD() \ | ||||
DO_FOR_FIELD(Name) \ | DO_FOR_FIELD(Name) \ | ||||
DO_FOR_FIELD(File) \ | DO_FOR_FIELD(File) \ | ||||
DO_FOR_FIELD(Scope) \ | DO_FOR_FIELD(Scope) \ | ||||
DO_FOR_FIELD(BaseType) \ | DO_FOR_FIELD(BaseType) \ | ||||
DO_FOR_FIELD(Elements) \ | DO_FOR_FIELD(Elements) \ | ||||
Show All 17 Lines | |||||
#undef DO_FOR_FIELD | #undef DO_FOR_FIELD | ||||
// Replace all the fields with new values that are distinct from each other. | // Replace all the fields with new values that are distinct from each other. | ||||
EXPECT_EQ(&CT, | EXPECT_EQ(&CT, | ||||
DICompositeType::buildODRType( | DICompositeType::buildODRType( | ||||
Context, UUID, Tag, Name, File, Line, Scope, BaseType, | Context, UUID, Tag, Name, File, Line, Scope, BaseType, | ||||
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial, | SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial, | ||||
Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr, | Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr, | ||||
nullptr, nullptr, nullptr)); | nullptr, nullptr, nullptr, nullptr)); | ||||
// Confirm that all the right fields got updated. | // Confirm that all the right fields got updated. | ||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X()); | #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X()); | ||||
FOR_EACH_MDFIELD(); | FOR_EACH_MDFIELD(); | ||||
#undef DO_FOR_FIELD | #undef DO_FOR_FIELD | ||||
#undef FOR_EACH_MDFIELD | #undef FOR_EACH_MDFIELD | ||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X()); | #define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.get##X()); | ||||
FOR_EACH_INLINEFIELD(); | FOR_EACH_INLINEFIELD(); | ||||
#undef DO_FOR_FIELD | #undef DO_FOR_FIELD | ||||
#undef FOR_EACH_INLINEFIELD | #undef FOR_EACH_INLINEFIELD | ||||
EXPECT_EQ(DINode::FlagArtificial, CT.getFlags()); | EXPECT_EQ(DINode::FlagArtificial, CT.getFlags()); | ||||
EXPECT_EQ(&UUID, CT.getRawIdentifier()); | EXPECT_EQ(&UUID, CT.getRawIdentifier()); | ||||
} | } | ||||
} // end namespace | } // end namespace |