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