| //===-- 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.contains('`'); |
| } |
| |
| 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(); |
| } |