|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
9 | 9 | #include "llvm/IR/DebugInfo.h"
|
| 10 | +#include "../lib/IR/LLVMContextImpl.h" |
10 | 11 | #include "llvm/ADT/APSInt.h"
|
11 | 12 | #include "llvm/AsmParser/Parser.h"
|
12 | 13 | #include "llvm/IR/DIBuilder.h"
|
|
19 | 20 | #include "llvm/IR/Verifier.h"
|
20 | 21 | #include "llvm/Support/SourceMgr.h"
|
21 | 22 | #include "llvm/Transforms/Utils/Local.h"
|
| 23 | + |
22 | 24 | #include "gtest/gtest.h"
|
23 | 25 |
|
24 | 26 | using namespace llvm;
|
@@ -231,7 +233,7 @@ TEST(DbgVariableIntrinsic, EmptyMDIsKillLocation) {
|
231 | 233 | EXPECT_TRUE(DbgDeclare->isKillLocation());
|
232 | 234 | }
|
233 | 235 |
|
234 |
| -TEST(DIBuiler, CreateFile) { |
| 236 | +TEST(DIBuilder, CreateFile) { |
235 | 237 | LLVMContext Ctx;
|
236 | 238 | std::unique_ptr<Module> M(new Module("MyModule", Ctx));
|
237 | 239 | DIBuilder DIB(*M);
|
@@ -730,4 +732,51 @@ TEST(AssignmentTrackingTest, InstrMethods) {
|
730 | 732 | }
|
731 | 733 | }
|
732 | 734 |
|
| 735 | +// Test that the hashing function for DISubprograms produce the same result |
| 736 | +// after replacing the temporary scope. |
| 737 | +TEST(DIBuilder, HashingDISubprogram) { |
| 738 | + LLVMContext Ctx; |
| 739 | + std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Ctx); |
| 740 | + DIBuilder DIB(*M); |
| 741 | + |
| 742 | + DIFile *F = DIB.createFile("main.c", "/"); |
| 743 | + DICompileUnit *CU = |
| 744 | + DIB.createCompileUnit(dwarf::DW_LANG_C, F, "Test", false, "", 0); |
| 745 | + |
| 746 | + llvm::TempDIType ForwardDeclaredType = |
| 747 | + llvm::TempDIType(DIB.createReplaceableCompositeType( |
| 748 | + llvm::dwarf::DW_TAG_structure_type, "MyType", CU, F, 0, 0, 8, 8, {}, |
| 749 | + "UniqueIdentifier")); |
| 750 | + |
| 751 | + // The hashing function is different for declarations and definitions, so |
| 752 | + // create one of each. |
| 753 | + DISubprogram *Declaration = |
| 754 | + DIB.createMethod(ForwardDeclaredType.get(), "MethodName", "LinkageName", |
| 755 | + F, 0, DIB.createSubroutineType({})); |
| 756 | + |
| 757 | + DISubprogram *Definition = DIB.createFunction( |
| 758 | + ForwardDeclaredType.get(), "MethodName", "LinkageName", F, 0, |
| 759 | + DIB.createSubroutineType({}), 0, DINode::FlagZero, |
| 760 | + llvm::DISubprogram::SPFlagDefinition, nullptr, Declaration); |
| 761 | + |
| 762 | + // Produce the hash with the temporary scope. |
| 763 | + unsigned HashDeclaration = |
| 764 | + MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); |
| 765 | + unsigned HashDefinition = |
| 766 | + MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); |
| 767 | + |
| 768 | + // Instantiate the real scope and replace the temporary one with it. |
| 769 | + DICompositeType *Type = DIB.createStructType(CU, "MyType", F, 0, 8, 8, {}, {}, |
| 770 | + {}, 0, {}, "UniqueIdentifier"); |
| 771 | + DIB.replaceTemporary(std::move(ForwardDeclaredType), Type); |
| 772 | + |
| 773 | + // Now make sure the hashing is consistent. |
| 774 | + unsigned HashDeclarationAfter = |
| 775 | + MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); |
| 776 | + unsigned HashDefinitionAfter = |
| 777 | + MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); |
| 778 | + |
| 779 | + EXPECT_EQ(HashDeclaration, HashDeclarationAfter); |
| 780 | + EXPECT_EQ(HashDefinition, HashDefinitionAfter); |
| 781 | +} |
733 | 782 | } // end namespace
|
0 commit comments