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