1 //===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MSVCUndecoratedNameParser.h" 11 12 #include <stack> 13 14 MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) { 15 std::size_t last_base_start = 0; 16 17 std::stack<std::size_t> stack; 18 unsigned int open_angle_brackets = 0; 19 for (size_t i = 0; i < name.size(); i++) { 20 switch (name[i]) { 21 case '<': 22 // Do not treat `operator<' and `operator<<' as templates 23 // (sometimes they represented as `<' and `<<' in the name). 24 if (i == last_base_start || 25 (i == last_base_start + 1 && name[last_base_start] == '<')) 26 break; 27 28 stack.push(i); 29 open_angle_brackets++; 30 31 break; 32 case '>': 33 if (!stack.empty() && name[stack.top()] == '<') { 34 open_angle_brackets--; 35 stack.pop(); 36 } 37 38 break; 39 case '`': 40 stack.push(i); 41 42 break; 43 case '\'': 44 while (!stack.empty()) { 45 std::size_t top = stack.top(); 46 if (name[top] == '<') 47 open_angle_brackets--; 48 49 stack.pop(); 50 51 if (name[top] == '`') 52 break; 53 } 54 55 break; 56 case ':': 57 if (open_angle_brackets) 58 break; 59 if (i == 0 || name[i - 1] != ':') 60 break; 61 62 m_specifiers.emplace_back(name.take_front(i - 1), 63 name.slice(last_base_start, i - 1)); 64 65 last_base_start = i + 1; 66 default: 67 break; 68 } 69 } 70 71 m_specifiers.emplace_back(name, name.drop_front(last_base_start)); 72 } 73 74 bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { 75 return name.find('`') != llvm::StringRef::npos; 76 } 77 78 bool 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 91 llvm::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