180814287SRaphael Isemann //===-- MSVCUndecoratedNameParser.cpp -------------------------------------===// 2c1e530eeSAleksandr Urakov // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c1e530eeSAleksandr Urakov // 7c1e530eeSAleksandr Urakov //===----------------------------------------------------------------------===// 8c1e530eeSAleksandr Urakov 9c1e530eeSAleksandr Urakov #include "MSVCUndecoratedNameParser.h" 10c1e530eeSAleksandr Urakov 11c1e530eeSAleksandr Urakov #include <stack> 12c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser(llvm::StringRef name)13c1e530eeSAleksandr UrakovMSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) { 14*8704281cSZequan Wu // Global ctor and dtor are global functions. 15*8704281cSZequan Wu if (name.contains("dynamic initializer for") || 16*8704281cSZequan Wu name.contains("dynamic atexit destructor for")) { 17*8704281cSZequan Wu m_specifiers.emplace_back(name, name); 18*8704281cSZequan Wu return; 19*8704281cSZequan Wu } 20*8704281cSZequan Wu 21c1e530eeSAleksandr Urakov std::size_t last_base_start = 0; 22c1e530eeSAleksandr Urakov 23c1e530eeSAleksandr Urakov std::stack<std::size_t> stack; 24c1e530eeSAleksandr Urakov unsigned int open_angle_brackets = 0; 25c1e530eeSAleksandr Urakov for (size_t i = 0; i < name.size(); i++) { 26c1e530eeSAleksandr Urakov switch (name[i]) { 27c1e530eeSAleksandr Urakov case '<': 28c1e530eeSAleksandr Urakov // Do not treat `operator<' and `operator<<' as templates 29c1e530eeSAleksandr Urakov // (sometimes they represented as `<' and `<<' in the name). 30c1e530eeSAleksandr Urakov if (i == last_base_start || 3198d9647dSBenjamin Kramer (i == last_base_start + 1 && name[last_base_start] == '<')) 32c1e530eeSAleksandr Urakov break; 33c1e530eeSAleksandr Urakov 34c1e530eeSAleksandr Urakov stack.push(i); 35c1e530eeSAleksandr Urakov open_angle_brackets++; 36c1e530eeSAleksandr Urakov 37c1e530eeSAleksandr Urakov break; 38c1e530eeSAleksandr Urakov case '>': 39c1e530eeSAleksandr Urakov if (!stack.empty() && name[stack.top()] == '<') { 40c1e530eeSAleksandr Urakov open_angle_brackets--; 41c1e530eeSAleksandr Urakov stack.pop(); 42c1e530eeSAleksandr Urakov } 43c1e530eeSAleksandr Urakov 44c1e530eeSAleksandr Urakov break; 45c1e530eeSAleksandr Urakov case '`': 46c1e530eeSAleksandr Urakov stack.push(i); 47c1e530eeSAleksandr Urakov 48c1e530eeSAleksandr Urakov break; 49c1e530eeSAleksandr Urakov case '\'': 50c1e530eeSAleksandr Urakov while (!stack.empty()) { 51c1e530eeSAleksandr Urakov std::size_t top = stack.top(); 52c1e530eeSAleksandr Urakov if (name[top] == '<') 53c1e530eeSAleksandr Urakov open_angle_brackets--; 54c1e530eeSAleksandr Urakov 55c1e530eeSAleksandr Urakov stack.pop(); 56c1e530eeSAleksandr Urakov 57c1e530eeSAleksandr Urakov if (name[top] == '`') 58c1e530eeSAleksandr Urakov break; 59c1e530eeSAleksandr Urakov } 60c1e530eeSAleksandr Urakov 61c1e530eeSAleksandr Urakov break; 62c1e530eeSAleksandr Urakov case ':': 63c1e530eeSAleksandr Urakov if (open_angle_brackets) 64c1e530eeSAleksandr Urakov break; 65c1e530eeSAleksandr Urakov if (i == 0 || name[i - 1] != ':') 66c1e530eeSAleksandr Urakov break; 67c1e530eeSAleksandr Urakov 68c1e530eeSAleksandr Urakov m_specifiers.emplace_back(name.take_front(i - 1), 69c1e530eeSAleksandr Urakov name.slice(last_base_start, i - 1)); 70c1e530eeSAleksandr Urakov 71c1e530eeSAleksandr Urakov last_base_start = i + 1; 72c7f57aa8SEric Christopher break; 73c1e530eeSAleksandr Urakov default: 74c1e530eeSAleksandr Urakov break; 75c1e530eeSAleksandr Urakov } 76c1e530eeSAleksandr Urakov } 77c1e530eeSAleksandr Urakov 78c1e530eeSAleksandr Urakov m_specifiers.emplace_back(name, name.drop_front(last_base_start)); 79c1e530eeSAleksandr Urakov } 80c1e530eeSAleksandr Urakov IsMSVCUndecoratedName(llvm::StringRef name)81c1e530eeSAleksandr Urakovbool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { 824ba9d9c8SKazu Hirata return name.contains('`'); 83c1e530eeSAleksandr Urakov } 84c1e530eeSAleksandr Urakov ExtractContextAndIdentifier(llvm::StringRef name,llvm::StringRef & context,llvm::StringRef & identifier)85c1e530eeSAleksandr Urakovbool MSVCUndecoratedNameParser::ExtractContextAndIdentifier( 86c1e530eeSAleksandr Urakov llvm::StringRef name, llvm::StringRef &context, 87c1e530eeSAleksandr Urakov llvm::StringRef &identifier) { 88c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser parser(name); 89c1e530eeSAleksandr Urakov llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 90c1e530eeSAleksandr Urakov 91c1e530eeSAleksandr Urakov std::size_t count = specs.size(); 92c1e530eeSAleksandr Urakov identifier = count > 0 ? specs[count - 1].GetBaseName() : ""; 93c1e530eeSAleksandr Urakov context = count > 1 ? specs[count - 2].GetFullName() : ""; 94c1e530eeSAleksandr Urakov 95c1e530eeSAleksandr Urakov return count; 96c1e530eeSAleksandr Urakov } 97c1e530eeSAleksandr Urakov DropScope(llvm::StringRef name)98c1e530eeSAleksandr Urakovllvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) { 99c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser parser(name); 100c1e530eeSAleksandr Urakov llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 101c1e530eeSAleksandr Urakov if (specs.empty()) 102c1e530eeSAleksandr Urakov return ""; 103c1e530eeSAleksandr Urakov 104c1e530eeSAleksandr Urakov return specs[specs.size() - 1].GetBaseName(); 105c1e530eeSAleksandr Urakov } 106