1 //===-- MSVCUndecoratedNameParser.cpp -------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "MSVCUndecoratedNameParser.h"
13 MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name
) {
14 // Global ctor and dtor are global functions.
15 if (name
.contains("dynamic initializer for") ||
16 name
.contains("dynamic atexit destructor for")) {
17 m_specifiers
.emplace_back(name
, name
);
21 std::size_t last_base_start
= 0;
23 std::stack
<std::size_t> stack
;
24 unsigned int open_angle_brackets
= 0;
25 for (size_t i
= 0; i
< name
.size(); i
++) {
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
] == '<'))
35 open_angle_brackets
++;
39 if (!stack
.empty() && name
[stack
.top()] == '<') {
40 open_angle_brackets
--;
50 while (!stack
.empty()) {
51 std::size_t top
= stack
.top();
53 open_angle_brackets
--;
63 if (open_angle_brackets
)
65 if (i
== 0 || name
[i
- 1] != ':')
68 m_specifiers
.emplace_back(name
.take_front(i
- 1),
69 name
.slice(last_base_start
, i
- 1));
71 last_base_start
= i
+ 1;
78 m_specifiers
.emplace_back(name
, name
.drop_front(last_base_start
));
81 bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name
) {
82 return name
.contains('`');
85 bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
86 llvm::StringRef name
, llvm::StringRef
&context
,
87 llvm::StringRef
&identifier
) {
88 MSVCUndecoratedNameParser
parser(name
);
89 llvm::ArrayRef
<MSVCUndecoratedNameSpecifier
> specs
= parser
.GetSpecifiers();
91 std::size_t count
= specs
.size();
92 identifier
= count
> 0 ? specs
[count
- 1].GetBaseName() : "";
93 context
= count
> 1 ? specs
[count
- 2].GetFullName() : "";
98 llvm::StringRef
MSVCUndecoratedNameParser::DropScope(llvm::StringRef name
) {
99 MSVCUndecoratedNameParser
parser(name
);
100 llvm::ArrayRef
<MSVCUndecoratedNameSpecifier
> specs
= parser
.GetSpecifiers();
104 return specs
[specs
.size() - 1].GetBaseName();