1 //===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===// 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 "gtest/gtest.h" 11 12 #include "llvm/ADT/STLExtras.h" 13 #include "llvm/Config/config.h" 14 #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 15 #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" 16 #include "llvm/Support/FileSystem.h" 17 #include "llvm/Support/Path.h" 18 19 #include "lldb/Core/Address.h" 20 #include "lldb/Core/ArchSpec.h" 21 #include "lldb/Core/Module.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Host/FileSpec.h" 24 #include "lldb/Host/HostInfo.h" 25 #include "lldb/Symbol/ClangASTContext.h" 26 #include "lldb/Symbol/CompileUnit.h" 27 #include "lldb/Symbol/LineTable.h" 28 #include "lldb/Symbol/SymbolVendor.h" 29 30 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" 31 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" 32 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" 33 34 #if defined(_MSC_VER) 35 #include "lldb/Host/windows/windows.h" 36 #include <objbase.h> 37 #endif 38 39 #include <algorithm> 40 41 extern const char *TestMainArgv0; 42 43 using namespace lldb_private; 44 45 class SymbolFilePDBTests : public testing::Test { 46 public: 47 void SetUp() override { 48 // Initialize and TearDown the plugin every time, so we get a brand new 49 // AST every time so that modifications to the AST from each test don't 50 // leak into the next test. 51 #if defined(_MSC_VER) 52 ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); 53 #endif 54 55 HostInfo::Initialize(); 56 ObjectFilePECOFF::Initialize(); 57 SymbolFileDWARF::Initialize(); 58 ClangASTContext::Initialize(); 59 SymbolFilePDB::Initialize(); 60 61 llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0); 62 llvm::SmallString<128> inputs_folder = exe_folder; 63 llvm::sys::path::append(inputs_folder, "Inputs"); 64 65 m_pdb_test_exe = inputs_folder; 66 m_dwarf_test_exe = inputs_folder; 67 m_types_test_exe = inputs_folder; 68 llvm::sys::path::append(m_pdb_test_exe, "test-pdb.exe"); 69 llvm::sys::path::append(m_dwarf_test_exe, "test-dwarf.exe"); 70 llvm::sys::path::append(m_types_test_exe, "test-pdb-types.exe"); 71 } 72 73 void TearDown() override { 74 SymbolFilePDB::Terminate(); 75 ClangASTContext::Initialize(); 76 SymbolFileDWARF::Terminate(); 77 ObjectFilePECOFF::Terminate(); 78 HostInfo::Terminate(); 79 80 #if defined(_MSC_VER) 81 ::CoUninitialize(); 82 #endif 83 } 84 85 protected: 86 llvm::SmallString<128> m_pdb_test_exe; 87 llvm::SmallString<128> m_dwarf_test_exe; 88 llvm::SmallString<128> m_types_test_exe; 89 90 bool FileSpecMatchesAsBaseOrFull(const FileSpec &left, 91 const FileSpec &right) const { 92 // If the filenames don't match, the paths can't be equal 93 if (!left.FileEquals(right)) 94 return false; 95 // If BOTH have a directory, also compare the directories. 96 if (left.GetDirectory() && right.GetDirectory()) 97 return left.DirectoryEquals(right); 98 99 // If one has a directory but not the other, they match. 100 return true; 101 } 102 103 void VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc, 104 const FileSpec &spec, LineTable <, uint32_t line, 105 lldb::addr_t addr) { 106 LineEntry entry; 107 Address address; 108 EXPECT_TRUE(module->ResolveFileAddress(addr, address)); 109 110 EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry)); 111 EXPECT_EQ(line, entry.line); 112 EXPECT_EQ(address, entry.range.GetBaseAddress()); 113 114 EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file)); 115 } 116 117 bool ContainsCompileUnit(const SymbolContextList &sc_list, 118 const FileSpec &spec) const { 119 for (size_t i = 0; i < sc_list.GetSize(); ++i) { 120 const SymbolContext &sc = sc_list[i]; 121 if (FileSpecMatchesAsBaseOrFull(*sc.comp_unit, spec)) 122 return true; 123 } 124 return false; 125 } 126 127 int GetGlobalConstantInteger(const llvm::pdb::IPDBSession &session, 128 llvm::StringRef var) const { 129 auto global = session.getGlobalScope(); 130 auto results = 131 global->findChildren(llvm::pdb::PDB_SymType::Data, var, 132 llvm::pdb::PDB_NameSearchFlags::NS_Default); 133 uint32_t count = results->getChildCount(); 134 if (count == 0) 135 return -1; 136 137 auto item = results->getChildAtIndex(0); 138 auto symbol = llvm::dyn_cast<llvm::pdb::PDBSymbolData>(item.get()); 139 if (!symbol) 140 return -1; 141 llvm::pdb::Variant value = symbol->getValue(); 142 switch (value.Type) { 143 case llvm::pdb::PDB_VariantType::Int16: 144 return value.Value.Int16; 145 case llvm::pdb::PDB_VariantType::Int32: 146 return value.Value.Int32; 147 case llvm::pdb::PDB_VariantType::UInt16: 148 return value.Value.UInt16; 149 case llvm::pdb::PDB_VariantType::UInt32: 150 return value.Value.UInt32; 151 default: 152 return 0; 153 } 154 } 155 }; 156 157 #if HAVE_DIA_SDK 158 #define REQUIRES_DIA_SDK(TestName) TestName 159 #else 160 #define REQUIRES_DIA_SDK(TestName) DISABLED_##TestName 161 #endif 162 163 TEST_F(SymbolFilePDBTests, TestAbilitiesForDWARF) { 164 // Test that when we have Dwarf debug info, SymbolFileDWARF is used. 165 FileSpec fspec(m_dwarf_test_exe.c_str(), false); 166 ArchSpec aspec("i686-pc-windows"); 167 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 168 169 SymbolVendor *plugin = module->GetSymbolVendor(); 170 EXPECT_NE(nullptr, plugin); 171 SymbolFile *symfile = plugin->GetSymbolFile(); 172 EXPECT_NE(nullptr, symfile); 173 EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic()); 174 175 uint32_t expected_abilities = SymbolFile::kAllAbilities; 176 EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); 177 } 178 179 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestAbilitiesForPDB)) { 180 // Test that when we have PDB debug info, SymbolFilePDB is used. 181 FileSpec fspec(m_pdb_test_exe.c_str(), false); 182 ArchSpec aspec("i686-pc-windows"); 183 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 184 185 SymbolVendor *plugin = module->GetSymbolVendor(); 186 EXPECT_NE(nullptr, plugin); 187 SymbolFile *symfile = plugin->GetSymbolFile(); 188 EXPECT_NE(nullptr, symfile); 189 EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); 190 191 uint32_t expected_abilities = 192 SymbolFile::CompileUnits | SymbolFile::LineTables; 193 EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); 194 } 195 196 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextBasename)) { 197 // Test that attempting to call ResolveSymbolContext with only a basename 198 // finds all full paths 199 // with the same basename 200 FileSpec fspec(m_pdb_test_exe.c_str(), false); 201 ArchSpec aspec("i686-pc-windows"); 202 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 203 204 SymbolVendor *plugin = module->GetSymbolVendor(); 205 EXPECT_NE(nullptr, plugin); 206 SymbolFile *symfile = plugin->GetSymbolFile(); 207 208 FileSpec header_spec("test-pdb.cpp", false); 209 SymbolContextList sc_list; 210 uint32_t result_count = symfile->ResolveSymbolContext( 211 header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list); 212 EXPECT_EQ(1u, result_count); 213 EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); 214 } 215 216 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextFullPath)) { 217 // Test that attempting to call ResolveSymbolContext with a full path only 218 // finds the one source 219 // file that matches the full path. 220 FileSpec fspec(m_pdb_test_exe.c_str(), false); 221 ArchSpec aspec("i686-pc-windows"); 222 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 223 224 SymbolVendor *plugin = module->GetSymbolVendor(); 225 EXPECT_NE(nullptr, plugin); 226 SymbolFile *symfile = plugin->GetSymbolFile(); 227 228 FileSpec header_spec( 229 R"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec", 230 false); 231 SymbolContextList sc_list; 232 uint32_t result_count = symfile->ResolveSymbolContext( 233 header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list); 234 EXPECT_GE(1u, result_count); 235 EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); 236 } 237 238 TEST_F(SymbolFilePDBTests, 239 REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithInlines)) { 240 // Test that when looking up a header file via ResolveSymbolContext (i.e. a 241 // file that was not by itself 242 // compiled, but only contributes to the combined code of other source files), 243 // a SymbolContext is returned 244 // for each compiland which has line contributions from the requested header. 245 FileSpec fspec(m_pdb_test_exe.c_str(), false); 246 ArchSpec aspec("i686-pc-windows"); 247 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 248 249 SymbolVendor *plugin = module->GetSymbolVendor(); 250 EXPECT_NE(nullptr, plugin); 251 SymbolFile *symfile = plugin->GetSymbolFile(); 252 253 FileSpec header_specs[] = {FileSpec("test-pdb.h", false), 254 FileSpec("test-pdb-nested.h", false)}; 255 FileSpec main_cpp_spec("test-pdb.cpp", false); 256 FileSpec alt_cpp_spec("test-pdb-alt.cpp", false); 257 for (const auto &hspec : header_specs) { 258 SymbolContextList sc_list; 259 uint32_t result_count = symfile->ResolveSymbolContext( 260 hspec, 0, true, lldb::eSymbolContextCompUnit, sc_list); 261 EXPECT_EQ(2u, result_count); 262 EXPECT_TRUE(ContainsCompileUnit(sc_list, main_cpp_spec)); 263 EXPECT_TRUE(ContainsCompileUnit(sc_list, alt_cpp_spec)); 264 } 265 } 266 267 TEST_F(SymbolFilePDBTests, 268 REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithNoInlines)) { 269 // Test that when looking up a header file via ResolveSymbolContext (i.e. a 270 // file that was not by itself 271 // compiled, but only contributes to the combined code of other source files), 272 // that if check_inlines 273 // is false, no SymbolContexts are returned. 274 FileSpec fspec(m_pdb_test_exe.c_str(), false); 275 ArchSpec aspec("i686-pc-windows"); 276 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 277 278 SymbolVendor *plugin = module->GetSymbolVendor(); 279 EXPECT_NE(nullptr, plugin); 280 SymbolFile *symfile = plugin->GetSymbolFile(); 281 282 FileSpec header_specs[] = {FileSpec("test-pdb.h", false), 283 FileSpec("test-pdb-nested.h", false)}; 284 for (const auto &hspec : header_specs) { 285 SymbolContextList sc_list; 286 uint32_t result_count = symfile->ResolveSymbolContext( 287 hspec, 0, false, lldb::eSymbolContextCompUnit, sc_list); 288 EXPECT_EQ(0u, result_count); 289 } 290 } 291 292 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchAll)) { 293 // Test that when calling ResolveSymbolContext with a line number of 0, all 294 // line entries from 295 // the specified files are returned. 296 FileSpec fspec(m_pdb_test_exe.c_str(), false); 297 ArchSpec aspec("i686-pc-windows"); 298 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 299 300 SymbolVendor *plugin = module->GetSymbolVendor(); 301 SymbolFile *symfile = plugin->GetSymbolFile(); 302 303 FileSpec source_file("test-pdb.cpp", false); 304 FileSpec header1("test-pdb.h", false); 305 FileSpec header2("test-pdb-nested.h", false); 306 uint32_t cus = symfile->GetNumCompileUnits(); 307 EXPECT_EQ(2u, cus); 308 309 SymbolContextList sc_list; 310 uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; 311 312 uint32_t count = 313 symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); 314 EXPECT_EQ(1u, count); 315 SymbolContext sc; 316 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); 317 318 LineTable *lt = sc.comp_unit->GetLineTable(); 319 EXPECT_NE(nullptr, lt); 320 count = lt->GetSize(); 321 // We expect one extra entry for termination (per function) 322 EXPECT_EQ(16u, count); 323 324 VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); 325 VerifyLineEntry(module, sc, source_file, *lt, 8, 0x401043); 326 VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); 327 328 VerifyLineEntry(module, sc, source_file, *lt, 13, 0x401050); 329 VerifyLineEntry(module, sc, source_file, *lt, 14, 0x401054); 330 VerifyLineEntry(module, sc, source_file, *lt, 15, 0x401070); 331 332 VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); 333 VerifyLineEntry(module, sc, header1, *lt, 10, 0x401093); 334 VerifyLineEntry(module, sc, header1, *lt, 11, 0x4010a2); 335 336 VerifyLineEntry(module, sc, header2, *lt, 5, 0x401080); 337 VerifyLineEntry(module, sc, header2, *lt, 6, 0x401083); 338 VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); 339 } 340 341 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchSpecific)) { 342 // Test that when calling ResolveSymbolContext with a specific line number, 343 // only line entries 344 // which match the requested line are returned. 345 FileSpec fspec(m_pdb_test_exe.c_str(), false); 346 ArchSpec aspec("i686-pc-windows"); 347 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 348 349 SymbolVendor *plugin = module->GetSymbolVendor(); 350 SymbolFile *symfile = plugin->GetSymbolFile(); 351 352 FileSpec source_file("test-pdb.cpp", false); 353 FileSpec header1("test-pdb.h", false); 354 FileSpec header2("test-pdb-nested.h", false); 355 uint32_t cus = symfile->GetNumCompileUnits(); 356 EXPECT_EQ(2u, cus); 357 358 SymbolContextList sc_list; 359 uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; 360 361 // First test with line 7, and verify that only line 7 entries are added. 362 uint32_t count = 363 symfile->ResolveSymbolContext(source_file, 7, true, scope, sc_list); 364 EXPECT_EQ(1u, count); 365 SymbolContext sc; 366 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); 367 368 LineTable *lt = sc.comp_unit->GetLineTable(); 369 EXPECT_NE(nullptr, lt); 370 count = lt->GetSize(); 371 // We expect one extra entry for termination 372 EXPECT_EQ(3u, count); 373 374 VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); 375 VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); 376 377 sc_list.Clear(); 378 // Then test with line 9, and verify that only line 9 entries are added. 379 count = symfile->ResolveSymbolContext(source_file, 9, true, scope, sc_list); 380 EXPECT_EQ(1u, count); 381 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); 382 383 lt = sc.comp_unit->GetLineTable(); 384 EXPECT_NE(nullptr, lt); 385 count = lt->GetSize(); 386 // We expect one extra entry for termination 387 EXPECT_EQ(3u, count); 388 389 VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); 390 VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); 391 } 392 393 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestSimpleClassTypes)) { 394 FileSpec fspec(m_types_test_exe.c_str(), false); 395 ArchSpec aspec("i686-pc-windows"); 396 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 397 398 SymbolVendor *plugin = module->GetSymbolVendor(); 399 SymbolFilePDB *symfile = 400 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 401 const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); 402 SymbolContext sc; 403 llvm::DenseSet<SymbolFile *> searched_files; 404 TypeMap results; 405 EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class"), nullptr, false, 0, 406 searched_files, results)); 407 EXPECT_EQ(1u, results.GetSize()); 408 lldb::TypeSP udt_type = results.GetTypeAtIndex(0); 409 EXPECT_EQ(ConstString("Class"), udt_type->GetName()); 410 CompilerType compiler_type = udt_type->GetForwardCompilerType(); 411 EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); 412 EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_Class")), 413 udt_type->GetByteSize()); 414 } 415 416 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNestedClassTypes)) { 417 FileSpec fspec(m_types_test_exe.c_str(), false); 418 ArchSpec aspec("i686-pc-windows"); 419 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 420 421 SymbolVendor *plugin = module->GetSymbolVendor(); 422 SymbolFilePDB *symfile = 423 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 424 const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); 425 SymbolContext sc; 426 llvm::DenseSet<SymbolFile *> searched_files; 427 TypeMap results; 428 EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class::NestedClass"), 429 nullptr, false, 0, searched_files, results)); 430 EXPECT_EQ(1u, results.GetSize()); 431 lldb::TypeSP udt_type = results.GetTypeAtIndex(0); 432 EXPECT_EQ(ConstString("Class::NestedClass"), udt_type->GetName()); 433 CompilerType compiler_type = udt_type->GetForwardCompilerType(); 434 EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); 435 EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_NestedClass")), 436 udt_type->GetByteSize()); 437 } 438 439 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestClassInNamespace)) { 440 FileSpec fspec(m_types_test_exe.c_str(), false); 441 ArchSpec aspec("i686-pc-windows"); 442 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 443 444 SymbolVendor *plugin = module->GetSymbolVendor(); 445 SymbolFilePDB *symfile = 446 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 447 const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); 448 SymbolContext sc; 449 llvm::DenseSet<SymbolFile *> searched_files; 450 TypeMap results; 451 EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("NS::NSClass"), nullptr, 452 false, 0, searched_files, results)); 453 EXPECT_EQ(1u, results.GetSize()); 454 lldb::TypeSP udt_type = results.GetTypeAtIndex(0); 455 EXPECT_EQ(ConstString("NS::NSClass"), udt_type->GetName()); 456 CompilerType compiler_type = udt_type->GetForwardCompilerType(); 457 EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); 458 EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"), 459 udt_type->GetByteSize()); 460 } 461 462 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestEnumTypes)) { 463 FileSpec fspec(m_types_test_exe.c_str(), false); 464 ArchSpec aspec("i686-pc-windows"); 465 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 466 467 SymbolVendor *plugin = module->GetSymbolVendor(); 468 SymbolFilePDB *symfile = 469 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 470 const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); 471 SymbolContext sc; 472 llvm::DenseSet<SymbolFile *> searched_files; 473 const char *EnumsToCheck[] = {"Enum", "ShortEnum"}; 474 for (auto Enum : EnumsToCheck) { 475 TypeMap results; 476 EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Enum), nullptr, false, 0, 477 searched_files, results)); 478 EXPECT_EQ(1u, results.GetSize()); 479 lldb::TypeSP enum_type = results.GetTypeAtIndex(0); 480 EXPECT_EQ(ConstString(Enum), enum_type->GetName()); 481 CompilerType compiler_type = enum_type->GetFullCompilerType(); 482 EXPECT_TRUE(ClangASTContext::IsEnumType(compiler_type.GetOpaqueQualType())); 483 clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(compiler_type); 484 EXPECT_NE(nullptr, enum_decl); 485 EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(), 486 enum_decl->enumerator_end())); 487 488 std::string sizeof_var = "sizeof_"; 489 sizeof_var.append(Enum); 490 EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), 491 enum_type->GetByteSize()); 492 } 493 } 494 495 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestArrayTypes)) { 496 // In order to get this test working, we need to support lookup by symbol 497 // name. Because array 498 // types themselves do not have names, only the symbols have names (i.e. the 499 // name of the array). 500 } 501 502 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestFunctionTypes)) { 503 // In order to get this test working, we need to support lookup by symbol 504 // name. Because array 505 // types themselves do not have names, only the symbols have names (i.e. the 506 // name of the array). 507 } 508 509 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestTypedefs)) { 510 FileSpec fspec(m_types_test_exe.c_str(), false); 511 ArchSpec aspec("i686-pc-windows"); 512 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 513 514 SymbolVendor *plugin = module->GetSymbolVendor(); 515 SymbolFilePDB *symfile = 516 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 517 const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); 518 SymbolContext sc; 519 llvm::DenseSet<SymbolFile *> searched_files; 520 TypeMap results; 521 522 const char *TypedefsToCheck[] = {"ClassTypedef", "NSClassTypedef"}; 523 for (auto Typedef : TypedefsToCheck) { 524 TypeMap results; 525 EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Typedef), nullptr, false, 526 0, searched_files, results)); 527 EXPECT_EQ(1u, results.GetSize()); 528 lldb::TypeSP typedef_type = results.GetTypeAtIndex(0); 529 EXPECT_EQ(ConstString(Typedef), typedef_type->GetName()); 530 CompilerType compiler_type = typedef_type->GetFullCompilerType(); 531 ClangASTContext *clang_type_system = 532 llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); 533 EXPECT_TRUE( 534 clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType())); 535 536 std::string sizeof_var = "sizeof_"; 537 sizeof_var.append(Typedef); 538 EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), 539 typedef_type->GetByteSize()); 540 } 541 } 542 543 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestRegexNameMatch)) { 544 FileSpec fspec(m_types_test_exe.c_str(), false); 545 ArchSpec aspec("i686-pc-windows"); 546 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 547 548 SymbolVendor *plugin = module->GetSymbolVendor(); 549 SymbolFilePDB *symfile = 550 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 551 SymbolContext sc; 552 llvm::DenseSet<SymbolFile *> searched_files; 553 TypeMap results; 554 uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, 555 false, 0, searched_files, results); 556 EXPECT_GT(num_results, 1u); 557 EXPECT_EQ(num_results, results.GetSize()); 558 } 559 560 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestMaxMatches)) { 561 FileSpec fspec(m_types_test_exe.c_str(), false); 562 ArchSpec aspec("i686-pc-windows"); 563 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 564 565 SymbolVendor *plugin = module->GetSymbolVendor(); 566 SymbolFilePDB *symfile = 567 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 568 SymbolContext sc; 569 llvm::DenseSet<SymbolFile *> searched_files; 570 TypeMap results; 571 uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, 572 false, 0, searched_files, results); 573 // Try to limit ourselves from 1 to 10 results, otherwise we could be doing 574 // this thousands of times. 575 // The idea is just to make sure that for a variety of values, the number of 576 // limited results always 577 // comes out to the number we are expecting. 578 uint32_t iterations = std::min(num_results, 10u); 579 for (uint32_t i = 1; i <= iterations; ++i) { 580 uint32_t num_limited_results = symfile->FindTypes( 581 sc, ConstString(".*"), nullptr, false, i, searched_files, results); 582 EXPECT_EQ(i, num_limited_results); 583 EXPECT_EQ(num_limited_results, results.GetSize()); 584 } 585 } 586 587 TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNullName)) { 588 FileSpec fspec(m_types_test_exe.c_str(), false); 589 ArchSpec aspec("i686-pc-windows"); 590 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); 591 592 SymbolVendor *plugin = module->GetSymbolVendor(); 593 SymbolFilePDB *symfile = 594 static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); 595 SymbolContext sc; 596 llvm::DenseSet<SymbolFile *> searched_files; 597 TypeMap results; 598 uint32_t num_results = symfile->FindTypes(sc, ConstString(), nullptr, false, 599 0, searched_files, results); 600 EXPECT_EQ(0u, num_results); 601 EXPECT_EQ(0u, results.GetSize()); 602 } 603