106 lines
2.8 KiB
C++
106 lines
2.8 KiB
C++
//===-- 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) {
|
|
// Global ctor and dtor are global functions.
|
|
if (name.contains("dynamic initializer for") ||
|
|
name.contains("dynamic atexit destructor for")) {
|
|
m_specifiers.emplace_back(name, name);
|
|
return;
|
|
}
|
|
|
|
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();
|
|
}
|