brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.4 KiB · 90cd4d5 Raw
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 &lt, 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