MSVCUndecoratedNameParser.cpp
2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//===-- MSVCUndecoratedNameParser.cpp -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "MSVCUndecoratedNameParser.h"
#include <stack>
MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) {
std::size_t last_base_start = 0;
std::stack<std::size_t> stack;
unsigned int open_angle_brackets = 0;
for (size_t i = 0; i < name.size(); i++) {
switch (name[i]) {
case '<':
// Do not treat `operator<' and `operator<<' as templates
// (sometimes they represented as `<' and `<<' in the name).
if (i == last_base_start ||
(i == last_base_start + 1 && name[last_base_start] == '<'))
break;
stack.push(i);
open_angle_brackets++;
break;
case '>':
if (!stack.empty() && name[stack.top()] == '<') {
open_angle_brackets--;
stack.pop();
}
break;
case '`':
stack.push(i);
break;
case '\'':
while (!stack.empty()) {
std::size_t top = stack.top();
if (name[top] == '<')
open_angle_brackets--;
stack.pop();
if (name[top] == '`')
break;
}
break;
case ':':
if (open_angle_brackets)
break;
if (i == 0 || name[i - 1] != ':')
break;
m_specifiers.emplace_back(name.take_front(i - 1),
name.slice(last_base_start, i - 1));
last_base_start = i + 1;
break;
default:
break;
}
}
m_specifiers.emplace_back(name, name.drop_front(last_base_start));
}
bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {
return name.find('`') != llvm::StringRef::npos;
}
bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
llvm::StringRef name, llvm::StringRef &context,
llvm::StringRef &identifier) {
MSVCUndecoratedNameParser parser(name);
llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
std::size_t count = specs.size();
identifier = count > 0 ? specs[count - 1].GetBaseName() : "";
context = count > 1 ? specs[count - 2].GetFullName() : "";
return count;
}
llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
MSVCUndecoratedNameParser parser(name);
llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
if (specs.empty())
return "";
return specs[specs.size() - 1].GetBaseName();
}