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 MSVCUndecoratedNameParser(llvm::StringRef name)14MSVCUndecoratedNameParser::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 break; 67 default: 68 break; 69 } 70 } 71 72 m_specifiers.emplace_back(name, name.drop_front(last_base_start)); 73 } 74 IsMSVCUndecoratedName(llvm::StringRef name)75bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { 76 return name.find('`') != llvm::StringRef::npos; 77 } 78 ExtractContextAndIdentifier(llvm::StringRef name,llvm::StringRef & context,llvm::StringRef & identifier)79bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier( 80 llvm::StringRef name, llvm::StringRef &context, 81 llvm::StringRef &identifier) { 82 MSVCUndecoratedNameParser parser(name); 83 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 84 85 std::size_t count = specs.size(); 86 identifier = count > 0 ? specs[count - 1].GetBaseName() : ""; 87 context = count > 1 ? specs[count - 2].GetFullName() : ""; 88 89 return count; 90 } 91 DropScope(llvm::StringRef name)92llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) { 93 MSVCUndecoratedNameParser parser(name); 94 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 95 if (specs.empty()) 96 return ""; 97 98 return specs[specs.size() - 1].GetBaseName(); 99 } 100