106 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "MSVCUndecoratedNameParser.h"10 11#include <stack>12 13MSVCUndecoratedNameParser::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;19 }20 21 std::size_t last_base_start = 0;22 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 templates29 // (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;33 34 stack.push(i);35 open_angle_brackets++;36 37 break;38 case '>':39 if (!stack.empty() && name[stack.top()] == '<') {40 open_angle_brackets--;41 stack.pop();42 }43 44 break;45 case '`':46 stack.push(i);47 48 break;49 case '\'':50 while (!stack.empty()) {51 std::size_t top = stack.top();52 if (name[top] == '<')53 open_angle_brackets--;54 55 stack.pop();56 57 if (name[top] == '`')58 break;59 }60 61 break;62 case ':':63 if (open_angle_brackets)64 break;65 if (i == 0 || name[i - 1] != ':')66 break;67 68 m_specifiers.emplace_back(name.take_front(i - 1),69 name.slice(last_base_start, i - 1));70 71 last_base_start = i + 1;72 break;73 default:74 break;75 }76 }77 78 m_specifiers.emplace_back(name, name.drop_front(last_base_start));79}80 81bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {82 return name.contains('`');83}84 85bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(86 llvm::StringRef name, llvm::StringRef &context,87 llvm::StringRef &identifier) {88 MSVCUndecoratedNameParser parser(name);89 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();90 91 std::size_t count = specs.size();92 identifier = count > 0 ? specs[count - 1].GetBaseName() : "";93 context = count > 1 ? specs[count - 2].GetFullName() : "";94 95 return count;96}97 98llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {99 MSVCUndecoratedNameParser parser(name);100 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();101 if (specs.empty())102 return "";103 104 return specs[specs.size() - 1].GetBaseName();105}106