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