Files
acceptance-tests
data
debian
docs
external
Newtonsoft.Json
api-doc-tools
api-snapshot
aspnetwebstack
bdwgc
binary-reference-assemblies
bockbuild
boringssl
cecil
cecil-legacy
corefx
corert
helix-binaries
ikdasm
ikvm
illinker-test-assets
linker
llvm-project
clang
clang-tools-extra
compiler-rt
libcxx
libcxxabi
libunwind
lld
lldb
cmake
docs
examples
include
lit
lldb.xcodeproj
lldb.xcworkspace
packages
resources
scripts
source
third_party
tools
unittests
Breakpoint
Core
Editline
Expression
Host
Interpreter
Language
ObjectFile
Platform
Process
ScriptInterpreter
Signals
Symbol
SymbolFile
DWARF
PDB
Inputs
CMakeLists.txt
SymbolFilePDBTests.cpp
CMakeLists.txt
Target
TestingSupport
UnwindAssembly
Utility
debugserver
tools
CMakeLists.txt
gtest_common.h
utils
www
.arcconfig
.clang-format
.gitignore
CMakeLists.txt
CODE_OWNERS.txt
INSTALL.txt
LICENSE.TXT
use_lldb_suite_root.py
llvm
openmp
polly
nuget-buildtasks
nunit-lite
roslyn-binaries
rx
xunit-binaries
how-to-bump-roslyn-binaries.md
ikvm-native
llvm
m4
man
mcs
mk
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
linux-packaging-mono/external/llvm-project/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp

570 lines
21 KiB
C++
Raw Normal View History

//===-- 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/DebugInfo/PDB/PDBSymbolData.h"
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.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 "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#if defined(_MSC_VER)
#include "lldb/Host/windows/windows.h"
#include <objbase.h>
#endif
#include <algorithm>
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();
m_pdb_test_exe = GetInputFilePath("test-pdb.exe");
m_types_test_exe = GetInputFilePath("test-pdb-types.exe");
}
void TearDown() override {
SymbolFilePDB::Terminate();
ClangASTContext::Initialize();
SymbolFileDWARF::Terminate();
ObjectFilePECOFF::Terminate();
HostInfo::Terminate();
#if defined(_MSC_VER)
::CoUninitialize();
#endif
}
protected:
std::string m_pdb_test_exe;
std::string 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 &lt, 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;
}
uint64_t GetGlobalConstantInteger(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;
}
}
};
TEST_F(SymbolFilePDBTests, 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::kAllAbilities;
EXPECT_EQ(expected_abilities, symfile->CalculateAbilities());
}
TEST_F(SymbolFilePDBTests, 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, 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,
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, 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, 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, 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, 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());
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(GetGlobalConstantInteger(session, "sizeof_Class"),
udt_type->GetByteSize());
}
TEST_F(SymbolFilePDBTests, 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());
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(GetGlobalConstantInteger(session, "sizeof_NestedClass"),
udt_type->GetByteSize());
}
TEST_F(SymbolFilePDBTests, 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());
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, 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());
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),
enum_type->GetByteSize());
}
}
TEST_F(SymbolFilePDBTests, 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, 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, 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());
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),
typedef_type->GetByteSize());
}
}
TEST_F(SymbolFilePDBTests, 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());
TypeMap results;
symfile->FindTypesByRegex(RegularExpression(".*"), 0, results);
EXPECT_GT(results.GetSize(), 1u);
// We expect no exception thrown if the given regex can't be compiled
results.Clear();
symfile->FindTypesByRegex(RegularExpression("**"), 0, results);
EXPECT_EQ(0u, results.GetSize());
}
TEST_F(SymbolFilePDBTests, 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;
const ConstString name("ClassTypedef");
uint32_t num_results = symfile->FindTypes(sc, name, 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, name, nullptr, false, i, searched_files, results);
EXPECT_EQ(i, num_limited_results);
EXPECT_EQ(num_limited_results, results.GetSize());
}
}
TEST_F(SymbolFilePDBTests, 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());
}