xref: /llvm-project/lldb/unittests/Symbol/TestLineEntry.cpp (revision a669a237c45a515bea0d258cbbecdbbb3170d57a)
180814287SRaphael Isemann //===-- TestLineEntry.cpp -------------------------------------------------===//
2eeed7ee2SGreg Clayton //
3c874dd53SChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c874dd53SChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information.
5c874dd53SChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eeed7ee2SGreg Clayton //
7eeed7ee2SGreg Clayton //===----------------------------------------------------------------------===//
8eeed7ee2SGreg Clayton 
9eeed7ee2SGreg Clayton #include "gtest/gtest.h"
10eeed7ee2SGreg Clayton #include <iostream>
11f190ce62SKazu Hirata #include <optional>
12eeed7ee2SGreg Clayton 
13eeed7ee2SGreg Clayton #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
14eeed7ee2SGreg Clayton #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
15eeed7ee2SGreg Clayton #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
168be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
175dca0596SRaphael Isemann #include "TestingSupport/SubsystemRAII.h"
18eeed7ee2SGreg Clayton #include "TestingSupport/TestUtilities.h"
19eeed7ee2SGreg Clayton 
20eeed7ee2SGreg Clayton #include "lldb/Core/Module.h"
21eeed7ee2SGreg Clayton #include "lldb/Host/FileSystem.h"
22eeed7ee2SGreg Clayton #include "lldb/Host/HostInfo.h"
23eeed7ee2SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
24eeed7ee2SGreg Clayton #include "lldb/Symbol/SymbolContext.h"
25eeed7ee2SGreg Clayton 
26eeed7ee2SGreg Clayton #include "llvm/Support/FileUtilities.h"
27eeed7ee2SGreg Clayton #include "llvm/Support/Program.h"
28eeed7ee2SGreg Clayton #include "llvm/Testing/Support/Error.h"
29eeed7ee2SGreg Clayton 
30eeed7ee2SGreg Clayton using namespace lldb;
31*a669a237Swalter erquinigo using namespace lldb_private;
32*a669a237Swalter erquinigo using namespace lldb_private::plugin::dwarf;
33eeed7ee2SGreg Clayton 
34eeed7ee2SGreg Clayton class LineEntryTest : public testing::Test {
355dca0596SRaphael Isemann   SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
366e3b0cc2SRaphael Isemann                 TypeSystemClang>
375dca0596SRaphael Isemann       subsystem;
385dca0596SRaphael Isemann 
39eeed7ee2SGreg Clayton public:
40a2e270faSPavel Labath   void SetUp() override;
41eeed7ee2SGreg Clayton 
42eeed7ee2SGreg Clayton protected:
433973d8b2SKim-Anh Tran   llvm::Expected<SymbolContextList>
442fe83274SKazu Hirata   GetLineEntriesForLine(uint32_t line, std::optional<uint16_t> column);
452fe83274SKazu Hirata   std::optional<TestFile> m_file;
46eeed7ee2SGreg Clayton   ModuleSP m_module_sp;
47eeed7ee2SGreg Clayton };
48eeed7ee2SGreg Clayton 
SetUp()49a2e270faSPavel Labath void LineEntryTest::SetUp() {
50a2e270faSPavel Labath   auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml");
51a2e270faSPavel Labath   ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
52a2e270faSPavel Labath   m_file.emplace(std::move(*ExpectedFile));
53a4a00cedSFred Riss   m_module_sp = std::make_shared<Module>(m_file->moduleSpec());
54eeed7ee2SGreg Clayton }
55eeed7ee2SGreg Clayton 
563e2ed744SMed Ismail Bennani   // TODO: Handle SourceLocationSpec column information
GetLineEntriesForLine(uint32_t line,std::optional<uint16_t> column=std::nullopt)573973d8b2SKim-Anh Tran llvm::Expected<SymbolContextList> LineEntryTest::GetLineEntriesForLine(
582fe83274SKazu Hirata     uint32_t line, std::optional<uint16_t> column = std::nullopt) {
59eeed7ee2SGreg Clayton   SymbolContextList sc_comp_units;
60eeed7ee2SGreg Clayton   SymbolContextList sc_line_entries;
61eeed7ee2SGreg Clayton   FileSpec file_spec("inlined-functions.cpp");
623e2ed744SMed Ismail Bennani   m_module_sp->ResolveSymbolContextsForFileSpec(
633e2ed744SMed Ismail Bennani       file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit,
64eeed7ee2SGreg Clayton       sc_comp_units);
65eeed7ee2SGreg Clayton   if (sc_comp_units.GetSize() == 0)
66eeed7ee2SGreg Clayton     return llvm::createStringError(llvm::inconvertibleErrorCode(),
67eeed7ee2SGreg Clayton                                    "No comp unit found on the test object.");
683e2ed744SMed Ismail Bennani 
693973d8b2SKim-Anh Tran   SourceLocationSpec location_spec(file_spec, line, column,
703e2ed744SMed Ismail Bennani                                    /*check_inlines=*/true,
713e2ed744SMed Ismail Bennani                                    /*exact_match=*/true);
723e2ed744SMed Ismail Bennani 
73eeed7ee2SGreg Clayton   sc_comp_units[0].comp_unit->ResolveSymbolContext(
743e2ed744SMed Ismail Bennani       location_spec, eSymbolContextLineEntry, sc_line_entries);
75eeed7ee2SGreg Clayton   if (sc_line_entries.GetSize() == 0)
76eeed7ee2SGreg Clayton     return llvm::createStringError(llvm::inconvertibleErrorCode(),
77eeed7ee2SGreg Clayton                                    "No line entry found on the test object.");
783973d8b2SKim-Anh Tran   return sc_line_entries;
793973d8b2SKim-Anh Tran }
803973d8b2SKim-Anh Tran 
813973d8b2SKim-Anh Tran // This tests if we can get all line entries that match the passed line, if
823973d8b2SKim-Anh Tran // no column is specified.
TEST_F(LineEntryTest,GetAllExactLineMatchesWithoutColumn)833973d8b2SKim-Anh Tran TEST_F(LineEntryTest, GetAllExactLineMatchesWithoutColumn) {
843973d8b2SKim-Anh Tran   auto sc_line_entries = GetLineEntriesForLine(12);
853973d8b2SKim-Anh Tran   ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
863973d8b2SKim-Anh Tran   ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 6u);
873973d8b2SKim-Anh Tran }
883973d8b2SKim-Anh Tran 
893973d8b2SKim-Anh Tran // This tests if we can get exact line and column matches.
TEST_F(LineEntryTest,GetAllExactLineColumnMatches)903973d8b2SKim-Anh Tran TEST_F(LineEntryTest, GetAllExactLineColumnMatches) {
913973d8b2SKim-Anh Tran   auto sc_line_entries = GetLineEntriesForLine(12, 39);
923973d8b2SKim-Anh Tran   ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
933973d8b2SKim-Anh Tran   ASSERT_EQ(sc_line_entries->NumLineEntriesWithLine(12), 1u);
943973d8b2SKim-Anh Tran   auto line_entry = sc_line_entries.get()[0].line_entry;
953973d8b2SKim-Anh Tran   ASSERT_EQ(line_entry.column, 39);
96eeed7ee2SGreg Clayton }
97eeed7ee2SGreg Clayton 
TEST_F(LineEntryTest,GetSameLineContiguousAddressRangeNoInlines)98eeed7ee2SGreg Clayton TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) {
993973d8b2SKim-Anh Tran   auto sc_line_entries = GetLineEntriesForLine(18);
1003973d8b2SKim-Anh Tran   ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
1013973d8b2SKim-Anh Tran   auto line_entry = sc_line_entries.get()[0].line_entry;
102eeed7ee2SGreg Clayton   bool include_inlined_functions = false;
103eeed7ee2SGreg Clayton   auto range =
1043973d8b2SKim-Anh Tran       line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
105eeed7ee2SGreg Clayton   ASSERT_EQ(range.GetByteSize(), (uint64_t)0x24);
106eeed7ee2SGreg Clayton }
107eeed7ee2SGreg Clayton 
TEST_F(LineEntryTest,GetSameLineContiguousAddressRangeOneInline)108eeed7ee2SGreg Clayton TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeOneInline) {
1093973d8b2SKim-Anh Tran   auto sc_line_entries = GetLineEntriesForLine(18);
1103973d8b2SKim-Anh Tran   ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
1113973d8b2SKim-Anh Tran   auto line_entry = sc_line_entries.get()[0].line_entry;
112eeed7ee2SGreg Clayton   bool include_inlined_functions = true;
113eeed7ee2SGreg Clayton   auto range =
1143973d8b2SKim-Anh Tran       line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
115eeed7ee2SGreg Clayton   ASSERT_EQ(range.GetByteSize(), (uint64_t)0x49);
116eeed7ee2SGreg Clayton }
117eeed7ee2SGreg Clayton 
TEST_F(LineEntryTest,GetSameLineContiguousAddressRangeNestedInline)118eeed7ee2SGreg Clayton TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNestedInline) {
1193973d8b2SKim-Anh Tran   auto sc_line_entries = GetLineEntriesForLine(12);
1203973d8b2SKim-Anh Tran   ASSERT_THAT_EXPECTED(sc_line_entries, llvm::Succeeded());
1213973d8b2SKim-Anh Tran   auto line_entry = sc_line_entries.get()[0].line_entry;
122eeed7ee2SGreg Clayton   bool include_inlined_functions = true;
123eeed7ee2SGreg Clayton   auto range =
1243973d8b2SKim-Anh Tran       line_entry.GetSameLineContiguousAddressRange(include_inlined_functions);
125eeed7ee2SGreg Clayton   ASSERT_EQ(range.GetByteSize(), (uint64_t)0x33);
126eeed7ee2SGreg Clayton }
127eeed7ee2SGreg Clayton 
128eeed7ee2SGreg Clayton /*
129eeed7ee2SGreg Clayton # inlined-functions.cpp
130eeed7ee2SGreg Clayton inline __attribute__((always_inline)) int sum2(int a, int b) {
131eeed7ee2SGreg Clayton     int result = a + b;
132eeed7ee2SGreg Clayton     return result;
133eeed7ee2SGreg Clayton }
134eeed7ee2SGreg Clayton 
135eeed7ee2SGreg Clayton int sum3(int a, int b, int c) {
136eeed7ee2SGreg Clayton     int result = a + b + c;
137eeed7ee2SGreg Clayton     return result;
138eeed7ee2SGreg Clayton }
139eeed7ee2SGreg Clayton 
140eeed7ee2SGreg Clayton inline __attribute__((always_inline)) int sum4(int a, int b, int c, int d) {
141eeed7ee2SGreg Clayton     int result = sum2(a, b) + sum2(c, d);
142eeed7ee2SGreg Clayton     result += 0;
143eeed7ee2SGreg Clayton     return result;
144eeed7ee2SGreg Clayton }
145eeed7ee2SGreg Clayton 
146eeed7ee2SGreg Clayton int main(int argc, char** argv) {
147eeed7ee2SGreg Clayton     sum3(3, 4, 5) + sum2(1, 2);
148eeed7ee2SGreg Clayton     int sum = sum4(1, 2, 3, 4);
149eeed7ee2SGreg Clayton     sum2(5, 6);
150eeed7ee2SGreg Clayton     return 0;
151eeed7ee2SGreg Clayton }
152eeed7ee2SGreg Clayton 
153eeed7ee2SGreg Clayton // g++ -c inlined-functions.cpp -o inlined-functions.o -g -Wno-unused-value
154eeed7ee2SGreg Clayton // obj2yaml inlined-functions.o > inlined-functions.yaml
155eeed7ee2SGreg Clayton 
156eeed7ee2SGreg Clayton # Dump of source line per address:
157eeed7ee2SGreg Clayton # inlined-functions.cpp is src.cpp for space considerations.
158eeed7ee2SGreg Clayton 0x20: src.cpp:17
159eeed7ee2SGreg Clayton 0x21: src.cpp:17
160eeed7ee2SGreg Clayton 0x26: src.cpp:17
161eeed7ee2SGreg Clayton 0x27: src.cpp:17
162eeed7ee2SGreg Clayton 0x29: src.cpp:17
163eeed7ee2SGreg Clayton 0x2e: src.cpp:17
164eeed7ee2SGreg Clayton 0x2f: src.cpp:17
165eeed7ee2SGreg Clayton 0x31: src.cpp:17
166eeed7ee2SGreg Clayton 0x36: src.cpp:18
167eeed7ee2SGreg Clayton 0x37: src.cpp:18
168eeed7ee2SGreg Clayton 0x39: src.cpp:18
169eeed7ee2SGreg Clayton 0x3e: src.cpp:18
170eeed7ee2SGreg Clayton 0x3f: src.cpp:18
171eeed7ee2SGreg Clayton 0x41: src.cpp:18
172eeed7ee2SGreg Clayton 0x46: src.cpp:18
173eeed7ee2SGreg Clayton 0x47: src.cpp:18
174eeed7ee2SGreg Clayton 0x49: src.cpp:18
175eeed7ee2SGreg Clayton 0x4e: src.cpp:18
176eeed7ee2SGreg Clayton 0x4f: src.cpp:18
177eeed7ee2SGreg Clayton 0x51: src.cpp:18
178eeed7ee2SGreg Clayton 0x56: src.cpp:18
179eeed7ee2SGreg Clayton 0x57: src.cpp:18
180eeed7ee2SGreg Clayton 0x59: src.cpp:18
181eeed7ee2SGreg Clayton 0x5e: src.cpp:18 -> sum2@src.cpp:2
182eeed7ee2SGreg Clayton 0x5f: src.cpp:18 -> sum2@src.cpp:2
183eeed7ee2SGreg Clayton 0x61: src.cpp:18 -> sum2@src.cpp:2
184eeed7ee2SGreg Clayton 0x66: src.cpp:18 -> sum2@src.cpp:2
185eeed7ee2SGreg Clayton 0x67: src.cpp:18 -> sum2@src.cpp:2
186eeed7ee2SGreg Clayton 0x69: src.cpp:18 -> sum2@src.cpp:2
187eeed7ee2SGreg Clayton 0x6e: src.cpp:18 -> sum2@src.cpp:2
188eeed7ee2SGreg Clayton 0x6f: src.cpp:18 -> sum2@src.cpp:2
189eeed7ee2SGreg Clayton 0x71: src.cpp:18 -> sum2@src.cpp:2
190eeed7ee2SGreg Clayton 0x76: src.cpp:18 -> sum2@src.cpp:2
191eeed7ee2SGreg Clayton 0x77: src.cpp:18 -> sum2@src.cpp:2
192eeed7ee2SGreg Clayton 0x79: src.cpp:18 -> sum2@src.cpp:2
193eeed7ee2SGreg Clayton 0x7e: src.cpp:18 -> sum2@src.cpp:2
194eeed7ee2SGreg Clayton 0x7f: src.cpp:19 -> sum4@src.cpp:12
195eeed7ee2SGreg Clayton 0x81: src.cpp:19 -> sum4@src.cpp:12
196eeed7ee2SGreg Clayton 0x86: src.cpp:19 -> sum4@src.cpp:12
197eeed7ee2SGreg Clayton 0x87: src.cpp:19 -> sum4@src.cpp:12
198eeed7ee2SGreg Clayton 0x89: src.cpp:19 -> sum4@src.cpp:12
199eeed7ee2SGreg Clayton 0x8e: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
200eeed7ee2SGreg Clayton 0x8f: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
201eeed7ee2SGreg Clayton 0x91: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
202eeed7ee2SGreg Clayton 0x96: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:3
203eeed7ee2SGreg Clayton 0x97: src.cpp:19 -> sum4@src.cpp:12
204eeed7ee2SGreg Clayton 0x99: src.cpp:19 -> sum4@src.cpp:12
205eeed7ee2SGreg Clayton 0x9e: src.cpp:19 -> sum4@src.cpp:12
206eeed7ee2SGreg Clayton 0x9f: src.cpp:19 -> sum4@src.cpp:12
207eeed7ee2SGreg Clayton 0xa1: src.cpp:19 -> sum4@src.cpp:12
208eeed7ee2SGreg Clayton 0xa6: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
209eeed7ee2SGreg Clayton 0xa7: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
210eeed7ee2SGreg Clayton 0xa9: src.cpp:19 -> sum4@src.cpp:12 -> sum2@src.cpp:2
211eeed7ee2SGreg Clayton 0xae: src.cpp:19 -> sum4@src.cpp:12
212eeed7ee2SGreg Clayton 0xaf: src.cpp:19 -> sum4@src.cpp:12
213eeed7ee2SGreg Clayton 0xb1: src.cpp:19 -> sum4@src.cpp:12
214eeed7ee2SGreg Clayton 0xb6: src.cpp:19 -> sum4@src.cpp:13
215eeed7ee2SGreg Clayton 0xb7: src.cpp:19 -> sum4@src.cpp:13
216eeed7ee2SGreg Clayton 0xb9: src.cpp:19 -> sum4@src.cpp:14
217eeed7ee2SGreg Clayton 0xbe: src.cpp:19
218eeed7ee2SGreg Clayton 0xbf: src.cpp:19
219eeed7ee2SGreg Clayton 0xc1: src.cpp:19
220eeed7ee2SGreg Clayton 0xc6: src.cpp:19
221eeed7ee2SGreg Clayton 0xc7: src.cpp:19
222eeed7ee2SGreg Clayton 0xc9: src.cpp:19
223eeed7ee2SGreg Clayton 0xce: src.cpp:20 -> sum2@src.cpp:2
224eeed7ee2SGreg Clayton 0xcf: src.cpp:20 -> sum2@src.cpp:2
225eeed7ee2SGreg Clayton 0xd1: src.cpp:20 -> sum2@src.cpp:2
226eeed7ee2SGreg Clayton 0xd6: src.cpp:21
227eeed7ee2SGreg Clayton 0xd7: src.cpp:21
228eeed7ee2SGreg Clayton 0xd9: src.cpp:21
229eeed7ee2SGreg Clayton 0xde: src.cpp:21
230eeed7ee2SGreg Clayton */
231