Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/RichManglingContext.cpp
Line
Count
Source (jump to first uncovered line)
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
9
#include "lldb/Core/RichManglingContext.h"
10
#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
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
115k
RichManglingContext::~RichManglingContext() {
20
115k
  std::free(m_ipd_buf);
21
115k
  ResetCxxMethodParser();
22
115k
}
23
24
21.6M
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
21.6M
  if (m_cxx_method_parser.has_value()) {
28
4
    assert(m_provider == PluginCxxLanguage);
29
4
    delete get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser);
30
4
    m_cxx_method_parser.reset();
31
4
  }
32
21.6M
}
33
34
21.5M
void RichManglingContext::ResetProvider(InfoProvider new_provider) {
35
21.5M
  ResetCxxMethodParser();
36
37
21.5M
  assert(new_provider != None && "Only reset to a valid provider");
38
21.5M
  m_provider = new_provider;
39
21.5M
}
40
41
21.5M
bool RichManglingContext::FromItaniumName(ConstString mangled) {
42
21.5M
  bool err = m_ipd.partialDemangle(mangled.GetCString());
43
21.5M
  if (!err) {
44
21.5M
    ResetProvider(ItaniumPartialDemangler);
45
21.5M
  }
46
47
21.5M
  if (Log *log = GetLog(LLDBLog::Demangle)) {
48
0
    if (!err) {
49
0
      ParseFullName();
50
0
      LLDB_LOG(log, "demangled itanium: {0} -> \"{1}\"", mangled, m_ipd_buf);
51
0
    } else {
52
0
      LLDB_LOG(log, "demangled itanium: {0} -> error: failed to demangle",
53
0
               mangled);
54
0
    }
55
0
  }
56
57
21.5M
  return !err; // true == success
58
21.5M
}
59
60
4
bool RichManglingContext::FromCxxMethodName(ConstString demangled) {
61
4
  ResetProvider(PluginCxxLanguage);
62
4
  m_cxx_method_parser = new CPlusPlusLanguage::MethodName(demangled);
63
4
  return true;
64
4
}
65
66
19.4M
bool RichManglingContext::IsCtorOrDtor() const {
67
19.4M
  assert(m_provider != None && "Initialize a provider first");
68
19.4M
  switch (m_provider) {
69
19.4M
  case ItaniumPartialDemangler:
70
19.4M
    return m_ipd.isCtorOrDtor();
71
1
  case PluginCxxLanguage: {
72
    // We can only check for destructors here.
73
1
    auto base_name =
74
1
        get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->GetBasename();
75
1
    return base_name.startswith("~");
76
0
  }
77
0
  case None:
78
0
    return false;
79
19.4M
  }
80
0
  llvm_unreachable("Fully covered switch above!");
81
0
}
82
83
llvm::StringRef RichManglingContext::processIPDStrResult(char *ipd_res,
84
42.0M
                                                         size_t res_size) {
85
  // Error case: Clear the buffer.
86
42.0M
  if (LLVM_UNLIKELY(ipd_res == nullptr)) {
87
973k
    assert(res_size == m_ipd_buf_size &&
88
973k
           "Failed IPD queries keep the original size in the N parameter");
89
90
973k
    m_ipd_buf[0] = '\0';
91
973k
    return llvm::StringRef(m_ipd_buf, 0);
92
973k
  }
93
94
  // IPD's res_size includes null terminator.
95
41.1M
  assert(ipd_res[res_size - 1] == '\0' &&
96
41.1M
         "IPD returns null-terminated strings and we rely on that");
97
98
  // Update buffer/size on realloc.
99
41.1M
  if (LLVM_UNLIKELY(ipd_res != m_ipd_buf || res_size > m_ipd_buf_size)) {
100
66
    m_ipd_buf = ipd_res;       // std::realloc freed or reused the old buffer.
101
66
    m_ipd_buf_size = res_size; // May actually be bigger, but we can't know.
102
103
66
    if (Log *log = GetLog(LLDBLog::Demangle))
104
0
      LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}",
105
66
               m_ipd_buf_size);
106
66
  }
107
108
  // 99% case: Just remember the string length.
109
41.1M
  return llvm::StringRef(m_ipd_buf, res_size - 1);
110
41.1M
}
111
112
21.5M
llvm::StringRef RichManglingContext::ParseFunctionBaseName() {
113
21.5M
  assert(m_provider != None && "Initialize a provider first");
114
21.5M
  switch (m_provider) {
115
21.5M
  case ItaniumPartialDemangler: {
116
21.5M
    auto n = m_ipd_buf_size;
117
21.5M
    auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n);
118
21.5M
    return processIPDStrResult(buf, n);
119
0
  }
120
1
  case PluginCxxLanguage:
121
1
    return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
122
1
        ->GetBasename();
123
0
  case None:
124
0
    return {};
125
21.5M
  }
126
0
  llvm_unreachable("Fully covered switch above!");
127
0
}
128
129
20.5M
llvm::StringRef RichManglingContext::ParseFunctionDeclContextName() {
130
20.5M
  assert(m_provider != None && "Initialize a provider first");
131
20.5M
  switch (m_provider) {
132
20.5M
  case ItaniumPartialDemangler: {
133
20.5M
    auto n = m_ipd_buf_size;
134
20.5M
    auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n);
135
20.5M
    return processIPDStrResult(buf, n);
136
0
  }
137
2
  case PluginCxxLanguage:
138
2
    return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
139
2
        ->GetContext();
140
0
  case None:
141
0
    return {};
142
20.5M
  }
143
0
  llvm_unreachable("Fully covered switch above!");
144
0
}
145
146
8
llvm::StringRef RichManglingContext::ParseFullName() {
147
8
  assert(m_provider != None && "Initialize a provider first");
148
8
  switch (m_provider) {
149
6
  case ItaniumPartialDemangler: {
150
6
    auto n = m_ipd_buf_size;
151
6
    auto buf = m_ipd.finishDemangle(m_ipd_buf, &n);
152
6
    return processIPDStrResult(buf, n);
153
0
  }
154
2
  case PluginCxxLanguage:
155
2
    return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)
156
2
        ->GetFullName()
157
2
        .GetStringRef();
158
0
  case None:
159
0
    return {};
160
8
  }
161
0
  llvm_unreachable("Fully covered switch above!");
162
0
}