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

source code of lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp