1 //===-- PythonDataObjectsTests.cpp ----------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
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"
18 #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h"
19 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
20 #include "Plugins/SymbolFile/PDB/SymbolFilePDB.h"
21 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
22 #include "TestingSupport/TestUtilities.h"
23 #include "lldb/Core/Address.h"
24 #include "lldb/Core/Module.h"
25 #include "lldb/Core/ModuleSpec.h"
26 #include "lldb/Host/FileSystem.h"
27 #include "lldb/Host/HostInfo.h"
28 #include "lldb/Symbol/CompileUnit.h"
29 #include "lldb/Symbol/LineTable.h"
30 #include "lldb/Symbol/TypeMap.h"
31 #include "lldb/Utility/ArchSpec.h"
32 #include "lldb/Utility/FileSpec.h"
35 #include "lldb/Host/windows/windows.h"
41 using namespace lldb_private
;
43 class SymbolFilePDBTests
: public testing::Test
{
45 void SetUp() override
{
46 // Initialize and TearDown the plugin every time, so we get a brand new
47 // AST every time so that modifications to the AST from each test don't
48 // leak into the next test.
50 ::CoInitializeEx(nullptr, COINIT_MULTITHREADED
);
53 FileSystem::Initialize();
54 HostInfo::Initialize();
55 ObjectFilePECOFF::Initialize();
56 plugin::dwarf::SymbolFileDWARF::Initialize();
57 TypeSystemClang::Initialize();
58 SymbolFilePDB::Initialize();
60 m_pdb_test_exe
= GetInputFilePath("test-pdb.exe");
61 m_types_test_exe
= GetInputFilePath("test-pdb-types.exe");
64 void TearDown() override
{
65 SymbolFilePDB::Terminate();
66 TypeSystemClang::Initialize();
67 plugin::dwarf::SymbolFileDWARF::Terminate();
68 ObjectFilePECOFF::Terminate();
69 HostInfo::Terminate();
70 FileSystem::Terminate();
78 std::string m_pdb_test_exe
;
79 std::string m_types_test_exe
;
81 bool FileSpecMatchesAsBaseOrFull(const FileSpec
&left
,
82 const FileSpec
&right
) const {
83 // If the filenames don't match, the paths can't be equal
84 if (!left
.FileEquals(right
))
86 // If BOTH have a directory, also compare the directories.
87 if (left
.GetDirectory() && right
.GetDirectory())
88 return left
.DirectoryEquals(right
);
90 // If one has a directory but not the other, they match.
94 void VerifyLineEntry(lldb::ModuleSP module
, const SymbolContext
&sc
,
95 const FileSpec
&spec
, LineTable
<
, uint32_t line
,
99 EXPECT_TRUE(module
->ResolveFileAddress(addr
, address
));
101 EXPECT_TRUE(lt
.FindLineEntryByAddress(address
, entry
));
102 EXPECT_EQ(line
, entry
.line
);
103 EXPECT_EQ(address
, entry
.range
.GetBaseAddress());
105 EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec
, entry
.file
));
108 bool ContainsCompileUnit(const SymbolContextList
&sc_list
,
109 const FileSpec
&spec
) const {
110 for (size_t i
= 0; i
< sc_list
.GetSize(); ++i
) {
111 const SymbolContext
&sc
= sc_list
[i
];
112 if (FileSpecMatchesAsBaseOrFull(sc
.comp_unit
->GetPrimaryFile(), spec
))
118 uint64_t GetGlobalConstantInteger(llvm::pdb::IPDBSession
&session
,
119 llvm::StringRef var
) const {
120 auto global
= session
.getGlobalScope();
122 global
->findChildren(llvm::pdb::PDB_SymType::Data
, var
,
123 llvm::pdb::PDB_NameSearchFlags::NS_Default
);
124 uint32_t count
= results
->getChildCount();
128 auto item
= results
->getChildAtIndex(0);
129 auto symbol
= llvm::dyn_cast
<llvm::pdb::PDBSymbolData
>(item
.get());
132 llvm::pdb::Variant value
= symbol
->getValue();
133 switch (value
.Type
) {
134 case llvm::pdb::PDB_VariantType::Int16
:
135 return value
.Value
.Int16
;
136 case llvm::pdb::PDB_VariantType::Int32
:
137 return value
.Value
.Int32
;
138 case llvm::pdb::PDB_VariantType::UInt16
:
139 return value
.Value
.UInt16
;
140 case llvm::pdb::PDB_VariantType::UInt32
:
141 return value
.Value
.UInt32
;
148 TEST_F(SymbolFilePDBTests
, TestAbilitiesForPDB
) {
149 // Test that when we have PDB debug info, SymbolFilePDB is used.
150 FileSpec
fspec(m_pdb_test_exe
);
151 ArchSpec
aspec("i686-pc-windows");
152 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
154 SymbolFile
*symfile
= module
->GetSymbolFile();
155 EXPECT_NE(nullptr, symfile
);
156 EXPECT_EQ(symfile
->GetPluginName(), SymbolFilePDB::GetPluginNameStatic());
158 uint32_t expected_abilities
= SymbolFile::kAllAbilities
;
159 EXPECT_EQ(expected_abilities
, symfile
->CalculateAbilities());
162 TEST_F(SymbolFilePDBTests
, TestResolveSymbolContextBasename
) {
163 // Test that attempting to call ResolveSymbolContext with only a basename
164 // finds all full paths
165 // with the same basename
166 FileSpec
fspec(m_pdb_test_exe
);
167 ArchSpec
aspec("i686-pc-windows");
168 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
170 SymbolFile
*symfile
= module
->GetSymbolFile();
172 FileSpec
header_spec("test-pdb.cpp");
173 SymbolContextList sc_list
;
174 SourceLocationSpec
location_spec(header_spec
, /*line=*/0);
175 uint32_t result_count
= symfile
->ResolveSymbolContext(
176 location_spec
, lldb::eSymbolContextCompUnit
, sc_list
);
177 EXPECT_EQ(1u, result_count
);
178 EXPECT_TRUE(ContainsCompileUnit(sc_list
, header_spec
));
181 TEST_F(SymbolFilePDBTests
, TestResolveSymbolContextFullPath
) {
182 // Test that attempting to call ResolveSymbolContext with a full path only
183 // finds the one source
184 // file that matches the full path.
185 FileSpec
fspec(m_pdb_test_exe
);
186 ArchSpec
aspec("i686-pc-windows");
187 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
189 SymbolFile
*symfile
= module
->GetSymbolFile();
191 FileSpec
header_spec(
192 R
"spec(D:\src\llvm\tools\lldb\unittests\SymbolFile\PDB\Inputs\test-pdb.cpp)spec");
193 SymbolContextList sc_list
;
194 SourceLocationSpec
location_spec(header_spec
, /*line=*/0);
195 uint32_t result_count
= symfile
->ResolveSymbolContext(
196 location_spec
, lldb::eSymbolContextCompUnit
, sc_list
);
197 EXPECT_GE(1u, result_count
);
198 EXPECT_TRUE(ContainsCompileUnit(sc_list
, header_spec
));
201 TEST_F(SymbolFilePDBTests
, TestLookupOfHeaderFileWithInlines
) {
202 // Test that when looking up a header file via ResolveSymbolContext (i.e. a
203 // file that was not by itself
204 // compiled, but only contributes to the combined code of other source files),
205 // a SymbolContext is returned
206 // for each compiland which has line contributions from the requested header.
207 FileSpec
fspec(m_pdb_test_exe
);
208 ArchSpec
aspec("i686-pc-windows");
209 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
211 SymbolFile
*symfile
= module
->GetSymbolFile();
213 FileSpec header_specs
[] = {FileSpec("test-pdb.h"),
214 FileSpec("test-pdb-nested.h")};
215 FileSpec
main_cpp_spec("test-pdb.cpp");
216 FileSpec
alt_cpp_spec("test-pdb-alt.cpp");
217 for (const auto &hspec
: header_specs
) {
218 SymbolContextList sc_list
;
219 SourceLocationSpec
location_spec(hspec
, /*line=*/0, /*column=*/std::nullopt
,
220 /*check_inlines=*/true);
221 uint32_t result_count
= symfile
->ResolveSymbolContext(
222 location_spec
, lldb::eSymbolContextCompUnit
, sc_list
);
223 EXPECT_EQ(2u, result_count
);
224 EXPECT_TRUE(ContainsCompileUnit(sc_list
, main_cpp_spec
));
225 EXPECT_TRUE(ContainsCompileUnit(sc_list
, alt_cpp_spec
));
229 TEST_F(SymbolFilePDBTests
, TestLookupOfHeaderFileWithNoInlines
) {
230 // Test that when looking up a header file via ResolveSymbolContext (i.e. a
231 // file that was not by itself
232 // compiled, but only contributes to the combined code of other source files),
233 // that if check_inlines
234 // is false, no SymbolContexts are returned.
235 FileSpec
fspec(m_pdb_test_exe
);
236 ArchSpec
aspec("i686-pc-windows");
237 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
239 SymbolFile
*symfile
= module
->GetSymbolFile();
241 FileSpec header_specs
[] = {FileSpec("test-pdb.h"),
242 FileSpec("test-pdb-nested.h")};
243 for (const auto &hspec
: header_specs
) {
244 SymbolContextList sc_list
;
245 SourceLocationSpec
location_spec(hspec
, /*line=*/0);
246 uint32_t result_count
= symfile
->ResolveSymbolContext(
247 location_spec
, lldb::eSymbolContextCompUnit
, sc_list
);
248 EXPECT_EQ(0u, result_count
);
252 TEST_F(SymbolFilePDBTests
, TestLineTablesMatchAll
) {
253 // Test that when calling ResolveSymbolContext with a line number of 0, all
255 // the specified files are returned.
256 FileSpec
fspec(m_pdb_test_exe
);
257 ArchSpec
aspec("i686-pc-windows");
258 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
260 SymbolFile
*symfile
= module
->GetSymbolFile();
262 FileSpec
source_file("test-pdb.cpp");
263 FileSpec
header1("test-pdb.h");
264 FileSpec
header2("test-pdb-nested.h");
265 uint32_t cus
= symfile
->GetNumCompileUnits();
268 SymbolContextList sc_list
;
269 lldb::SymbolContextItem scope
=
270 lldb::eSymbolContextCompUnit
| lldb::eSymbolContextLineEntry
;
272 SourceLocationSpec
location_spec(
273 source_file
, /*line=*/0, /*column=*/std::nullopt
, /*check_inlines=*/true);
274 uint32_t count
= symfile
->ResolveSymbolContext(location_spec
, scope
, sc_list
);
275 EXPECT_EQ(1u, count
);
277 EXPECT_TRUE(sc_list
.GetContextAtIndex(0, sc
));
279 LineTable
*lt
= sc
.comp_unit
->GetLineTable();
280 EXPECT_NE(nullptr, lt
);
281 count
= lt
->GetSize();
282 // We expect one extra entry for termination (per function)
283 EXPECT_EQ(16u, count
);
285 VerifyLineEntry(module
, sc
, source_file
, *lt
, 7, 0x401040);
286 VerifyLineEntry(module
, sc
, source_file
, *lt
, 8, 0x401043);
287 VerifyLineEntry(module
, sc
, source_file
, *lt
, 9, 0x401045);
289 VerifyLineEntry(module
, sc
, source_file
, *lt
, 13, 0x401050);
290 VerifyLineEntry(module
, sc
, source_file
, *lt
, 14, 0x401054);
291 VerifyLineEntry(module
, sc
, source_file
, *lt
, 15, 0x401070);
293 VerifyLineEntry(module
, sc
, header1
, *lt
, 9, 0x401090);
294 VerifyLineEntry(module
, sc
, header1
, *lt
, 10, 0x401093);
295 VerifyLineEntry(module
, sc
, header1
, *lt
, 11, 0x4010a2);
297 VerifyLineEntry(module
, sc
, header2
, *lt
, 5, 0x401080);
298 VerifyLineEntry(module
, sc
, header2
, *lt
, 6, 0x401083);
299 VerifyLineEntry(module
, sc
, header2
, *lt
, 7, 0x401089);
302 TEST_F(SymbolFilePDBTests
, TestLineTablesMatchSpecific
) {
303 // Test that when calling ResolveSymbolContext with a specific line number,
305 // which match the requested line are returned.
306 FileSpec
fspec(m_pdb_test_exe
);
307 ArchSpec
aspec("i686-pc-windows");
308 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
310 SymbolFile
*symfile
= module
->GetSymbolFile();
312 FileSpec
source_file("test-pdb.cpp");
313 FileSpec
header1("test-pdb.h");
314 FileSpec
header2("test-pdb-nested.h");
315 uint32_t cus
= symfile
->GetNumCompileUnits();
318 SymbolContextList sc_list
;
319 lldb::SymbolContextItem scope
=
320 lldb::eSymbolContextCompUnit
| lldb::eSymbolContextLineEntry
;
322 // First test with line 7, and verify that only line 7 entries are added.
323 SourceLocationSpec
location_spec(
324 source_file
, /*line=*/7, /*column=*/std::nullopt
, /*check_inlines=*/true);
325 uint32_t count
= symfile
->ResolveSymbolContext(location_spec
, scope
, sc_list
);
326 EXPECT_EQ(1u, count
);
328 EXPECT_TRUE(sc_list
.GetContextAtIndex(0, sc
));
330 LineTable
*lt
= sc
.comp_unit
->GetLineTable();
331 EXPECT_NE(nullptr, lt
);
332 count
= lt
->GetSize();
333 // We expect one extra entry for termination
334 EXPECT_EQ(3u, count
);
336 VerifyLineEntry(module
, sc
, source_file
, *lt
, 7, 0x401040);
337 VerifyLineEntry(module
, sc
, header2
, *lt
, 7, 0x401089);
340 // Then test with line 9, and verify that only line 9 entries are added.
341 location_spec
= SourceLocationSpec(
342 source_file
, /*line=*/9, /*column=*/std::nullopt
, /*check_inlines=*/true);
343 count
= symfile
->ResolveSymbolContext(location_spec
, scope
, sc_list
);
344 EXPECT_EQ(1u, count
);
345 EXPECT_TRUE(sc_list
.GetContextAtIndex(0, sc
));
347 lt
= sc
.comp_unit
->GetLineTable();
348 EXPECT_NE(nullptr, lt
);
349 count
= lt
->GetSize();
350 // We expect one extra entry for termination
351 EXPECT_EQ(3u, count
);
353 VerifyLineEntry(module
, sc
, source_file
, *lt
, 9, 0x401045);
354 VerifyLineEntry(module
, sc
, header1
, *lt
, 9, 0x401090);
357 TEST_F(SymbolFilePDBTests
, TestSimpleClassTypes
) {
358 FileSpec
fspec(m_types_test_exe
);
359 ArchSpec
aspec("i686-pc-windows");
360 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
362 SymbolFilePDB
*symfile
=
363 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
364 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
365 llvm::DenseSet
<SymbolFile
*> searched_files
;
367 symfile
->FindTypes(ConstString("Class"), CompilerDeclContext(), 0,
368 searched_files
, results
);
369 EXPECT_EQ(1u, results
.GetSize());
370 lldb::TypeSP udt_type
= results
.GetTypeAtIndex(0);
371 EXPECT_EQ(ConstString("Class"), udt_type
->GetName());
372 CompilerType compiler_type
= udt_type
->GetForwardCompilerType();
373 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type
.GetOpaqueQualType()));
374 EXPECT_EQ(GetGlobalConstantInteger(session
, "sizeof_Class"),
375 udt_type
->GetByteSize(nullptr));
378 TEST_F(SymbolFilePDBTests
, TestNestedClassTypes
) {
379 FileSpec
fspec(m_types_test_exe
);
380 ArchSpec
aspec("i686-pc-windows");
381 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
383 SymbolFilePDB
*symfile
=
384 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
385 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
386 llvm::DenseSet
<SymbolFile
*> searched_files
;
389 auto clang_ast_ctx_or_err
=
390 symfile
->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus
);
391 ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err
, llvm::Succeeded());
394 llvm::dyn_cast_or_null
<TypeSystemClang
>(clang_ast_ctx_or_err
->get());
395 EXPECT_NE(nullptr, clang_ast_ctx
);
397 symfile
->FindTypes(ConstString("Class"), CompilerDeclContext(), 0,
398 searched_files
, results
);
399 EXPECT_EQ(1u, results
.GetSize());
401 auto Class
= results
.GetTypeAtIndex(0);
403 EXPECT_TRUE(Class
->IsValidType());
405 auto ClassCompilerType
= Class
->GetFullCompilerType();
406 EXPECT_TRUE(ClassCompilerType
.IsValid());
408 auto ClassDeclCtx
= clang_ast_ctx
->GetDeclContextForType(ClassCompilerType
);
409 EXPECT_NE(nullptr, ClassDeclCtx
);
411 // There are two symbols for nested classes: one belonging to enclosing class
412 // and one is global. We process correctly this case and create the same
413 // compiler type for both, but `FindTypes` may return more than one type
414 // (with the same compiler type) because the symbols have different IDs.
416 TypeMap more_results
;
417 auto ClassCompilerDeclCtx
= CompilerDeclContext(clang_ast_ctx
, ClassDeclCtx
);
418 symfile
->FindTypes(ConstString("NestedClass"), ClassCompilerDeclCtx
, 0,
419 searched_files
, more_results
);
420 EXPECT_LE(1u, more_results
.GetSize());
422 lldb::TypeSP udt_type
= more_results
.GetTypeAtIndex(0);
423 EXPECT_EQ(ConstString("NestedClass"), udt_type
->GetName());
425 CompilerType compiler_type
= udt_type
->GetForwardCompilerType();
426 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type
.GetOpaqueQualType()));
428 EXPECT_EQ(GetGlobalConstantInteger(session
, "sizeof_NestedClass"),
429 udt_type
->GetByteSize(nullptr));
432 TEST_F(SymbolFilePDBTests
, TestClassInNamespace
) {
433 FileSpec
fspec(m_types_test_exe
);
434 ArchSpec
aspec("i686-pc-windows");
435 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
437 SymbolFilePDB
*symfile
=
438 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
439 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
440 llvm::DenseSet
<SymbolFile
*> searched_files
;
443 auto clang_ast_ctx_or_err
=
444 symfile
->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus
);
445 ASSERT_THAT_EXPECTED(clang_ast_ctx_or_err
, llvm::Succeeded());
448 llvm::dyn_cast_or_null
<TypeSystemClang
>(clang_ast_ctx_or_err
->get());
449 EXPECT_NE(nullptr, clang_ast_ctx
);
451 clang::ASTContext
&ast_ctx
= clang_ast_ctx
->getASTContext();
453 auto tu
= ast_ctx
.getTranslationUnitDecl();
454 EXPECT_NE(nullptr, tu
);
456 symfile
->ParseDeclsForContext(CompilerDeclContext(
457 clang_ast_ctx
, static_cast<clang::DeclContext
*>(tu
)));
460 symfile
->FindNamespace(ConstString("NS"), CompilerDeclContext(), true);
461 EXPECT_TRUE(ns_namespace
.IsValid());
463 symfile
->FindTypes(ConstString("NSClass"), ns_namespace
, 0, searched_files
,
465 EXPECT_EQ(1u, results
.GetSize());
467 lldb::TypeSP udt_type
= results
.GetTypeAtIndex(0);
468 EXPECT_EQ(ConstString("NSClass"), udt_type
->GetName());
470 CompilerType compiler_type
= udt_type
->GetForwardCompilerType();
471 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type
.GetOpaqueQualType()));
473 EXPECT_EQ(GetGlobalConstantInteger(session
, "sizeof_NSClass"),
474 udt_type
->GetByteSize(nullptr));
477 TEST_F(SymbolFilePDBTests
, TestEnumTypes
) {
478 FileSpec
fspec(m_types_test_exe
);
479 ArchSpec
aspec("i686-pc-windows");
480 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
482 SymbolFilePDB
*symfile
=
483 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
484 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
485 llvm::DenseSet
<SymbolFile
*> searched_files
;
486 const char *EnumsToCheck
[] = {"Enum", "ShortEnum"};
487 for (auto Enum
: EnumsToCheck
) {
489 symfile
->FindTypes(ConstString(Enum
), CompilerDeclContext(), 0,
490 searched_files
, results
);
491 EXPECT_EQ(1u, results
.GetSize());
492 lldb::TypeSP enum_type
= results
.GetTypeAtIndex(0);
493 EXPECT_EQ(ConstString(Enum
), enum_type
->GetName());
494 CompilerType compiler_type
= enum_type
->GetFullCompilerType();
495 EXPECT_TRUE(TypeSystemClang::IsEnumType(compiler_type
.GetOpaqueQualType()));
496 clang::EnumDecl
*enum_decl
= TypeSystemClang::GetAsEnumDecl(compiler_type
);
497 EXPECT_NE(nullptr, enum_decl
);
498 EXPECT_EQ(2, std::distance(enum_decl
->enumerator_begin(),
499 enum_decl
->enumerator_end()));
501 std::string sizeof_var
= "sizeof_";
502 sizeof_var
.append(Enum
);
503 EXPECT_EQ(GetGlobalConstantInteger(session
, sizeof_var
),
504 enum_type
->GetByteSize(nullptr));
508 TEST_F(SymbolFilePDBTests
, TestArrayTypes
) {
509 // In order to get this test working, we need to support lookup by symbol
510 // name. Because array
511 // types themselves do not have names, only the symbols have names (i.e. the
512 // name of the array).
515 TEST_F(SymbolFilePDBTests
, TestFunctionTypes
) {
516 // In order to get this test working, we need to support lookup by symbol
517 // name. Because array
518 // types themselves do not have names, only the symbols have names (i.e. the
519 // name of the array).
522 TEST_F(SymbolFilePDBTests
, TestTypedefs
) {
523 FileSpec
fspec(m_types_test_exe
);
524 ArchSpec
aspec("i686-pc-windows");
525 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
527 SymbolFilePDB
*symfile
=
528 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
529 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
530 llvm::DenseSet
<SymbolFile
*> searched_files
;
533 const char *TypedefsToCheck
[] = {"ClassTypedef", "NSClassTypedef",
534 "FuncPointerTypedef",
535 "VariadicFuncPointerTypedef"};
536 for (auto Typedef
: TypedefsToCheck
) {
538 symfile
->FindTypes(ConstString(Typedef
), CompilerDeclContext(), 0,
539 searched_files
, results
);
540 EXPECT_EQ(1u, results
.GetSize());
541 lldb::TypeSP typedef_type
= results
.GetTypeAtIndex(0);
542 EXPECT_EQ(ConstString(Typedef
), typedef_type
->GetName());
543 CompilerType compiler_type
= typedef_type
->GetFullCompilerType();
544 auto clang_type_system
=
545 compiler_type
.GetTypeSystem().dyn_cast_or_null
<TypeSystemClang
>();
547 clang_type_system
->IsTypedefType(compiler_type
.GetOpaqueQualType()));
549 std::string sizeof_var
= "sizeof_";
550 sizeof_var
.append(Typedef
);
551 EXPECT_EQ(GetGlobalConstantInteger(session
, sizeof_var
),
552 typedef_type
->GetByteSize(nullptr));
556 TEST_F(SymbolFilePDBTests
, TestRegexNameMatch
) {
557 FileSpec
fspec(m_types_test_exe
);
558 ArchSpec
aspec("i686-pc-windows");
559 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
561 SymbolFilePDB
*symfile
=
562 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
565 symfile
->FindTypesByRegex(RegularExpression(".*"), 0, results
);
566 EXPECT_GT(results
.GetSize(), 1u);
568 // We expect no exception thrown if the given regex can't be compiled
570 symfile
->FindTypesByRegex(RegularExpression("**"), 0, results
);
571 EXPECT_EQ(0u, results
.GetSize());
574 TEST_F(SymbolFilePDBTests
, TestMaxMatches
) {
575 FileSpec
fspec(m_types_test_exe
);
576 ArchSpec
aspec("i686-pc-windows");
577 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
579 SymbolFilePDB
*symfile
=
580 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
581 llvm::DenseSet
<SymbolFile
*> searched_files
;
583 const ConstString
name("ClassTypedef");
584 symfile
->FindTypes(name
, CompilerDeclContext(), 0, searched_files
, results
);
585 // Try to limit ourselves from 1 to 10 results, otherwise we could
586 // be doing this thousands of times. The idea is just to make sure
587 // that for a variety of values, the number of limited results
588 // always comes out to the number we are expecting.
589 uint32_t num_results
= results
.GetSize();
590 uint32_t iterations
= std::min(num_results
, 10u);
591 for (uint32_t i
= 1; i
<= iterations
; ++i
) {
592 TypeMap more_results
;
593 symfile
->FindTypes(name
, CompilerDeclContext(), i
, searched_files
,
595 uint32_t num_limited_results
= more_results
.GetSize();
596 EXPECT_EQ(i
, num_limited_results
);
600 TEST_F(SymbolFilePDBTests
, TestNullName
) {
601 FileSpec
fspec(m_types_test_exe
);
602 ArchSpec
aspec("i686-pc-windows");
603 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
605 SymbolFilePDB
*symfile
=
606 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
607 llvm::DenseSet
<SymbolFile
*> searched_files
;
609 symfile
->FindTypes(ConstString(), CompilerDeclContext(), 0, searched_files
,
611 EXPECT_EQ(0u, results
.GetSize());
614 TEST_F(SymbolFilePDBTests
, TestFindSymbolsWithNameAndType
) {
615 FileSpec
fspec(m_pdb_test_exe
.c_str());
616 ArchSpec
aspec("i686-pc-windows");
617 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
619 SymbolContextList sc_list
;
620 module
->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"),
621 lldb::eSymbolTypeAny
, sc_list
);
622 EXPECT_EQ(1u, sc_list
.GetSize());
625 EXPECT_TRUE(sc_list
.GetContextAtIndex(0, sc
));
626 EXPECT_STREQ("int foo(int)",
627 sc
.GetFunctionName(Mangled::ePreferDemangled
).AsCString());