Coverage Report

Created: 2022-01-25 06:29

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