diff options
Diffstat (limited to 'unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp')
-rw-r--r-- | unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp | 583 |
1 files changed, 583 insertions, 0 deletions
diff --git a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp new file mode 100644 index 0000000000000..b303ae7bac4bc --- /dev/null +++ b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -0,0 +1,583 @@ +//===-- PythonDataObjectsTests.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "llvm/ADT/STLExtras.h" +#include "llvm/Config/config.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" +#include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/SymbolVendor.h" + +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" +#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" +#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h" + +#if defined(_MSC_VER) +#include "lldb/Host/windows/windows.h" +#include <objbase.h> +#endif + +#include <algorithm> + +extern const char *TestMainArgv0; + +using namespace lldb_private; + +class SymbolFilePDBTests : public testing::Test +{ +public: + void + SetUp() override + { +// Initialize and TearDown the plugin every time, so we get a brand new +// AST every time so that modifications to the AST from each test don't +// leak into the next test. +#if defined(_MSC_VER) + ::CoInitializeEx(nullptr, COINIT_MULTITHREADED); +#endif + + HostInfo::Initialize(); + ObjectFilePECOFF::Initialize(); + SymbolFileDWARF::Initialize(); + ClangASTContext::Initialize(); + SymbolFilePDB::Initialize(); + + llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0); + llvm::SmallString<128> inputs_folder = exe_folder; + llvm::sys::path::append(inputs_folder, "Inputs"); + + m_pdb_test_exe = inputs_folder; + m_dwarf_test_exe = inputs_folder; + m_types_test_exe = inputs_folder; + llvm::sys::path::append(m_pdb_test_exe, "test-pdb.exe"); + llvm::sys::path::append(m_dwarf_test_exe, "test-dwarf.exe"); + llvm::sys::path::append(m_types_test_exe, "test-pdb-types.exe"); + } + + void + TearDown() override + { + SymbolFilePDB::Terminate(); + ClangASTContext::Initialize(); + SymbolFileDWARF::Terminate(); + ObjectFilePECOFF::Terminate(); + HostInfo::Terminate(); + +#if defined(_MSC_VER) + ::CoUninitialize(); +#endif + } + +protected: + llvm::SmallString<128> m_pdb_test_exe; + llvm::SmallString<128> m_dwarf_test_exe; + llvm::SmallString<128> m_types_test_exe; + + bool + FileSpecMatchesAsBaseOrFull(const FileSpec &left, const FileSpec &right) const + { + // If the filenames don't match, the paths can't be equal + if (!left.FileEquals(right)) + return false; + // If BOTH have a directory, also compare the directories. + if (left.GetDirectory() && right.GetDirectory()) + return left.DirectoryEquals(right); + + // If one has a directory but not the other, they match. + return true; + } + + void + VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc, const FileSpec &spec, LineTable <, uint32_t line, + lldb::addr_t addr) + { + LineEntry entry; + Address address; + EXPECT_TRUE(module->ResolveFileAddress(addr, address)); + + EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry)); + EXPECT_EQ(line, entry.line); + EXPECT_EQ(address, entry.range.GetBaseAddress()); + + EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file)); + } + + bool + ContainsCompileUnit(const SymbolContextList &sc_list, const FileSpec &spec) const + { + for (size_t i = 0; i < sc_list.GetSize(); ++i) + { + const SymbolContext &sc = sc_list[i]; + if (FileSpecMatchesAsBaseOrFull(*sc.comp_unit, spec)) + return true; + } + return false; + } + + int + GetGlobalConstantInteger(const llvm::pdb::IPDBSession &session, llvm::StringRef var) const + { + auto global = session.getGlobalScope(); + auto results = + global->findChildren(llvm::pdb::PDB_SymType::Data, var, llvm::pdb::PDB_NameSearchFlags::NS_Default); + uint32_t count = results->getChildCount(); + if (count == 0) + return -1; + + auto item = results->getChildAtIndex(0); + auto symbol = llvm::dyn_cast<llvm::pdb::PDBSymbolData>(item.get()); + if (!symbol) + return -1; + llvm::pdb::Variant value = symbol->getValue(); + switch (value.Type) + { + case llvm::pdb::PDB_VariantType::Int16: + return value.Value.Int16; + case llvm::pdb::PDB_VariantType::Int32: + return value.Value.Int32; + case llvm::pdb::PDB_VariantType::UInt16: + return value.Value.UInt16; + case llvm::pdb::PDB_VariantType::UInt32: + return value.Value.UInt32; + default: + return 0; + } + } +}; + +#if defined(HAVE_DIA_SDK) +#define REQUIRES_DIA_SDK(TestName) TestName +#else +#define REQUIRES_DIA_SDK(TestName) DISABLED_##TestName +#endif + +TEST_F(SymbolFilePDBTests, TestAbilitiesForDWARF) +{ + // Test that when we have Dwarf debug info, SymbolFileDWARF is used. + FileSpec fspec(m_dwarf_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + EXPECT_NE(nullptr, symfile); + EXPECT_EQ(symfile->GetPluginName(), SymbolFileDWARF::GetPluginNameStatic()); + + uint32_t expected_abilities = SymbolFile::kAllAbilities; + EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestAbilitiesForPDB)) +{ + // Test that when we have PDB debug info, SymbolFilePDB is used. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + EXPECT_NE(nullptr, symfile); + EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); + + uint32_t expected_abilities = SymbolFile::CompileUnits | SymbolFile::LineTables; + EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextBasename)) +{ + // Test that attempting to call ResolveSymbolContext with only a basename finds all full paths + // with the same basename + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec header_spec("test-pdb.cpp", false); + SymbolContextList sc_list; + uint32_t result_count = symfile->ResolveSymbolContext(header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list); + EXPECT_EQ(1u, result_count); + EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestResolveSymbolContextFullPath)) +{ + // Test that attempting to call ResolveSymbolContext with a full path only finds the one source + // file that matches the full path. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec header_spec(R"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec", false); + SymbolContextList sc_list; + uint32_t result_count = symfile->ResolveSymbolContext(header_spec, 0, false, lldb::eSymbolContextCompUnit, sc_list); + EXPECT_GE(1u, result_count); + EXPECT_TRUE(ContainsCompileUnit(sc_list, header_spec)); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithInlines)) +{ + // Test that when looking up a header file via ResolveSymbolContext (i.e. a file that was not by itself + // compiled, but only contributes to the combined code of other source files), a SymbolContext is returned + // for each compiland which has line contributions from the requested header. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec header_specs[] = {FileSpec("test-pdb.h", false), FileSpec("test-pdb-nested.h", false)}; + FileSpec main_cpp_spec("test-pdb.cpp", false); + FileSpec alt_cpp_spec("test-pdb-alt.cpp", false); + for (const auto &hspec : header_specs) + { + SymbolContextList sc_list; + uint32_t result_count = symfile->ResolveSymbolContext(hspec, 0, true, lldb::eSymbolContextCompUnit, sc_list); + EXPECT_EQ(2u, result_count); + EXPECT_TRUE(ContainsCompileUnit(sc_list, main_cpp_spec)); + EXPECT_TRUE(ContainsCompileUnit(sc_list, alt_cpp_spec)); + } +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLookupOfHeaderFileWithNoInlines)) +{ + // Test that when looking up a header file via ResolveSymbolContext (i.e. a file that was not by itself + // compiled, but only contributes to the combined code of other source files), that if check_inlines + // is false, no SymbolContexts are returned. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + EXPECT_NE(nullptr, plugin); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec header_specs[] = {FileSpec("test-pdb.h", false), FileSpec("test-pdb-nested.h", false)}; + for (const auto &hspec : header_specs) + { + SymbolContextList sc_list; + uint32_t result_count = symfile->ResolveSymbolContext(hspec, 0, false, lldb::eSymbolContextCompUnit, sc_list); + EXPECT_EQ(0u, result_count); + } +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchAll)) +{ + // Test that when calling ResolveSymbolContext with a line number of 0, all line entries from + // the specified files are returned. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec source_file("test-pdb.cpp", false); + FileSpec header1("test-pdb.h", false); + FileSpec header2("test-pdb-nested.h", false); + uint32_t cus = symfile->GetNumCompileUnits(); + EXPECT_EQ(2u, cus); + + SymbolContextList sc_list; + uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + + uint32_t count = symfile->ResolveSymbolContext(source_file, 0, true, scope, sc_list); + EXPECT_EQ(1u, count); + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + + LineTable *lt = sc.comp_unit->GetLineTable(); + EXPECT_NE(nullptr, lt); + count = lt->GetSize(); + // We expect one extra entry for termination (per function) + EXPECT_EQ(16u, count); + + VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); + VerifyLineEntry(module, sc, source_file, *lt, 8, 0x401043); + VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); + + VerifyLineEntry(module, sc, source_file, *lt, 13, 0x401050); + VerifyLineEntry(module, sc, source_file, *lt, 14, 0x401054); + VerifyLineEntry(module, sc, source_file, *lt, 15, 0x401070); + + VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); + VerifyLineEntry(module, sc, header1, *lt, 10, 0x401093); + VerifyLineEntry(module, sc, header1, *lt, 11, 0x4010a2); + + VerifyLineEntry(module, sc, header2, *lt, 5, 0x401080); + VerifyLineEntry(module, sc, header2, *lt, 6, 0x401083); + VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestLineTablesMatchSpecific)) +{ + // Test that when calling ResolveSymbolContext with a specific line number, only line entries + // which match the requested line are returned. + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFile *symfile = plugin->GetSymbolFile(); + + FileSpec source_file("test-pdb.cpp", false); + FileSpec header1("test-pdb.h", false); + FileSpec header2("test-pdb-nested.h", false); + uint32_t cus = symfile->GetNumCompileUnits(); + EXPECT_EQ(2u, cus); + + SymbolContextList sc_list; + uint32_t scope = lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry; + + // First test with line 7, and verify that only line 7 entries are added. + uint32_t count = symfile->ResolveSymbolContext(source_file, 7, true, scope, sc_list); + EXPECT_EQ(1u, count); + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + + LineTable *lt = sc.comp_unit->GetLineTable(); + EXPECT_NE(nullptr, lt); + count = lt->GetSize(); + // We expect one extra entry for termination + EXPECT_EQ(3u, count); + + VerifyLineEntry(module, sc, source_file, *lt, 7, 0x401040); + VerifyLineEntry(module, sc, header2, *lt, 7, 0x401089); + + sc_list.Clear(); + // Then test with line 9, and verify that only line 9 entries are added. + count = symfile->ResolveSymbolContext(source_file, 9, true, scope, sc_list); + EXPECT_EQ(1u, count); + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + + lt = sc.comp_unit->GetLineTable(); + EXPECT_NE(nullptr, lt); + count = lt->GetSize(); + // We expect one extra entry for termination + EXPECT_EQ(3u, count); + + VerifyLineEntry(module, sc, source_file, *lt, 9, 0x401045); + VerifyLineEntry(module, sc, header1, *lt, 9, 0x401090); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestSimpleClassTypes)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class"), nullptr, false, 0, searched_files, results)); + EXPECT_EQ(1u, results.GetSize()); + lldb::TypeSP udt_type = results.GetTypeAtIndex(0); + EXPECT_EQ(ConstString("Class"), udt_type->GetName()); + CompilerType compiler_type = udt_type->GetForwardCompilerType(); + EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_Class")), udt_type->GetByteSize()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNestedClassTypes)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("Class::NestedClass"), nullptr, false, 0, searched_files, results)); + EXPECT_EQ(1u, results.GetSize()); + lldb::TypeSP udt_type = results.GetTypeAtIndex(0); + EXPECT_EQ(ConstString("Class::NestedClass"), udt_type->GetName()); + CompilerType compiler_type = udt_type->GetForwardCompilerType(); + EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_EQ(uint64_t(GetGlobalConstantInteger(session, "sizeof_NestedClass")), udt_type->GetByteSize()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestClassInNamespace)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString("NS::NSClass"), nullptr, false, 0, searched_files, results)); + EXPECT_EQ(1u, results.GetSize()); + lldb::TypeSP udt_type = results.GetTypeAtIndex(0); + EXPECT_EQ(ConstString("NS::NSClass"), udt_type->GetName()); + CompilerType compiler_type = udt_type->GetForwardCompilerType(); + EXPECT_TRUE(ClangASTContext::IsClassType(compiler_type.GetOpaqueQualType())); + EXPECT_EQ(GetGlobalConstantInteger(session, "sizeof_NSClass"), udt_type->GetByteSize()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestEnumTypes)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + const char *EnumsToCheck[] = {"Enum", "ShortEnum"}; + for (auto Enum : EnumsToCheck) + { + TypeMap results; + EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Enum), nullptr, false, 0, searched_files, results)); + EXPECT_EQ(1u, results.GetSize()); + lldb::TypeSP enum_type = results.GetTypeAtIndex(0); + EXPECT_EQ(ConstString(Enum), enum_type->GetName()); + CompilerType compiler_type = enum_type->GetFullCompilerType(); + EXPECT_TRUE(ClangASTContext::IsEnumType(compiler_type.GetOpaqueQualType())); + clang::EnumDecl *enum_decl = ClangASTContext::GetAsEnumDecl(compiler_type); + EXPECT_NE(nullptr, enum_decl); + EXPECT_EQ(2, std::distance(enum_decl->enumerator_begin(), enum_decl->enumerator_end())); + + std::string sizeof_var = "sizeof_"; + sizeof_var.append(Enum); + EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), enum_type->GetByteSize()); + } +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestArrayTypes)) +{ + // In order to get this test working, we need to support lookup by symbol name. Because array + // types themselves do not have names, only the symbols have names (i.e. the name of the array). +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestFunctionTypes)) +{ + // In order to get this test working, we need to support lookup by symbol name. Because array + // types themselves do not have names, only the symbols have names (i.e. the name of the array). +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestTypedefs)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + const llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + + const char *TypedefsToCheck[] = {"ClassTypedef", "NSClassTypedef"}; + for (auto Typedef : TypedefsToCheck) + { + TypeMap results; + EXPECT_EQ(1u, symfile->FindTypes(sc, ConstString(Typedef), nullptr, false, 0, searched_files, results)); + EXPECT_EQ(1u, results.GetSize()); + lldb::TypeSP typedef_type = results.GetTypeAtIndex(0); + EXPECT_EQ(ConstString(Typedef), typedef_type->GetName()); + CompilerType compiler_type = typedef_type->GetFullCompilerType(); + ClangASTContext *clang_type_system = llvm::dyn_cast_or_null<ClangASTContext>(compiler_type.GetTypeSystem()); + EXPECT_TRUE(clang_type_system->IsTypedefType(compiler_type.GetOpaqueQualType())); + + std::string sizeof_var = "sizeof_"; + sizeof_var.append(Typedef); + EXPECT_EQ(GetGlobalConstantInteger(session, sizeof_var.c_str()), typedef_type->GetByteSize()); + } +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestRegexNameMatch)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, 0, searched_files, results); + EXPECT_GT(num_results, 1u); + EXPECT_EQ(num_results, results.GetSize()); +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestMaxMatches)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, 0, searched_files, results); + // Try to limit ourselves from 1 to 10 results, otherwise we could be doing this thousands of times. + // The idea is just to make sure that for a variety of values, the number of limited results always + // comes out to the number we are expecting. + uint32_t iterations = std::min(num_results, 10u); + for (uint32_t i = 1; i <= iterations; ++i) + { + uint32_t num_limited_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, false, i, searched_files, results); + EXPECT_EQ(i, num_limited_results); + EXPECT_EQ(num_limited_results, results.GetSize()); + } +} + +TEST_F(SymbolFilePDBTests, REQUIRES_DIA_SDK(TestNullName)) +{ + FileSpec fspec(m_types_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(fspec, aspec); + + SymbolVendor *plugin = module->GetSymbolVendor(); + SymbolFilePDB *symfile = static_cast<SymbolFilePDB *>(plugin->GetSymbolFile()); + SymbolContext sc; + llvm::DenseSet<SymbolFile *> searched_files; + TypeMap results; + uint32_t num_results = symfile->FindTypes(sc, ConstString(), nullptr, false, 0, searched_files, results); + EXPECT_EQ(0u, num_results); + EXPECT_EQ(0u, results.GetSize()); +} |