LLDB  mainline
SourceManager.cpp
Go to the documentation of this file.
1 //===-- SourceManager.cpp ---------------------------------------*- C++ -*-===//
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 
10 
11 #include "lldb/Core/Address.h"
12 #include "lldb/Core/AddressRange.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/FormatEntity.h"
15 #include "lldb/Core/Highlighter.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/ModuleList.h"
18 #include "lldb/Host/FileSystem.h"
20 #include "lldb/Symbol/Function.h"
21 #include "lldb/Symbol/LineEntry.h"
24 #include "lldb/Target/Target.h"
29 #include "lldb/Utility/Stream.h"
30 #include "lldb/lldb-enumerations.h"
31 
32 #include "llvm/ADT/Twine.h"
33 
34 #include <memory>
35 #include <utility>
36 
37 #include <assert.h>
38 #include <stdio.h>
39 
40 namespace lldb_private {
41 class ExecutionContext;
42 }
43 namespace lldb_private {
44 class ValueObject;
45 }
46 
47 using namespace lldb;
48 using namespace lldb_private;
49 
50 static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; }
51 
52 // SourceManager constructor
53 SourceManager::SourceManager(const TargetSP &target_sp)
54  : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false),
55  m_target_wp(target_sp),
56  m_debugger_wp(target_sp->GetDebugger().shared_from_this()) {}
57 
58 SourceManager::SourceManager(const DebuggerSP &debugger_sp)
59  : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false),
60  m_target_wp(), m_debugger_wp(debugger_sp) {}
61 
62 // Destructor
64 
66  bool same_as_previous =
67  m_last_file_sp && m_last_file_sp->FileSpecMatches(file_spec);
68 
69  DebuggerSP debugger_sp(m_debugger_wp.lock());
70  FileSP file_sp;
71  if (same_as_previous)
72  file_sp = m_last_file_sp;
73  else if (debugger_sp)
74  file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec);
75 
76  TargetSP target_sp(m_target_wp.lock());
77 
78  // It the target source path map has been updated, get this file again so we
79  // can successfully remap the source file
80  if (target_sp && file_sp &&
81  file_sp->GetSourceMapModificationID() !=
82  target_sp->GetSourcePathMap().GetModificationID())
83  file_sp.reset();
84 
85  // Update the file contents if needed if we found a file
86  if (file_sp)
87  file_sp->UpdateIfNeeded();
88 
89  // If file_sp is no good or it points to a non-existent file, reset it.
90  if (!file_sp || !FileSystem::Instance().Exists(file_sp->GetFileSpec())) {
91  if (target_sp)
92  file_sp = std::make_shared<File>(file_spec, target_sp.get());
93  else
94  file_sp = std::make_shared<File>(file_spec, debugger_sp);
95 
96  if (debugger_sp)
97  debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
98  }
99  return file_sp;
100 }
101 
102 static bool should_highlight_source(DebuggerSP debugger_sp) {
103  if (!debugger_sp)
104  return false;
105 
106  // We don't use ANSI stop column formatting if the debugger doesn't think it
107  // should be using color.
108  if (!debugger_sp->GetUseColor())
109  return false;
110 
111  return debugger_sp->GetHighlightSource();
112 }
113 
114 static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) {
115  // We don't use ANSI stop column formatting if we can't lookup values from
116  // the debugger.
117  if (!debugger_sp)
118  return false;
119 
120  // We don't use ANSI stop column formatting if the debugger doesn't think it
121  // should be using color.
122  if (!debugger_sp->GetUseColor())
123  return false;
124 
125  // We only use ANSI stop column formatting if we're either supposed to show
126  // ANSI where available (which we know we have when we get to this point), or
127  // if we're only supposed to use ANSI.
128  const auto value = debugger_sp->GetStopShowColumn();
129  return ((value == eStopShowColumnAnsiOrCaret) ||
130  (value == eStopShowColumnAnsi));
131 }
132 
133 static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp) {
134  // We don't use text-based stop column formatting if we can't lookup values
135  // from the debugger.
136  if (!debugger_sp)
137  return false;
138 
139  // If we're asked to show the first available of ANSI or caret, then we do
140  // show the caret when ANSI is not available.
141  const auto value = debugger_sp->GetStopShowColumn();
142  if ((value == eStopShowColumnAnsiOrCaret) && !debugger_sp->GetUseColor())
143  return true;
144 
145  // The only other time we use caret is if we're explicitly asked to show
146  // caret.
147  return value == eStopShowColumnCaret;
148 }
149 
151  uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
152  const char *current_line_cstr, Stream *s,
153  const SymbolContextList *bp_locs) {
154  if (count == 0)
155  return 0;
156 
157  Stream::ByteDelta delta(*s);
158 
159  if (start_line == 0) {
160  if (m_last_line != 0 && m_last_line != UINT32_MAX)
161  start_line = m_last_line + m_last_count;
162  else
163  start_line = 1;
164  }
165 
166  if (!m_default_set) {
167  FileSpec tmp_spec;
168  uint32_t tmp_line;
169  GetDefaultFileAndLine(tmp_spec, tmp_line);
170  }
171 
172  m_last_line = start_line;
173  m_last_count = count;
174 
175  if (m_last_file_sp.get()) {
176  const uint32_t end_line = start_line + count - 1;
177  for (uint32_t line = start_line; line <= end_line; ++line) {
178  if (!m_last_file_sp->LineIsValid(line)) {
179  m_last_line = UINT32_MAX;
180  break;
181  }
182 
183  char prefix[32] = "";
184  if (bp_locs) {
185  uint32_t bp_count = bp_locs->NumLineEntriesWithLine(line);
186 
187  if (bp_count > 0)
188  ::snprintf(prefix, sizeof(prefix), "[%u] ", bp_count);
189  else
190  ::snprintf(prefix, sizeof(prefix), " ");
191  }
192 
193  s->Printf("%s%2.2s %-4u\t", prefix,
194  line == curr_line ? current_line_cstr : "", line);
195 
196  // So far we treated column 0 as a special 'no column value', but
197  // DisplaySourceLines starts counting columns from 0 (and no column is
198  // expressed by passing an empty optional).
199  llvm::Optional<size_t> columnToHighlight;
200  if (line == curr_line && column)
201  columnToHighlight = column - 1;
202 
203  size_t this_line_size =
204  m_last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s);
205  if (column != 0 && line == curr_line &&
206  should_show_stop_column_with_caret(m_debugger_wp.lock())) {
207  // Display caret cursor.
208  std::string src_line;
209  m_last_file_sp->GetLine(line, src_line);
210  s->Printf(" \t");
211  // Insert a space for every non-tab character in the source line.
212  for (size_t i = 0; i + 1 < column && i < src_line.length(); ++i)
213  s->PutChar(src_line[i] == '\t' ? '\t' : ' ');
214  // Now add the caret.
215  s->Printf("^\n");
216  }
217  if (this_line_size == 0) {
218  m_last_line = UINT32_MAX;
219  break;
220  }
221  }
222  }
223  return *delta;
224 }
225 
227  const FileSpec &file_spec, uint32_t line, uint32_t column,
228  uint32_t context_before, uint32_t context_after,
229  const char *current_line_cstr, Stream *s,
230  const SymbolContextList *bp_locs) {
231  FileSP file_sp(GetFile(file_spec));
232 
233  uint32_t start_line;
234  uint32_t count = context_before + context_after + 1;
235  if (line > context_before)
236  start_line = line - context_before;
237  else
238  start_line = 1;
239 
240  if (m_last_file_sp.get() != file_sp.get()) {
241  if (line == 0)
242  m_last_line = 0;
243  m_last_file_sp = file_sp;
244  }
245  return DisplaySourceLinesWithLineNumbersUsingLastFile(
246  start_line, count, line, column, current_line_cstr, s, bp_locs);
247 }
248 
250  Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs) {
251  // If we get called before anybody has set a default file and line, then try
252  // to figure it out here.
253  const bool have_default_file_line = m_last_file_sp && m_last_line > 0;
254  if (!m_default_set) {
255  FileSpec tmp_spec;
256  uint32_t tmp_line;
257  GetDefaultFileAndLine(tmp_spec, tmp_line);
258  }
259 
260  if (m_last_file_sp) {
261  if (m_last_line == UINT32_MAX)
262  return 0;
263 
264  if (reverse && m_last_line == 1)
265  return 0;
266 
267  if (count > 0)
268  m_last_count = count;
269  else if (m_last_count == 0)
270  m_last_count = 10;
271 
272  if (m_last_line > 0) {
273  if (reverse) {
274  // If this is the first time we've done a reverse, then back up one
275  // more time so we end up showing the chunk before the last one we've
276  // shown:
277  if (m_last_line > m_last_count)
278  m_last_line -= m_last_count;
279  else
280  m_last_line = 1;
281  } else if (have_default_file_line)
282  m_last_line += m_last_count;
283  } else
284  m_last_line = 1;
285 
286  const uint32_t column = 0;
287  return DisplaySourceLinesWithLineNumbersUsingLastFile(
288  m_last_line, m_last_count, UINT32_MAX, column, "", s, bp_locs);
289  }
290  return 0;
291 }
292 
294  uint32_t line) {
295  FileSP old_file_sp = m_last_file_sp;
296  m_last_file_sp = GetFile(file_spec);
297 
298  m_default_set = true;
299  if (m_last_file_sp) {
300  m_last_line = line;
301  return true;
302  } else {
303  m_last_file_sp = old_file_sp;
304  return false;
305  }
306 }
307 
309  if (m_last_file_sp) {
310  file_spec = m_last_file_sp->GetFileSpec();
311  line = m_last_line;
312  return true;
313  } else if (!m_default_set) {
314  TargetSP target_sp(m_target_wp.lock());
315 
316  if (target_sp) {
317  // If nobody has set the default file and line then try here. If there's
318  // no executable, then we will try again later when there is one.
319  // Otherwise, if we can't find it we won't look again, somebody will have
320  // to set it (for instance when we stop somewhere...)
321  Module *executable_ptr = target_sp->GetExecutableModulePointer();
322  if (executable_ptr) {
323  SymbolContextList sc_list;
324  ConstString main_name("main");
325  bool symbols_okay = false; // Force it to be a debug symbol.
326  bool inlines_okay = true;
327  bool append = false;
328  size_t num_matches = executable_ptr->FindFunctions(
329  main_name, NULL, lldb::eFunctionNameTypeBase, inlines_okay,
330  symbols_okay, append, sc_list);
331  for (size_t idx = 0; idx < num_matches; idx++) {
332  SymbolContext sc;
333  sc_list.GetContextAtIndex(idx, sc);
334  if (sc.function) {
335  lldb_private::LineEntry line_entry;
336  if (sc.function->GetAddressRange()
337  .GetBaseAddress()
338  .CalculateSymbolContextLineEntry(line_entry)) {
339  SetDefaultFileAndLine(line_entry.file, line_entry.line);
340  file_spec = m_last_file_sp->GetFileSpec();
341  line = m_last_line;
342  return true;
343  }
344  }
345  }
346  }
347  }
348  }
349  return false;
350 }
351 
353  RegularExpression &regex,
354  uint32_t start_line,
355  uint32_t end_line,
356  std::vector<uint32_t> &match_lines) {
357  match_lines.clear();
358  FileSP file_sp = GetFile(file_spec);
359  if (!file_sp)
360  return;
361  return file_sp->FindLinesMatchingRegex(regex, start_line, end_line,
362  match_lines);
363 }
364 
366  lldb::DebuggerSP debugger_sp)
367  : m_file_spec_orig(file_spec), m_file_spec(file_spec),
368  m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
369  m_debugger_wp(debugger_sp) {
370  CommonInitializer(file_spec, nullptr);
371 }
372 
373 SourceManager::File::File(const FileSpec &file_spec, Target *target)
374  : m_file_spec_orig(file_spec), m_file_spec(file_spec),
375  m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
376  m_debugger_wp(target ? target->GetDebugger().shared_from_this()
377  : DebuggerSP()) {
378  CommonInitializer(file_spec, target);
379 }
380 
381 void SourceManager::File::CommonInitializer(const FileSpec &file_spec,
382  Target *target) {
383  if (m_mod_time == llvm::sys::TimePoint<>()) {
384  if (target) {
386 
387  if (!file_spec.GetDirectory() && file_spec.GetFilename()) {
388  // If this is just a file name, lets see if we can find it in the
389  // target:
390  bool check_inlines = false;
391  SymbolContextList sc_list;
392  size_t num_matches =
394  file_spec.GetFilename().AsCString(), 0, check_inlines,
395  SymbolContextItem(eSymbolContextModule |
396  eSymbolContextCompUnit),
397  sc_list);
398  bool got_multiple = false;
399  if (num_matches != 0) {
400  if (num_matches > 1) {
401  SymbolContext sc;
402  FileSpec *test_cu_spec = NULL;
403 
404  for (unsigned i = 0; i < num_matches; i++) {
405  sc_list.GetContextAtIndex(i, sc);
406  if (sc.comp_unit) {
407  if (test_cu_spec) {
408  if (test_cu_spec != static_cast<FileSpec *>(sc.comp_unit))
409  got_multiple = true;
410  break;
411  } else
412  test_cu_spec = sc.comp_unit;
413  }
414  }
415  }
416  if (!got_multiple) {
417  SymbolContext sc;
418  sc_list.GetContextAtIndex(0, sc);
419  m_file_spec = sc.comp_unit;
421  }
422  }
423  }
424  // Try remapping if m_file_spec does not correspond to an existing file.
425  if (!FileSystem::Instance().Exists(m_file_spec)) {
426  FileSpec new_file_spec;
427  // Check target specific source remappings first, then fall back to
428  // modules objects can have individual path remappings that were
429  // detected when the debug info for a module was found. then
430  if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) ||
431  target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) {
432  m_file_spec = new_file_spec;
434  }
435  }
436  }
437  }
438 
439  if (m_mod_time != llvm::sys::TimePoint<>())
441 }
442 
444  if (line == 0)
445  return UINT32_MAX;
446 
447  if (line == 1)
448  return 0;
449 
450  if (CalculateLineOffsets(line)) {
451  if (line < m_offsets.size())
452  return m_offsets[line - 1]; // yes we want "line - 1" in the index
453  }
454  return UINT32_MAX;
455 }
456 
459  return m_offsets.size();
460 }
461 
463  if (!LineIsValid(line))
464  return NULL;
465 
466  size_t line_offset = GetLineOffset(line);
467  if (line_offset < m_data_sp->GetByteSize())
468  return (const char *)m_data_sp->GetBytes() + line_offset;
469  return NULL;
470 }
471 
473  bool include_newline_chars) {
474  if (!LineIsValid(line))
475  return false;
476 
477  size_t start_offset = GetLineOffset(line);
478  size_t end_offset = GetLineOffset(line + 1);
479  if (end_offset == UINT32_MAX)
480  end_offset = m_data_sp->GetByteSize();
481 
482  if (end_offset > start_offset) {
483  uint32_t length = end_offset - start_offset;
484  if (!include_newline_chars) {
485  const char *line_start =
486  (const char *)m_data_sp->GetBytes() + start_offset;
487  while (length > 0) {
488  const char last_char = line_start[length - 1];
489  if ((last_char == '\r') || (last_char == '\n'))
490  --length;
491  else
492  break;
493  }
494  }
495  return length;
496  }
497  return 0;
498 }
499 
501  if (line == 0)
502  return false;
503 
504  if (CalculateLineOffsets(line))
505  return line < m_offsets.size();
506  return false;
507 }
508 
510  // TODO: use host API to sign up for file modifications to anything in our
511  // source cache and only update when we determine a file has been updated.
512  // For now we check each time we want to display info for the file.
513  auto curr_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
514 
515  if (curr_mod_time != llvm::sys::TimePoint<>() &&
516  m_mod_time != curr_mod_time) {
517  m_mod_time = curr_mod_time;
519  m_offsets.clear();
520  }
521 }
522 
524  llvm::Optional<size_t> column,
525  uint32_t context_before,
526  uint32_t context_after,
527  Stream *s) {
528  // Nothing to write if there's no stream.
529  if (!s)
530  return 0;
531 
532  // Sanity check m_data_sp before proceeding.
533  if (!m_data_sp)
534  return 0;
535 
536  size_t bytes_written = s->GetWrittenBytes();
537 
538  auto debugger_sp = m_debugger_wp.lock();
539 
540  HighlightStyle style;
541  // Use the default Vim style if source highlighting is enabled.
542  if (should_highlight_source(debugger_sp))
544 
545  // If we should mark the stop column with color codes, then copy the prefix
546  // and suffix to our color style.
547  if (should_show_stop_column_with_ansi(debugger_sp))
548  style.selected.Set(debugger_sp->GetStopShowColumnAnsiPrefix(),
549  debugger_sp->GetStopShowColumnAnsiSuffix());
550 
551  HighlighterManager mgr;
552  std::string path = GetFileSpec().GetPath(/*denormalize*/ false);
553  // FIXME: Find a way to get the definitive language this file was written in
554  // and pass it to the highlighter.
555  const auto &h = mgr.getHighlighterFor(lldb::eLanguageTypeUnknown, path);
556 
557  const uint32_t start_line =
558  line <= context_before ? 1 : line - context_before;
559  const uint32_t start_line_offset = GetLineOffset(start_line);
560  if (start_line_offset != UINT32_MAX) {
561  const uint32_t end_line = line + context_after;
562  uint32_t end_line_offset = GetLineOffset(end_line + 1);
563  if (end_line_offset == UINT32_MAX)
564  end_line_offset = m_data_sp->GetByteSize();
565 
566  assert(start_line_offset <= end_line_offset);
567  if (start_line_offset < end_line_offset) {
568  size_t count = end_line_offset - start_line_offset;
569  const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset;
570 
571  auto ref = llvm::StringRef(reinterpret_cast<const char *>(cstr), count);
572 
573  h.Highlight(style, ref, column, "", *s);
574 
575  // Ensure we get an end of line character one way or another.
576  if (!is_newline_char(ref.back()))
577  s->EOL();
578  }
579  }
580  return s->GetWrittenBytes() - bytes_written;
581 }
582 
584  RegularExpression &regex, uint32_t start_line, uint32_t end_line,
585  std::vector<uint32_t> &match_lines) {
586  match_lines.clear();
587 
588  if (!LineIsValid(start_line) ||
589  (end_line != UINT32_MAX && !LineIsValid(end_line)))
590  return;
591  if (start_line > end_line)
592  return;
593 
594  for (uint32_t line_no = start_line; line_no < end_line; line_no++) {
595  std::string buffer;
596  if (!GetLine(line_no, buffer))
597  break;
598  if (regex.Execute(buffer)) {
599  match_lines.push_back(line_no);
600  }
601  }
602 }
603 
605  return FileSpec::Equal(m_file_spec, file_spec, false);
606 }
607 
609  const SourceManager::File &rhs) {
610  if (lhs.m_file_spec != rhs.m_file_spec)
611  return false;
612  return lhs.m_mod_time == rhs.m_mod_time;
613 }
614 
616  line =
617  UINT32_MAX; // TODO: take this line out when we support partial indexing
618  if (line == UINT32_MAX) {
619  // Already done?
620  if (!m_offsets.empty() && m_offsets[0] == UINT32_MAX)
621  return true;
622 
623  if (m_offsets.empty()) {
624  if (m_data_sp.get() == NULL)
625  return false;
626 
627  const char *start = (char *)m_data_sp->GetBytes();
628  if (start) {
629  const char *end = start + m_data_sp->GetByteSize();
630 
631  // Calculate all line offsets from scratch
632 
633  // Push a 1 at index zero to indicate the file has been completely
634  // indexed.
635  m_offsets.push_back(UINT32_MAX);
636  const char *s;
637  for (s = start; s < end; ++s) {
638  char curr_ch = *s;
639  if (is_newline_char(curr_ch)) {
640  if (s + 1 < end) {
641  char next_ch = s[1];
642  if (is_newline_char(next_ch)) {
643  if (curr_ch != next_ch)
644  ++s;
645  }
646  }
647  m_offsets.push_back(s + 1 - start);
648  }
649  }
650  if (!m_offsets.empty()) {
651  if (m_offsets.back() < size_t(end - start))
652  m_offsets.push_back(end - start);
653  }
654  return true;
655  }
656  } else {
657  // Some lines have been populated, start where we last left off
658  assert("Not implemented yet" && false);
659  }
660 
661  } else {
662  // Calculate all line offsets up to "line"
663  assert("Not implemented yet" && false);
664  }
665  return false;
666 }
667 
668 bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) {
669  if (!LineIsValid(line_no))
670  return false;
671 
672  size_t start_offset = GetLineOffset(line_no);
673  size_t end_offset = GetLineOffset(line_no + 1);
674  if (end_offset == UINT32_MAX) {
675  end_offset = m_data_sp->GetByteSize();
676  }
677  buffer.assign((char *)m_data_sp->GetBytes() + start_offset,
678  end_offset - start_offset);
679 
680  return true;
681 }
682 
684  FileSpec file_spec;
685  FileCache::iterator pos = m_file_cache.find(file_spec);
686  if (pos == m_file_cache.end())
687  m_file_cache[file_spec] = file_sp;
688  else {
689  if (file_sp != pos->second)
690  m_file_cache[file_spec] = file_sp;
691  }
692 }
693 
695  const FileSpec &file_spec) const {
696  FileSP file_sp;
697  FileCache::const_iterator pos = m_file_cache.find(file_spec);
698  if (pos != m_file_cache.end())
699  file_sp = pos->second;
700  return file_sp;
701 }
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:369
A line table entry class.
Definition: LineEntry.h:20
Defines a list of symbol context objects.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:224
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool CalculateLineOffsets(uint32_t line=UINT32_MAX)
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
bool FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const
Finds a source file given a file spec using the path remappings.
bool FileSpecMatches(const FileSpec &file_spec)
size_t GetWrittenBytes() const
Definition: Stream.h:106
static bool is_newline_char(char ch)
std::shared_ptr< DataBufferLLVM > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
A file utility class.
Definition: FileSpec.h:55
"lldb/Utility/RegularExpression.h" A C++ wrapper class for regex.
Manages the available highlighters.
Definition: Highlighter.h:136
CompileUnit * comp_unit
The CompileUnit for a given query.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
FileSP FindSourceFile(const FileSpec &file_spec) const
llvm::sys::TimePoint m_mod_time
Definition: SourceManager.h:88
size_t DisplaySourceLines(uint32_t line, llvm::Optional< size_t > column, uint32_t context_before, uint32_t context_after, Stream *s)
static FileSystem & Instance()
const Highlighter & getHighlighterFor(lldb::LanguageType language_type, llvm::StringRef path) const
Queries all known highlighter for one that can highlight some source code.
Definition: Highlighter.cpp:64
static HighlightStyle MakeVimStyle()
Returns a HighlightStyle that is based on vim&#39;s default highlight style.
Definition: Highlighter.cpp:55
bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const
Definition: ModuleList.cpp:575
Function * function
The Function for a given query.
static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp)
bool operator==(const Address &lhs, const Address &rhs)
Definition: Address.cpp:973
#define UINT32_MAX
Definition: lldb-defines.h:31
static bool should_highlight_source(DebuggerSP debugger_sp)
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
void FindLinesMatchingRegex(RegularExpression &regex, uint32_t start_line, uint32_t end_line, std::vector< uint32_t > &match_lines)
A class that describes an executable image and its associated object and symbol files.
Definition: Module.h:109
File(const FileSpec &file_spec, Target *target)
size_t DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
FileSpec file
The source file, possibly mapped by the target.source-map setting.
Definition: LineEntry.h:151
uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, bool check_inlines, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const
Resolve items in the symbol context for a given file and line. (const char
Definition: ModuleList.cpp:685
uint32_t line
The source line number, or zero if there is no line number information.
Definition: LineEntry.h:154
size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs=nullptr)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
ColorStyle selected
The style for the token which is below the cursor of the user.
Definition: Highlighter.h:54
static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp)
uint32_t NumLineEntriesWithLine(uint32_t line) const
bool SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line)
size_t DisplaySourceLinesWithLineNumbersUsingLastFile(uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const
Definition: Address.cpp:864
PathMappingList & GetSourcePathMap() const
Definition: Target.cpp:3857
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:899
Represents style that the highlighter should apply to the given source code.
Definition: Highlighter.h:23
size_t PutChar(char ch)
Definition: Stream.cpp:103
const char * PeekLineData(uint32_t line)
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:363
SourceManager(const lldb::DebuggerSP &debugger_sp)
uint32_t GetLineOffset(uint32_t line)
A uniqued constant string class.
Definition: ConstString.h:38
Unknown or invalid language value.
bool Execute(llvm::StringRef string, Match *match=nullptr) const
Executes a regular expression.
static bool Equal(const FileSpec &a, const FileSpec &b, bool full)
Definition: FileSpec.cpp:319
FileSP GetFile(const FileSpec &file_spec)
Definition: SBAddress.h:15
uint32_t GetLineLength(uint32_t line, bool include_newline_chars)
std::shared_ptr< File > FileSP
size_t FindFunctions(ConstString name, const CompilerDeclContext *parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool symbols_ok, bool inlines_ok, bool append, SymbolContextList &sc_list)
Find functions by name.
void FindLinesMatchingRegex(FileSpec &file_spec, RegularExpression &regex, uint32_t start_line, uint32_t end_line, std::vector< uint32_t > &match_lines)
bool GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line)
void Set(llvm::StringRef prefix, llvm::StringRef suffix)
Sets the prefix and suffix strings.
Definition: Highlighter.cpp:21
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:220
uint32_t GetModificationID() const
const AddressRange & GetAddressRange()
Definition: Function.h:371
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
bool GetLine(uint32_t line_no, std::string &buffer)
llvm::sys::TimePoint GetModificationTime(const FileSpec &file_spec) const
Returns the modification time of the given file.