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 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 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=*/llvm::None
,
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=*/llvm::None
, /*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=*/llvm::None
, /*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=*/llvm::None
, /*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
)));
459 auto ns_namespace
= symfile
->FindNamespace(ConstString("NS"), CompilerDeclContext());
460 EXPECT_TRUE(ns_namespace
.IsValid());
462 symfile
->FindTypes(ConstString("NSClass"), ns_namespace
, 0, searched_files
,
464 EXPECT_EQ(1u, results
.GetSize());
466 lldb::TypeSP udt_type
= results
.GetTypeAtIndex(0);
467 EXPECT_EQ(ConstString("NSClass"), udt_type
->GetName());
469 CompilerType compiler_type
= udt_type
->GetForwardCompilerType();
470 EXPECT_TRUE(TypeSystemClang::IsClassType(compiler_type
.GetOpaqueQualType()));
472 EXPECT_EQ(GetGlobalConstantInteger(session
, "sizeof_NSClass"),
473 udt_type
->GetByteSize(nullptr));
476 TEST_F(SymbolFilePDBTests
, TestEnumTypes
) {
477 FileSpec
fspec(m_types_test_exe
);
478 ArchSpec
aspec("i686-pc-windows");
479 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
481 SymbolFilePDB
*symfile
=
482 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
483 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
484 llvm::DenseSet
<SymbolFile
*> searched_files
;
485 const char *EnumsToCheck
[] = {"Enum", "ShortEnum"};
486 for (auto Enum
: EnumsToCheck
) {
488 symfile
->FindTypes(ConstString(Enum
), CompilerDeclContext(), 0,
489 searched_files
, results
);
490 EXPECT_EQ(1u, results
.GetSize());
491 lldb::TypeSP enum_type
= results
.GetTypeAtIndex(0);
492 EXPECT_EQ(ConstString(Enum
), enum_type
->GetName());
493 CompilerType compiler_type
= enum_type
->GetFullCompilerType();
494 EXPECT_TRUE(TypeSystemClang::IsEnumType(compiler_type
.GetOpaqueQualType()));
495 clang::EnumDecl
*enum_decl
= TypeSystemClang::GetAsEnumDecl(compiler_type
);
496 EXPECT_NE(nullptr, enum_decl
);
497 EXPECT_EQ(2, std::distance(enum_decl
->enumerator_begin(),
498 enum_decl
->enumerator_end()));
500 std::string sizeof_var
= "sizeof_";
501 sizeof_var
.append(Enum
);
502 EXPECT_EQ(GetGlobalConstantInteger(session
, sizeof_var
),
503 enum_type
->GetByteSize(nullptr));
507 TEST_F(SymbolFilePDBTests
, TestArrayTypes
) {
508 // In order to get this test working, we need to support lookup by symbol
509 // name. Because array
510 // types themselves do not have names, only the symbols have names (i.e. the
511 // name of the array).
514 TEST_F(SymbolFilePDBTests
, TestFunctionTypes
) {
515 // In order to get this test working, we need to support lookup by symbol
516 // name. Because array
517 // types themselves do not have names, only the symbols have names (i.e. the
518 // name of the array).
521 TEST_F(SymbolFilePDBTests
, TestTypedefs
) {
522 FileSpec
fspec(m_types_test_exe
);
523 ArchSpec
aspec("i686-pc-windows");
524 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
526 SymbolFilePDB
*symfile
=
527 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
528 llvm::pdb::IPDBSession
&session
= symfile
->GetPDBSession();
529 llvm::DenseSet
<SymbolFile
*> searched_files
;
532 const char *TypedefsToCheck
[] = {"ClassTypedef", "NSClassTypedef",
533 "FuncPointerTypedef",
534 "VariadicFuncPointerTypedef"};
535 for (auto Typedef
: TypedefsToCheck
) {
537 symfile
->FindTypes(ConstString(Typedef
), CompilerDeclContext(), 0,
538 searched_files
, results
);
539 EXPECT_EQ(1u, results
.GetSize());
540 lldb::TypeSP typedef_type
= results
.GetTypeAtIndex(0);
541 EXPECT_EQ(ConstString(Typedef
), typedef_type
->GetName());
542 CompilerType compiler_type
= typedef_type
->GetFullCompilerType();
543 TypeSystemClang
*clang_type_system
=
544 llvm::dyn_cast_or_null
<TypeSystemClang
>(compiler_type
.GetTypeSystem());
546 clang_type_system
->IsTypedefType(compiler_type
.GetOpaqueQualType()));
548 std::string sizeof_var
= "sizeof_";
549 sizeof_var
.append(Typedef
);
550 EXPECT_EQ(GetGlobalConstantInteger(session
, sizeof_var
),
551 typedef_type
->GetByteSize(nullptr));
555 TEST_F(SymbolFilePDBTests
, TestRegexNameMatch
) {
556 FileSpec
fspec(m_types_test_exe
);
557 ArchSpec
aspec("i686-pc-windows");
558 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
560 SymbolFilePDB
*symfile
=
561 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
564 symfile
->FindTypesByRegex(RegularExpression(".*"), 0, results
);
565 EXPECT_GT(results
.GetSize(), 1u);
567 // We expect no exception thrown if the given regex can't be compiled
569 symfile
->FindTypesByRegex(RegularExpression("**"), 0, results
);
570 EXPECT_EQ(0u, results
.GetSize());
573 TEST_F(SymbolFilePDBTests
, TestMaxMatches
) {
574 FileSpec
fspec(m_types_test_exe
);
575 ArchSpec
aspec("i686-pc-windows");
576 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
578 SymbolFilePDB
*symfile
=
579 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
580 llvm::DenseSet
<SymbolFile
*> searched_files
;
582 const ConstString
name("ClassTypedef");
583 symfile
->FindTypes(name
, CompilerDeclContext(), 0, searched_files
, results
);
584 // Try to limit ourselves from 1 to 10 results, otherwise we could
585 // be doing this thousands of times. The idea is just to make sure
586 // that for a variety of values, the number of limited results
587 // always comes out to the number we are expecting.
588 uint32_t num_results
= results
.GetSize();
589 uint32_t iterations
= std::min(num_results
, 10u);
590 for (uint32_t i
= 1; i
<= iterations
; ++i
) {
591 TypeMap more_results
;
592 symfile
->FindTypes(name
, CompilerDeclContext(), i
, searched_files
,
594 uint32_t num_limited_results
= more_results
.GetSize();
595 EXPECT_EQ(i
, num_limited_results
);
599 TEST_F(SymbolFilePDBTests
, TestNullName
) {
600 FileSpec
fspec(m_types_test_exe
);
601 ArchSpec
aspec("i686-pc-windows");
602 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
604 SymbolFilePDB
*symfile
=
605 static_cast<SymbolFilePDB
*>(module
->GetSymbolFile());
606 llvm::DenseSet
<SymbolFile
*> searched_files
;
608 symfile
->FindTypes(ConstString(), CompilerDeclContext(), 0, searched_files
,
610 EXPECT_EQ(0u, results
.GetSize());
613 TEST_F(SymbolFilePDBTests
, TestFindSymbolsWithNameAndType
) {
614 FileSpec
fspec(m_pdb_test_exe
.c_str());
615 ArchSpec
aspec("i686-pc-windows");
616 lldb::ModuleSP module
= std::make_shared
<Module
>(fspec
, aspec
);
618 SymbolContextList sc_list
;
619 module
->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"),
620 lldb::eSymbolTypeAny
, sc_list
);
621 EXPECT_EQ(1u, sc_list
.GetSize());
624 EXPECT_TRUE(sc_list
.GetContextAtIndex(0, sc
));
625 EXPECT_STREQ("int foo(int)",
626 sc
.GetFunctionName(Mangled::ePreferDemangled
).AsCString());