xref: /llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp (revision 8704281c567705822a1c23b9ec40f5bdc5d58352)
180814287SRaphael Isemann //===-- MSVCUndecoratedNameParser.cpp -------------------------------------===//
2c1e530eeSAleksandr Urakov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c1e530eeSAleksandr Urakov //
7c1e530eeSAleksandr Urakov //===----------------------------------------------------------------------===//
8c1e530eeSAleksandr Urakov 
9c1e530eeSAleksandr Urakov #include "MSVCUndecoratedNameParser.h"
10c1e530eeSAleksandr Urakov 
11c1e530eeSAleksandr Urakov #include <stack>
12c1e530eeSAleksandr Urakov 
MSVCUndecoratedNameParser(llvm::StringRef name)13c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) {
14*8704281cSZequan Wu   // Global ctor and dtor are global functions.
15*8704281cSZequan Wu   if (name.contains("dynamic initializer for") ||
16*8704281cSZequan Wu       name.contains("dynamic atexit destructor for")) {
17*8704281cSZequan Wu     m_specifiers.emplace_back(name, name);
18*8704281cSZequan Wu     return;
19*8704281cSZequan Wu   }
20*8704281cSZequan Wu 
21c1e530eeSAleksandr Urakov   std::size_t last_base_start = 0;
22c1e530eeSAleksandr Urakov 
23c1e530eeSAleksandr Urakov   std::stack<std::size_t> stack;
24c1e530eeSAleksandr Urakov   unsigned int open_angle_brackets = 0;
25c1e530eeSAleksandr Urakov   for (size_t i = 0; i < name.size(); i++) {
26c1e530eeSAleksandr Urakov     switch (name[i]) {
27c1e530eeSAleksandr Urakov     case '<':
28c1e530eeSAleksandr Urakov       // Do not treat `operator<' and `operator<<' as templates
29c1e530eeSAleksandr Urakov       // (sometimes they represented as `<' and `<<' in the name).
30c1e530eeSAleksandr Urakov       if (i == last_base_start ||
3198d9647dSBenjamin Kramer           (i == last_base_start + 1 && name[last_base_start] == '<'))
32c1e530eeSAleksandr Urakov         break;
33c1e530eeSAleksandr Urakov 
34c1e530eeSAleksandr Urakov       stack.push(i);
35c1e530eeSAleksandr Urakov       open_angle_brackets++;
36c1e530eeSAleksandr Urakov 
37c1e530eeSAleksandr Urakov       break;
38c1e530eeSAleksandr Urakov     case '>':
39c1e530eeSAleksandr Urakov       if (!stack.empty() && name[stack.top()] == '<') {
40c1e530eeSAleksandr Urakov         open_angle_brackets--;
41c1e530eeSAleksandr Urakov         stack.pop();
42c1e530eeSAleksandr Urakov       }
43c1e530eeSAleksandr Urakov 
44c1e530eeSAleksandr Urakov       break;
45c1e530eeSAleksandr Urakov     case '`':
46c1e530eeSAleksandr Urakov       stack.push(i);
47c1e530eeSAleksandr Urakov 
48c1e530eeSAleksandr Urakov       break;
49c1e530eeSAleksandr Urakov     case '\'':
50c1e530eeSAleksandr Urakov       while (!stack.empty()) {
51c1e530eeSAleksandr Urakov         std::size_t top = stack.top();
52c1e530eeSAleksandr Urakov         if (name[top] == '<')
53c1e530eeSAleksandr Urakov           open_angle_brackets--;
54c1e530eeSAleksandr Urakov 
55c1e530eeSAleksandr Urakov         stack.pop();
56c1e530eeSAleksandr Urakov 
57c1e530eeSAleksandr Urakov         if (name[top] == '`')
58c1e530eeSAleksandr Urakov           break;
59c1e530eeSAleksandr Urakov       }
60c1e530eeSAleksandr Urakov 
61c1e530eeSAleksandr Urakov       break;
62c1e530eeSAleksandr Urakov     case ':':
63c1e530eeSAleksandr Urakov       if (open_angle_brackets)
64c1e530eeSAleksandr Urakov         break;
65c1e530eeSAleksandr Urakov       if (i == 0 || name[i - 1] != ':')
66c1e530eeSAleksandr Urakov         break;
67c1e530eeSAleksandr Urakov 
68c1e530eeSAleksandr Urakov       m_specifiers.emplace_back(name.take_front(i - 1),
69c1e530eeSAleksandr Urakov                                 name.slice(last_base_start, i - 1));
70c1e530eeSAleksandr Urakov 
71c1e530eeSAleksandr Urakov       last_base_start = i + 1;
72c7f57aa8SEric Christopher       break;
73c1e530eeSAleksandr Urakov     default:
74c1e530eeSAleksandr Urakov       break;
75c1e530eeSAleksandr Urakov     }
76c1e530eeSAleksandr Urakov   }
77c1e530eeSAleksandr Urakov 
78c1e530eeSAleksandr Urakov   m_specifiers.emplace_back(name, name.drop_front(last_base_start));
79c1e530eeSAleksandr Urakov }
80c1e530eeSAleksandr Urakov 
IsMSVCUndecoratedName(llvm::StringRef name)81c1e530eeSAleksandr Urakov bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {
824ba9d9c8SKazu Hirata   return name.contains('`');
83c1e530eeSAleksandr Urakov }
84c1e530eeSAleksandr Urakov 
ExtractContextAndIdentifier(llvm::StringRef name,llvm::StringRef & context,llvm::StringRef & identifier)85c1e530eeSAleksandr Urakov bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
86c1e530eeSAleksandr Urakov     llvm::StringRef name, llvm::StringRef &context,
87c1e530eeSAleksandr Urakov     llvm::StringRef &identifier) {
88c1e530eeSAleksandr Urakov   MSVCUndecoratedNameParser parser(name);
89c1e530eeSAleksandr Urakov   llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
90c1e530eeSAleksandr Urakov 
91c1e530eeSAleksandr Urakov   std::size_t count = specs.size();
92c1e530eeSAleksandr Urakov   identifier = count > 0 ? specs[count - 1].GetBaseName() : "";
93c1e530eeSAleksandr Urakov   context = count > 1 ? specs[count - 2].GetFullName() : "";
94c1e530eeSAleksandr Urakov 
95c1e530eeSAleksandr Urakov   return count;
96c1e530eeSAleksandr Urakov }
97c1e530eeSAleksandr Urakov 
DropScope(llvm::StringRef name)98c1e530eeSAleksandr Urakov llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
99c1e530eeSAleksandr Urakov   MSVCUndecoratedNameParser parser(name);
100c1e530eeSAleksandr Urakov   llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
101c1e530eeSAleksandr Urakov   if (specs.empty())
102c1e530eeSAleksandr Urakov     return "";
103c1e530eeSAleksandr Urakov 
104c1e530eeSAleksandr Urakov   return specs[specs.size() - 1].GetBaseName();
105c1e530eeSAleksandr Urakov }
106