1 //===-- TestLineEntry.cpp -------------------------------------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "gtest/gtest.h" 10 #include <iostream> 11 12 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" 13 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" 14 #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" 15 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 16 #include "TestingSupport/SubsystemRAII.h" 17 #include "TestingSupport/TestUtilities.h" 18 19 #include "lldb/Core/Module.h" 20 #include "lldb/Host/FileSystem.h" 21 #include "lldb/Host/HostInfo.h" 22 #include "lldb/Symbol/CompileUnit.h" 23 #include "lldb/Symbol/SymbolContext.h" 24 25 #include "llvm/Support/FileUtilities.h" 26 #include "llvm/Support/Program.h" 27 #include "llvm/Testing/Support/Error.h" 28 29 using namespace lldb_private; 30 using namespace lldb; 31 32 class LineEntryTest : public testing::Test { 33 SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF, 34 TypeSystemClang> 35 subsystem; 36 37 public: 38 void SetUp() override; 39 40 protected: 41 llvm::Expected<LineEntry> GetLineEntryForLine(uint32_t line); 42 llvm::Optional<TestFile> m_file; 43 ModuleSP m_module_sp; 44 }; 45 46 void LineEntryTest::SetUp() { 47 auto ExpectedFile = TestFile::fromYamlFile("inlined-functions.yaml"); 48 ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); 49 m_file.emplace(std::move(*ExpectedFile)); 50 m_module_sp = std::make_shared<Module>(m_file->moduleSpec()); 51 } 52 53 llvm::Expected<LineEntry> LineEntryTest::GetLineEntryForLine(uint32_t line) { 54 // TODO: Handle SourceLocationSpec column information 55 SymbolContextList sc_comp_units; 56 SymbolContextList sc_line_entries; 57 FileSpec file_spec("inlined-functions.cpp"); 58 m_module_sp->ResolveSymbolContextsForFileSpec( 59 file_spec, line, /*check_inlines=*/true, lldb::eSymbolContextCompUnit, 60 sc_comp_units); 61 if (sc_comp_units.GetSize() == 0) 62 return llvm::createStringError(llvm::inconvertibleErrorCode(), 63 "No comp unit found on the test object."); 64 65 SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None, 66 /*check_inlines=*/true, 67 /*exact_match=*/true); 68 69 sc_comp_units[0].comp_unit->ResolveSymbolContext( 70 location_spec, eSymbolContextLineEntry, sc_line_entries); 71 if (sc_line_entries.GetSize() == 0) 72 return llvm::createStringError(llvm::inconvertibleErrorCode(), 73 "No line entry found on the test object."); 74 return sc_line_entries[0].line_entry; 75 } 76 77 TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNoInlines) { 78 auto line_entry = GetLineEntryForLine(18); 79 ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); 80 bool include_inlined_functions = false; 81 auto range = 82 line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); 83 ASSERT_EQ(range.GetByteSize(), (uint64_t)0x24); 84 } 85 86 TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeOneInline) { 87 auto line_entry = GetLineEntryForLine(18); 88 ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); 89 bool include_inlined_functions = true; 90 auto range = 91 line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); 92 ASSERT_EQ(range.GetByteSize(), (uint64_t)0x49); 93 } 94 95 TEST_F(LineEntryTest, GetSameLineContiguousAddressRangeNestedInline) { 96 auto line_entry = GetLineEntryForLine(12); 97 ASSERT_THAT_EXPECTED(line_entry, llvm::Succeeded()); 98 bool include_inlined_functions = true; 99 auto range = 100 line_entry->GetSameLineContiguousAddressRange(include_inlined_functions); 101 ASSERT_EQ(range.GetByteSize(), (uint64_t)0x33); 102 } 103 104 /* 105 # inlined-functions.cpp 106 inline __attribute__((always_inline)) int sum2(int a, int b) { 107 int result = a + b; 108 return result; 109 } 110 111 int sum3(int a, int b, int c) { 112 int result = a + b + c; 113 return result; 114 } 115 116 inline __attribute__((always_inline)) int sum4(int a, int b, int c, int d) { 117 int result = sum2(a, b) + sum2(c, d); 118 result += 0; 119 return result; 120 } 121 122 int main(int argc, char** argv) { 123 sum3(3, 4, 5) + sum2(1, 2); 124 int sum = sum4(1, 2, 3, 4); 125 sum2(5, 6); 126 return 0; 127 } 128 129 // g++ -c inlined-functions.cpp -o inlined-functions.o -g -Wno-unused-value 130 // obj2yaml inlined-functions.o > inlined-functions.yaml 131 132 # Dump of source line per address: 133 # inlined-functions.cpp is src.cpp for space considerations. 134 0x20: src.cpp:17 135 0x21: src.cpp:17 136 0x26: src.cpp:17 137 0x27: src.cpp:17 138 0x29: src.cpp:17 139 0x2e: src.cpp:17 140 0x2f: src.cpp:17 141 0x31: src.cpp:17 142 0x36: src.cpp:18 143 0x37: src.cpp:18 144 0x39: src.cpp:18 145 0x3e: src.cpp:18 146 0x3f: src.cpp:18 147 0x41: src.cpp:18 148 0x46: src.cpp:18 149 0x47: src.cpp:18 150 0x49: src.cpp:18 151 0x4e: src.cpp:18 152 0x4f: src.cpp:18 153 0x51: src.cpp:18 154 0x56: src.cpp:18 155 0x57: src.cpp:18 156 0x59: src.cpp:18 157 0x5e: src.cpp:18 -> [email protected]:2 158 0x5f: src.cpp:18 -> [email protected]:2 159 0x61: src.cpp:18 -> [email protected]:2 160 0x66: src.cpp:18 -> [email protected]:2 161 0x67: src.cpp:18 -> [email protected]:2 162 0x69: src.cpp:18 -> [email protected]:2 163 0x6e: src.cpp:18 -> [email protected]:2 164 0x6f: src.cpp:18 -> [email protected]:2 165 0x71: src.cpp:18 -> [email protected]:2 166 0x76: src.cpp:18 -> [email protected]:2 167 0x77: src.cpp:18 -> [email protected]:2 168 0x79: src.cpp:18 -> [email protected]:2 169 0x7e: src.cpp:18 -> [email protected]:2 170 0x7f: src.cpp:19 -> [email protected]:12 171 0x81: src.cpp:19 -> [email protected]:12 172 0x86: src.cpp:19 -> [email protected]:12 173 0x87: src.cpp:19 -> [email protected]:12 174 0x89: src.cpp:19 -> [email protected]:12 175 0x8e: src.cpp:19 -> [email protected]:12 -> [email protected]:2 176 0x8f: src.cpp:19 -> [email protected]:12 -> [email protected]:2 177 0x91: src.cpp:19 -> [email protected]:12 -> [email protected]:2 178 0x96: src.cpp:19 -> [email protected]:12 -> [email protected]:3 179 0x97: src.cpp:19 -> [email protected]:12 180 0x99: src.cpp:19 -> [email protected]:12 181 0x9e: src.cpp:19 -> [email protected]:12 182 0x9f: src.cpp:19 -> [email protected]:12 183 0xa1: src.cpp:19 -> [email protected]:12 184 0xa6: src.cpp:19 -> [email protected]:12 -> [email protected]:2 185 0xa7: src.cpp:19 -> [email protected]:12 -> [email protected]:2 186 0xa9: src.cpp:19 -> [email protected]:12 -> [email protected]:2 187 0xae: src.cpp:19 -> [email protected]:12 188 0xaf: src.cpp:19 -> [email protected]:12 189 0xb1: src.cpp:19 -> [email protected]:12 190 0xb6: src.cpp:19 -> [email protected]:13 191 0xb7: src.cpp:19 -> [email protected]:13 192 0xb9: src.cpp:19 -> [email protected]:14 193 0xbe: src.cpp:19 194 0xbf: src.cpp:19 195 0xc1: src.cpp:19 196 0xc6: src.cpp:19 197 0xc7: src.cpp:19 198 0xc9: src.cpp:19 199 0xce: src.cpp:20 -> [email protected]:2 200 0xcf: src.cpp:20 -> [email protected]:2 201 0xd1: src.cpp:20 -> [email protected]:2 202 0xd6: src.cpp:21 203 0xd7: src.cpp:21 204 0xd9: src.cpp:21 205 0xde: src.cpp:21 206 */ 207