LLDB  mainline
RichManglingContext.cpp
Go to the documentation of this file.
1 //===-- RichManglingContext.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 
11 #include "lldb/Utility/LLDBLog.h"
12 
13 #include "llvm/ADT/StringRef.h"
14 
15 using namespace lldb;
16 using namespace lldb_private;
17 
18 // RichManglingContext
19 RichManglingContext::~RichManglingContext() {
20  std::free(m_ipd_buf);
21  ResetCxxMethodParser();
22 }
23 
24 void RichManglingContext::ResetCxxMethodParser() {
25  // If we want to support parsers for other languages some day, we need a
26  // switch here to delete the correct parser type.
27  if (m_cxx_method_parser.hasValue()) {
28  assert(m_provider == PluginCxxLanguage);
29  delete get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser);
30  m_cxx_method_parser.reset();
31  }
32 }
33 
34 void RichManglingContext::ResetProvider(InfoProvider new_provider) {
35  ResetCxxMethodParser();
36 
37  assert(new_provider != None && "Only reset to a valid provider");
38  m_provider = new_provider;
39 }
40 
41 bool RichManglingContext::FromItaniumName(ConstString mangled) {
42  bool err = m_ipd.partialDemangle(mangled.GetCString());
43  if (!err) {
44  ResetProvider(ItaniumPartialDemangler);
45  }
46 
47  if (Log *log = GetLog(LLDBLog::Demangle)) {
48  if (!err) {
49  ParseFullName();
50  LLDB_LOG(log, "demangled itanium: {0} -> \"{1}\"", mangled, m_ipd_buf);
51  } else {
52  LLDB_LOG(log, "demangled itanium: {0} -> error: failed to demangle",
53  mangled);
54  }
55  }
56 
57  return !err; // true == success
58 }
59 
60 bool RichManglingContext::FromCxxMethodName(ConstString demangled) {
61  ResetProvider(PluginCxxLanguage);
62  m_cxx_method_parser = new CPlusPlusLanguage::MethodName(demangled);
63  return true;
64 }
65 
66 bool RichManglingContext::IsCtorOrDtor() const {
67  assert(m_provider != None && "Initialize a provider first");
68  switch (m_provider) {
69  case ItaniumPartialDemangler:
70  return m_ipd.isCtorOrDtor();
71  case PluginCxxLanguage: {
72  // We can only check for destructors here.
73  auto base_name =
74  get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
75  return base_name.startswith("~");
76  }
77  case None:
78  return false;
79  }
80  llvm_unreachable("Fully covered switch above!");
81 }
82 
83 llvm::StringRef RichManglingContext::processIPDStrResult(char *ipd_res,
84  size_t res_size) {
85  // Error case: Clear the buffer.
86  if (LLVM_UNLIKELY(ipd_res == nullptr)) {
87  assert(res_size == m_ipd_buf_size &&
88  "Failed IPD queries keep the original size in the N parameter");
89 
90  m_ipd_buf[0] = '\0';
91  return llvm::StringRef(m_ipd_buf, 0);
92  }
93 
94  // IPD's res_size includes null terminator.
95  assert(ipd_res[res_size - 1] == '\0' &&
96  "IPD returns null-terminated strings and we rely on that");
97 
98  // Update buffer/size on realloc.
99  if (LLVM_UNLIKELY(ipd_res != m_ipd_buf || res_size > m_ipd_buf_size)) {
100  m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer.
101  m_ipd_buf_size = res_size; // May actually be bigger, but we can't know.
102 
103  if (Log *log = GetLog(LLDBLog::Demangle))
104  LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}",
105  m_ipd_buf_size);
106  }
107 
108  // 99% case: Just remember the string length.
109  return llvm::StringRef(m_ipd_buf, res_size - 1);
110 }
111 
112 llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
113  assert(m_provider != None && "Initialize a provider first");
114  switch (m_provider) {
115  case ItaniumPartialDemangler: {
116  auto n = m_ipd_buf_size;
117  auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n);
118  return processIPDStrResult(buf, n);
119  }
120  case PluginCxxLanguage:
121  return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
122  ->GetBasename();
123  case None:
124  return {};
125  }
126  llvm_unreachable("Fully covered switch above!");
127 }
128 
129 llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
130  assert(m_provider != None && "Initialize a provider first");
131  switch (m_provider) {
132  case ItaniumPartialDemangler: {
133  auto n = m_ipd_buf_size;
134  auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n);
135  return processIPDStrResult(buf, n);
136  }
137  case PluginCxxLanguage:
138  return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
139  ->GetContext();
140  case None:
141  return {};
142  }
143  llvm_unreachable("Fully covered switch above!");
144 }
145 
146 llvm::StringRef RichManglingContext::ParseFullName() {
147  assert(m_provider != None && "Initialize a provider first");
148  switch (m_provider) {
149  case ItaniumPartialDemangler: {
150  auto n = m_ipd_buf_size;
151  auto buf = m_ipd.finishDemangle(m_ipd_buf, &n);
152  return processIPDStrResult(buf, n);
153  }
154  case PluginCxxLanguage:
155  return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
156  ->GetFullName()
157  .GetStringRef();
158  case None:
159  return {};
160  }
161  llvm_unreachable("Fully covered switch above!");
162 }
CPlusPlusLanguage.h
lldb_private::RichManglingContext::InfoProvider
InfoProvider
Definition: RichManglingContext.h:57
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::CPlusPlusLanguage::MethodName
Definition: CPlusPlusLanguage.h:28
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:336
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
RichManglingContext.h
lldb_private::Log
Definition: Log.h:115
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:308
lldb
Definition: SBAddress.h:15
LLDBLog.h