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