639 lines · cpp
1//===-- PythonDataObjectsTests.cpp ----------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "gtest/gtest.h"10 11#include "llvm/ADT/STLExtras.h"12#include "llvm/DebugInfo/PDB/PDBSymbolData.h"13#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"14#include "llvm/Support/FileSystem.h"15#include "llvm/Support/Path.h"16#include "llvm/Testing/Support/Error.h"17 18#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"19#include "Plugins/Platform/Windows/PlatformWindows.h"20#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"21#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"22#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"23#include "TestingSupport/TestUtilities.h"24#include "lldb/Core/Address.h"25#include "lldb/Core/Debugger.h"26#include "lldb/Core/Module.h"27#include "lldb/Core/ModuleSpec.h"28#include "lldb/Host/FileSystem.h"29#include "lldb/Host/HostInfo.h"30#include "lldb/Symbol/CompileUnit.h"31#include "lldb/Symbol/LineTable.h"32#include "lldb/Symbol/TypeMap.h"33#include "lldb/Utility/ArchSpec.h"34#include "lldb/Utility/FileSpec.h"35 36#if defined(_WIN32)37#include "lldb/Host/windows/windows.h"38#include <objbase.h>39#endif40 41#include <algorithm>42 43using namespace lldb_private;44 45class SymbolFilePDBTests : public testing::Test {46public:47 void SetUp() override {48// Initialize and TearDown the plugin every time, so we get a brand new49// AST every time so that modifications to the AST from each test don't50// leak into the next test.51#if defined(_WIN32)52 ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);53#endif54 55 FileSystem::Initialize();56 HostInfo::Initialize();57 ObjectFilePECOFF::Initialize();58 plugin::dwarf::SymbolFileDWARF::Initialize();59 TypeSystemClang::Initialize();60 SymbolFilePDB::Initialize();61 62 m_pdb_test_exe = GetInputFilePath("test-pdb.exe");63 m_types_test_exe = GetInputFilePath("test-pdb-types.exe");64 65 ArchSpec arch("x86_64-pc-windows-msvc");66 Platform::SetHostPlatform(PlatformWindows::CreateInstance(true, &arch));67 m_debugger_sp = Debugger::CreateInstance();68 m_debugger_sp->SetPropertyValue(nullptr,69 lldb_private::eVarSetOperationAssign,70 "plugin.symbol-file.pdb.reader", "dia");71 }72 73 void TearDown() override {74 SymbolFilePDB::Terminate();75 TypeSystemClang::Initialize();76 plugin::dwarf::SymbolFileDWARF::Terminate();77 ObjectFilePECOFF::Terminate();78 HostInfo::Terminate();79 FileSystem::Terminate();80 81#if defined(_WIN32)82 ::CoUninitialize();83#endif84 }85 86protected:87 std::string m_pdb_test_exe;88 std::string m_types_test_exe;89 lldb::DebuggerSP m_debugger_sp;90 91 bool FileSpecMatchesAsBaseOrFull(const FileSpec &left,92 const FileSpec &right) const {93 // If the filenames don't match, the paths can't be equal94 if (!left.FileEquals(right))95 return false;96 // If BOTH have a directory, also compare the directories.97 if (left.GetDirectory() && right.GetDirectory())98 return left.DirectoryEquals(right);99 100 // If one has a directory but not the other, they match.101 return true;102 }103 104 void VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc,105 const FileSpec &spec, LineTable <, uint32_t line,106 lldb::addr_t addr) {107 LineEntry entry;108 Address address;109 EXPECT_TRUE(module->ResolveFileAddress(addr, address));110 111 EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry));112 EXPECT_EQ(line, entry.line);113 EXPECT_EQ(address, entry.range.GetBaseAddress());114 115 EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.GetFile()));116 }117 118 bool ContainsCompileUnit(const SymbolContextList &sc_list,119 const FileSpec &spec) const {120 for (size_t i = 0; i < sc_list.GetSize(); ++i) {121 const SymbolContext &sc = sc_list[i];122 if (FileSpecMatchesAsBaseOrFull(sc.comp_unit->GetPrimaryFile(), spec))123 return true;124 }125 return false;126 }127 128 uint64_t GetGlobalConstantInteger(llvm::pdb::IPDBSession &session,129 llvm::StringRef var) const {130 auto global = session.getGlobalScope();131 auto results =132 global->findChildren(llvm::pdb::PDB_SymType::Data, var,133 llvm::pdb::PDB_NameSearchFlags::NS_Default);134 uint32_t count = results->getChildCount();135 if (count == 0)136 return -1;137 138 auto item = results->getChildAtIndex(0);139 auto symbol = llvm::dyn_cast<llvm::pdb::PDBSymbolData>(item.get());140 if (!symbol)141 return -1;142 llvm::pdb::Variant value = symbol->getValue();143 switch (value.Type) {144 case llvm::pdb::PDB_VariantType::Int16:145 return value.Value.Int16;146 case llvm::pdb::PDB_VariantType::Int32:147 return value.Value.Int32;148 case llvm::pdb::PDB_VariantType::UInt16:149 return value.Value.UInt16;150 case llvm::pdb::PDB_VariantType::UInt32:151 return value.Value.UInt32;152 default:153 return 0;154 }155 }156};157 158TEST_F(SymbolFilePDBTests, TestAbilitiesForPDB) {159 // Test that when we have PDB debug info, SymbolFilePDB is used.160 FileSpec fspec(m_pdb_test_exe);161 ArchSpec aspec("i686-pc-windows");162 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);163 164 SymbolFile *symfile = module->GetSymbolFile();165 EXPECT_NE(nullptr, symfile);166 EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic());167 168 uint32_t expected_abilities = SymbolFile::kAllAbilities;169 EXPECT_EQ(expected_abilities, symfile->CalculateAbilities());170}171 172TEST_F(SymbolFilePDBTests, TestResolveSymbolContextBasename) {173 // Test that attempting to call ResolveSymbolContext with only a basename174 // finds all full paths175 // with the same basename176 FileSpec fspec(m_pdb_test_exe);177 ArchSpec aspec("i686-pc-windows");178 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);179 180 SymbolFile *symfile = module->GetSymbolFile();181 182 FileSpec header_spec("test-pdb.cpp");183 SymbolContextList sc_list;184 SourceLocationSpec location_spec(header_spec, /*line=*/0);185 uint32_t result_count = symfile->ResolveSymbolContext(186 location_spec, lldb::eSymbolContextCompUnit, sc_list);187 EXPECT_EQ(1u, result_count);188 EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec));189}190 191TEST_F(SymbolFilePDBTests, TestResolveSymbolContextFullPath) {192 // Test that attempting to call ResolveSymbolContext with a full path only193 // finds the one source194 // file that matches the full path.195 FileSpec fspec(m_pdb_test_exe);196 ArchSpec aspec("i686-pc-windows");197 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);198 199 SymbolFile *symfile = module->GetSymbolFile();200 201 FileSpec header_spec(202 R"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec");203 SymbolContextList sc_list;204 SourceLocationSpec location_spec(header_spec, /*line=*/0);205 uint32_t result_count = symfile->ResolveSymbolContext(206 location_spec, lldb::eSymbolContextCompUnit, sc_list);207 EXPECT_GE(1u, result_count);208 EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec));209}210 211TEST_F(SymbolFilePDBTests, TestLookupOfHeaderFileWithInlines) {212 // Test that when looking up a header file via ResolveSymbolContext (i.e. a213 // file that was not by itself214 // compiled, but only contributes to the combined code of other source files),215 // a SymbolContext is returned216 // for each compiland which has line contributions from the requested header.217 FileSpec fspec(m_pdb_test_exe);218 ArchSpec aspec("i686-pc-windows");219 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);220 221 SymbolFile *symfile = module->GetSymbolFile();222 223 FileSpec header_specs[] = {FileSpec("test-pdb.h"),224 FileSpec("test-pdb-nested.h")};225 FileSpec main_cpp_spec("test-pdb.cpp");226 FileSpec alt_cpp_spec("test-pdb-alt.cpp");227 for (const auto &hspec : header_specs) {228 SymbolContextList sc_list;229 SourceLocationSpec location_spec(hspec, /*line=*/0, /*column=*/std::nullopt,230 /*check_inlines=*/true);231 uint32_t result_count = symfile->ResolveSymbolContext(232 location_spec, lldb::eSymbolContextCompUnit, sc_list);233 EXPECT_EQ(2u, result_count);234 EXPECT_TRUE(ContainsCompileUnit(sc_list, main_cpp_spec));235 EXPECT_TRUE(ContainsCompileUnit(sc_list, alt_cpp_spec));236 }237}238 239TEST_F(SymbolFilePDBTests, TestLookupOfHeaderFileWithNoInlines) {240 // Test that when looking up a header file via ResolveSymbolContext (i.e. a241 // file that was not by itself242 // compiled, but only contributes to the combined code of other source files),243 // that if check_inlines244 // is false, no SymbolContexts are returned.245 FileSpec fspec(m_pdb_test_exe);246 ArchSpec aspec("i686-pc-windows");247 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);248 249 SymbolFile *symfile = module->GetSymbolFile();250 251 FileSpec header_specs[] = {FileSpec("test-pdb.h"),252 FileSpec("test-pdb-nested.h")};253 for (const auto &hspec : header_specs) {254 SymbolContextList sc_list;255 SourceLocationSpec location_spec(hspec, /*line=*/0);256 uint32_t result_count = symfile->ResolveSymbolContext(257 location_spec, lldb::eSymbolContextCompUnit, sc_list);258 EXPECT_EQ(0u, result_count);259 }260}261 262TEST_F(SymbolFilePDBTests, TestLineTablesMatchAll) {263 // Test that when calling ResolveSymbolContext with a line number of 0, all264 // line entries from265 // the specified files are returned.266 FileSpec fspec(m_pdb_test_exe);267 ArchSpec aspec("i686-pc-windows");268 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);269 270 SymbolFile *symfile = module->GetSymbolFile();271 272 FileSpec source_file("test-pdb.cpp");273 FileSpec header1("test-pdb.h");274 FileSpec header2("test-pdb-nested.h");275 uint32_t cus = symfile->GetNumCompileUnits();276 EXPECT_EQ(2u, cus);277 278 SymbolContextList sc_list;279 lldb::SymbolContextItem scope =280 lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry;281 282 SourceLocationSpec location_spec(283 source_file, /*line=*/0, /*column=*/std::nullopt, /*check_inlines=*/true);284 uint32_t count = symfile->ResolveSymbolContext(location_spec, scope, sc_list);285 EXPECT_EQ(1u, count);286 SymbolContext sc;287 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));288 289 LineTable *lt = sc.comp_unit->GetLineTable();290 EXPECT_NE(nullptr, lt);291 count = lt->GetSize();292 // We expect one extra entry for termination (per function)293 EXPECT_EQ(16u, count);294 295 VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040);296 VerifyLineEntry(module, sc, source_file, *lt, 8, 0x401043);297 VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045);298 299 VerifyLineEntry(module, sc, source_file, *lt, 13, 0x401050);300 VerifyLineEntry(module, sc, source_file, *lt, 14, 0x401054);301 VerifyLineEntry(module, sc, source_file, *lt, 15, 0x401070);302 303 VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090);304 VerifyLineEntry(module, sc, header1, *lt, 10, 0x401093);305 VerifyLineEntry(module, sc, header1, *lt, 11, 0x4010a2);306 307 VerifyLineEntry(module, sc, header2, *lt, 5, 0x401080);308 VerifyLineEntry(module, sc, header2, *lt, 6, 0x401083);309 VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089);310}311 312TEST_F(SymbolFilePDBTests, TestLineTablesMatchSpecific) {313 // Test that when calling ResolveSymbolContext with a specific line number,314 // only line entries315 // which match the requested line are returned.316 FileSpec fspec(m_pdb_test_exe);317 ArchSpec aspec("i686-pc-windows");318 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);319 320 SymbolFile *symfile = module->GetSymbolFile();321 322 FileSpec source_file("test-pdb.cpp");323 FileSpec header1("test-pdb.h");324 FileSpec header2("test-pdb-nested.h");325 uint32_t cus = symfile->GetNumCompileUnits();326 EXPECT_EQ(2u, cus);327 328 SymbolContextList sc_list;329 lldb::SymbolContextItem scope =330 lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry;331 332 // First test with line 7, and verify that only line 7 entries are added.333 SourceLocationSpec location_spec(334 source_file, /*line=*/7, /*column=*/std::nullopt, /*check_inlines=*/true);335 uint32_t count = symfile->ResolveSymbolContext(location_spec, scope, sc_list);336 EXPECT_EQ(1u, count);337 SymbolContext sc;338 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));339 340 LineTable *lt = sc.comp_unit->GetLineTable();341 EXPECT_NE(nullptr, lt);342 count = lt->GetSize();343 // We expect one extra entry for termination344 EXPECT_EQ(3u, count);345 346 VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040);347 VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089);348 349 sc_list.Clear();350 // Then test with line 9, and verify that only line 9 entries are added.351 location_spec = SourceLocationSpec(352 source_file, /*line=*/9, /*column=*/std::nullopt, /*check_inlines=*/true);353 count = symfile->ResolveSymbolContext(location_spec, scope, sc_list);354 EXPECT_EQ(1u, count);355 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));356 357 lt = sc.comp_unit->GetLineTable();358 EXPECT_NE(nullptr, lt);359 count = lt->GetSize();360 // We expect one extra entry for termination361 EXPECT_EQ(3u, count);362 363 VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045);364 VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090);365}366 367TEST_F(SymbolFilePDBTests, TestSimpleClassTypes) {368 FileSpec fspec(m_types_test_exe);369 ArchSpec aspec("i686-pc-windows");370 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);371 372 SymbolFilePDB *symfile =373 static_cast<SymbolFilePDB *>(module->GetSymbolFile());374 llvm::pdb::IPDBSession &session = symfile->GetPDBSession();375 TypeResults query_results;376 symfile->FindTypes(TypeQuery("Class"), query_results);377 TypeMap &results = query_results.GetTypeMap();378 EXPECT_EQ(1u, results.GetSize());379 lldb::TypeSP udt_type = results.GetTypeAtIndex(0);380 EXPECT_EQ(ConstString("Class"), udt_type->GetName());381 CompilerType compiler_type = udt_type->GetForwardCompilerType();382 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType()));383 EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_Class"),384 llvm::expectedToOptional(udt_type->GetByteSize(nullptr)));385}386 387TEST_F(SymbolFilePDBTests, TestNestedClassTypes) {388 FileSpec fspec(m_types_test_exe);389 ArchSpec aspec("i686-pc-windows");390 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);391 392 SymbolFilePDB *symfile =393 static_cast<SymbolFilePDB *>(module->GetSymbolFile());394 llvm::pdb::IPDBSession &session = symfile->GetPDBSession();395 396 auto clang_ast_ctx_or_err =397 symfile->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);398 ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded());399 400 auto clang_ast_ctx =401 llvm::dyn_cast_or_null<TypeSystemClang>(clang_ast_ctx_or_err->get());402 EXPECT_NE(nullptr, clang_ast_ctx);403 404 TypeResults query_results;405 symfile->FindTypes(TypeQuery("Class"), query_results);406 TypeMap &results = query_results.GetTypeMap();407 408 EXPECT_EQ(1u, results.GetSize());409 410 auto Class = results.GetTypeAtIndex(0);411 EXPECT_TRUE(Class);412 EXPECT_TRUE(Class->IsValidType());413 414 auto ClassCompilerType = Class->GetFullCompilerType();415 EXPECT_TRUE(ClassCompilerType.IsValid());416 417 auto ClassDeclCtx = clang_ast_ctx->GetDeclContextForType(ClassCompilerType);418 EXPECT_NE(nullptr, ClassDeclCtx);419 420 // There are two symbols for nested classes: one belonging to enclosing class421 // and one is global. We process correctly this case and create the same422 // compiler type for both, but `FindTypes` may return more than one type423 // (with the same compiler type) because the symbols have different IDs.424 425 auto ClassCompilerDeclCtx = CompilerDeclContext(clang_ast_ctx, ClassDeclCtx);426 TypeResults query_results_nested;427 symfile->FindTypes(428 TypeQuery(ClassCompilerDeclCtx, ConstString("NestedClass")),429 query_results_nested);430 TypeMap &more_results = query_results_nested.GetTypeMap();431 EXPECT_LE(1u, more_results.GetSize());432 433 lldb::TypeSP udt_type = more_results.GetTypeAtIndex(0);434 EXPECT_EQ(ConstString("NestedClass"), udt_type->GetName());435 436 CompilerType compiler_type = udt_type->GetForwardCompilerType();437 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType()));438 439 EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NestedClass"),440 llvm::expectedToOptional(udt_type->GetByteSize(nullptr)));441}442 443TEST_F(SymbolFilePDBTests, TestClassInNamespace) {444 FileSpec fspec(m_types_test_exe);445 ArchSpec aspec("i686-pc-windows");446 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);447 448 SymbolFilePDB *symfile =449 static_cast<SymbolFilePDB *>(module->GetSymbolFile());450 llvm::pdb::IPDBSession &session = symfile->GetPDBSession();451 auto clang_ast_ctx_or_err =452 symfile->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);453 ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err, llvm::Succeeded());454 455 auto clang_ast_ctx =456 llvm::dyn_cast_or_null<TypeSystemClang>(clang_ast_ctx_or_err->get());457 EXPECT_NE(nullptr, clang_ast_ctx);458 459 clang::ASTContext &ast_ctx = clang_ast_ctx->getASTContext();460 461 auto tu = ast_ctx.getTranslationUnitDecl();462 EXPECT_NE(nullptr, tu);463 464 symfile->ParseDeclsForContext(CompilerDeclContext(465 clang_ast_ctx, static_cast<clang::DeclContext *>(tu)));466 467 auto ns_namespace_decl_ctx =468 symfile->FindNamespace(ConstString("NS"), CompilerDeclContext(), true);469 EXPECT_TRUE(ns_namespace_decl_ctx.IsValid());470 471 TypeResults query_results;472 symfile->FindTypes(TypeQuery(ns_namespace_decl_ctx, ConstString("NSClass")),473 query_results);474 TypeMap &results = query_results.GetTypeMap();475 EXPECT_EQ(1u, results.GetSize());476 477 lldb::TypeSP udt_type = results.GetTypeAtIndex(0);478 EXPECT_EQ(ConstString("NSClass"), udt_type->GetName());479 480 CompilerType compiler_type = udt_type->GetForwardCompilerType();481 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type.GetOpaqueQualType()));482 483 EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"),484 llvm::expectedToOptional(udt_type->GetByteSize(nullptr)));485}486 487TEST_F(SymbolFilePDBTests, TestEnumTypes) {488 FileSpec fspec(m_types_test_exe);489 ArchSpec aspec("i686-pc-windows");490 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);491 492 SymbolFilePDB *symfile =493 static_cast<SymbolFilePDB *>(module->GetSymbolFile());494 llvm::pdb::IPDBSession &session = symfile->GetPDBSession();495 const char *EnumsToCheck[] = {"Enum", "ShortEnum"};496 for (auto Enum : EnumsToCheck) {497 498 TypeResults query_results;499 symfile->FindTypes(TypeQuery(Enum), query_results);500 TypeMap &results = query_results.GetTypeMap();501 EXPECT_EQ(1u, results.GetSize());502 lldb::TypeSP enum_type = results.GetTypeAtIndex(0);503 EXPECT_EQ(ConstString(Enum), enum_type->GetName());504 CompilerType compiler_type = enum_type->GetFullCompilerType();505 EXPECT_TRUE(TypeSystemClang::IsEnumType(compiler_type.GetOpaqueQualType()));506 clang::EnumDecl *enum_decl = TypeSystemClang::GetAsEnumDecl(compiler_type);507 EXPECT_NE(nullptr, enum_decl);508 EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(),509 enum_decl->enumerator_end()));510 511 std::string sizeof_var = "sizeof_";512 sizeof_var.append(Enum);513 EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var),514 llvm::expectedToOptional(enum_type->GetByteSize(nullptr)));515 }516}517 518TEST_F(SymbolFilePDBTests, TestArrayTypes) {519 // In order to get this test working, we need to support lookup by symbol520 // name. Because array521 // types themselves do not have names, only the symbols have names (i.e. the522 // name of the array).523}524 525TEST_F(SymbolFilePDBTests, TestFunctionTypes) {526 // In order to get this test working, we need to support lookup by symbol527 // name. Because array528 // types themselves do not have names, only the symbols have names (i.e. the529 // name of the array).530}531 532TEST_F(SymbolFilePDBTests, TestTypedefs) {533 FileSpec fspec(m_types_test_exe);534 ArchSpec aspec("i686-pc-windows");535 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);536 537 SymbolFilePDB *symfile =538 static_cast<SymbolFilePDB *>(module->GetSymbolFile());539 llvm::pdb::IPDBSession &session = symfile->GetPDBSession();540 541 const char *TypedefsToCheck[] = {"ClassTypedef", "NSClassTypedef",542 "FuncPointerTypedef",543 "VariadicFuncPointerTypedef"};544 for (auto Typedef : TypedefsToCheck) {545 TypeResults query_results;546 symfile->FindTypes(TypeQuery(Typedef), query_results);547 TypeMap &results = query_results.GetTypeMap();548 EXPECT_EQ(1u, results.GetSize());549 lldb::TypeSP typedef_type = results.GetTypeAtIndex(0);550 EXPECT_EQ(ConstString(Typedef), typedef_type->GetName());551 CompilerType compiler_type = typedef_type->GetFullCompilerType();552 auto clang_type_system =553 compiler_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();554 EXPECT_TRUE(555 clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType()));556 557 std::string sizeof_var = "sizeof_";558 sizeof_var.append(Typedef);559 EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var),560 llvm::expectedToOptional(typedef_type->GetByteSize(nullptr)));561 }562}563 564TEST_F(SymbolFilePDBTests, TestRegexNameMatch) {565 FileSpec fspec(m_types_test_exe);566 ArchSpec aspec("i686-pc-windows");567 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);568 569 SymbolFilePDB *symfile =570 static_cast<SymbolFilePDB *>(module->GetSymbolFile());571 TypeMap results;572 573 symfile->FindTypesByRegex(RegularExpression(".*"), 0, results);574 EXPECT_GT(results.GetSize(), 1u);575 576 // We expect no exception thrown if the given regex can't be compiled577 results.Clear();578 symfile->FindTypesByRegex(RegularExpression("**"), 0, results);579 EXPECT_EQ(0u, results.GetSize());580}581 582TEST_F(SymbolFilePDBTests, TestMaxMatches) {583 FileSpec fspec(m_types_test_exe);584 ArchSpec aspec("i686-pc-windows");585 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);586 587 SymbolFilePDB *symfile =588 static_cast<SymbolFilePDB *>(module->GetSymbolFile());589 590 // Make a type query object we can use for all types and for one type591 TypeQuery query("NestedClass");592 {593 // Find all types that match594 TypeResults query_results;595 symfile->FindTypes(query, query_results);596 TypeMap &results = query_results.GetTypeMap();597 // We expect to find Class::NestedClass and ClassTypedef::NestedClass.598 EXPECT_EQ(results.GetSize(), 2u);599 }600 {601 // Find a single type that matches602 query.SetFindOne(true);603 TypeResults query_results;604 symfile->FindTypes(query, query_results);605 TypeMap &results = query_results.GetTypeMap();606 EXPECT_EQ(results.GetSize(), 1u);607 }608}609 610TEST_F(SymbolFilePDBTests, TestNullName) {611 FileSpec fspec(m_types_test_exe);612 ArchSpec aspec("i686-pc-windows");613 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);614 615 SymbolFilePDB *symfile =616 static_cast<SymbolFilePDB *>(module->GetSymbolFile());617 618 TypeResults query_results;619 symfile->FindTypes(TypeQuery(llvm::StringRef()), query_results);620 TypeMap &results = query_results.GetTypeMap();621 EXPECT_EQ(0u, results.GetSize());622}623 624TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) {625 FileSpec fspec(m_pdb_test_exe.c_str());626 ArchSpec aspec("i686-pc-windows");627 lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec);628 629 SymbolContextList sc_list;630 module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"),631 lldb::eSymbolTypeAny, sc_list);632 EXPECT_EQ(1u, sc_list.GetSize());633 634 SymbolContext sc;635 EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc));636 EXPECT_STREQ("int foo(int)",637 sc.GetFunctionName(Mangled::ePreferDemangled).AsCString());638}639