[C++20] [Modules] Fix may-be incorrect ADL for module local entities (#123931)
[llvm-project.git] / lldb / source / Plugins / Language / CPlusPlus / MSVCUndecoratedNameParser.cpp
blob72afc6fe75accd3a08ed548a2343ccb883b90cc5
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 //===----------------------------------------------------------------------===//
9 #include "MSVCUndecoratedNameParser.h"
11 #include <stack>
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);
18 return;
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++) {
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;
34 stack.push(i);
35 open_angle_brackets++;
37 break;
38 case '>':
39 if (!stack.empty() && name[stack.top()] == '<') {
40 open_angle_brackets--;
41 stack.pop();
44 break;
45 case '`':
46 stack.push(i);
48 break;
49 case '\'':
50 while (!stack.empty()) {
51 std::size_t top = stack.top();
52 if (name[top] == '<')
53 open_angle_brackets--;
55 stack.pop();
57 if (name[top] == '`')
58 break;
61 break;
62 case ':':
63 if (open_angle_brackets)
64 break;
65 if (i == 0 || name[i - 1] != ':')
66 break;
68 m_specifiers.emplace_back(name.take_front(i - 1),
69 name.slice(last_base_start, i - 1));
71 last_base_start = i + 1;
72 break;
73 default:
74 break;
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() : "";
95 return count;
98 llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
99 MSVCUndecoratedNameParser parser(name);
100 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
101 if (specs.empty())
102 return "";
104 return specs[specs.size() - 1].GetBaseName();