Index: vendor/lldb/dist/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- vendor/lldb/dist/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h (revision 327309) +++ vendor/lldb/dist/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h (revision 327310) @@ -1,191 +1,191 @@ //===-- SymbolFilePDB.h -------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ #define lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/UserID.h" #include "llvm/ADT/DenseMap.h" #include "llvm/DebugInfo/PDB/IPDBSession.h" #include "llvm/DebugInfo/PDB/PDB.h" class SymbolFilePDB : public lldb_private::SymbolFile { public: //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ static void Initialize(); static void Terminate(); static void DebuggerInitialize(lldb_private::Debugger &debugger); static lldb_private::ConstString GetPluginNameStatic(); static const char *GetPluginDescriptionStatic(); static lldb_private::SymbolFile * CreateInstance(lldb_private::ObjectFile *obj_file); //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ SymbolFilePDB(lldb_private::ObjectFile *ofile); ~SymbolFilePDB() override; uint32_t CalculateAbilities() override; void InitializeObject() override; //------------------------------------------------------------------ // Compile Unit function calls //------------------------------------------------------------------ uint32_t GetNumCompileUnits() override; lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; size_t ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; bool ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; bool ParseCompileUnitSupportFiles( const lldb_private::SymbolContext &sc, lldb_private::FileSpecList &support_files) override; bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) override; size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; size_t ParseTypes(const lldb_private::SymbolContext &sc) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; void ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t FindGlobalVariables(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::VariableList &variables) override; uint32_t FindGlobalVariables(const lldb_private::RegularExpression ®ex, bool append, uint32_t max_matches, lldb_private::VariableList &variables) override; uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) override; void GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector &mangled_names) override; uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; size_t FindTypes(const std::vector &context, bool append, lldb_private::TypeMap &types) override; + void FindTypesByRegex(const lldb_private::RegularExpression ®ex, + uint32_t max_matches, + lldb_private::TypeMap &types); + lldb_private::TypeList *GetTypeList() override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, uint32_t type_mask, lldb_private::TypeList &type_list) override; lldb_private::TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language) override; lldb_private::CompilerDeclContext FindNamespace( const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; lldb_private::ConstString GetPluginName() override; uint32_t GetPluginVersion() override; llvm::pdb::IPDBSession &GetPDBSession(); const llvm::pdb::IPDBSession &GetPDBSession() const; private: lldb::CompUnitSP ParseCompileUnitForSymIndex(uint32_t id); bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, uint32_t match_line); void BuildSupportFileIdToSupportFileIndexMap( const llvm::pdb::PDBSymbolCompiland &cu, llvm::DenseMap &index_map) const; - - void FindTypesByRegex(const lldb_private::RegularExpression ®ex, - uint32_t max_matches, - lldb_private::TypeMap &types); void FindTypesByName(const std::string &name, uint32_t max_matches, lldb_private::TypeMap &types); llvm::DenseMap m_comp_units; llvm::DenseMap m_types; std::vector m_builtin_types; std::unique_ptr m_session_up; uint32_t m_cached_compile_unit_count; std::unique_ptr m_tu_decl_ctx_up; }; #endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ Index: vendor/lldb/dist/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp =================================================================== --- vendor/lldb/dist/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp (revision 327309) +++ vendor/lldb/dist/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp (revision 327310) @@ -1,573 +1,569 @@ //===-- 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 #endif #include 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 <, 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(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(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(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(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(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(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(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(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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); SymbolContext sc; llvm::DenseSet 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); SymbolContext sc; llvm::DenseSet 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); SymbolContext sc; llvm::DenseSet 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); SymbolContext sc; llvm::DenseSet 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); llvm::pdb::IPDBSession &session = symfile->GetPDBSession(); SymbolContext sc; llvm::DenseSet 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(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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); - SymbolContext sc; - llvm::DenseSet 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()); + + 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(); - num_results = symfile->FindTypes(sc, ConstString("**"), nullptr, - false, 0, searched_files, results); - EXPECT_EQ(num_results, 0u); - EXPECT_EQ(num_results, results.GetSize()); + 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); SymbolContext sc; llvm::DenseSet searched_files; TypeMap results; - uint32_t num_results = symfile->FindTypes(sc, ConstString(".*"), nullptr, + 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, ConstString(".*"), nullptr, false, i, searched_files, results); + 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(fspec, aspec); SymbolVendor *plugin = module->GetSymbolVendor(); SymbolFilePDB *symfile = static_cast(plugin->GetSymbolFile()); SymbolContext sc; llvm::DenseSet 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()); }