brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 72afc6f Raw
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