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) { 14c1e530eeSAleksandr Urakov std::size_t last_base_start = 0; 15c1e530eeSAleksandr Urakov 16c1e530eeSAleksandr Urakov std::stack<std::size_t> stack; 17c1e530eeSAleksandr Urakov unsigned int open_angle_brackets = 0; 18c1e530eeSAleksandr Urakov for (size_t i = 0; i < name.size(); i++) { 19c1e530eeSAleksandr Urakov switch (name[i]) { 20c1e530eeSAleksandr Urakov case '<': 21c1e530eeSAleksandr Urakov // Do not treat `operator<' and `operator<<' as templates 22c1e530eeSAleksandr Urakov // (sometimes they represented as `<' and `<<' in the name). 23c1e530eeSAleksandr Urakov if (i == last_base_start || 2498d9647dSBenjamin Kramer (i == last_base_start + 1 && name[last_base_start] == '<')) 25c1e530eeSAleksandr Urakov break; 26c1e530eeSAleksandr Urakov 27c1e530eeSAleksandr Urakov stack.push(i); 28c1e530eeSAleksandr Urakov open_angle_brackets++; 29c1e530eeSAleksandr Urakov 30c1e530eeSAleksandr Urakov break; 31c1e530eeSAleksandr Urakov case '>': 32c1e530eeSAleksandr Urakov if (!stack.empty() && name[stack.top()] == '<') { 33c1e530eeSAleksandr Urakov open_angle_brackets--; 34c1e530eeSAleksandr Urakov stack.pop(); 35c1e530eeSAleksandr Urakov } 36c1e530eeSAleksandr Urakov 37c1e530eeSAleksandr Urakov break; 38c1e530eeSAleksandr Urakov case '`': 39c1e530eeSAleksandr Urakov stack.push(i); 40c1e530eeSAleksandr Urakov 41c1e530eeSAleksandr Urakov break; 42c1e530eeSAleksandr Urakov case '\'': 43c1e530eeSAleksandr Urakov while (!stack.empty()) { 44c1e530eeSAleksandr Urakov std::size_t top = stack.top(); 45c1e530eeSAleksandr Urakov if (name[top] == '<') 46c1e530eeSAleksandr Urakov open_angle_brackets--; 47c1e530eeSAleksandr Urakov 48c1e530eeSAleksandr Urakov stack.pop(); 49c1e530eeSAleksandr Urakov 50c1e530eeSAleksandr Urakov if (name[top] == '`') 51c1e530eeSAleksandr Urakov break; 52c1e530eeSAleksandr Urakov } 53c1e530eeSAleksandr Urakov 54c1e530eeSAleksandr Urakov break; 55c1e530eeSAleksandr Urakov case ':': 56c1e530eeSAleksandr Urakov if (open_angle_brackets) 57c1e530eeSAleksandr Urakov break; 58c1e530eeSAleksandr Urakov if (i == 0 || name[i - 1] != ':') 59c1e530eeSAleksandr Urakov break; 60c1e530eeSAleksandr Urakov 61c1e530eeSAleksandr Urakov m_specifiers.emplace_back(name.take_front(i - 1), 62c1e530eeSAleksandr Urakov name.slice(last_base_start, i - 1)); 63c1e530eeSAleksandr Urakov 64c1e530eeSAleksandr Urakov last_base_start = i + 1; 65c7f57aa8SEric Christopher break; 66c1e530eeSAleksandr Urakov default: 67c1e530eeSAleksandr Urakov break; 68c1e530eeSAleksandr Urakov } 69c1e530eeSAleksandr Urakov } 70c1e530eeSAleksandr Urakov 71c1e530eeSAleksandr Urakov m_specifiers.emplace_back(name, name.drop_front(last_base_start)); 72c1e530eeSAleksandr Urakov } 73c1e530eeSAleksandr Urakov IsMSVCUndecoratedName(llvm::StringRef name)74c1e530eeSAleksandr Urakovbool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { 75*4ba9d9c8SKazu Hirata return name.contains('`'); 76c1e530eeSAleksandr Urakov } 77c1e530eeSAleksandr Urakov ExtractContextAndIdentifier(llvm::StringRef name,llvm::StringRef & context,llvm::StringRef & identifier)78c1e530eeSAleksandr Urakovbool MSVCUndecoratedNameParser::ExtractContextAndIdentifier( 79c1e530eeSAleksandr Urakov llvm::StringRef name, llvm::StringRef &context, 80c1e530eeSAleksandr Urakov llvm::StringRef &identifier) { 81c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser parser(name); 82c1e530eeSAleksandr Urakov llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 83c1e530eeSAleksandr Urakov 84c1e530eeSAleksandr Urakov std::size_t count = specs.size(); 85c1e530eeSAleksandr Urakov identifier = count > 0 ? specs[count - 1].GetBaseName() : ""; 86c1e530eeSAleksandr Urakov context = count > 1 ? specs[count - 2].GetFullName() : ""; 87c1e530eeSAleksandr Urakov 88c1e530eeSAleksandr Urakov return count; 89c1e530eeSAleksandr Urakov } 90c1e530eeSAleksandr Urakov DropScope(llvm::StringRef name)91c1e530eeSAleksandr Urakovllvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) { 92c1e530eeSAleksandr Urakov MSVCUndecoratedNameParser parser(name); 93c1e530eeSAleksandr Urakov llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 94c1e530eeSAleksandr Urakov if (specs.empty()) 95c1e530eeSAleksandr Urakov return ""; 96c1e530eeSAleksandr Urakov 97c1e530eeSAleksandr Urakov return specs[specs.size() - 1].GetBaseName(); 98c1e530eeSAleksandr Urakov } 99