Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- MSVCUndecoratedNameParser.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 "MSVCUndecoratedNameParser.h"
10
11
#include <stack>
12
13
3
MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) {
14
  // Global ctor and dtor are global functions.
15
3
  if (name.contains("dynamic initializer for") ||
16
3
      name.contains("dynamic atexit destructor for")) {
17
0
    m_specifiers.emplace_back(name, name);
18
0
    return;
19
0
  }
20
21
3
  std::size_t last_base_start = 0;
22
23
3
  std::stack<std::size_t> stack;
24
3
  unsigned int open_angle_brackets = 0;
25
104
  for (size_t i = 0; i < name.size(); 
i++101
) {
26
101
    switch (name[i]) {
27
5
    case '<':
28
      // Do not treat `operator<' and `operator<<' as templates
29
      // (sometimes they represented as `<' and `<<' in the name).
30
5
      if (i == last_base_start ||
31
5
          
(4
i == last_base_start + 14
&&
name[last_base_start] == '<'2
))
32
2
        break;
33
34
3
      stack.push(i);
35
3
      open_angle_brackets++;
36
37
3
      break;
38
3
    case '>':
39
3
      if (!stack.empty() && 
name[stack.top()] == '<'2
) {
40
2
        open_angle_brackets--;
41
2
        stack.pop();
42
2
      }
43
44
3
      break;
45
4
    case '`':
46
4
      stack.push(i);
47
48
4
      break;
49
4
    case '\'':
50
5
      while (!stack.empty()) {
51
5
        std::size_t top = stack.top();
52
5
        if (name[top] == '<')
53
1
          open_angle_brackets--;
54
55
5
        stack.pop();
56
57
5
        if (name[top] == '`')
58
4
          break;
59
5
      }
60
61
4
      break;
62
16
    case ':':
63
16
      if (open_angle_brackets)
64
0
        break;
65
16
      if (i == 0 || name[i - 1] != ':')
66
8
        break;
67
68
8
      m_specifiers.emplace_back(name.take_front(i - 1),
69
8
                                name.slice(last_base_start, i - 1));
70
71
8
      last_base_start = i + 1;
72
8
      break;
73
69
    default:
74
69
      break;
75
101
    }
76
101
  }
77
78
3
  m_specifiers.emplace_back(name, name.drop_front(last_base_start));
79
3
}
80
81
680k
bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {
82
680k
  return name.contains('`');
83
680k
}
84
85
bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
86
    llvm::StringRef name, llvm::StringRef &context,
87
3
    llvm::StringRef &identifier) {
88
3
  MSVCUndecoratedNameParser parser(name);
89
3
  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
90
91
3
  std::size_t count = specs.size();
92
3
  identifier = count > 0 ? specs[count - 1].GetBaseName() : 
""0
;
93
3
  context = count > 1 ? specs[count - 2].GetFullName() : 
""0
;
94
95
3
  return count;
96
3
}
97
98
0
llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
99
0
  MSVCUndecoratedNameParser parser(name);
100
0
  llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
101
0
  if (specs.empty())
102
0
    return "";
103
104
0
  return specs[specs.size() - 1].GetBaseName();
105
0
}