|
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"
|
|
20 | 21 | #include "llvm/IR/Verifier.h"
|
21 | 22 | #include "llvm/Support/SourceMgr.h"
|
22 | 23 | #include "llvm/Transforms/Utils/Local.h"
|
| 24 | + |
23 | 25 | #include "gtest/gtest.h"
|
24 | 26 |
|
25 | 27 | using namespace llvm;
|
@@ -349,7 +351,7 @@ TEST(MetadataTest, OrderingOfDbgVariableRecords) {
|
349 | 351 | UseNewDbgInfoFormat = OldDbgValueMode;
|
350 | 352 | }
|
351 | 353 |
|
352 |
| -TEST(DIBuiler, CreateFile) { |
| 354 | +TEST(DIBuilder, CreateFile) { |
353 | 355 | LLVMContext Ctx;
|
354 | 356 | std::unique_ptr<Module> M(new Module("MyModule", Ctx));
|
355 | 357 | DIBuilder DIB(*M);
|
@@ -1184,4 +1186,52 @@ TEST(MetadataTest, DbgVariableRecordConversionRoutines) {
|
1184 | 1186 | UseNewDbgInfoFormat = false;
|
1185 | 1187 | }
|
1186 | 1188 |
|
| 1189 | +// Test that the hashing function for DISubprograms produce the same result |
| 1190 | +// after replacing the temporary scope. |
| 1191 | +TEST(DIBuilder, HashingDISubprogram) { |
| 1192 | + LLVMContext Ctx; |
| 1193 | + std::unique_ptr<Module> M = std::make_unique<Module>("MyModule", Ctx); |
| 1194 | + DIBuilder DIB(*M); |
| 1195 | + |
| 1196 | + DIFile *F = DIB.createFile("main.c", "/"); |
| 1197 | + DICompileUnit *CU = |
| 1198 | + DIB.createCompileUnit(dwarf::DW_LANG_C, F, "Test", false, "", 0); |
| 1199 | + |
| 1200 | + llvm::TempDIType ForwardDeclaredType = |
| 1201 | + llvm::TempDIType(DIB.createReplaceableCompositeType( |
| 1202 | + llvm::dwarf::DW_TAG_structure_type, "MyType", CU, F, 0, 0, 8, 8, {}, |
| 1203 | + "UniqueIdentifier")); |
| 1204 | + |
| 1205 | + // The hashing function is different for declarations and definitions, so |
| 1206 | + // create one of each. |
| 1207 | + DISubprogram *Declaration = |
| 1208 | + DIB.createMethod(ForwardDeclaredType.get(), "MethodName", "LinkageName", |
| 1209 | + F, 0, DIB.createSubroutineType({})); |
| 1210 | + |
| 1211 | + DISubprogram *Definition = DIB.createFunction( |
| 1212 | + ForwardDeclaredType.get(), "MethodName", "LinkageName", F, 0, |
| 1213 | + DIB.createSubroutineType({}), 0, DINode::FlagZero, |
| 1214 | + llvm::DISubprogram::SPFlagDefinition, nullptr, Declaration); |
| 1215 | + |
| 1216 | + // Produce the hash with the temporary scope. |
| 1217 | + unsigned HashDeclaration = |
| 1218 | + MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); |
| 1219 | + unsigned HashDefinition = |
| 1220 | + MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); |
| 1221 | + |
| 1222 | + // Instantiate the real scope and replace the temporary one with it. |
| 1223 | + DICompositeType *Type = DIB.createStructType(CU, "MyType", F, 0, 8, 8, {}, {}, |
| 1224 | + {}, 0, {}, "UniqueIdentifier"); |
| 1225 | + DIB.replaceTemporary(std::move(ForwardDeclaredType), Type); |
| 1226 | + |
| 1227 | + // Now make sure the hashing is consistent. |
| 1228 | + unsigned HashDeclarationAfter = |
| 1229 | + MDNodeKeyImpl<DISubprogram>(Declaration).getHashValue(); |
| 1230 | + unsigned HashDefinitionAfter = |
| 1231 | + MDNodeKeyImpl<DISubprogram>(Definition).getHashValue(); |
| 1232 | + |
| 1233 | + EXPECT_EQ(HashDeclaration, HashDeclarationAfter); |
| 1234 | + EXPECT_EQ(HashDefinition, HashDefinitionAfter); |
| 1235 | +} |
| 1236 | + |
1187 | 1237 | } // end namespace
|
0 commit comments