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 // 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 templates 29 // (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 IsMSVCUndecoratedName(llvm::StringRef name)81bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { 82 return name.contains('`'); 83 } 84 ExtractContextAndIdentifier(llvm::StringRef name,llvm::StringRef & context,llvm::StringRef & identifier)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 DropScope(llvm::StringRef name)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