1254721Semaste//===-- Mangled.cpp ---------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste 11254721Semaste// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h 12254721Semaste#include <cstddef> 13263367Semaste#if defined(_MSC_VER) 14263367Semaste// Cannot enable the builtin demangler on msvc as it does not support the cpp11 within the implementation. 15263367Semaste#elif defined (__FreeBSD__) 16263363Semaste#define LLDB_USE_BUILTIN_DEMANGLER 17263363Semaste#else 18254721Semaste#include <cxxabi.h> 19263363Semaste#endif 20254721Semaste 21263363Semaste#ifdef LLDB_USE_BUILTIN_DEMANGLER 22254721Semaste 23263363Semaste//---------------------------------------------------------------------- 24263363Semaste// Inlined copy of: 25263363Semaste// http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp 26269024Semaste// revision 199944. 27263363Semaste// 28263363Semaste// Changes include: 29263363Semaste// - remove the "__cxxabiv1" namespace 30263363Semaste// - stripped GCC attributes() 31263363Semaste// - removed extern "C" from the cxa_demangle function 32263363Semaste// - Changed the scope of the unnamed namespace to include cxa_demangle 33263363Semaste// function. 34269024Semaste// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning 35263363Semaste//---------------------------------------------------------------------- 36263363Semaste 37269024Semaste#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below 38269024Semaste 39269024Semaste//===-------------------------- cxa_demangle.cpp --------------------------===// 40269024Semaste// 41269024Semaste// The LLVM Compiler Infrastructure 42269024Semaste// 43269024Semaste// This file is dual licensed under the MIT and the University of Illinois Open 44269024Semaste// Source Licenses. See LICENSE.TXT for details. 45269024Semaste// 46269024Semaste//===----------------------------------------------------------------------===// 47269024Semaste 48269024Semaste#define _LIBCPP_EXTERN_TEMPLATE(...) 49269024Semaste#define _LIBCPP_NO_EXCEPTIONS 50269024Semaste 51269024Semaste#include <vector> 52269024Semaste#include <algorithm> 53269024Semaste#include <string> 54269024Semaste#include <numeric> 55269024Semaste#include <cstdlib> 56269024Semaste#include <cstring> 57269024Semaste#include <cctype> 58269024Semaste 59269024Semaste 60263363Semastenamespace 61263363Semaste{ 62263363Semaste 63263363Semasteenum 64263363Semaste{ 65263363Semaste unknown_error = -4, 66263363Semaste invalid_args = -3, 67263363Semaste invalid_mangled_name, 68263363Semaste memory_alloc_failure, 69263363Semaste success 70263363Semaste}; 71263363Semaste 72263363Semastetemplate <class C> 73263363Semaste const char* parse_type(const char* first, const char* last, C& db); 74263363Semastetemplate <class C> 75263363Semaste const char* parse_encoding(const char* first, const char* last, C& db); 76263363Semastetemplate <class C> 77263363Semaste const char* parse_name(const char* first, const char* last, C& db); 78263363Semastetemplate <class C> 79263363Semaste const char* parse_expression(const char* first, const char* last, C& db); 80263363Semastetemplate <class C> 81263363Semaste const char* parse_template_args(const char* first, const char* last, C& db); 82263363Semastetemplate <class C> 83263363Semaste const char* parse_operator_name(const char* first, const char* last, C& db); 84263363Semastetemplate <class C> 85263363Semaste const char* parse_unqualified_name(const char* first, const char* last, C& db); 86263363Semastetemplate <class C> 87263363Semaste const char* parse_decltype(const char* first, const char* last, C& db); 88263363Semaste 89263363Semastetemplate <class C> 90263363Semastevoid 91263363Semasteprint_stack(const C& db) 92263363Semaste{ 93263363Semaste printf("---------\n"); 94263363Semaste printf("names:\n"); 95263363Semaste for (auto& s : db.names) 96263363Semaste printf("{%s#%s}\n", s.first.c_str(), s.second.c_str()); 97263363Semaste int i = -1; 98263363Semaste printf("subs:\n"); 99263363Semaste for (auto& v : db.subs) 100263363Semaste { 101263363Semaste if (i >= 0) 102263363Semaste printf("S%i_ = {", i); 103263363Semaste else 104263363Semaste printf("S_ = {"); 105263363Semaste for (auto& s : v) 106263363Semaste printf("{%s#%s}", s.first.c_str(), s.second.c_str()); 107263363Semaste printf("}\n"); 108263363Semaste ++i; 109263363Semaste } 110263363Semaste printf("template_param:\n"); 111263363Semaste for (auto& t : db.template_param) 112263363Semaste { 113263363Semaste printf("--\n"); 114263363Semaste i = -1; 115263363Semaste for (auto& v : t) 116263363Semaste { 117263363Semaste if (i >= 0) 118263363Semaste printf("T%i_ = {", i); 119263363Semaste else 120263363Semaste printf("T_ = {"); 121263363Semaste for (auto& s : v) 122263363Semaste printf("{%s#%s}", s.first.c_str(), s.second.c_str()); 123263363Semaste printf("}\n"); 124263363Semaste ++i; 125263363Semaste } 126263363Semaste } 127263363Semaste printf("---------\n\n"); 128263363Semaste} 129263363Semaste 130263363Semastetemplate <class C> 131263363Semastevoid 132263363Semasteprint_state(const char* msg, const char* first, const char* last, const C& db) 133263363Semaste{ 134263363Semaste printf("%s: ", msg); 135263363Semaste for (; first != last; ++first) 136263363Semaste printf("%c", *first); 137263363Semaste printf("\n"); 138263363Semaste print_stack(db); 139263363Semaste} 140263363Semaste 141263363Semaste// <number> ::= [n] <non-negative decimal integer> 142263363Semaste 143263363Semasteconst char* 144263363Semasteparse_number(const char* first, const char* last) 145263363Semaste{ 146263363Semaste if (first != last) 147263363Semaste { 148263363Semaste const char* t = first; 149263363Semaste if (*t == 'n') 150263363Semaste ++t; 151263363Semaste if (t != last) 152263363Semaste { 153263363Semaste if (*t == '0') 154263363Semaste { 155263363Semaste first = t+1; 156263363Semaste } 157263363Semaste else if ('1' <= *t && *t <= '9') 158263363Semaste { 159263363Semaste first = t+1; 160263363Semaste while (first != last && std::isdigit(*first)) 161263363Semaste ++first; 162263363Semaste } 163263363Semaste } 164263363Semaste } 165263363Semaste return first; 166263363Semaste} 167263363Semaste 168263363Semastetemplate <class Float> 169263363Semastestruct float_data; 170263363Semaste 171263363Semastetemplate <> 172263363Semastestruct float_data<float> 173263363Semaste{ 174263363Semaste static const size_t mangled_size = 8; 175263363Semaste static const size_t max_demangled_size = 24; 176263363Semaste static constexpr const char* spec = "%af"; 177263363Semaste}; 178263363Semaste 179263363Semasteconstexpr const char* float_data<float>::spec; 180263363Semaste 181263363Semastetemplate <> 182263363Semastestruct float_data<double> 183263363Semaste{ 184263363Semaste static const size_t mangled_size = 16; 185263363Semaste static const size_t max_demangled_size = 32; 186263363Semaste static constexpr const char* spec = "%a"; 187263363Semaste}; 188263363Semaste 189263363Semasteconstexpr const char* float_data<double>::spec; 190263363Semaste 191263363Semastetemplate <> 192263363Semastestruct float_data<long double> 193263363Semaste{ 194263363Semaste static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms 195263363Semaste static const size_t max_demangled_size = 40; 196263363Semaste static constexpr const char* spec = "%LaL"; 197263363Semaste}; 198263363Semaste 199263363Semasteconstexpr const char* float_data<long double>::spec; 200263363Semaste 201263363Semastetemplate <class Float, class C> 202263363Semasteconst char* 203263363Semasteparse_floating_number(const char* first, const char* last, C& db) 204263363Semaste{ 205263363Semaste const size_t N = float_data<Float>::mangled_size; 206263363Semaste if (static_cast<std::size_t>(last - first) > N) 207263363Semaste { 208263363Semaste last = first + N; 209263363Semaste union 210263363Semaste { 211263363Semaste Float value; 212263363Semaste char buf[sizeof(Float)]; 213263363Semaste }; 214263363Semaste const char* t = first; 215263363Semaste char* e = buf; 216263363Semaste for (; t != last; ++t, ++e) 217263363Semaste { 218263363Semaste if (!isxdigit(*t)) 219263363Semaste return first; 220263363Semaste unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') : 221263363Semaste static_cast<unsigned>(*t - 'a' + 10); 222263363Semaste ++t; 223263363Semaste unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') : 224263363Semaste static_cast<unsigned>(*t - 'a' + 10); 225263363Semaste *e = static_cast<char>((d1 << 4) + d0); 226263363Semaste } 227263363Semaste if (*t == 'E') 228263363Semaste { 229263363Semaste#if __LITTLE_ENDIAN__ 230263363Semaste std::reverse(buf, e); 231263363Semaste#endif 232263363Semaste char num[float_data<Float>::max_demangled_size] = {0}; 233263363Semaste int n = snprintf(num, sizeof(num), float_data<Float>::spec, value); 234263363Semaste if (static_cast<std::size_t>(n) >= sizeof(num)) 235263363Semaste return first; 236263363Semaste db.names.push_back(typename C::String(num, static_cast<std::size_t>(n))); 237263363Semaste first = t+1; 238263363Semaste } 239263363Semaste } 240263363Semaste return first; 241263363Semaste} 242263363Semaste 243263363Semaste// <source-name> ::= <positive length number> <identifier> 244263363Semaste 245263363Semastetemplate <class C> 246263363Semasteconst char* 247263363Semasteparse_source_name(const char* first, const char* last, C& db) 248263363Semaste{ 249263363Semaste if (first != last) 250263363Semaste { 251263363Semaste char c = *first; 252263363Semaste if (isdigit(c) && first+1 != last) 253263363Semaste { 254263363Semaste const char* t = first+1; 255263363Semaste size_t n = static_cast<size_t>(c - '0'); 256263363Semaste for (c = *t; isdigit(c); c = *t) 257263363Semaste { 258263363Semaste n = n * 10 + static_cast<size_t>(c - '0'); 259263363Semaste if (++t == last) 260263363Semaste return first; 261263363Semaste } 262263363Semaste if (static_cast<size_t>(last - t) >= n) 263263363Semaste { 264263363Semaste typename C::String r(t, n); 265263363Semaste if (r.substr(0, 10) == "_GLOBAL__N") 266263363Semaste db.names.push_back("(anonymous namespace)"); 267263363Semaste else 268263363Semaste db.names.push_back(std::move(r)); 269263363Semaste first = t + n; 270263363Semaste } 271263363Semaste } 272263363Semaste } 273263363Semaste return first; 274263363Semaste} 275263363Semaste 276263363Semaste// <substitution> ::= S <seq-id> _ 277263363Semaste// ::= S_ 278263363Semaste// <substitution> ::= Sa # ::std::allocator 279263363Semaste// <substitution> ::= Sb # ::std::basic_string 280263363Semaste// <substitution> ::= Ss # ::std::basic_string < char, 281263363Semaste// ::std::char_traits<char>, 282263363Semaste// ::std::allocator<char> > 283263363Semaste// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > 284263363Semaste// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > 285263363Semaste// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > 286263363Semaste 287263363Semastetemplate <class C> 288263363Semasteconst char* 289263363Semasteparse_substitution(const char* first, const char* last, C& db) 290263363Semaste{ 291263363Semaste if (last - first >= 2) 292263363Semaste { 293263363Semaste if (*first == 'S') 294263363Semaste { 295263363Semaste switch (first[1]) 296263363Semaste { 297263363Semaste case 'a': 298263363Semaste db.names.push_back("std::allocator"); 299263363Semaste first += 2; 300263363Semaste break; 301263363Semaste case 'b': 302263363Semaste db.names.push_back("std::basic_string"); 303263363Semaste first += 2; 304263363Semaste break; 305263363Semaste case 's': 306263363Semaste db.names.push_back("std::string"); 307263363Semaste first += 2; 308263363Semaste break; 309263363Semaste case 'i': 310263363Semaste db.names.push_back("std::istream"); 311263363Semaste first += 2; 312263363Semaste break; 313263363Semaste case 'o': 314263363Semaste db.names.push_back("std::ostream"); 315263363Semaste first += 2; 316263363Semaste break; 317263363Semaste case 'd': 318263363Semaste db.names.push_back("std::iostream"); 319263363Semaste first += 2; 320263363Semaste break; 321263363Semaste case '_': 322263363Semaste if (!db.subs.empty()) 323263363Semaste { 324263363Semaste for (const auto& n : db.subs.front()) 325263363Semaste db.names.push_back(n); 326263363Semaste first += 2; 327263363Semaste } 328263363Semaste break; 329263363Semaste default: 330263363Semaste if (std::isdigit(first[1]) || std::isupper(first[1])) 331263363Semaste { 332263363Semaste size_t sub = 0; 333263363Semaste const char* t = first+1; 334263363Semaste if (std::isdigit(*t)) 335263363Semaste sub = static_cast<size_t>(*t - '0'); 336263363Semaste else 337263363Semaste sub = static_cast<size_t>(*t - 'A') + 10; 338263363Semaste for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t) 339263363Semaste { 340263363Semaste sub *= 36; 341263363Semaste if (std::isdigit(*t)) 342263363Semaste sub += static_cast<size_t>(*t - '0'); 343263363Semaste else 344263363Semaste sub += static_cast<size_t>(*t - 'A') + 10; 345263363Semaste } 346263363Semaste if (t == last || *t != '_') 347263363Semaste return first; 348263363Semaste ++sub; 349263363Semaste if (sub < db.subs.size()) 350263363Semaste { 351263363Semaste for (const auto& n : db.subs[sub]) 352263363Semaste db.names.push_back(n); 353263363Semaste first = t+1; 354263363Semaste } 355263363Semaste } 356263363Semaste break; 357263363Semaste } 358263363Semaste } 359263363Semaste } 360263363Semaste return first; 361263363Semaste} 362263363Semaste 363263363Semaste// <builtin-type> ::= v # void 364263363Semaste// ::= w # wchar_t 365263363Semaste// ::= b # bool 366263363Semaste// ::= c # char 367263363Semaste// ::= a # signed char 368263363Semaste// ::= h # unsigned char 369263363Semaste// ::= s # short 370263363Semaste// ::= t # unsigned short 371263363Semaste// ::= i # int 372263363Semaste// ::= j # unsigned int 373263363Semaste// ::= l # long 374263363Semaste// ::= m # unsigned long 375263363Semaste// ::= x # long long, __int64 376263363Semaste// ::= y # unsigned long long, __int64 377263363Semaste// ::= n # __int128 378263363Semaste// ::= o # unsigned __int128 379263363Semaste// ::= f # float 380263363Semaste// ::= d # double 381263363Semaste// ::= e # long double, __float80 382263363Semaste// ::= g # __float128 383263363Semaste// ::= z # ellipsis 384263363Semaste// ::= Dd # IEEE 754r decimal floating point (64 bits) 385263363Semaste// ::= De # IEEE 754r decimal floating point (128 bits) 386263363Semaste// ::= Df # IEEE 754r decimal floating point (32 bits) 387263363Semaste// ::= Dh # IEEE 754r half-precision floating point (16 bits) 388263363Semaste// ::= Di # char32_t 389263363Semaste// ::= Ds # char16_t 390263363Semaste// ::= Da # auto (in dependent new-expressions) 391263363Semaste// ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) 392263363Semaste// ::= u <source-name> # vendor extended type 393263363Semaste 394263363Semastetemplate <class C> 395263363Semasteconst char* 396263363Semasteparse_builtin_type(const char* first, const char* last, C& db) 397263363Semaste{ 398263363Semaste if (first != last) 399263363Semaste { 400263363Semaste switch (*first) 401263363Semaste { 402263363Semaste case 'v': 403263363Semaste db.names.push_back("void"); 404263363Semaste ++first; 405263363Semaste break; 406263363Semaste case 'w': 407263363Semaste db.names.push_back("wchar_t"); 408263363Semaste ++first; 409263363Semaste break; 410263363Semaste case 'b': 411263363Semaste db.names.push_back("bool"); 412263363Semaste ++first; 413263363Semaste break; 414263363Semaste case 'c': 415263363Semaste db.names.push_back("char"); 416263363Semaste ++first; 417263363Semaste break; 418263363Semaste case 'a': 419263363Semaste db.names.push_back("signed char"); 420263363Semaste ++first; 421263363Semaste break; 422263363Semaste case 'h': 423263363Semaste db.names.push_back("unsigned char"); 424263363Semaste ++first; 425263363Semaste break; 426263363Semaste case 's': 427263363Semaste db.names.push_back("short"); 428263363Semaste ++first; 429263363Semaste break; 430263363Semaste case 't': 431263363Semaste db.names.push_back("unsigned short"); 432263363Semaste ++first; 433263363Semaste break; 434263363Semaste case 'i': 435263363Semaste db.names.push_back("int"); 436263363Semaste ++first; 437263363Semaste break; 438263363Semaste case 'j': 439263363Semaste db.names.push_back("unsigned int"); 440263363Semaste ++first; 441263363Semaste break; 442263363Semaste case 'l': 443263363Semaste db.names.push_back("long"); 444263363Semaste ++first; 445263363Semaste break; 446263363Semaste case 'm': 447263363Semaste db.names.push_back("unsigned long"); 448263363Semaste ++first; 449263363Semaste break; 450263363Semaste case 'x': 451263363Semaste db.names.push_back("long long"); 452263363Semaste ++first; 453263363Semaste break; 454263363Semaste case 'y': 455263363Semaste db.names.push_back("unsigned long long"); 456263363Semaste ++first; 457263363Semaste break; 458263363Semaste case 'n': 459263363Semaste db.names.push_back("__int128"); 460263363Semaste ++first; 461263363Semaste break; 462263363Semaste case 'o': 463263363Semaste db.names.push_back("unsigned __int128"); 464263363Semaste ++first; 465263363Semaste break; 466263363Semaste case 'f': 467263363Semaste db.names.push_back("float"); 468263363Semaste ++first; 469263363Semaste break; 470263363Semaste case 'd': 471263363Semaste db.names.push_back("double"); 472263363Semaste ++first; 473263363Semaste break; 474263363Semaste case 'e': 475263363Semaste db.names.push_back("long double"); 476263363Semaste ++first; 477263363Semaste break; 478263363Semaste case 'g': 479263363Semaste db.names.push_back("__float128"); 480263363Semaste ++first; 481263363Semaste break; 482263363Semaste case 'z': 483263363Semaste db.names.push_back("..."); 484263363Semaste ++first; 485263363Semaste break; 486263363Semaste case 'u': 487263363Semaste { 488263363Semaste const char*t = parse_source_name(first+1, last, db); 489263363Semaste if (t != first+1) 490263363Semaste first = t; 491263363Semaste } 492263363Semaste break; 493263363Semaste case 'D': 494263363Semaste if (first+1 != last) 495263363Semaste { 496263363Semaste switch (first[1]) 497263363Semaste { 498263363Semaste case 'd': 499263363Semaste db.names.push_back("decimal64"); 500263363Semaste first += 2; 501263363Semaste break; 502263363Semaste case 'e': 503263363Semaste db.names.push_back("decimal128"); 504263363Semaste first += 2; 505263363Semaste break; 506263363Semaste case 'f': 507263363Semaste db.names.push_back("decimal32"); 508263363Semaste first += 2; 509263363Semaste break; 510263363Semaste case 'h': 511263363Semaste db.names.push_back("decimal16"); 512263363Semaste first += 2; 513263363Semaste break; 514263363Semaste case 'i': 515263363Semaste db.names.push_back("char32_t"); 516263363Semaste first += 2; 517263363Semaste break; 518263363Semaste case 's': 519263363Semaste db.names.push_back("char16_t"); 520263363Semaste first += 2; 521263363Semaste break; 522263363Semaste case 'a': 523263363Semaste db.names.push_back("auto"); 524263363Semaste first += 2; 525263363Semaste break; 526263363Semaste case 'n': 527263363Semaste db.names.push_back("std::nullptr_t"); 528263363Semaste first += 2; 529263363Semaste break; 530263363Semaste } 531263363Semaste } 532263363Semaste break; 533263363Semaste } 534263363Semaste } 535263363Semaste return first; 536263363Semaste} 537263363Semaste 538263363Semaste// <CV-qualifiers> ::= [r] [V] [K] 539263363Semaste 540263363Semasteconst char* 541263363Semasteparse_cv_qualifiers(const char* first, const char* last, unsigned& cv) 542263363Semaste{ 543263363Semaste cv = 0; 544263363Semaste if (first != last) 545263363Semaste { 546263363Semaste if (*first == 'r') 547263363Semaste { 548263363Semaste cv |= 4; 549263363Semaste ++first; 550263363Semaste } 551263363Semaste if (*first == 'V') 552263363Semaste { 553263363Semaste cv |= 2; 554263363Semaste ++first; 555263363Semaste } 556263363Semaste if (*first == 'K') 557263363Semaste { 558263363Semaste cv |= 1; 559263363Semaste ++first; 560263363Semaste } 561263363Semaste } 562263363Semaste return first; 563263363Semaste} 564263363Semaste 565263363Semaste// <template-param> ::= T_ # first template parameter 566263363Semaste// ::= T <parameter-2 non-negative number> _ 567263363Semaste 568263363Semastetemplate <class C> 569263363Semasteconst char* 570263363Semasteparse_template_param(const char* first, const char* last, C& db) 571263363Semaste{ 572263363Semaste if (last - first >= 2) 573263363Semaste { 574263363Semaste if (*first == 'T') 575263363Semaste { 576263363Semaste if (first[1] == '_') 577263363Semaste { 578269024Semaste if (db.template_param.empty()) 579269024Semaste return first; 580263363Semaste if (!db.template_param.back().empty()) 581263363Semaste { 582263363Semaste for (auto& t : db.template_param.back().front()) 583263363Semaste db.names.push_back(t); 584263363Semaste first += 2; 585263363Semaste } 586263363Semaste else 587263363Semaste { 588263363Semaste db.names.push_back("T_"); 589263363Semaste first += 2; 590263363Semaste db.fix_forward_references = true; 591263363Semaste } 592263363Semaste } 593263363Semaste else if (isdigit(first[1])) 594263363Semaste { 595263363Semaste const char* t = first+1; 596263363Semaste size_t sub = static_cast<size_t>(*t - '0'); 597263363Semaste for (++t; t != last && isdigit(*t); ++t) 598263363Semaste { 599263363Semaste sub *= 10; 600263363Semaste sub += static_cast<size_t>(*t - '0'); 601263363Semaste } 602269024Semaste if (t == last || *t != '_' || db.template_param.empty()) 603263363Semaste return first; 604263363Semaste ++sub; 605263363Semaste if (sub < db.template_param.back().size()) 606263363Semaste { 607263363Semaste for (auto& temp : db.template_param.back()[sub]) 608263363Semaste db.names.push_back(temp); 609263363Semaste first = t+1; 610263363Semaste } 611263363Semaste else 612263363Semaste { 613263363Semaste db.names.push_back(typename C::String(first, t+1)); 614263363Semaste first = t+1; 615263363Semaste db.fix_forward_references = true; 616263363Semaste } 617263363Semaste } 618263363Semaste } 619263363Semaste } 620263363Semaste return first; 621263363Semaste} 622263363Semaste 623263363Semaste// cc <type> <expression> # const_cast<type> (expression) 624263363Semaste 625263363Semastetemplate <class C> 626263363Semasteconst char* 627263363Semasteparse_const_cast_expr(const char* first, const char* last, C& db) 628263363Semaste{ 629263363Semaste if (last - first >= 3 && first[0] == 'c' && first[1] == 'c') 630263363Semaste { 631263363Semaste const char* t = parse_type(first+2, last, db); 632263363Semaste if (t != first+2) 633263363Semaste { 634263363Semaste const char* t1 = parse_expression(t, last, db); 635263363Semaste if (t1 != t) 636263363Semaste { 637269024Semaste if (db.names.size() < 2) 638269024Semaste return first; 639263363Semaste auto expr = db.names.back().move_full(); 640263363Semaste db.names.pop_back(); 641263363Semaste db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")"; 642263363Semaste first = t1; 643263363Semaste } 644263363Semaste } 645263363Semaste } 646263363Semaste return first; 647263363Semaste} 648263363Semaste 649263363Semaste// dc <type> <expression> # dynamic_cast<type> (expression) 650263363Semaste 651263363Semastetemplate <class C> 652263363Semasteconst char* 653263363Semasteparse_dynamic_cast_expr(const char* first, const char* last, C& db) 654263363Semaste{ 655263363Semaste if (last - first >= 3 && first[0] == 'd' && first[1] == 'c') 656263363Semaste { 657263363Semaste const char* t = parse_type(first+2, last, db); 658263363Semaste if (t != first+2) 659263363Semaste { 660263363Semaste const char* t1 = parse_expression(t, last, db); 661263363Semaste if (t1 != t) 662263363Semaste { 663269024Semaste if (db.names.size() < 2) 664269024Semaste return first; 665263363Semaste auto expr = db.names.back().move_full(); 666263363Semaste db.names.pop_back(); 667263363Semaste db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")"; 668263363Semaste first = t1; 669263363Semaste } 670263363Semaste } 671263363Semaste } 672263363Semaste return first; 673263363Semaste} 674263363Semaste 675263363Semaste// rc <type> <expression> # reinterpret_cast<type> (expression) 676263363Semaste 677263363Semastetemplate <class C> 678263363Semasteconst char* 679263363Semasteparse_reinterpret_cast_expr(const char* first, const char* last, C& db) 680263363Semaste{ 681263363Semaste if (last - first >= 3 && first[0] == 'r' && first[1] == 'c') 682263363Semaste { 683263363Semaste const char* t = parse_type(first+2, last, db); 684263363Semaste if (t != first+2) 685263363Semaste { 686263363Semaste const char* t1 = parse_expression(t, last, db); 687263363Semaste if (t1 != t) 688263363Semaste { 689269024Semaste if (db.names.size() < 2) 690269024Semaste return first; 691263363Semaste auto expr = db.names.back().move_full(); 692263363Semaste db.names.pop_back(); 693263363Semaste db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")"; 694263363Semaste first = t1; 695263363Semaste } 696263363Semaste } 697263363Semaste } 698263363Semaste return first; 699263363Semaste} 700263363Semaste 701263363Semaste// sc <type> <expression> # static_cast<type> (expression) 702263363Semaste 703263363Semastetemplate <class C> 704263363Semasteconst char* 705263363Semasteparse_static_cast_expr(const char* first, const char* last, C& db) 706263363Semaste{ 707263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 'c') 708263363Semaste { 709263363Semaste const char* t = parse_type(first+2, last, db); 710263363Semaste if (t != first+2) 711263363Semaste { 712263363Semaste const char* t1 = parse_expression(t, last, db); 713263363Semaste if (t1 != t) 714263363Semaste { 715269024Semaste if (db.names.size() < 2) 716269024Semaste return first; 717263363Semaste auto expr = db.names.back().move_full(); 718263363Semaste db.names.pop_back(); 719263363Semaste db.names.back() = "static_cast<" + db.names.back().move_full() + ">(" + expr + ")"; 720263363Semaste first = t1; 721263363Semaste } 722263363Semaste } 723263363Semaste } 724263363Semaste return first; 725263363Semaste} 726263363Semaste 727263363Semaste// sp <expression> # pack expansion 728263363Semaste 729263363Semastetemplate <class C> 730263363Semasteconst char* 731263363Semasteparse_pack_expansion(const char* first, const char* last, C& db) 732263363Semaste{ 733263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 'p') 734263363Semaste { 735263363Semaste const char* t = parse_expression(first+2, last, db); 736263363Semaste if (t != first+2) 737263363Semaste first = t; 738263363Semaste } 739263363Semaste return first; 740263363Semaste} 741263363Semaste 742263363Semaste// st <type> # sizeof (a type) 743263363Semaste 744263363Semastetemplate <class C> 745263363Semasteconst char* 746263363Semasteparse_sizeof_type_expr(const char* first, const char* last, C& db) 747263363Semaste{ 748263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 't') 749263363Semaste { 750263363Semaste const char* t = parse_type(first+2, last, db); 751263363Semaste if (t != first+2) 752263363Semaste { 753269024Semaste if (db.names.empty()) 754269024Semaste return first; 755263363Semaste db.names.back() = "sizeof (" + db.names.back().move_full() + ")"; 756263363Semaste first = t; 757263363Semaste } 758263363Semaste } 759263363Semaste return first; 760263363Semaste} 761263363Semaste 762263363Semaste// sz <expr> # sizeof (a expression) 763263363Semaste 764263363Semastetemplate <class C> 765263363Semasteconst char* 766263363Semasteparse_sizeof_expr_expr(const char* first, const char* last, C& db) 767263363Semaste{ 768263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 'z') 769263363Semaste { 770263363Semaste const char* t = parse_expression(first+2, last, db); 771263363Semaste if (t != first+2) 772263363Semaste { 773269024Semaste if (db.names.empty()) 774269024Semaste return first; 775263363Semaste db.names.back() = "sizeof (" + db.names.back().move_full() + ")"; 776263363Semaste first = t; 777263363Semaste } 778263363Semaste } 779263363Semaste return first; 780263363Semaste} 781263363Semaste 782263363Semaste// sZ <template-param> # size of a parameter pack 783263363Semaste 784263363Semastetemplate <class C> 785263363Semasteconst char* 786263363Semasteparse_sizeof_param_pack_expr(const char* first, const char* last, C& db) 787263363Semaste{ 788263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T') 789263363Semaste { 790263363Semaste size_t k0 = db.names.size(); 791263363Semaste const char* t = parse_template_param(first+2, last, db); 792263363Semaste size_t k1 = db.names.size(); 793263363Semaste if (t != first+2) 794263363Semaste { 795263363Semaste typename C::String tmp("sizeof...("); 796263363Semaste size_t k = k0; 797263363Semaste if (k != k1) 798263363Semaste { 799263363Semaste tmp += db.names[k].move_full(); 800263363Semaste for (++k; k != k1; ++k) 801263363Semaste tmp += ", " + db.names[k].move_full(); 802263363Semaste } 803263363Semaste tmp += ")"; 804263363Semaste for (; k1 != k0; --k1) 805263363Semaste db.names.pop_back(); 806263363Semaste db.names.push_back(std::move(tmp)); 807263363Semaste first = t; 808263363Semaste } 809263363Semaste } 810263363Semaste return first; 811263363Semaste} 812263363Semaste 813263363Semaste// <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter 814263363Semaste// ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters 815263363Semaste// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _ # L > 0, first parameter 816263363Semaste// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters 817263363Semaste 818263363Semastetemplate <class C> 819263363Semasteconst char* 820263363Semasteparse_function_param(const char* first, const char* last, C& db) 821263363Semaste{ 822263363Semaste if (last - first >= 3 && *first == 'f') 823263363Semaste { 824263363Semaste if (first[1] == 'p') 825263363Semaste { 826263363Semaste unsigned cv; 827263363Semaste const char* t = parse_cv_qualifiers(first+2, last, cv); 828263363Semaste const char* t1 = parse_number(t, last); 829263363Semaste if (t1 != last && *t1 == '_') 830263363Semaste { 831263363Semaste db.names.push_back("fp" + typename C::String(t, t1)); 832263363Semaste first = t1+1; 833263363Semaste } 834263363Semaste } 835263363Semaste else if (first[1] == 'L') 836263363Semaste { 837263363Semaste unsigned cv; 838263363Semaste const char* t0 = parse_number(first+2, last); 839263363Semaste if (t0 != last && *t0 == 'p') 840263363Semaste { 841263363Semaste ++t0; 842263363Semaste const char* t = parse_cv_qualifiers(t0, last, cv); 843263363Semaste const char* t1 = parse_number(t, last); 844263363Semaste if (t1 != last && *t1 == '_') 845263363Semaste { 846263363Semaste db.names.push_back("fp" + typename C::String(t, t1)); 847263363Semaste first = t1+1; 848263363Semaste } 849263363Semaste } 850263363Semaste } 851263363Semaste } 852263363Semaste return first; 853263363Semaste} 854263363Semaste 855263363Semaste// sZ <function-param> # size of a function parameter pack 856263363Semaste 857263363Semastetemplate <class C> 858263363Semasteconst char* 859263363Semasteparse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db) 860263363Semaste{ 861263363Semaste if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f') 862263363Semaste { 863263363Semaste const char* t = parse_function_param(first+2, last, db); 864263363Semaste if (t != first+2) 865263363Semaste { 866269024Semaste if (db.names.empty()) 867269024Semaste return first; 868263363Semaste db.names.back() = "sizeof...(" + db.names.back().move_full() + ")"; 869263363Semaste first = t; 870263363Semaste } 871263363Semaste } 872263363Semaste return first; 873263363Semaste} 874263363Semaste 875263363Semaste// te <expression> # typeid (expression) 876263363Semaste// ti <type> # typeid (type) 877263363Semaste 878263363Semastetemplate <class C> 879263363Semasteconst char* 880263363Semasteparse_typeid_expr(const char* first, const char* last, C& db) 881263363Semaste{ 882263363Semaste if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i')) 883263363Semaste { 884263363Semaste const char* t; 885263363Semaste if (first[1] == 'e') 886263363Semaste t = parse_expression(first+2, last, db); 887263363Semaste else 888263363Semaste t = parse_type(first+2, last, db); 889263363Semaste if (t != first+2) 890263363Semaste { 891269024Semaste if (db.names.empty()) 892269024Semaste return first; 893263363Semaste db.names.back() = "typeid(" + db.names.back().move_full() + ")"; 894263363Semaste first = t; 895263363Semaste } 896263363Semaste } 897263363Semaste return first; 898263363Semaste} 899263363Semaste 900263363Semaste// tw <expression> # throw expression 901263363Semaste 902263363Semastetemplate <class C> 903263363Semasteconst char* 904263363Semasteparse_throw_expr(const char* first, const char* last, C& db) 905263363Semaste{ 906263363Semaste if (last - first >= 3 && first[0] == 't' && first[1] == 'w') 907263363Semaste { 908263363Semaste const char* t = parse_expression(first+2, last, db); 909263363Semaste if (t != first+2) 910263363Semaste { 911269024Semaste if (db.names.empty()) 912269024Semaste return first; 913263363Semaste db.names.back() = "throw " + db.names.back().move_full(); 914263363Semaste first = t; 915263363Semaste } 916263363Semaste } 917263363Semaste return first; 918263363Semaste} 919263363Semaste 920263363Semaste// ds <expression> <expression> # expr.*expr 921263363Semaste 922263363Semastetemplate <class C> 923263363Semasteconst char* 924263363Semasteparse_dot_star_expr(const char* first, const char* last, C& db) 925263363Semaste{ 926263363Semaste if (last - first >= 3 && first[0] == 'd' && first[1] == 's') 927263363Semaste { 928263363Semaste const char* t = parse_expression(first+2, last, db); 929263363Semaste if (t != first+2) 930263363Semaste { 931263363Semaste const char* t1 = parse_expression(t, last, db); 932263363Semaste if (t1 != t) 933263363Semaste { 934269024Semaste if (db.names.size() < 2) 935269024Semaste return first; 936263363Semaste auto expr = db.names.back().move_full(); 937263363Semaste db.names.pop_back(); 938263363Semaste db.names.back().first += ".*" + expr; 939263363Semaste first = t1; 940263363Semaste } 941263363Semaste } 942263363Semaste } 943263363Semaste return first; 944263363Semaste} 945263363Semaste 946263363Semaste// <simple-id> ::= <source-name> [ <template-args> ] 947263363Semaste 948263363Semastetemplate <class C> 949263363Semasteconst char* 950263363Semasteparse_simple_id(const char* first, const char* last, C& db) 951263363Semaste{ 952263363Semaste if (first != last) 953263363Semaste { 954263363Semaste const char* t = parse_source_name(first, last, db); 955263363Semaste if (t != first) 956263363Semaste { 957263363Semaste const char* t1 = parse_template_args(t, last, db); 958263363Semaste if (t1 != t) 959263363Semaste { 960269024Semaste if (db.names.size() < 2) 961269024Semaste return first; 962263363Semaste auto args = db.names.back().move_full(); 963263363Semaste db.names.pop_back(); 964263363Semaste db.names.back().first += std::move(args); 965263363Semaste } 966263363Semaste first = t1; 967263363Semaste } 968263363Semaste else 969263363Semaste first = t; 970263363Semaste } 971263363Semaste return first; 972263363Semaste} 973263363Semaste 974263363Semaste// <unresolved-type> ::= <template-param> 975263363Semaste// ::= <decltype> 976263363Semaste// ::= <substitution> 977263363Semaste 978263363Semastetemplate <class C> 979263363Semasteconst char* 980263363Semasteparse_unresolved_type(const char* first, const char* last, C& db) 981263363Semaste{ 982263363Semaste if (first != last) 983263363Semaste { 984263363Semaste const char* t = first; 985263363Semaste switch (*first) 986263363Semaste { 987263363Semaste case 'T': 988263363Semaste { 989263363Semaste size_t k0 = db.names.size(); 990263363Semaste t = parse_template_param(first, last, db); 991263363Semaste size_t k1 = db.names.size(); 992263363Semaste if (t != first && k1 == k0 + 1) 993263363Semaste { 994263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 995263363Semaste first = t; 996263363Semaste } 997263363Semaste else 998263363Semaste { 999263363Semaste for (; k1 != k0; --k1) 1000263363Semaste db.names.pop_back(); 1001263363Semaste } 1002263363Semaste break; 1003263363Semaste } 1004263363Semaste case 'D': 1005263363Semaste t = parse_decltype(first, last, db); 1006263363Semaste if (t != first) 1007263363Semaste { 1008269024Semaste if (db.names.empty()) 1009269024Semaste return first; 1010263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 1011263363Semaste first = t; 1012263363Semaste } 1013263363Semaste break; 1014263363Semaste case 'S': 1015263363Semaste t = parse_substitution(first, last, db); 1016263363Semaste if (t != first) 1017263363Semaste first = t; 1018263363Semaste else 1019263363Semaste { 1020263363Semaste if (last - first > 2 && first[1] == 't') 1021263363Semaste { 1022263363Semaste t = parse_unqualified_name(first+2, last, db); 1023263363Semaste if (t != first+2) 1024263363Semaste { 1025269024Semaste if (db.names.empty()) 1026269024Semaste return first; 1027263363Semaste db.names.back().first.insert(0, "std::"); 1028263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 1029263363Semaste first = t; 1030263363Semaste } 1031263363Semaste } 1032263363Semaste } 1033263363Semaste break; 1034263363Semaste } 1035263363Semaste } 1036263363Semaste return first; 1037263363Semaste} 1038263363Semaste 1039263363Semaste// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f()) 1040263363Semaste// ::= <simple-id> # e.g., ~A<2*N> 1041263363Semaste 1042263363Semastetemplate <class C> 1043263363Semasteconst char* 1044263363Semasteparse_destructor_name(const char* first, const char* last, C& db) 1045263363Semaste{ 1046263363Semaste if (first != last) 1047263363Semaste { 1048263363Semaste const char* t = parse_unresolved_type(first, last, db); 1049263363Semaste if (t == first) 1050263363Semaste t = parse_simple_id(first, last, db); 1051263363Semaste if (t != first) 1052263363Semaste { 1053269024Semaste if (db.names.empty()) 1054269024Semaste return first; 1055263363Semaste db.names.back().first.insert(0, "~"); 1056263363Semaste first = t; 1057263363Semaste } 1058263363Semaste } 1059263363Semaste return first; 1060263363Semaste} 1061263363Semaste 1062263363Semaste// <base-unresolved-name> ::= <simple-id> # unresolved name 1063263363Semaste// extension ::= <operator-name> # unresolved operator-function-id 1064263363Semaste// extension ::= <operator-name> <template-args> # unresolved operator template-id 1065263363Semaste// ::= on <operator-name> # unresolved operator-function-id 1066263363Semaste// ::= on <operator-name> <template-args> # unresolved operator template-id 1067263363Semaste// ::= dn <destructor-name> # destructor or pseudo-destructor; 1068263363Semaste// # e.g. ~X or ~X<N-1> 1069263363Semaste 1070263363Semastetemplate <class C> 1071263363Semasteconst char* 1072263363Semasteparse_base_unresolved_name(const char* first, const char* last, C& db) 1073263363Semaste{ 1074263363Semaste if (last - first >= 2) 1075263363Semaste { 1076263363Semaste if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n') 1077263363Semaste { 1078263363Semaste if (first[0] == 'o') 1079263363Semaste { 1080263363Semaste const char* t = parse_operator_name(first+2, last, db); 1081263363Semaste if (t != first+2) 1082263363Semaste { 1083263363Semaste first = parse_template_args(t, last, db); 1084263363Semaste if (first != t) 1085263363Semaste { 1086269024Semaste if (db.names.size() < 2) 1087269024Semaste return first; 1088263363Semaste auto args = db.names.back().move_full(); 1089263363Semaste db.names.pop_back(); 1090263363Semaste db.names.back().first += std::move(args); 1091263363Semaste } 1092263363Semaste } 1093263363Semaste } 1094263363Semaste else 1095263363Semaste { 1096263363Semaste const char* t = parse_destructor_name(first+2, last, db); 1097263363Semaste if (t != first+2) 1098263363Semaste first = t; 1099263363Semaste } 1100263363Semaste } 1101263363Semaste else 1102263363Semaste { 1103263363Semaste const char* t = parse_simple_id(first, last, db); 1104263363Semaste if (t == first) 1105263363Semaste { 1106263363Semaste t = parse_operator_name(first, last, db); 1107263363Semaste if (t != first) 1108263363Semaste { 1109263363Semaste first = parse_template_args(t, last, db); 1110263363Semaste if (first != t) 1111263363Semaste { 1112269024Semaste if (db.names.size() < 2) 1113269024Semaste return first; 1114263363Semaste auto args = db.names.back().move_full(); 1115263363Semaste db.names.pop_back(); 1116263363Semaste db.names.back().first += std::move(args); 1117263363Semaste } 1118263363Semaste } 1119263363Semaste } 1120263363Semaste else 1121263363Semaste first = t; 1122263363Semaste } 1123263363Semaste } 1124263363Semaste return first; 1125263363Semaste} 1126263363Semaste 1127263363Semaste// <unresolved-qualifier-level> ::= <simple-id> 1128263363Semaste 1129263363Semastetemplate <class C> 1130263363Semasteconst char* 1131263363Semasteparse_unresolved_qualifier_level(const char* first, const char* last, C& db) 1132263363Semaste{ 1133263363Semaste return parse_simple_id(first, last, db); 1134263363Semaste} 1135263363Semaste 1136263363Semaste// <unresolved-name> 1137263363Semaste// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> 1138263363Semaste// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x 1139263363Semaste// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> 1140263363Semaste// # A::x, N::y, A<T>::z; "gs" means leading "::" 1141263363Semaste// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x 1142263363Semaste// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name> 1143263363Semaste// # T::N::x /decltype(p)::N::x 1144263363Semaste// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name> 1145263363Semaste 1146263363Semastetemplate <class C> 1147263363Semasteconst char* 1148263363Semasteparse_unresolved_name(const char* first, const char* last, C& db) 1149263363Semaste{ 1150263363Semaste if (last - first > 2) 1151263363Semaste { 1152263363Semaste const char* t = first; 1153263363Semaste bool global = false; 1154263363Semaste if (t[0] == 'g' && t[1] == 's') 1155263363Semaste { 1156263363Semaste global = true; 1157263363Semaste t += 2; 1158263363Semaste } 1159263363Semaste const char* t2 = parse_base_unresolved_name(t, last, db); 1160263363Semaste if (t2 != t) 1161263363Semaste { 1162263363Semaste if (global) 1163269024Semaste { 1164269024Semaste if (db.names.empty()) 1165269024Semaste return first; 1166263363Semaste db.names.back().first.insert(0, "::"); 1167269024Semaste } 1168263363Semaste first = t2; 1169263363Semaste } 1170263363Semaste else if (last - t > 2 && t[0] == 's' && t[1] == 'r') 1171263363Semaste { 1172263363Semaste if (t[2] == 'N') 1173263363Semaste { 1174263363Semaste t += 3; 1175263363Semaste const char* t1 = parse_unresolved_type(t, last, db); 1176263363Semaste if (t1 == t || t1 == last) 1177263363Semaste return first; 1178263363Semaste t = t1; 1179263363Semaste t1 = parse_template_args(t, last, db); 1180263363Semaste if (t1 != t) 1181263363Semaste { 1182269024Semaste if (db.names.size() < 2) 1183269024Semaste return first; 1184263363Semaste auto args = db.names.back().move_full(); 1185263363Semaste db.names.pop_back(); 1186263363Semaste db.names.back().first += std::move(args); 1187263363Semaste t = t1; 1188263363Semaste if (t == last) 1189263363Semaste { 1190263363Semaste db.names.pop_back(); 1191263363Semaste return first; 1192263363Semaste } 1193263363Semaste } 1194263363Semaste while (*t != 'E') 1195263363Semaste { 1196263363Semaste t1 = parse_unresolved_qualifier_level(t, last, db); 1197269024Semaste if (t1 == t || t1 == last || db.names.size() < 2) 1198263363Semaste return first; 1199263363Semaste auto s = db.names.back().move_full(); 1200263363Semaste db.names.pop_back(); 1201263363Semaste db.names.back().first += "::" + std::move(s); 1202263363Semaste t = t1; 1203263363Semaste } 1204263363Semaste ++t; 1205263363Semaste t1 = parse_base_unresolved_name(t, last, db); 1206263363Semaste if (t1 == t) 1207263363Semaste { 1208269024Semaste if (!db.names.empty()) 1209269024Semaste db.names.pop_back(); 1210263363Semaste return first; 1211263363Semaste } 1212269024Semaste if (db.names.size() < 2) 1213269024Semaste return first; 1214263363Semaste auto s = db.names.back().move_full(); 1215263363Semaste db.names.pop_back(); 1216263363Semaste db.names.back().first += "::" + std::move(s); 1217263363Semaste first = t1; 1218263363Semaste } 1219263363Semaste else 1220263363Semaste { 1221263363Semaste t += 2; 1222263363Semaste const char* t1 = parse_unresolved_type(t, last, db); 1223263363Semaste if (t1 != t) 1224263363Semaste { 1225263363Semaste t = t1; 1226263363Semaste t1 = parse_template_args(t, last, db); 1227263363Semaste if (t1 != t) 1228263363Semaste { 1229269024Semaste if (db.names.size() < 2) 1230269024Semaste return first; 1231263363Semaste auto args = db.names.back().move_full(); 1232263363Semaste db.names.pop_back(); 1233263363Semaste db.names.back().first += std::move(args); 1234263363Semaste t = t1; 1235263363Semaste } 1236263363Semaste t1 = parse_base_unresolved_name(t, last, db); 1237263363Semaste if (t1 == t) 1238263363Semaste { 1239269024Semaste if (!db.names.empty()) 1240269024Semaste db.names.pop_back(); 1241263363Semaste return first; 1242263363Semaste } 1243269024Semaste if (db.names.size() < 2) 1244269024Semaste return first; 1245263363Semaste auto s = db.names.back().move_full(); 1246263363Semaste db.names.pop_back(); 1247263363Semaste db.names.back().first += "::" + std::move(s); 1248263363Semaste first = t1; 1249263363Semaste } 1250263363Semaste else 1251263363Semaste { 1252263363Semaste t1 = parse_unresolved_qualifier_level(t, last, db); 1253263363Semaste if (t1 == t || t1 == last) 1254263363Semaste return first; 1255263363Semaste t = t1; 1256263363Semaste if (global) 1257269024Semaste { 1258269024Semaste if (db.names.empty()) 1259269024Semaste return first; 1260263363Semaste db.names.back().first.insert(0, "::"); 1261269024Semaste } 1262263363Semaste while (*t != 'E') 1263263363Semaste { 1264263363Semaste t1 = parse_unresolved_qualifier_level(t, last, db); 1265269024Semaste if (t1 == t || t1 == last || db.names.size() < 2) 1266263363Semaste return first; 1267263363Semaste auto s = db.names.back().move_full(); 1268263363Semaste db.names.pop_back(); 1269263363Semaste db.names.back().first += "::" + std::move(s); 1270263363Semaste t = t1; 1271263363Semaste } 1272263363Semaste ++t; 1273263363Semaste t1 = parse_base_unresolved_name(t, last, db); 1274263363Semaste if (t1 == t) 1275263363Semaste { 1276269024Semaste if (!db.names.empty()) 1277269024Semaste db.names.pop_back(); 1278263363Semaste return first; 1279263363Semaste } 1280269024Semaste if (db.names.size() < 2) 1281269024Semaste return first; 1282263363Semaste auto s = db.names.back().move_full(); 1283263363Semaste db.names.pop_back(); 1284263363Semaste db.names.back().first += "::" + std::move(s); 1285263363Semaste first = t1; 1286263363Semaste } 1287263363Semaste } 1288263363Semaste } 1289263363Semaste } 1290263363Semaste return first; 1291263363Semaste} 1292263363Semaste 1293263363Semaste// dt <expression> <unresolved-name> # expr.name 1294263363Semaste 1295263363Semastetemplate <class C> 1296263363Semasteconst char* 1297263363Semasteparse_dot_expr(const char* first, const char* last, C& db) 1298263363Semaste{ 1299263363Semaste if (last - first >= 3 && first[0] == 'd' && first[1] == 't') 1300263363Semaste { 1301263363Semaste const char* t = parse_expression(first+2, last, db); 1302263363Semaste if (t != first+2) 1303263363Semaste { 1304263363Semaste const char* t1 = parse_unresolved_name(t, last, db); 1305263363Semaste if (t1 != t) 1306263363Semaste { 1307269024Semaste if (db.names.size() < 2) 1308269024Semaste return first; 1309263363Semaste auto name = db.names.back().move_full(); 1310263363Semaste db.names.pop_back(); 1311263363Semaste db.names.back().first += "." + name; 1312263363Semaste first = t1; 1313263363Semaste } 1314263363Semaste } 1315263363Semaste } 1316263363Semaste return first; 1317263363Semaste} 1318263363Semaste 1319263363Semaste// cl <expression>+ E # call 1320263363Semaste 1321263363Semastetemplate <class C> 1322263363Semasteconst char* 1323263363Semasteparse_call_expr(const char* first, const char* last, C& db) 1324263363Semaste{ 1325263363Semaste if (last - first >= 4 && first[0] == 'c' && first[1] == 'l') 1326263363Semaste { 1327263363Semaste const char* t = parse_expression(first+2, last, db); 1328263363Semaste if (t != first+2) 1329263363Semaste { 1330263363Semaste if (t == last) 1331263363Semaste return first; 1332269024Semaste if (db.names.empty()) 1333269024Semaste return first; 1334263363Semaste db.names.back().first += db.names.back().second; 1335263363Semaste db.names.back().second = typename C::String(); 1336263363Semaste db.names.back().first.append("("); 1337263363Semaste bool first_expr = true; 1338263363Semaste while (*t != 'E') 1339263363Semaste { 1340263363Semaste const char* t1 = parse_expression(t, last, db); 1341263363Semaste if (t1 == t || t1 == last) 1342263363Semaste return first; 1343269024Semaste if (db.names.empty()) 1344269024Semaste return first; 1345263363Semaste auto tmp = db.names.back().move_full(); 1346263363Semaste db.names.pop_back(); 1347263363Semaste if (!tmp.empty()) 1348263363Semaste { 1349269024Semaste if (db.names.empty()) 1350269024Semaste return first; 1351263363Semaste if (!first_expr) 1352263363Semaste { 1353263363Semaste db.names.back().first.append(", "); 1354263363Semaste first_expr = false; 1355263363Semaste } 1356263363Semaste db.names.back().first.append(tmp); 1357263363Semaste } 1358263363Semaste t = t1; 1359263363Semaste } 1360263363Semaste ++t; 1361269024Semaste if (db.names.empty()) 1362269024Semaste return first; 1363263363Semaste db.names.back().first.append(")"); 1364263363Semaste first = t; 1365263363Semaste } 1366263363Semaste } 1367263363Semaste return first; 1368263363Semaste} 1369263363Semaste 1370263363Semaste// [gs] nw <expression>* _ <type> E # new (expr-list) type 1371263363Semaste// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 1372263363Semaste// [gs] na <expression>* _ <type> E # new[] (expr-list) type 1373263363Semaste// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 1374263363Semaste// <initializer> ::= pi <expression>* E # parenthesized initialization 1375263363Semaste 1376263363Semastetemplate <class C> 1377263363Semasteconst char* 1378263363Semasteparse_new_expr(const char* first, const char* last, C& db) 1379263363Semaste{ 1380263363Semaste if (last - first >= 4) 1381263363Semaste { 1382263363Semaste const char* t = first; 1383263363Semaste bool parsed_gs = false; 1384263363Semaste if (t[0] == 'g' && t[1] == 's') 1385263363Semaste { 1386263363Semaste t += 2; 1387263363Semaste parsed_gs = true; 1388263363Semaste } 1389263363Semaste if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a')) 1390263363Semaste { 1391263363Semaste bool is_array = t[1] == 'a'; 1392263363Semaste t += 2; 1393263363Semaste if (t == last) 1394263363Semaste return first; 1395263363Semaste bool has_expr_list = false; 1396263363Semaste bool first_expr = true; 1397263363Semaste while (*t != '_') 1398263363Semaste { 1399263363Semaste const char* t1 = parse_expression(t, last, db); 1400263363Semaste if (t1 == t || t1 == last) 1401263363Semaste return first; 1402263363Semaste has_expr_list = true; 1403263363Semaste if (!first_expr) 1404263363Semaste { 1405269024Semaste if (db.names.empty()) 1406269024Semaste return first; 1407263363Semaste auto tmp = db.names.back().move_full(); 1408263363Semaste db.names.pop_back(); 1409263363Semaste if (!tmp.empty()) 1410263363Semaste { 1411269024Semaste if (db.names.empty()) 1412269024Semaste return first; 1413263363Semaste db.names.back().first.append(", "); 1414263363Semaste db.names.back().first.append(tmp); 1415263363Semaste first_expr = false; 1416263363Semaste } 1417263363Semaste } 1418263363Semaste t = t1; 1419263363Semaste } 1420263363Semaste ++t; 1421263363Semaste const char* t1 = parse_type(t, last, db); 1422263363Semaste if (t1 == t || t1 == last) 1423263363Semaste return first; 1424263363Semaste t = t1; 1425263363Semaste bool has_init = false; 1426263363Semaste if (last - t >= 3 && t[0] == 'p' && t[1] == 'i') 1427263363Semaste { 1428263363Semaste t += 2; 1429263363Semaste has_init = true; 1430263363Semaste first_expr = true; 1431263363Semaste while (*t != 'E') 1432263363Semaste { 1433263363Semaste t1 = parse_expression(t, last, db); 1434263363Semaste if (t1 == t || t1 == last) 1435263363Semaste return first; 1436263363Semaste if (!first_expr) 1437263363Semaste { 1438269024Semaste if (db.names.empty()) 1439269024Semaste return first; 1440263363Semaste auto tmp = db.names.back().move_full(); 1441263363Semaste db.names.pop_back(); 1442263363Semaste if (!tmp.empty()) 1443263363Semaste { 1444269024Semaste if (db.names.empty()) 1445269024Semaste return first; 1446263363Semaste db.names.back().first.append(", "); 1447263363Semaste db.names.back().first.append(tmp); 1448263363Semaste first_expr = false; 1449263363Semaste } 1450263363Semaste } 1451263363Semaste t = t1; 1452263363Semaste } 1453263363Semaste } 1454263363Semaste if (*t != 'E') 1455263363Semaste return first; 1456263363Semaste typename C::String init_list; 1457263363Semaste if (has_init) 1458263363Semaste { 1459269024Semaste if (db.names.empty()) 1460269024Semaste return first; 1461263363Semaste init_list = db.names.back().move_full(); 1462263363Semaste db.names.pop_back(); 1463263363Semaste } 1464269024Semaste if (db.names.empty()) 1465269024Semaste return first; 1466263363Semaste auto type = db.names.back().move_full(); 1467263363Semaste db.names.pop_back(); 1468263363Semaste typename C::String expr_list; 1469263363Semaste if (has_expr_list) 1470263363Semaste { 1471269024Semaste if (db.names.empty()) 1472269024Semaste return first; 1473263363Semaste expr_list = db.names.back().move_full(); 1474263363Semaste db.names.pop_back(); 1475263363Semaste } 1476263363Semaste typename C::String r; 1477263363Semaste if (parsed_gs) 1478263363Semaste r = "::"; 1479263363Semaste if (is_array) 1480263363Semaste r += "[] "; 1481263363Semaste else 1482263363Semaste r += " "; 1483263363Semaste if (has_expr_list) 1484263363Semaste r += "(" + expr_list + ") "; 1485263363Semaste r += type; 1486263363Semaste if (has_init) 1487263363Semaste r += " (" + init_list + ")"; 1488263363Semaste db.names.push_back(std::move(r)); 1489263363Semaste first = t+1; 1490263363Semaste } 1491263363Semaste } 1492263363Semaste return first; 1493263363Semaste} 1494263363Semaste 1495263363Semaste// cv <type> <expression> # conversion with one argument 1496263363Semaste// cv <type> _ <expression>* E # conversion with a different number of arguments 1497263363Semaste 1498263363Semastetemplate <class C> 1499263363Semasteconst char* 1500263363Semasteparse_conversion_expr(const char* first, const char* last, C& db) 1501263363Semaste{ 1502263363Semaste if (last - first >= 3 && first[0] == 'c' && first[1] == 'v') 1503263363Semaste { 1504263363Semaste bool try_to_parse_template_args = db.try_to_parse_template_args; 1505263363Semaste db.try_to_parse_template_args = false; 1506263363Semaste const char* t = parse_type(first+2, last, db); 1507263363Semaste db.try_to_parse_template_args = try_to_parse_template_args; 1508263363Semaste if (t != first+2 && t != last) 1509263363Semaste { 1510263363Semaste if (*t != '_') 1511263363Semaste { 1512263363Semaste const char* t1 = parse_expression(t, last, db); 1513263363Semaste if (t1 == t) 1514263363Semaste return first; 1515263363Semaste t = t1; 1516263363Semaste } 1517263363Semaste else 1518263363Semaste { 1519263363Semaste ++t; 1520263363Semaste if (t == last) 1521263363Semaste return first; 1522263363Semaste if (*t == 'E') 1523263363Semaste db.names.emplace_back(); 1524263363Semaste else 1525263363Semaste { 1526263363Semaste bool first_expr = true; 1527263363Semaste while (*t != 'E') 1528263363Semaste { 1529263363Semaste const char* t1 = parse_expression(t, last, db); 1530263363Semaste if (t1 == t || t1 == last) 1531263363Semaste return first; 1532263363Semaste if (!first_expr) 1533263363Semaste { 1534269024Semaste if (db.names.empty()) 1535269024Semaste return first; 1536263363Semaste auto tmp = db.names.back().move_full(); 1537263363Semaste db.names.pop_back(); 1538263363Semaste if (!tmp.empty()) 1539263363Semaste { 1540269024Semaste if (db.names.empty()) 1541269024Semaste return first; 1542263363Semaste db.names.back().first.append(", "); 1543263363Semaste db.names.back().first.append(tmp); 1544263363Semaste first_expr = false; 1545263363Semaste } 1546263363Semaste } 1547263363Semaste t = t1; 1548263363Semaste } 1549263363Semaste } 1550263363Semaste ++t; 1551263363Semaste } 1552269024Semaste if (db.names.size() < 2) 1553269024Semaste return first; 1554263363Semaste auto tmp = db.names.back().move_full(); 1555263363Semaste db.names.pop_back(); 1556263363Semaste db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")"; 1557263363Semaste first = t; 1558263363Semaste } 1559263363Semaste } 1560263363Semaste return first; 1561263363Semaste} 1562263363Semaste 1563263363Semaste// pt <expression> <expression> # expr->name 1564263363Semaste 1565263363Semastetemplate <class C> 1566263363Semasteconst char* 1567263363Semasteparse_arrow_expr(const char* first, const char* last, C& db) 1568263363Semaste{ 1569263363Semaste if (last - first >= 3 && first[0] == 'p' && first[1] == 't') 1570263363Semaste { 1571263363Semaste const char* t = parse_expression(first+2, last, db); 1572263363Semaste if (t != first+2) 1573263363Semaste { 1574263363Semaste const char* t1 = parse_expression(t, last, db); 1575263363Semaste if (t1 != t) 1576263363Semaste { 1577269024Semaste if (db.names.size() < 2) 1578269024Semaste return first; 1579263363Semaste auto tmp = db.names.back().move_full(); 1580263363Semaste db.names.pop_back(); 1581263363Semaste db.names.back().first += "->"; 1582263363Semaste db.names.back().first += tmp; 1583263363Semaste first = t1; 1584263363Semaste } 1585263363Semaste } 1586263363Semaste } 1587263363Semaste return first; 1588263363Semaste} 1589263363Semaste 1590263363Semaste// <ref-qualifier> ::= R # & ref-qualifier 1591263363Semaste// <ref-qualifier> ::= O # && ref-qualifier 1592263363Semaste 1593263363Semaste// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E 1594263363Semaste 1595263363Semastetemplate <class C> 1596263363Semasteconst char* 1597263363Semasteparse_function_type(const char* first, const char* last, C& db) 1598263363Semaste{ 1599263363Semaste if (first != last && *first == 'F') 1600263363Semaste { 1601263363Semaste const char* t = first+1; 1602263363Semaste if (t != last) 1603263363Semaste { 1604263363Semaste bool externC = false; 1605263363Semaste if (*t == 'Y') 1606263363Semaste { 1607263363Semaste externC = true; 1608263363Semaste if (++t == last) 1609263363Semaste return first; 1610263363Semaste } 1611263363Semaste const char* t1 = parse_type(t, last, db); 1612263363Semaste if (t1 != t) 1613263363Semaste { 1614263363Semaste t = t1; 1615263363Semaste typename C::String sig("("); 1616263363Semaste int ref_qual = 0; 1617263363Semaste while (true) 1618263363Semaste { 1619263363Semaste if (t == last) 1620263363Semaste { 1621263363Semaste db.names.pop_back(); 1622263363Semaste return first; 1623263363Semaste } 1624263363Semaste if (*t == 'E') 1625263363Semaste { 1626263363Semaste ++t; 1627263363Semaste break; 1628263363Semaste } 1629263363Semaste if (*t == 'v') 1630263363Semaste { 1631263363Semaste ++t; 1632263363Semaste continue; 1633263363Semaste } 1634263363Semaste if (*t == 'R' && t+1 != last && t[1] == 'E') 1635263363Semaste { 1636263363Semaste ref_qual = 1; 1637263363Semaste ++t; 1638263363Semaste continue; 1639263363Semaste } 1640263363Semaste if (*t == 'O' && t+1 != last && t[1] == 'E') 1641263363Semaste { 1642263363Semaste ref_qual = 2; 1643263363Semaste ++t; 1644263363Semaste continue; 1645263363Semaste } 1646263363Semaste size_t k0 = db.names.size(); 1647263363Semaste t1 = parse_type(t, last, db); 1648263363Semaste size_t k1 = db.names.size(); 1649263363Semaste if (t1 == t || t1 == last) 1650263363Semaste return first; 1651263363Semaste for (size_t k = k0; k < k1; ++k) 1652263363Semaste { 1653263363Semaste if (sig.size() > 1) 1654263363Semaste sig += ", "; 1655263363Semaste sig += db.names[k].move_full(); 1656263363Semaste } 1657263363Semaste for (size_t k = k0; k < k1; ++k) 1658263363Semaste db.names.pop_back(); 1659263363Semaste t = t1; 1660263363Semaste } 1661263363Semaste sig += ")"; 1662263363Semaste switch (ref_qual) 1663263363Semaste { 1664263363Semaste case 1: 1665263363Semaste sig += " &"; 1666263363Semaste break; 1667263363Semaste case 2: 1668263363Semaste sig += " &&"; 1669263363Semaste break; 1670263363Semaste } 1671269024Semaste if (db.names.empty()) 1672269024Semaste return first; 1673263363Semaste db.names.back().first += " "; 1674263363Semaste db.names.back().second.insert(0, sig); 1675263363Semaste first = t; 1676263363Semaste } 1677263363Semaste } 1678263363Semaste } 1679263363Semaste return first; 1680263363Semaste} 1681263363Semaste 1682263363Semaste// <pointer-to-member-type> ::= M <class type> <member type> 1683263363Semaste 1684263363Semastetemplate <class C> 1685263363Semasteconst char* 1686263363Semasteparse_pointer_to_member_type(const char* first, const char* last, C& db) 1687263363Semaste{ 1688263363Semaste if (first != last && *first == 'M') 1689263363Semaste { 1690263363Semaste const char* t = parse_type(first+1, last, db); 1691263363Semaste if (t != first+1) 1692263363Semaste { 1693263363Semaste const char* t2 = parse_type(t, last, db); 1694263363Semaste if (t2 != t) 1695263363Semaste { 1696269024Semaste if (db.names.size() < 2) 1697269024Semaste return first; 1698263363Semaste auto func = std::move(db.names.back()); 1699263363Semaste db.names.pop_back(); 1700263363Semaste auto class_type = std::move(db.names.back()); 1701263363Semaste if (func.second.front() == '(') 1702263363Semaste { 1703263363Semaste db.names.back().first = std::move(func.first) + "(" + class_type.move_full() + "::*"; 1704263363Semaste db.names.back().second = ")" + std::move(func.second); 1705263363Semaste } 1706263363Semaste else 1707263363Semaste { 1708263363Semaste db.names.back().first = std::move(func.first) + " " + class_type.move_full() + "::*"; 1709263363Semaste db.names.back().second = std::move(func.second); 1710263363Semaste } 1711263363Semaste first = t2; 1712263363Semaste } 1713263363Semaste } 1714263363Semaste } 1715263363Semaste return first; 1716263363Semaste} 1717263363Semaste 1718263363Semaste// <array-type> ::= A <positive dimension number> _ <element type> 1719263363Semaste// ::= A [<dimension expression>] _ <element type> 1720263363Semaste 1721263363Semastetemplate <class C> 1722263363Semasteconst char* 1723263363Semasteparse_array_type(const char* first, const char* last, C& db) 1724263363Semaste{ 1725263363Semaste if (first != last && *first == 'A' && first+1 != last) 1726263363Semaste { 1727263363Semaste if (first[1] == '_') 1728263363Semaste { 1729263363Semaste const char* t = parse_type(first+2, last, db); 1730263363Semaste if (t != first+2) 1731263363Semaste { 1732269024Semaste if (db.names.empty()) 1733269024Semaste return first; 1734263363Semaste if (db.names.back().second.substr(0, 2) == " [") 1735263363Semaste db.names.back().second.erase(0, 1); 1736263363Semaste db.names.back().second.insert(0, " []"); 1737263363Semaste first = t; 1738263363Semaste } 1739263363Semaste } 1740263363Semaste else if ('1' <= first[1] && first[1] <= '9') 1741263363Semaste { 1742263363Semaste const char* t = parse_number(first+1, last); 1743263363Semaste if (t != last && *t == '_') 1744263363Semaste { 1745263363Semaste const char* t2 = parse_type(t+1, last, db); 1746263363Semaste if (t2 != t+1) 1747263363Semaste { 1748269024Semaste if (db.names.empty()) 1749269024Semaste return first; 1750263363Semaste if (db.names.back().second.substr(0, 2) == " [") 1751263363Semaste db.names.back().second.erase(0, 1); 1752263363Semaste db.names.back().second.insert(0, " [" + typename C::String(first+1, t) + "]"); 1753263363Semaste first = t2; 1754263363Semaste } 1755263363Semaste } 1756263363Semaste } 1757263363Semaste else 1758263363Semaste { 1759263363Semaste const char* t = parse_expression(first+1, last, db); 1760263363Semaste if (t != first+1 && t != last && *t == '_') 1761263363Semaste { 1762263363Semaste const char* t2 = parse_type(++t, last, db); 1763263363Semaste if (t2 != t) 1764263363Semaste { 1765269024Semaste if (db.names.size() < 2) 1766269024Semaste return first; 1767263363Semaste auto type = std::move(db.names.back()); 1768263363Semaste db.names.pop_back(); 1769263363Semaste auto expr = std::move(db.names.back()); 1770263363Semaste db.names.back().first = std::move(type.first); 1771263363Semaste if (type.second.substr(0, 2) == " [") 1772263363Semaste type.second.erase(0, 1); 1773263363Semaste db.names.back().second = " [" + expr.move_full() + "]" + std::move(type.second); 1774263363Semaste first = t2; 1775263363Semaste } 1776263363Semaste } 1777263363Semaste } 1778263363Semaste } 1779263363Semaste return first; 1780263363Semaste} 1781263363Semaste 1782263363Semaste// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) 1783263363Semaste// ::= DT <expression> E # decltype of an expression (C++0x) 1784263363Semaste 1785263363Semastetemplate <class C> 1786263363Semasteconst char* 1787263363Semasteparse_decltype(const char* first, const char* last, C& db) 1788263363Semaste{ 1789263363Semaste if (last - first >= 4 && first[0] == 'D') 1790263363Semaste { 1791263363Semaste switch (first[1]) 1792263363Semaste { 1793263363Semaste case 't': 1794263363Semaste case 'T': 1795263363Semaste { 1796263363Semaste const char* t = parse_expression(first+2, last, db); 1797263363Semaste if (t != first+2 && t != last && *t == 'E') 1798263363Semaste { 1799269024Semaste if (db.names.empty()) 1800269024Semaste return first; 1801263363Semaste db.names.back() = "decltype(" + db.names.back().move_full() + ")"; 1802263363Semaste first = t+1; 1803263363Semaste } 1804263363Semaste } 1805263363Semaste break; 1806263363Semaste } 1807263363Semaste } 1808263363Semaste return first; 1809263363Semaste} 1810263363Semaste 1811263363Semaste// extension: 1812263363Semaste// <vector-type> ::= Dv <positive dimension number> _ 1813263363Semaste// <extended element type> 1814263363Semaste// ::= Dv [<dimension expression>] _ <element type> 1815263363Semaste// <extended element type> ::= <element type> 1816263363Semaste// ::= p # AltiVec vector pixel 1817263363Semaste 1818263363Semastetemplate <class C> 1819263363Semasteconst char* 1820263363Semasteparse_vector_type(const char* first, const char* last, C& db) 1821263363Semaste{ 1822263363Semaste if (last - first > 3 && first[0] == 'D' && first[1] == 'v') 1823263363Semaste { 1824263363Semaste if ('1' <= first[2] && first[2] <= '9') 1825263363Semaste { 1826263363Semaste const char* t = parse_number(first+2, last); 1827263363Semaste if (t == last || *t != '_') 1828263363Semaste return first; 1829263363Semaste const char* num = first + 2; 1830263363Semaste size_t sz = static_cast<size_t>(t - num); 1831263363Semaste if (++t != last) 1832263363Semaste { 1833263363Semaste if (*t != 'p') 1834263363Semaste { 1835263363Semaste const char* t1 = parse_type(t, last, db); 1836263363Semaste if (t1 != t) 1837263363Semaste { 1838269024Semaste if (db.names.empty()) 1839269024Semaste return first; 1840263363Semaste db.names.back().first += " vector[" + typename C::String(num, sz) + "]"; 1841263363Semaste first = t1; 1842263363Semaste } 1843263363Semaste } 1844263363Semaste else 1845263363Semaste { 1846263363Semaste ++t; 1847263363Semaste db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]"); 1848263363Semaste first = t; 1849263363Semaste } 1850263363Semaste } 1851263363Semaste } 1852263363Semaste else 1853263363Semaste { 1854263363Semaste typename C::String num; 1855263363Semaste const char* t1 = first+2; 1856263363Semaste if (*t1 != '_') 1857263363Semaste { 1858263363Semaste const char* t = parse_expression(t1, last, db); 1859263363Semaste if (t != t1) 1860263363Semaste { 1861269024Semaste if (db.names.empty()) 1862269024Semaste return first; 1863263363Semaste num = db.names.back().move_full(); 1864263363Semaste db.names.pop_back(); 1865263363Semaste t1 = t; 1866263363Semaste } 1867263363Semaste } 1868263363Semaste if (t1 != last && *t1 == '_' && ++t1 != last) 1869263363Semaste { 1870263363Semaste const char* t = parse_type(t1, last, db); 1871263363Semaste if (t != t1) 1872263363Semaste { 1873269024Semaste if (db.names.empty()) 1874269024Semaste return first; 1875263363Semaste db.names.back().first += " vector[" + num + "]"; 1876263363Semaste first = t; 1877263363Semaste } 1878263363Semaste } 1879263363Semaste } 1880263363Semaste } 1881263363Semaste return first; 1882263363Semaste} 1883263363Semaste 1884263363Semaste// <type> ::= <builtin-type> 1885263363Semaste// ::= <function-type> 1886263363Semaste// ::= <class-enum-type> 1887263363Semaste// ::= <array-type> 1888263363Semaste// ::= <pointer-to-member-type> 1889263363Semaste// ::= <template-param> 1890263363Semaste// ::= <template-template-param> <template-args> 1891263363Semaste// ::= <decltype> 1892263363Semaste// ::= <substitution> 1893263363Semaste// ::= <CV-qualifiers> <type> 1894263363Semaste// ::= P <type> # pointer-to 1895263363Semaste// ::= R <type> # reference-to 1896263363Semaste// ::= O <type> # rvalue reference-to (C++0x) 1897263363Semaste// ::= C <type> # complex pair (C 2000) 1898263363Semaste// ::= G <type> # imaginary (C 2000) 1899263363Semaste// ::= Dp <type> # pack expansion (C++0x) 1900263363Semaste// ::= U <source-name> <type> # vendor extended type qualifier 1901263363Semaste// extension := U <objc-name> <objc-type> # objc-type<identifier> 1902263363Semaste// extension := <vector-type> # <vector-type> starts with Dv 1903263363Semaste 1904263363Semaste// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1 1905263363Semaste// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name> 1906263363Semaste 1907263363Semastetemplate <class C> 1908263363Semasteconst char* 1909263363Semasteparse_type(const char* first, const char* last, C& db) 1910263363Semaste{ 1911263363Semaste if (first != last) 1912263363Semaste { 1913263363Semaste switch (*first) 1914263363Semaste { 1915263363Semaste case 'r': 1916263363Semaste case 'V': 1917263363Semaste case 'K': 1918263363Semaste { 1919263363Semaste unsigned cv = 0; 1920263363Semaste const char* t = parse_cv_qualifiers(first, last, cv); 1921263363Semaste if (t != first) 1922263363Semaste { 1923263363Semaste bool is_function = *t == 'F'; 1924263363Semaste size_t k0 = db.names.size(); 1925263363Semaste const char* t1 = parse_type(t, last, db); 1926263363Semaste size_t k1 = db.names.size(); 1927263363Semaste if (t1 != t) 1928263363Semaste { 1929263363Semaste if (is_function) 1930263363Semaste db.subs.pop_back(); 1931263363Semaste db.subs.emplace_back(db.names.get_allocator()); 1932263363Semaste for (size_t k = k0; k < k1; ++k) 1933263363Semaste { 1934263363Semaste if (is_function) 1935263363Semaste { 1936263363Semaste size_t p = db.names[k].second.size(); 1937263363Semaste if (db.names[k].second[p-2] == '&') 1938263363Semaste p -= 3; 1939263363Semaste else if (db.names[k].second.back() == '&') 1940263363Semaste p -= 2; 1941263363Semaste if (cv & 1) 1942263363Semaste { 1943263363Semaste db.names[k].second.insert(p, " const"); 1944263363Semaste p += 6; 1945263363Semaste } 1946263363Semaste if (cv & 2) 1947263363Semaste { 1948263363Semaste db.names[k].second.insert(p, " volatile"); 1949263363Semaste p += 9; 1950263363Semaste } 1951263363Semaste if (cv & 4) 1952263363Semaste db.names[k].second.insert(p, " restrict"); 1953263363Semaste } 1954263363Semaste else 1955263363Semaste { 1956263363Semaste if (cv & 1) 1957263363Semaste db.names[k].first.append(" const"); 1958263363Semaste if (cv & 2) 1959263363Semaste db.names[k].first.append(" volatile"); 1960263363Semaste if (cv & 4) 1961263363Semaste db.names[k].first.append(" restrict"); 1962263363Semaste } 1963263363Semaste db.subs.back().push_back(db.names[k]); 1964263363Semaste } 1965263363Semaste first = t1; 1966263363Semaste } 1967263363Semaste } 1968263363Semaste } 1969263363Semaste break; 1970263363Semaste default: 1971263363Semaste { 1972263363Semaste const char* t = parse_builtin_type(first, last, db); 1973263363Semaste if (t != first) 1974263363Semaste { 1975263363Semaste first = t; 1976263363Semaste } 1977263363Semaste else 1978263363Semaste { 1979263363Semaste switch (*first) 1980263363Semaste { 1981263363Semaste case 'A': 1982263363Semaste t = parse_array_type(first, last, db); 1983263363Semaste if (t != first) 1984263363Semaste { 1985269024Semaste if (db.names.empty()) 1986269024Semaste return first; 1987263363Semaste first = t; 1988263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 1989263363Semaste } 1990263363Semaste break; 1991263363Semaste case 'C': 1992263363Semaste t = parse_type(first+1, last, db); 1993263363Semaste if (t != first+1) 1994263363Semaste { 1995269024Semaste if (db.names.empty()) 1996269024Semaste return first; 1997263363Semaste db.names.back().first.append(" complex"); 1998263363Semaste first = t; 1999263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2000263363Semaste } 2001263363Semaste break; 2002263363Semaste case 'F': 2003263363Semaste t = parse_function_type(first, last, db); 2004263363Semaste if (t != first) 2005263363Semaste { 2006269024Semaste if (db.names.empty()) 2007269024Semaste return first; 2008263363Semaste first = t; 2009263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2010263363Semaste } 2011263363Semaste break; 2012263363Semaste case 'G': 2013263363Semaste t = parse_type(first+1, last, db); 2014263363Semaste if (t != first+1) 2015263363Semaste { 2016269024Semaste if (db.names.empty()) 2017269024Semaste return first; 2018263363Semaste db.names.back().first.append(" imaginary"); 2019263363Semaste first = t; 2020263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2021263363Semaste } 2022263363Semaste break; 2023263363Semaste case 'M': 2024263363Semaste t = parse_pointer_to_member_type(first, last, db); 2025263363Semaste if (t != first) 2026263363Semaste { 2027269024Semaste if (db.names.empty()) 2028269024Semaste return first; 2029263363Semaste first = t; 2030263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2031263363Semaste } 2032263363Semaste break; 2033263363Semaste case 'O': 2034263363Semaste { 2035263363Semaste size_t k0 = db.names.size(); 2036263363Semaste t = parse_type(first+1, last, db); 2037263363Semaste size_t k1 = db.names.size(); 2038263363Semaste if (t != first+1) 2039263363Semaste { 2040263363Semaste db.subs.emplace_back(db.names.get_allocator()); 2041263363Semaste for (size_t k = k0; k < k1; ++k) 2042263363Semaste { 2043263363Semaste if (db.names[k].second.substr(0, 2) == " [") 2044263363Semaste { 2045263363Semaste db.names[k].first += " ("; 2046263363Semaste db.names[k].second.insert(0, ")"); 2047263363Semaste } 2048263363Semaste else if (db.names[k].second.front() == '(') 2049263363Semaste { 2050263363Semaste db.names[k].first += "("; 2051263363Semaste db.names[k].second.insert(0, ")"); 2052263363Semaste } 2053263363Semaste db.names[k].first.append("&&"); 2054263363Semaste db.subs.back().push_back(db.names[k]); 2055263363Semaste } 2056263363Semaste first = t; 2057263363Semaste } 2058263363Semaste break; 2059263363Semaste } 2060263363Semaste case 'P': 2061263363Semaste { 2062263363Semaste size_t k0 = db.names.size(); 2063263363Semaste t = parse_type(first+1, last, db); 2064263363Semaste size_t k1 = db.names.size(); 2065263363Semaste if (t != first+1) 2066263363Semaste { 2067263363Semaste db.subs.emplace_back(db.names.get_allocator()); 2068263363Semaste for (size_t k = k0; k < k1; ++k) 2069263363Semaste { 2070263363Semaste if (db.names[k].second.substr(0, 2) == " [") 2071263363Semaste { 2072263363Semaste db.names[k].first += " ("; 2073263363Semaste db.names[k].second.insert(0, ")"); 2074263363Semaste } 2075263363Semaste else if (db.names[k].second.front() == '(') 2076263363Semaste { 2077263363Semaste db.names[k].first += "("; 2078263363Semaste db.names[k].second.insert(0, ")"); 2079263363Semaste } 2080263363Semaste if (first[1] != 'U' || db.names[k].first.substr(0, 12) != "objc_object<") 2081263363Semaste { 2082263363Semaste db.names[k].first.append("*"); 2083263363Semaste } 2084263363Semaste else 2085263363Semaste { 2086263363Semaste db.names[k].first.replace(0, 11, "id"); 2087263363Semaste } 2088263363Semaste db.subs.back().push_back(db.names[k]); 2089263363Semaste } 2090263363Semaste first = t; 2091263363Semaste } 2092263363Semaste break; 2093263363Semaste } 2094263363Semaste case 'R': 2095263363Semaste { 2096263363Semaste size_t k0 = db.names.size(); 2097263363Semaste t = parse_type(first+1, last, db); 2098263363Semaste size_t k1 = db.names.size(); 2099263363Semaste if (t != first+1) 2100263363Semaste { 2101263363Semaste db.subs.emplace_back(db.names.get_allocator()); 2102263363Semaste for (size_t k = k0; k < k1; ++k) 2103263363Semaste { 2104263363Semaste if (db.names[k].second.substr(0, 2) == " [") 2105263363Semaste { 2106263363Semaste db.names[k].first += " ("; 2107263363Semaste db.names[k].second.insert(0, ")"); 2108263363Semaste } 2109263363Semaste else if (db.names[k].second.front() == '(') 2110263363Semaste { 2111263363Semaste db.names[k].first += "("; 2112263363Semaste db.names[k].second.insert(0, ")"); 2113263363Semaste } 2114263363Semaste db.names[k].first.append("&"); 2115263363Semaste db.subs.back().push_back(db.names[k]); 2116263363Semaste } 2117263363Semaste first = t; 2118263363Semaste } 2119263363Semaste break; 2120263363Semaste } 2121263363Semaste case 'T': 2122263363Semaste { 2123263363Semaste size_t k0 = db.names.size(); 2124263363Semaste t = parse_template_param(first, last, db); 2125263363Semaste size_t k1 = db.names.size(); 2126263363Semaste if (t != first) 2127263363Semaste { 2128263363Semaste db.subs.emplace_back(db.names.get_allocator()); 2129263363Semaste for (size_t k = k0; k < k1; ++k) 2130263363Semaste db.subs.back().push_back(db.names[k]); 2131263363Semaste if (db.try_to_parse_template_args && k1 == k0+1) 2132263363Semaste { 2133263363Semaste const char* t1 = parse_template_args(t, last, db); 2134263363Semaste if (t1 != t) 2135263363Semaste { 2136263363Semaste auto args = db.names.back().move_full(); 2137263363Semaste db.names.pop_back(); 2138263363Semaste db.names.back().first += std::move(args); 2139263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2140263363Semaste t = t1; 2141263363Semaste } 2142263363Semaste } 2143263363Semaste first = t; 2144263363Semaste } 2145263363Semaste break; 2146263363Semaste } 2147263363Semaste case 'U': 2148263363Semaste if (first+1 != last) 2149263363Semaste { 2150263363Semaste t = parse_source_name(first+1, last, db); 2151263363Semaste if (t != first+1) 2152263363Semaste { 2153263363Semaste const char* t2 = parse_type(t, last, db); 2154263363Semaste if (t2 != t) 2155263363Semaste { 2156269024Semaste if (db.names.size() < 2) 2157269024Semaste return first; 2158263363Semaste auto type = db.names.back().move_full(); 2159263363Semaste db.names.pop_back(); 2160263363Semaste if (db.names.back().first.substr(0, 9) != "objcproto") 2161263363Semaste { 2162263363Semaste db.names.back() = type + " " + db.names.back().move_full(); 2163263363Semaste } 2164263363Semaste else 2165263363Semaste { 2166263363Semaste auto proto = db.names.back().move_full(); 2167263363Semaste db.names.pop_back(); 2168263363Semaste t = parse_source_name(proto.data() + 9, proto.data() + proto.size(), db); 2169263363Semaste if (t != proto.data() + 9) 2170263363Semaste { 2171263363Semaste db.names.back() = type + "<" + db.names.back().move_full() + ">"; 2172263363Semaste } 2173263363Semaste else 2174263363Semaste { 2175263363Semaste db.names.push_back(type + " " + proto); 2176263363Semaste } 2177263363Semaste } 2178263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2179263363Semaste first = t2; 2180263363Semaste } 2181263363Semaste } 2182263363Semaste } 2183263363Semaste break; 2184263363Semaste case 'S': 2185263363Semaste if (first+1 != last && first[1] == 't') 2186263363Semaste { 2187263363Semaste t = parse_name(first, last, db); 2188263363Semaste if (t != first) 2189263363Semaste { 2190269024Semaste if (db.names.empty()) 2191269024Semaste return first; 2192263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2193263363Semaste first = t; 2194263363Semaste } 2195263363Semaste } 2196263363Semaste else 2197263363Semaste { 2198263363Semaste t = parse_substitution(first, last, db); 2199263363Semaste if (t != first) 2200263363Semaste { 2201263363Semaste first = t; 2202263363Semaste // Parsed a substitution. If the substitution is a 2203263363Semaste // <template-param> it might be followed by <template-args>. 2204263363Semaste t = parse_template_args(first, last, db); 2205263363Semaste if (t != first) 2206263363Semaste { 2207269024Semaste if (db.names.size() < 2) 2208269024Semaste return first; 2209263363Semaste auto template_args = db.names.back().move_full(); 2210263363Semaste db.names.pop_back(); 2211263363Semaste db.names.back().first += template_args; 2212263363Semaste // Need to create substitution for <template-template-param> <template-args> 2213263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2214263363Semaste first = t; 2215263363Semaste } 2216263363Semaste } 2217263363Semaste } 2218263363Semaste break; 2219263363Semaste case 'D': 2220263363Semaste if (first+1 != last) 2221263363Semaste { 2222263363Semaste switch (first[1]) 2223263363Semaste { 2224263363Semaste case 'p': 2225263363Semaste { 2226263363Semaste size_t k0 = db.names.size(); 2227263363Semaste t = parse_type(first+2, last, db); 2228263363Semaste size_t k1 = db.names.size(); 2229263363Semaste if (t != first+2) 2230263363Semaste { 2231263363Semaste db.subs.emplace_back(db.names.get_allocator()); 2232263363Semaste for (size_t k = k0; k < k1; ++k) 2233263363Semaste db.subs.back().push_back(db.names[k]); 2234263363Semaste first = t; 2235263363Semaste return first; 2236263363Semaste } 2237263363Semaste break; 2238263363Semaste } 2239263363Semaste case 't': 2240263363Semaste case 'T': 2241263363Semaste t = parse_decltype(first, last, db); 2242263363Semaste if (t != first) 2243263363Semaste { 2244269024Semaste if (db.names.empty()) 2245269024Semaste return first; 2246263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2247263363Semaste first = t; 2248263363Semaste return first; 2249263363Semaste } 2250263363Semaste break; 2251263363Semaste case 'v': 2252263363Semaste t = parse_vector_type(first, last, db); 2253263363Semaste if (t != first) 2254263363Semaste { 2255269024Semaste if (db.names.empty()) 2256269024Semaste return first; 2257263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2258263363Semaste first = t; 2259263363Semaste return first; 2260263363Semaste } 2261263363Semaste break; 2262263363Semaste } 2263263363Semaste } 2264263363Semaste // drop through 2265263363Semaste default: 2266263363Semaste // must check for builtin-types before class-enum-types to avoid 2267263363Semaste // ambiguities with operator-names 2268263363Semaste t = parse_builtin_type(first, last, db); 2269263363Semaste if (t != first) 2270263363Semaste { 2271263363Semaste first = t; 2272263363Semaste } 2273263363Semaste else 2274263363Semaste { 2275263363Semaste t = parse_name(first, last, db); 2276263363Semaste if (t != first) 2277263363Semaste { 2278269024Semaste if (db.names.empty()) 2279269024Semaste return first; 2280263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 2281263363Semaste first = t; 2282263363Semaste } 2283263363Semaste } 2284263363Semaste break; 2285263363Semaste } 2286263363Semaste } 2287263363Semaste break; 2288263363Semaste } 2289263363Semaste } 2290263363Semaste } 2291263363Semaste return first; 2292263363Semaste} 2293263363Semaste 2294263363Semaste// <operator-name> 2295263363Semaste// ::= aa # && 2296263363Semaste// ::= ad # & (unary) 2297263363Semaste// ::= an # & 2298263363Semaste// ::= aN # &= 2299263363Semaste// ::= aS # = 2300263363Semaste// ::= cl # () 2301263363Semaste// ::= cm # , 2302263363Semaste// ::= co # ~ 2303263363Semaste// ::= cv <type> # (cast) 2304263363Semaste// ::= da # delete[] 2305263363Semaste// ::= de # * (unary) 2306263363Semaste// ::= dl # delete 2307263363Semaste// ::= dv # / 2308263363Semaste// ::= dV # /= 2309263363Semaste// ::= eo # ^ 2310263363Semaste// ::= eO # ^= 2311263363Semaste// ::= eq # == 2312263363Semaste// ::= ge # >= 2313263363Semaste// ::= gt # > 2314263363Semaste// ::= ix # [] 2315263363Semaste// ::= le # <= 2316269024Semaste// ::= li <source-name> # operator "" 2317263363Semaste// ::= ls # << 2318263363Semaste// ::= lS # <<= 2319263363Semaste// ::= lt # < 2320263363Semaste// ::= mi # - 2321263363Semaste// ::= mI # -= 2322263363Semaste// ::= ml # * 2323263363Semaste// ::= mL # *= 2324263363Semaste// ::= mm # -- (postfix in <expression> context) 2325263363Semaste// ::= na # new[] 2326263363Semaste// ::= ne # != 2327263363Semaste// ::= ng # - (unary) 2328263363Semaste// ::= nt # ! 2329263363Semaste// ::= nw # new 2330263363Semaste// ::= oo # || 2331263363Semaste// ::= or # | 2332263363Semaste// ::= oR # |= 2333263363Semaste// ::= pm # ->* 2334263363Semaste// ::= pl # + 2335263363Semaste// ::= pL # += 2336263363Semaste// ::= pp # ++ (postfix in <expression> context) 2337263363Semaste// ::= ps # + (unary) 2338263363Semaste// ::= pt # -> 2339263363Semaste// ::= qu # ? 2340263363Semaste// ::= rm # % 2341263363Semaste// ::= rM # %= 2342263363Semaste// ::= rs # >> 2343263363Semaste// ::= rS # >>= 2344263363Semaste// ::= v <digit> <source-name> # vendor extended operator 2345263363Semaste 2346263363Semastetemplate <class C> 2347263363Semasteconst char* 2348263363Semasteparse_operator_name(const char* first, const char* last, C& db) 2349263363Semaste{ 2350263363Semaste if (last - first >= 2) 2351263363Semaste { 2352263363Semaste switch (first[0]) 2353263363Semaste { 2354263363Semaste case 'a': 2355263363Semaste switch (first[1]) 2356263363Semaste { 2357263363Semaste case 'a': 2358263363Semaste db.names.push_back("operator&&"); 2359263363Semaste first += 2; 2360263363Semaste break; 2361263363Semaste case 'd': 2362263363Semaste case 'n': 2363263363Semaste db.names.push_back("operator&"); 2364263363Semaste first += 2; 2365263363Semaste break; 2366263363Semaste case 'N': 2367263363Semaste db.names.push_back("operator&="); 2368263363Semaste first += 2; 2369263363Semaste break; 2370263363Semaste case 'S': 2371263363Semaste db.names.push_back("operator="); 2372263363Semaste first += 2; 2373263363Semaste break; 2374263363Semaste } 2375263363Semaste break; 2376263363Semaste case 'c': 2377263363Semaste switch (first[1]) 2378263363Semaste { 2379263363Semaste case 'l': 2380263363Semaste db.names.push_back("operator()"); 2381263363Semaste first += 2; 2382263363Semaste break; 2383263363Semaste case 'm': 2384263363Semaste db.names.push_back("operator,"); 2385263363Semaste first += 2; 2386263363Semaste break; 2387263363Semaste case 'o': 2388263363Semaste db.names.push_back("operator~"); 2389263363Semaste first += 2; 2390263363Semaste break; 2391263363Semaste case 'v': 2392263363Semaste { 2393263363Semaste bool try_to_parse_template_args = db.try_to_parse_template_args; 2394263363Semaste db.try_to_parse_template_args = false; 2395263363Semaste const char* t = parse_type(first+2, last, db); 2396263363Semaste db.try_to_parse_template_args = try_to_parse_template_args; 2397263363Semaste if (t != first+2) 2398263363Semaste { 2399269024Semaste if (db.names.empty()) 2400269024Semaste return first; 2401263363Semaste db.names.back().first.insert(0, "operator "); 2402263363Semaste db.parsed_ctor_dtor_cv = true; 2403263363Semaste first = t; 2404263363Semaste } 2405263363Semaste } 2406263363Semaste break; 2407263363Semaste } 2408263363Semaste break; 2409263363Semaste case 'd': 2410263363Semaste switch (first[1]) 2411263363Semaste { 2412263363Semaste case 'a': 2413263363Semaste db.names.push_back("operator delete[]"); 2414263363Semaste first += 2; 2415263363Semaste break; 2416263363Semaste case 'e': 2417263363Semaste db.names.push_back("operator*"); 2418263363Semaste first += 2; 2419263363Semaste break; 2420263363Semaste case 'l': 2421263363Semaste db.names.push_back("operator delete"); 2422263363Semaste first += 2; 2423263363Semaste break; 2424263363Semaste case 'v': 2425263363Semaste db.names.push_back("operator/"); 2426263363Semaste first += 2; 2427263363Semaste break; 2428263363Semaste case 'V': 2429263363Semaste db.names.push_back("operator/="); 2430263363Semaste first += 2; 2431263363Semaste break; 2432263363Semaste } 2433263363Semaste break; 2434263363Semaste case 'e': 2435263363Semaste switch (first[1]) 2436263363Semaste { 2437263363Semaste case 'o': 2438263363Semaste db.names.push_back("operator^"); 2439263363Semaste first += 2; 2440263363Semaste break; 2441263363Semaste case 'O': 2442263363Semaste db.names.push_back("operator^="); 2443263363Semaste first += 2; 2444263363Semaste break; 2445263363Semaste case 'q': 2446263363Semaste db.names.push_back("operator=="); 2447263363Semaste first += 2; 2448263363Semaste break; 2449263363Semaste } 2450263363Semaste break; 2451263363Semaste case 'g': 2452263363Semaste switch (first[1]) 2453263363Semaste { 2454263363Semaste case 'e': 2455263363Semaste db.names.push_back("operator>="); 2456263363Semaste first += 2; 2457263363Semaste break; 2458263363Semaste case 't': 2459263363Semaste db.names.push_back("operator>"); 2460263363Semaste first += 2; 2461263363Semaste break; 2462263363Semaste } 2463263363Semaste break; 2464263363Semaste case 'i': 2465263363Semaste if (first[1] == 'x') 2466263363Semaste { 2467263363Semaste db.names.push_back("operator[]"); 2468263363Semaste first += 2; 2469263363Semaste } 2470263363Semaste break; 2471263363Semaste case 'l': 2472263363Semaste switch (first[1]) 2473263363Semaste { 2474263363Semaste case 'e': 2475263363Semaste db.names.push_back("operator<="); 2476263363Semaste first += 2; 2477263363Semaste break; 2478269024Semaste case 'i': 2479269024Semaste { 2480269024Semaste const char* t = parse_source_name(first+2, last, db); 2481269024Semaste if (t != first+2) 2482269024Semaste { 2483269024Semaste if (db.names.empty()) 2484269024Semaste return first; 2485269024Semaste db.names.back().first.insert(0, "operator\"\" "); 2486269024Semaste first = t; 2487269024Semaste } 2488269024Semaste } 2489269024Semaste break; 2490263363Semaste case 's': 2491263363Semaste db.names.push_back("operator<<"); 2492263363Semaste first += 2; 2493263363Semaste break; 2494263363Semaste case 'S': 2495263363Semaste db.names.push_back("operator<<="); 2496263363Semaste first += 2; 2497263363Semaste break; 2498263363Semaste case 't': 2499263363Semaste db.names.push_back("operator<"); 2500263363Semaste first += 2; 2501263363Semaste break; 2502263363Semaste } 2503263363Semaste break; 2504263363Semaste case 'm': 2505263363Semaste switch (first[1]) 2506263363Semaste { 2507263363Semaste case 'i': 2508263363Semaste db.names.push_back("operator-"); 2509263363Semaste first += 2; 2510263363Semaste break; 2511263363Semaste case 'I': 2512263363Semaste db.names.push_back("operator-="); 2513263363Semaste first += 2; 2514263363Semaste break; 2515263363Semaste case 'l': 2516263363Semaste db.names.push_back("operator*"); 2517263363Semaste first += 2; 2518263363Semaste break; 2519263363Semaste case 'L': 2520263363Semaste db.names.push_back("operator*="); 2521263363Semaste first += 2; 2522263363Semaste break; 2523263363Semaste case 'm': 2524263363Semaste db.names.push_back("operator--"); 2525263363Semaste first += 2; 2526263363Semaste break; 2527263363Semaste } 2528263363Semaste break; 2529263363Semaste case 'n': 2530263363Semaste switch (first[1]) 2531263363Semaste { 2532263363Semaste case 'a': 2533263363Semaste db.names.push_back("operator new[]"); 2534263363Semaste first += 2; 2535263363Semaste break; 2536263363Semaste case 'e': 2537263363Semaste db.names.push_back("operator!="); 2538263363Semaste first += 2; 2539263363Semaste break; 2540263363Semaste case 'g': 2541263363Semaste db.names.push_back("operator-"); 2542263363Semaste first += 2; 2543263363Semaste break; 2544263363Semaste case 't': 2545263363Semaste db.names.push_back("operator!"); 2546263363Semaste first += 2; 2547263363Semaste break; 2548263363Semaste case 'w': 2549263363Semaste db.names.push_back("operator new"); 2550263363Semaste first += 2; 2551263363Semaste break; 2552263363Semaste } 2553263363Semaste break; 2554263363Semaste case 'o': 2555263363Semaste switch (first[1]) 2556263363Semaste { 2557263363Semaste case 'o': 2558263363Semaste db.names.push_back("operator||"); 2559263363Semaste first += 2; 2560263363Semaste break; 2561263363Semaste case 'r': 2562263363Semaste db.names.push_back("operator|"); 2563263363Semaste first += 2; 2564263363Semaste break; 2565263363Semaste case 'R': 2566263363Semaste db.names.push_back("operator|="); 2567263363Semaste first += 2; 2568263363Semaste break; 2569263363Semaste } 2570263363Semaste break; 2571263363Semaste case 'p': 2572263363Semaste switch (first[1]) 2573263363Semaste { 2574263363Semaste case 'm': 2575263363Semaste db.names.push_back("operator->*"); 2576263363Semaste first += 2; 2577263363Semaste break; 2578263363Semaste case 'l': 2579263363Semaste db.names.push_back("operator+"); 2580263363Semaste first += 2; 2581263363Semaste break; 2582263363Semaste case 'L': 2583263363Semaste db.names.push_back("operator+="); 2584263363Semaste first += 2; 2585263363Semaste break; 2586263363Semaste case 'p': 2587263363Semaste db.names.push_back("operator++"); 2588263363Semaste first += 2; 2589263363Semaste break; 2590263363Semaste case 's': 2591263363Semaste db.names.push_back("operator+"); 2592263363Semaste first += 2; 2593263363Semaste break; 2594263363Semaste case 't': 2595263363Semaste db.names.push_back("operator->"); 2596263363Semaste first += 2; 2597263363Semaste break; 2598263363Semaste } 2599263363Semaste break; 2600263363Semaste case 'q': 2601263363Semaste if (first[1] == 'u') 2602263363Semaste { 2603263363Semaste db.names.push_back("operator?"); 2604263363Semaste first += 2; 2605263363Semaste } 2606263363Semaste break; 2607263363Semaste case 'r': 2608263363Semaste switch (first[1]) 2609263363Semaste { 2610263363Semaste case 'm': 2611263363Semaste db.names.push_back("operator%"); 2612263363Semaste first += 2; 2613263363Semaste break; 2614263363Semaste case 'M': 2615263363Semaste db.names.push_back("operator%="); 2616263363Semaste first += 2; 2617263363Semaste break; 2618263363Semaste case 's': 2619263363Semaste db.names.push_back("operator>>"); 2620263363Semaste first += 2; 2621263363Semaste break; 2622263363Semaste case 'S': 2623263363Semaste db.names.push_back("operator>>="); 2624263363Semaste first += 2; 2625263363Semaste break; 2626263363Semaste } 2627263363Semaste break; 2628263363Semaste case 'v': 2629263363Semaste if (std::isdigit(first[1])) 2630263363Semaste { 2631263363Semaste const char* t = parse_source_name(first+2, last, db); 2632263363Semaste if (t != first+2) 2633263363Semaste { 2634269024Semaste if (db.names.empty()) 2635269024Semaste return first; 2636263363Semaste db.names.back().first.insert(0, "operator "); 2637263363Semaste first = t; 2638263363Semaste } 2639263363Semaste } 2640263363Semaste break; 2641263363Semaste } 2642263363Semaste } 2643263363Semaste return first; 2644263363Semaste} 2645263363Semaste 2646263363Semastetemplate <class C> 2647263363Semasteconst char* 2648263363Semasteparse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db) 2649263363Semaste{ 2650263363Semaste const char* t = parse_number(first, last); 2651263363Semaste if (t != first && t != last && *t == 'E') 2652263363Semaste { 2653263363Semaste if (lit.size() > 3) 2654263363Semaste db.names.push_back("(" + lit + ")"); 2655263363Semaste else 2656263363Semaste db.names.emplace_back(); 2657263363Semaste if (*first == 'n') 2658263363Semaste { 2659263363Semaste db.names.back().first += '-'; 2660263363Semaste ++first; 2661263363Semaste } 2662263363Semaste db.names.back().first.append(first, t); 2663263363Semaste if (lit.size() <= 3) 2664263363Semaste db.names.back().first += lit; 2665263363Semaste first = t+1; 2666263363Semaste } 2667263363Semaste return first; 2668263363Semaste} 2669263363Semaste 2670263363Semaste// <expr-primary> ::= L <type> <value number> E # integer literal 2671263363Semaste// ::= L <type> <value float> E # floating literal 2672263363Semaste// ::= L <string type> E # string literal 2673263363Semaste// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE") 2674263363Semaste// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000) 2675263363Semaste// ::= L <mangled-name> E # external name 2676263363Semaste 2677263363Semastetemplate <class C> 2678263363Semasteconst char* 2679263363Semasteparse_expr_primary(const char* first, const char* last, C& db) 2680263363Semaste{ 2681263363Semaste if (last - first >= 4 && *first == 'L') 2682263363Semaste { 2683263363Semaste switch (first[1]) 2684263363Semaste { 2685263363Semaste case 'w': 2686263363Semaste { 2687263363Semaste const char* t = parse_integer_literal(first+2, last, "wchar_t", db); 2688263363Semaste if (t != first+2) 2689263363Semaste first = t; 2690263363Semaste } 2691263363Semaste break; 2692263363Semaste case 'b': 2693263363Semaste if (first[3] == 'E') 2694263363Semaste { 2695263363Semaste switch (first[2]) 2696263363Semaste { 2697263363Semaste case '0': 2698263363Semaste db.names.push_back("false"); 2699263363Semaste first += 4; 2700263363Semaste break; 2701263363Semaste case '1': 2702263363Semaste db.names.push_back("true"); 2703263363Semaste first += 4; 2704263363Semaste break; 2705263363Semaste } 2706263363Semaste } 2707263363Semaste break; 2708263363Semaste case 'c': 2709263363Semaste { 2710263363Semaste const char* t = parse_integer_literal(first+2, last, "char", db); 2711263363Semaste if (t != first+2) 2712263363Semaste first = t; 2713263363Semaste } 2714263363Semaste break; 2715263363Semaste case 'a': 2716263363Semaste { 2717263363Semaste const char* t = parse_integer_literal(first+2, last, "signed char", db); 2718263363Semaste if (t != first+2) 2719263363Semaste first = t; 2720263363Semaste } 2721263363Semaste break; 2722263363Semaste case 'h': 2723263363Semaste { 2724263363Semaste const char* t = parse_integer_literal(first+2, last, "unsigned char", db); 2725263363Semaste if (t != first+2) 2726263363Semaste first = t; 2727263363Semaste } 2728263363Semaste break; 2729263363Semaste case 's': 2730263363Semaste { 2731263363Semaste const char* t = parse_integer_literal(first+2, last, "short", db); 2732263363Semaste if (t != first+2) 2733263363Semaste first = t; 2734263363Semaste } 2735263363Semaste break; 2736263363Semaste case 't': 2737263363Semaste { 2738263363Semaste const char* t = parse_integer_literal(first+2, last, "unsigned short", db); 2739263363Semaste if (t != first+2) 2740263363Semaste first = t; 2741263363Semaste } 2742263363Semaste break; 2743263363Semaste case 'i': 2744263363Semaste { 2745263363Semaste const char* t = parse_integer_literal(first+2, last, "", db); 2746263363Semaste if (t != first+2) 2747263363Semaste first = t; 2748263363Semaste } 2749263363Semaste break; 2750263363Semaste case 'j': 2751263363Semaste { 2752263363Semaste const char* t = parse_integer_literal(first+2, last, "u", db); 2753263363Semaste if (t != first+2) 2754263363Semaste first = t; 2755263363Semaste } 2756263363Semaste break; 2757263363Semaste case 'l': 2758263363Semaste { 2759263363Semaste const char* t = parse_integer_literal(first+2, last, "l", db); 2760263363Semaste if (t != first+2) 2761263363Semaste first = t; 2762263363Semaste } 2763263363Semaste break; 2764263363Semaste case 'm': 2765263363Semaste { 2766263363Semaste const char* t = parse_integer_literal(first+2, last, "ul", db); 2767263363Semaste if (t != first+2) 2768263363Semaste first = t; 2769263363Semaste } 2770263363Semaste break; 2771263363Semaste case 'x': 2772263363Semaste { 2773263363Semaste const char* t = parse_integer_literal(first+2, last, "ll", db); 2774263363Semaste if (t != first+2) 2775263363Semaste first = t; 2776263363Semaste } 2777263363Semaste break; 2778263363Semaste case 'y': 2779263363Semaste { 2780263363Semaste const char* t = parse_integer_literal(first+2, last, "ull", db); 2781263363Semaste if (t != first+2) 2782263363Semaste first = t; 2783263363Semaste } 2784263363Semaste break; 2785263363Semaste case 'n': 2786263363Semaste { 2787263363Semaste const char* t = parse_integer_literal(first+2, last, "__int128", db); 2788263363Semaste if (t != first+2) 2789263363Semaste first = t; 2790263363Semaste } 2791263363Semaste break; 2792263363Semaste case 'o': 2793263363Semaste { 2794263363Semaste const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db); 2795263363Semaste if (t != first+2) 2796263363Semaste first = t; 2797263363Semaste } 2798263363Semaste break; 2799263363Semaste case 'f': 2800263363Semaste { 2801263363Semaste const char* t = parse_floating_number<float>(first+2, last, db); 2802263363Semaste if (t != first+2) 2803263363Semaste first = t; 2804263363Semaste } 2805263363Semaste break; 2806263363Semaste case 'd': 2807263363Semaste { 2808263363Semaste const char* t = parse_floating_number<double>(first+2, last, db); 2809263363Semaste if (t != first+2) 2810263363Semaste first = t; 2811263363Semaste } 2812263363Semaste break; 2813263363Semaste case 'e': 2814263363Semaste { 2815263363Semaste const char* t = parse_floating_number<long double>(first+2, last, db); 2816263363Semaste if (t != first+2) 2817263363Semaste first = t; 2818263363Semaste } 2819263363Semaste break; 2820263363Semaste case '_': 2821263363Semaste if (first[2] == 'Z') 2822263363Semaste { 2823263363Semaste const char* t = parse_encoding(first+3, last, db); 2824263363Semaste if (t != first+3 && t != last && *t == 'E') 2825263363Semaste first = t+1; 2826263363Semaste } 2827263363Semaste break; 2828263363Semaste case 'T': 2829263363Semaste // Invalid mangled name per 2830263363Semaste // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html 2831263363Semaste break; 2832263363Semaste default: 2833263363Semaste { 2834263363Semaste // might be named type 2835263363Semaste const char* t = parse_type(first+1, last, db); 2836263363Semaste if (t != first+1 && t != last) 2837263363Semaste { 2838263363Semaste if (*t != 'E') 2839263363Semaste { 2840263363Semaste const char* n = t; 2841263363Semaste for (; n != last && isdigit(*n); ++n) 2842263363Semaste ; 2843263363Semaste if (n != t && n != last && *n == 'E') 2844263363Semaste { 2845269024Semaste if (db.names.empty()) 2846269024Semaste return first; 2847263363Semaste db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n); 2848263363Semaste first = n+1; 2849263363Semaste break; 2850263363Semaste } 2851263363Semaste } 2852263363Semaste else 2853263363Semaste { 2854263363Semaste first = t+1; 2855263363Semaste break; 2856263363Semaste } 2857263363Semaste } 2858263363Semaste } 2859263363Semaste } 2860263363Semaste } 2861263363Semaste return first; 2862263363Semaste} 2863263363Semaste 2864263363Semastetemplate <class String> 2865263363SemasteString 2866263363Semastebase_name(String& s) 2867263363Semaste{ 2868263363Semaste if (s.empty()) 2869263363Semaste return s; 2870263363Semaste if (s == "std::string") 2871263363Semaste { 2872263363Semaste s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"; 2873263363Semaste return "basic_string"; 2874263363Semaste } 2875263363Semaste if (s == "std::istream") 2876263363Semaste { 2877263363Semaste s = "std::basic_istream<char, std::char_traits<char> >"; 2878263363Semaste return "basic_istream"; 2879263363Semaste } 2880263363Semaste if (s == "std::ostream") 2881263363Semaste { 2882263363Semaste s = "std::basic_ostream<char, std::char_traits<char> >"; 2883263363Semaste return "basic_ostream"; 2884263363Semaste } 2885263363Semaste if (s == "std::iostream") 2886263363Semaste { 2887263363Semaste s = "std::basic_iostream<char, std::char_traits<char> >"; 2888263363Semaste return "basic_iostream"; 2889263363Semaste } 2890263363Semaste const char* const pf = s.data(); 2891263363Semaste const char* pe = pf + s.size(); 2892263363Semaste if (pe[-1] == '>') 2893263363Semaste { 2894263363Semaste unsigned c = 1; 2895263363Semaste while (true) 2896263363Semaste { 2897263363Semaste if (--pe == pf) 2898263363Semaste return String(); 2899263363Semaste if (pe[-1] == '<') 2900263363Semaste { 2901263363Semaste if (--c == 0) 2902263363Semaste { 2903263363Semaste --pe; 2904263363Semaste break; 2905263363Semaste } 2906263363Semaste } 2907263363Semaste else if (pe[-1] == '>') 2908263363Semaste ++c; 2909263363Semaste } 2910263363Semaste } 2911263363Semaste const char* p0 = pe - 1; 2912263363Semaste for (; p0 != pf; --p0) 2913263363Semaste { 2914263363Semaste if (*p0 == ':') 2915263363Semaste { 2916263363Semaste ++p0; 2917263363Semaste break; 2918263363Semaste } 2919263363Semaste } 2920263363Semaste return String(p0, pe); 2921263363Semaste} 2922263363Semaste 2923263363Semaste// <ctor-dtor-name> ::= C1 # complete object constructor 2924263363Semaste// ::= C2 # base object constructor 2925263363Semaste// ::= C3 # complete object allocating constructor 2926263363Semaste// extension ::= C5 # ? 2927263363Semaste// ::= D0 # deleting destructor 2928263363Semaste// ::= D1 # complete object destructor 2929263363Semaste// ::= D2 # base object destructor 2930263363Semaste// extension ::= D5 # ? 2931263363Semaste 2932263363Semastetemplate <class C> 2933263363Semasteconst char* 2934263363Semasteparse_ctor_dtor_name(const char* first, const char* last, C& db) 2935263363Semaste{ 2936263363Semaste if (last-first >= 2 && !db.names.empty()) 2937263363Semaste { 2938263363Semaste switch (first[0]) 2939263363Semaste { 2940263363Semaste case 'C': 2941263363Semaste switch (first[1]) 2942263363Semaste { 2943263363Semaste case '1': 2944263363Semaste case '2': 2945263363Semaste case '3': 2946263363Semaste case '5': 2947269024Semaste if (db.names.empty()) 2948269024Semaste return first; 2949263363Semaste db.names.push_back(base_name(db.names.back().first)); 2950263363Semaste first += 2; 2951263363Semaste db.parsed_ctor_dtor_cv = true; 2952263363Semaste break; 2953263363Semaste } 2954263363Semaste break; 2955263363Semaste case 'D': 2956263363Semaste switch (first[1]) 2957263363Semaste { 2958263363Semaste case '0': 2959263363Semaste case '1': 2960263363Semaste case '2': 2961263363Semaste case '5': 2962269024Semaste if (db.names.empty()) 2963269024Semaste return first; 2964263363Semaste db.names.push_back("~" + base_name(db.names.back().first)); 2965263363Semaste first += 2; 2966263363Semaste db.parsed_ctor_dtor_cv = true; 2967263363Semaste break; 2968263363Semaste } 2969263363Semaste break; 2970263363Semaste } 2971263363Semaste } 2972263363Semaste return first; 2973263363Semaste} 2974263363Semaste 2975263363Semaste// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _ 2976263363Semaste// ::= <closure-type-name> 2977263363Semaste// 2978263363Semaste// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ 2979263363Semaste// 2980263363Semaste// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters 2981263363Semaste 2982263363Semastetemplate <class C> 2983263363Semasteconst char* 2984263363Semasteparse_unnamed_type_name(const char* first, const char* last, C& db) 2985263363Semaste{ 2986263363Semaste if (last - first > 2 && first[0] == 'U') 2987263363Semaste { 2988263363Semaste char type = first[1]; 2989263363Semaste switch (type) 2990263363Semaste { 2991263363Semaste case 't': 2992263363Semaste { 2993263363Semaste db.names.push_back(typename C::String("'unnamed")); 2994263363Semaste const char* t0 = first+2; 2995263363Semaste if (t0 == last) 2996263363Semaste { 2997263363Semaste db.names.pop_back(); 2998263363Semaste return first; 2999263363Semaste } 3000263363Semaste if (std::isdigit(*t0)) 3001263363Semaste { 3002263363Semaste const char* t1 = t0 + 1; 3003263363Semaste while (t1 != last && std::isdigit(*t1)) 3004263363Semaste ++t1; 3005263363Semaste db.names.back().first.append(t0, t1); 3006263363Semaste t0 = t1; 3007263363Semaste } 3008263363Semaste db.names.back().first.push_back('\''); 3009263363Semaste if (t0 == last || *t0 != '_') 3010263363Semaste { 3011263363Semaste db.names.pop_back(); 3012263363Semaste return first; 3013263363Semaste } 3014263363Semaste first = t0 + 1; 3015263363Semaste } 3016263363Semaste break; 3017263363Semaste case 'l': 3018263363Semaste { 3019263363Semaste db.names.push_back(typename C::String("'lambda'(")); 3020263363Semaste const char* t0 = first+2; 3021263363Semaste if (first[2] == 'v') 3022263363Semaste { 3023263363Semaste db.names.back().first += ')'; 3024263363Semaste ++t0; 3025263363Semaste } 3026263363Semaste else 3027263363Semaste { 3028263363Semaste const char* t1 = parse_type(t0, last, db); 3029263363Semaste if (t1 == t0) 3030263363Semaste { 3031263363Semaste db.names.pop_back(); 3032263363Semaste return first; 3033263363Semaste } 3034269024Semaste if (db.names.size() < 2) 3035269024Semaste return first; 3036263363Semaste auto tmp = db.names.back().move_full(); 3037263363Semaste db.names.pop_back(); 3038263363Semaste db.names.back().first.append(tmp); 3039263363Semaste t0 = t1; 3040263363Semaste while (true) 3041263363Semaste { 3042263363Semaste t1 = parse_type(t0, last, db); 3043263363Semaste if (t1 == t0) 3044263363Semaste break; 3045269024Semaste if (db.names.size() < 2) 3046269024Semaste return first; 3047263363Semaste tmp = db.names.back().move_full(); 3048263363Semaste db.names.pop_back(); 3049263363Semaste if (!tmp.empty()) 3050263363Semaste { 3051263363Semaste db.names.back().first.append(", "); 3052263363Semaste db.names.back().first.append(tmp); 3053263363Semaste } 3054263363Semaste t0 = t1; 3055263363Semaste } 3056263363Semaste db.names.back().first.append(")"); 3057263363Semaste } 3058263363Semaste if (t0 == last || *t0 != 'E') 3059263363Semaste { 3060263363Semaste db.names.pop_back(); 3061263363Semaste return first; 3062263363Semaste } 3063263363Semaste ++t0; 3064263363Semaste if (t0 == last) 3065263363Semaste { 3066263363Semaste db.names.pop_back(); 3067263363Semaste return first; 3068263363Semaste } 3069263363Semaste if (std::isdigit(*t0)) 3070263363Semaste { 3071263363Semaste const char* t1 = t0 + 1; 3072263363Semaste while (t1 != last && std::isdigit(*t1)) 3073263363Semaste ++t1; 3074263363Semaste db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1); 3075263363Semaste t0 = t1; 3076263363Semaste } 3077263363Semaste if (t0 == last || *t0 != '_') 3078263363Semaste { 3079263363Semaste db.names.pop_back(); 3080263363Semaste return first; 3081263363Semaste } 3082263363Semaste first = t0 + 1; 3083263363Semaste } 3084263363Semaste break; 3085263363Semaste } 3086263363Semaste } 3087263363Semaste return first; 3088263363Semaste} 3089263363Semaste 3090263363Semaste// <unqualified-name> ::= <operator-name> 3091263363Semaste// ::= <ctor-dtor-name> 3092263363Semaste// ::= <source-name> 3093263363Semaste// ::= <unnamed-type-name> 3094263363Semaste 3095263363Semastetemplate <class C> 3096263363Semasteconst char* 3097263363Semasteparse_unqualified_name(const char* first, const char* last, C& db) 3098263363Semaste{ 3099263363Semaste if (first != last) 3100263363Semaste { 3101263363Semaste const char* t; 3102263363Semaste switch (*first) 3103263363Semaste { 3104263363Semaste case 'C': 3105263363Semaste case 'D': 3106263363Semaste t = parse_ctor_dtor_name(first, last, db); 3107263363Semaste if (t != first) 3108263363Semaste first = t; 3109263363Semaste break; 3110263363Semaste case 'U': 3111263363Semaste t = parse_unnamed_type_name(first, last, db); 3112263363Semaste if (t != first) 3113263363Semaste first = t; 3114263363Semaste break; 3115263363Semaste case '1': 3116263363Semaste case '2': 3117263363Semaste case '3': 3118263363Semaste case '4': 3119263363Semaste case '5': 3120263363Semaste case '6': 3121263363Semaste case '7': 3122263363Semaste case '8': 3123263363Semaste case '9': 3124263363Semaste t = parse_source_name(first, last, db); 3125263363Semaste if (t != first) 3126263363Semaste first = t; 3127263363Semaste break; 3128263363Semaste default: 3129263363Semaste t = parse_operator_name(first, last, db); 3130263363Semaste if (t != first) 3131263363Semaste first = t; 3132263363Semaste break; 3133263363Semaste }; 3134263363Semaste } 3135263363Semaste return first; 3136263363Semaste} 3137263363Semaste 3138263363Semaste// <unscoped-name> ::= <unqualified-name> 3139263363Semaste// ::= St <unqualified-name> # ::std:: 3140263363Semaste// extension ::= StL<unqualified-name> 3141263363Semaste 3142263363Semastetemplate <class C> 3143263363Semasteconst char* 3144263363Semasteparse_unscoped_name(const char* first, const char* last, C& db) 3145263363Semaste{ 3146263363Semaste if (last - first >= 2) 3147263363Semaste { 3148263363Semaste const char* t0 = first; 3149263363Semaste bool St = false; 3150263363Semaste if (first[0] == 'S' && first[1] == 't') 3151263363Semaste { 3152263363Semaste t0 += 2; 3153263363Semaste St = true; 3154263363Semaste if (t0 != last && *t0 == 'L') 3155263363Semaste ++t0; 3156263363Semaste } 3157263363Semaste const char* t1 = parse_unqualified_name(t0, last, db); 3158263363Semaste if (t1 != t0) 3159263363Semaste { 3160263363Semaste if (St) 3161269024Semaste { 3162269024Semaste if (db.names.empty()) 3163269024Semaste return first; 3164263363Semaste db.names.back().first.insert(0, "std::"); 3165269024Semaste } 3166263363Semaste first = t1; 3167263363Semaste } 3168263363Semaste } 3169263363Semaste return first; 3170263363Semaste} 3171263363Semaste 3172263363Semaste// at <type> # alignof (a type) 3173263363Semaste 3174263363Semastetemplate <class C> 3175263363Semasteconst char* 3176263363Semasteparse_alignof_type(const char* first, const char* last, C& db) 3177263363Semaste{ 3178263363Semaste if (last - first >= 3 && first[0] == 'a' && first[1] == 't') 3179263363Semaste { 3180263363Semaste const char* t = parse_type(first+2, last, db); 3181263363Semaste if (t != first+2) 3182263363Semaste { 3183269024Semaste if (db.names.empty()) 3184269024Semaste return first; 3185263363Semaste db.names.back().first = "alignof (" + db.names.back().move_full() + ")"; 3186263363Semaste first = t; 3187263363Semaste } 3188263363Semaste } 3189263363Semaste return first; 3190263363Semaste} 3191263363Semaste 3192263363Semaste// az <expression> # alignof (a expression) 3193263363Semaste 3194263363Semastetemplate <class C> 3195263363Semasteconst char* 3196263363Semasteparse_alignof_expr(const char* first, const char* last, C& db) 3197263363Semaste{ 3198263363Semaste if (last - first >= 3 && first[0] == 'a' && first[1] == 'z') 3199263363Semaste { 3200263363Semaste const char* t = parse_expression(first+2, last, db); 3201263363Semaste if (t != first+2) 3202263363Semaste { 3203269024Semaste if (db.names.empty()) 3204269024Semaste return first; 3205263363Semaste db.names.back().first = "alignof (" + db.names.back().move_full() + ")"; 3206263363Semaste first = t; 3207263363Semaste } 3208263363Semaste } 3209263363Semaste return first; 3210263363Semaste} 3211263363Semaste 3212263363Semastetemplate <class C> 3213263363Semasteconst char* 3214263363Semasteparse_noexcept_expression(const char* first, const char* last, C& db) 3215263363Semaste{ 3216263363Semaste const char* t1 = parse_expression(first, last, db); 3217263363Semaste if (t1 != first) 3218263363Semaste { 3219269024Semaste if (db.names.empty()) 3220269024Semaste return first; 3221263363Semaste db.names.back().first = "noexcept (" + db.names.back().move_full() + ")"; 3222263363Semaste first = t1; 3223263363Semaste } 3224263363Semaste return first; 3225263363Semaste} 3226263363Semaste 3227263363Semastetemplate <class C> 3228263363Semasteconst char* 3229263363Semasteparse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db) 3230263363Semaste{ 3231263363Semaste const char* t1 = parse_expression(first, last, db); 3232263363Semaste if (t1 != first) 3233263363Semaste { 3234269024Semaste if (db.names.empty()) 3235269024Semaste return first; 3236263363Semaste db.names.back().first = op + "(" + db.names.back().move_full() + ")"; 3237263363Semaste first = t1; 3238263363Semaste } 3239263363Semaste return first; 3240263363Semaste} 3241263363Semaste 3242263363Semastetemplate <class C> 3243263363Semasteconst char* 3244263363Semasteparse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db) 3245263363Semaste{ 3246263363Semaste const char* t1 = parse_expression(first, last, db); 3247263363Semaste if (t1 != first) 3248263363Semaste { 3249263363Semaste const char* t2 = parse_expression(t1, last, db); 3250263363Semaste if (t2 != t1) 3251263363Semaste { 3252269024Semaste if (db.names.size() < 2) 3253269024Semaste return first; 3254263363Semaste auto op2 = db.names.back().move_full(); 3255263363Semaste db.names.pop_back(); 3256263363Semaste auto op1 = db.names.back().move_full(); 3257263363Semaste auto& nm = db.names.back().first; 3258263363Semaste nm.clear(); 3259263363Semaste if (op == ">") 3260263363Semaste nm += '('; 3261263363Semaste nm += "(" + op1 + ") " + op + " (" + op2 + ")"; 3262263363Semaste if (op == ">") 3263263363Semaste nm += ')'; 3264263363Semaste first = t2; 3265263363Semaste } 3266263363Semaste else 3267263363Semaste db.names.pop_back(); 3268263363Semaste } 3269263363Semaste return first; 3270263363Semaste} 3271263363Semaste 3272263363Semaste// <expression> ::= <unary operator-name> <expression> 3273263363Semaste// ::= <binary operator-name> <expression> <expression> 3274263363Semaste// ::= <ternary operator-name> <expression> <expression> <expression> 3275263363Semaste// ::= cl <expression>+ E # call 3276263363Semaste// ::= cv <type> <expression> # conversion with one argument 3277263363Semaste// ::= cv <type> _ <expression>* E # conversion with a different number of arguments 3278263363Semaste// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type 3279263363Semaste// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init) 3280263363Semaste// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type 3281263363Semaste// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init) 3282263363Semaste// ::= [gs] dl <expression> # delete expression 3283263363Semaste// ::= [gs] da <expression> # delete[] expression 3284263363Semaste// ::= pp_ <expression> # prefix ++ 3285263363Semaste// ::= mm_ <expression> # prefix -- 3286263363Semaste// ::= ti <type> # typeid (type) 3287263363Semaste// ::= te <expression> # typeid (expression) 3288263363Semaste// ::= dc <type> <expression> # dynamic_cast<type> (expression) 3289263363Semaste// ::= sc <type> <expression> # static_cast<type> (expression) 3290263363Semaste// ::= cc <type> <expression> # const_cast<type> (expression) 3291263363Semaste// ::= rc <type> <expression> # reinterpret_cast<type> (expression) 3292263363Semaste// ::= st <type> # sizeof (a type) 3293263363Semaste// ::= sz <expression> # sizeof (an expression) 3294263363Semaste// ::= at <type> # alignof (a type) 3295263363Semaste// ::= az <expression> # alignof (an expression) 3296263363Semaste// ::= nx <expression> # noexcept (expression) 3297263363Semaste// ::= <template-param> 3298263363Semaste// ::= <function-param> 3299263363Semaste// ::= dt <expression> <unresolved-name> # expr.name 3300263363Semaste// ::= pt <expression> <unresolved-name> # expr->name 3301263363Semaste// ::= ds <expression> <expression> # expr.*expr 3302263363Semaste// ::= sZ <template-param> # size of a parameter pack 3303263363Semaste// ::= sZ <function-param> # size of a function parameter pack 3304263363Semaste// ::= sp <expression> # pack expansion 3305263363Semaste// ::= tw <expression> # throw expression 3306263363Semaste// ::= tr # throw with no operand (rethrow) 3307263363Semaste// ::= <unresolved-name> # f(p), N::f(p), ::f(p), 3308263363Semaste// # freestanding dependent name (e.g., T::x), 3309263363Semaste// # objectless nonstatic member reference 3310263363Semaste// ::= <expr-primary> 3311263363Semaste 3312263363Semastetemplate <class C> 3313263363Semasteconst char* 3314263363Semasteparse_expression(const char* first, const char* last, C& db) 3315263363Semaste{ 3316263363Semaste if (last - first >= 2) 3317263363Semaste { 3318263363Semaste const char* t = first; 3319263363Semaste bool parsed_gs = false; 3320263363Semaste if (last - first >= 4 && t[0] == 'g' && t[1] == 's') 3321263363Semaste { 3322263363Semaste t += 2; 3323263363Semaste parsed_gs = true; 3324263363Semaste } 3325263363Semaste switch (*t) 3326263363Semaste { 3327263363Semaste case 'L': 3328263363Semaste first = parse_expr_primary(first, last, db); 3329263363Semaste break; 3330263363Semaste case 'T': 3331263363Semaste first = parse_template_param(first, last, db); 3332263363Semaste break; 3333263363Semaste case 'f': 3334263363Semaste first = parse_function_param(first, last, db); 3335263363Semaste break; 3336263363Semaste case 'a': 3337263363Semaste switch (t[1]) 3338263363Semaste { 3339263363Semaste case 'a': 3340263363Semaste t = parse_binary_expression(first+2, last, "&&", db); 3341263363Semaste if (t != first+2) 3342263363Semaste first = t; 3343263363Semaste break; 3344263363Semaste case 'd': 3345263363Semaste t = parse_prefix_expression(first+2, last, "&", db); 3346263363Semaste if (t != first+2) 3347263363Semaste first = t; 3348263363Semaste break; 3349263363Semaste case 'n': 3350263363Semaste t = parse_binary_expression(first+2, last, "&", db); 3351263363Semaste if (t != first+2) 3352263363Semaste first = t; 3353263363Semaste break; 3354263363Semaste case 'N': 3355263363Semaste t = parse_binary_expression(first+2, last, "&=", db); 3356263363Semaste if (t != first+2) 3357263363Semaste first = t; 3358263363Semaste break; 3359263363Semaste case 'S': 3360263363Semaste t = parse_binary_expression(first+2, last, "=", db); 3361263363Semaste if (t != first+2) 3362263363Semaste first = t; 3363263363Semaste break; 3364263363Semaste case 't': 3365263363Semaste first = parse_alignof_type(first, last, db); 3366263363Semaste break; 3367263363Semaste case 'z': 3368263363Semaste first = parse_alignof_expr(first, last, db); 3369263363Semaste break; 3370263363Semaste } 3371263363Semaste break; 3372263363Semaste case 'c': 3373263363Semaste switch (t[1]) 3374263363Semaste { 3375263363Semaste case 'c': 3376263363Semaste first = parse_const_cast_expr(first, last, db); 3377263363Semaste break; 3378263363Semaste case 'l': 3379263363Semaste first = parse_call_expr(first, last, db); 3380263363Semaste break; 3381263363Semaste case 'm': 3382263363Semaste t = parse_binary_expression(first+2, last, ",", db); 3383263363Semaste if (t != first+2) 3384263363Semaste first = t; 3385263363Semaste break; 3386263363Semaste case 'o': 3387263363Semaste t = parse_prefix_expression(first+2, last, "~", db); 3388263363Semaste if (t != first+2) 3389263363Semaste first = t; 3390263363Semaste break; 3391263363Semaste case 'v': 3392263363Semaste first = parse_conversion_expr(first, last, db); 3393263363Semaste break; 3394263363Semaste } 3395263363Semaste break; 3396263363Semaste case 'd': 3397263363Semaste switch (t[1]) 3398263363Semaste { 3399263363Semaste case 'a': 3400263363Semaste { 3401263363Semaste const char* t1 = parse_expression(t+2, last, db); 3402263363Semaste if (t1 != t+2) 3403263363Semaste { 3404269024Semaste if (db.names.empty()) 3405269024Semaste return first; 3406263363Semaste db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) + 3407263363Semaste "delete[] " + db.names.back().move_full(); 3408263363Semaste first = t1; 3409263363Semaste } 3410263363Semaste } 3411263363Semaste break; 3412263363Semaste case 'c': 3413263363Semaste first = parse_dynamic_cast_expr(first, last, db); 3414263363Semaste break; 3415263363Semaste case 'e': 3416263363Semaste t = parse_prefix_expression(first+2, last, "*", db); 3417263363Semaste if (t != first+2) 3418263363Semaste first = t; 3419263363Semaste break; 3420263363Semaste case 'l': 3421263363Semaste { 3422263363Semaste const char* t1 = parse_expression(t+2, last, db); 3423263363Semaste if (t1 != t+2) 3424263363Semaste { 3425269024Semaste if (db.names.empty()) 3426269024Semaste return first; 3427263363Semaste db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) + 3428263363Semaste "delete " + db.names.back().move_full(); 3429263363Semaste first = t1; 3430263363Semaste } 3431263363Semaste } 3432263363Semaste break; 3433263363Semaste case 'n': 3434263363Semaste return parse_unresolved_name(first, last, db); 3435263363Semaste case 's': 3436263363Semaste first = parse_dot_star_expr(first, last, db); 3437263363Semaste break; 3438263363Semaste case 't': 3439263363Semaste first = parse_dot_expr(first, last, db); 3440263363Semaste break; 3441263363Semaste case 'v': 3442263363Semaste t = parse_binary_expression(first+2, last, "/", db); 3443263363Semaste if (t != first+2) 3444263363Semaste first = t; 3445263363Semaste break; 3446263363Semaste case 'V': 3447263363Semaste t = parse_binary_expression(first+2, last, "/=", db); 3448263363Semaste if (t != first+2) 3449263363Semaste first = t; 3450263363Semaste break; 3451263363Semaste } 3452263363Semaste break; 3453263363Semaste case 'e': 3454263363Semaste switch (t[1]) 3455263363Semaste { 3456263363Semaste case 'o': 3457263363Semaste t = parse_binary_expression(first+2, last, "^", db); 3458263363Semaste if (t != first+2) 3459263363Semaste first = t; 3460263363Semaste break; 3461263363Semaste case 'O': 3462263363Semaste t = parse_binary_expression(first+2, last, "^=", db); 3463263363Semaste if (t != first+2) 3464263363Semaste first = t; 3465263363Semaste break; 3466263363Semaste case 'q': 3467263363Semaste t = parse_binary_expression(first+2, last, "==", db); 3468263363Semaste if (t != first+2) 3469263363Semaste first = t; 3470263363Semaste break; 3471263363Semaste } 3472263363Semaste break; 3473263363Semaste case 'g': 3474263363Semaste switch (t[1]) 3475263363Semaste { 3476263363Semaste case 'e': 3477263363Semaste t = parse_binary_expression(first+2, last, ">=", db); 3478263363Semaste if (t != first+2) 3479263363Semaste first = t; 3480263363Semaste break; 3481263363Semaste case 't': 3482263363Semaste t = parse_binary_expression(first+2, last, ">", db); 3483263363Semaste if (t != first+2) 3484263363Semaste first = t; 3485263363Semaste break; 3486263363Semaste } 3487263363Semaste break; 3488263363Semaste case 'i': 3489263363Semaste if (t[1] == 'x') 3490263363Semaste { 3491263363Semaste const char* t1 = parse_expression(first+2, last, db); 3492263363Semaste if (t1 != first+2) 3493263363Semaste { 3494263363Semaste const char* t2 = parse_expression(t1, last, db); 3495263363Semaste if (t2 != t1) 3496263363Semaste { 3497269024Semaste if (db.names.size() < 2) 3498269024Semaste return first; 3499263363Semaste auto op2 = db.names.back().move_full(); 3500263363Semaste db.names.pop_back(); 3501263363Semaste auto op1 = db.names.back().move_full(); 3502263363Semaste db.names.back() = "(" + op1 + ")[" + op2 + "]"; 3503263363Semaste first = t2; 3504263363Semaste } 3505263363Semaste else 3506263363Semaste db.names.pop_back(); 3507263363Semaste } 3508263363Semaste } 3509263363Semaste break; 3510263363Semaste case 'l': 3511263363Semaste switch (t[1]) 3512263363Semaste { 3513263363Semaste case 'e': 3514263363Semaste t = parse_binary_expression(first+2, last, "<=", db); 3515263363Semaste if (t != first+2) 3516263363Semaste first = t; 3517263363Semaste break; 3518263363Semaste case 's': 3519263363Semaste t = parse_binary_expression(first+2, last, "<<", db); 3520263363Semaste if (t != first+2) 3521263363Semaste first = t; 3522263363Semaste break; 3523263363Semaste case 'S': 3524263363Semaste t = parse_binary_expression(first+2, last, "<<=", db); 3525263363Semaste if (t != first+2) 3526263363Semaste first = t; 3527263363Semaste break; 3528263363Semaste case 't': 3529263363Semaste t = parse_binary_expression(first+2, last, "<", db); 3530263363Semaste if (t != first+2) 3531263363Semaste first = t; 3532263363Semaste break; 3533263363Semaste } 3534263363Semaste break; 3535263363Semaste case 'm': 3536263363Semaste switch (t[1]) 3537263363Semaste { 3538263363Semaste case 'i': 3539263363Semaste t = parse_binary_expression(first+2, last, "-", db); 3540263363Semaste if (t != first+2) 3541263363Semaste first = t; 3542263363Semaste break; 3543263363Semaste case 'I': 3544263363Semaste t = parse_binary_expression(first+2, last, "-=", db); 3545263363Semaste if (t != first+2) 3546263363Semaste first = t; 3547263363Semaste break; 3548263363Semaste case 'l': 3549263363Semaste t = parse_binary_expression(first+2, last, "*", db); 3550263363Semaste if (t != first+2) 3551263363Semaste first = t; 3552263363Semaste break; 3553263363Semaste case 'L': 3554263363Semaste t = parse_binary_expression(first+2, last, "*=", db); 3555263363Semaste if (t != first+2) 3556263363Semaste first = t; 3557263363Semaste break; 3558263363Semaste case 'm': 3559263363Semaste if (first+2 != last && first[2] == '_') 3560263363Semaste { 3561263363Semaste t = parse_prefix_expression(first+3, last, "--", db); 3562263363Semaste if (t != first+3) 3563263363Semaste first = t; 3564263363Semaste } 3565263363Semaste else 3566263363Semaste { 3567263363Semaste const char* t1 = parse_expression(first+2, last, db); 3568263363Semaste if (t1 != first+2) 3569263363Semaste { 3570269024Semaste if (db.names.empty()) 3571269024Semaste return first; 3572263363Semaste db.names.back() = "(" + db.names.back().move_full() + ")--"; 3573263363Semaste first = t1; 3574263363Semaste } 3575263363Semaste } 3576263363Semaste break; 3577263363Semaste } 3578263363Semaste break; 3579263363Semaste case 'n': 3580263363Semaste switch (t[1]) 3581263363Semaste { 3582263363Semaste case 'a': 3583263363Semaste case 'w': 3584263363Semaste first = parse_new_expr(first, last, db); 3585263363Semaste break; 3586263363Semaste case 'e': 3587263363Semaste t = parse_binary_expression(first+2, last, "!=", db); 3588263363Semaste if (t != first+2) 3589263363Semaste first = t; 3590263363Semaste break; 3591263363Semaste case 'g': 3592263363Semaste t = parse_prefix_expression(first+2, last, "-", db); 3593263363Semaste if (t != first+2) 3594263363Semaste first = t; 3595263363Semaste break; 3596263363Semaste case 't': 3597263363Semaste t = parse_prefix_expression(first+2, last, "!", db); 3598263363Semaste if (t != first+2) 3599263363Semaste first = t; 3600263363Semaste break; 3601263363Semaste case 'x': 3602263363Semaste t = parse_noexcept_expression(first+2, last, db); 3603263363Semaste if (t != first+2) 3604263363Semaste first = t; 3605263363Semaste break; 3606263363Semaste } 3607263363Semaste break; 3608263363Semaste case 'o': 3609263363Semaste switch (t[1]) 3610263363Semaste { 3611263363Semaste case 'n': 3612263363Semaste return parse_unresolved_name(first, last, db); 3613263363Semaste case 'o': 3614263363Semaste t = parse_binary_expression(first+2, last, "||", db); 3615263363Semaste if (t != first+2) 3616263363Semaste first = t; 3617263363Semaste break; 3618263363Semaste case 'r': 3619263363Semaste t = parse_binary_expression(first+2, last, "|", db); 3620263363Semaste if (t != first+2) 3621263363Semaste first = t; 3622263363Semaste break; 3623263363Semaste case 'R': 3624263363Semaste t = parse_binary_expression(first+2, last, "|=", db); 3625263363Semaste if (t != first+2) 3626263363Semaste first = t; 3627263363Semaste break; 3628263363Semaste } 3629263363Semaste break; 3630263363Semaste case 'p': 3631263363Semaste switch (t[1]) 3632263363Semaste { 3633263363Semaste case 'm': 3634263363Semaste t = parse_binary_expression(first+2, last, "->*", db); 3635263363Semaste if (t != first+2) 3636263363Semaste first = t; 3637263363Semaste break; 3638263363Semaste case 'l': 3639263363Semaste t = parse_binary_expression(first+2, last, "+", db); 3640263363Semaste if (t != first+2) 3641263363Semaste first = t; 3642263363Semaste break; 3643263363Semaste case 'L': 3644263363Semaste t = parse_binary_expression(first+2, last, "+=", db); 3645263363Semaste if (t != first+2) 3646263363Semaste first = t; 3647263363Semaste break; 3648263363Semaste case 'p': 3649263363Semaste if (first+2 != last && first[2] == '_') 3650263363Semaste { 3651263363Semaste t = parse_prefix_expression(first+3, last, "++", db); 3652263363Semaste if (t != first+3) 3653263363Semaste first = t; 3654263363Semaste } 3655263363Semaste else 3656263363Semaste { 3657263363Semaste const char* t1 = parse_expression(first+2, last, db); 3658263363Semaste if (t1 != first+2) 3659263363Semaste { 3660269024Semaste if (db.names.empty()) 3661269024Semaste return first; 3662263363Semaste db.names.back() = "(" + db.names.back().move_full() + ")++"; 3663263363Semaste first = t1; 3664263363Semaste } 3665263363Semaste } 3666263363Semaste break; 3667263363Semaste case 's': 3668263363Semaste t = parse_prefix_expression(first+2, last, "+", db); 3669263363Semaste if (t != first+2) 3670263363Semaste first = t; 3671263363Semaste break; 3672263363Semaste case 't': 3673263363Semaste first = parse_arrow_expr(first, last, db); 3674263363Semaste break; 3675263363Semaste } 3676263363Semaste break; 3677263363Semaste case 'q': 3678263363Semaste if (t[1] == 'u') 3679263363Semaste { 3680263363Semaste const char* t1 = parse_expression(first+2, last, db); 3681263363Semaste if (t1 != first+2) 3682263363Semaste { 3683263363Semaste const char* t2 = parse_expression(t1, last, db); 3684263363Semaste if (t2 != t1) 3685263363Semaste { 3686263363Semaste const char* t3 = parse_expression(t2, last, db); 3687263363Semaste if (t3 != t2) 3688263363Semaste { 3689269024Semaste if (db.names.size() < 3) 3690269024Semaste return first; 3691263363Semaste auto op3 = db.names.back().move_full(); 3692263363Semaste db.names.pop_back(); 3693263363Semaste auto op2 = db.names.back().move_full(); 3694263363Semaste db.names.pop_back(); 3695263363Semaste auto op1 = db.names.back().move_full(); 3696263363Semaste db.names.back() = "(" + op1 + ") ? (" + op2 + ") : (" + op3 + ")"; 3697263363Semaste first = t3; 3698263363Semaste } 3699263363Semaste else 3700263363Semaste { 3701263363Semaste db.names.pop_back(); 3702263363Semaste db.names.pop_back(); 3703263363Semaste } 3704263363Semaste } 3705263363Semaste else 3706263363Semaste db.names.pop_back(); 3707263363Semaste } 3708263363Semaste } 3709263363Semaste break; 3710263363Semaste case 'r': 3711263363Semaste switch (t[1]) 3712263363Semaste { 3713263363Semaste case 'c': 3714263363Semaste first = parse_reinterpret_cast_expr(first, last, db); 3715263363Semaste break; 3716263363Semaste case 'm': 3717263363Semaste t = parse_binary_expression(first+2, last, "%", db); 3718263363Semaste if (t != first+2) 3719263363Semaste first = t; 3720263363Semaste break; 3721263363Semaste case 'M': 3722263363Semaste t = parse_binary_expression(first+2, last, "%=", db); 3723263363Semaste if (t != first+2) 3724263363Semaste first = t; 3725263363Semaste break; 3726263363Semaste case 's': 3727263363Semaste t = parse_binary_expression(first+2, last, ">>", db); 3728263363Semaste if (t != first+2) 3729263363Semaste first = t; 3730263363Semaste break; 3731263363Semaste case 'S': 3732263363Semaste t = parse_binary_expression(first+2, last, ">>=", db); 3733263363Semaste if (t != first+2) 3734263363Semaste first = t; 3735263363Semaste break; 3736263363Semaste } 3737263363Semaste break; 3738263363Semaste case 's': 3739263363Semaste switch (t[1]) 3740263363Semaste { 3741263363Semaste case 'c': 3742263363Semaste first = parse_static_cast_expr(first, last, db); 3743263363Semaste break; 3744263363Semaste case 'p': 3745263363Semaste first = parse_pack_expansion(first, last, db); 3746263363Semaste break; 3747263363Semaste case 'r': 3748263363Semaste return parse_unresolved_name(first, last, db); 3749263363Semaste case 't': 3750263363Semaste first = parse_sizeof_type_expr(first, last, db); 3751263363Semaste break; 3752263363Semaste case 'z': 3753263363Semaste first = parse_sizeof_expr_expr(first, last, db); 3754263363Semaste break; 3755263363Semaste case 'Z': 3756263363Semaste if (last - t >= 3) 3757263363Semaste { 3758263363Semaste switch (t[2]) 3759263363Semaste { 3760263363Semaste case 'T': 3761263363Semaste first = parse_sizeof_param_pack_expr(first, last, db); 3762263363Semaste break; 3763263363Semaste case 'f': 3764263363Semaste first = parse_sizeof_function_param_pack_expr(first, last, db); 3765263363Semaste break; 3766263363Semaste } 3767263363Semaste } 3768263363Semaste break; 3769263363Semaste } 3770263363Semaste break; 3771263363Semaste case 't': 3772263363Semaste switch (t[1]) 3773263363Semaste { 3774263363Semaste case 'e': 3775263363Semaste case 'i': 3776263363Semaste first = parse_typeid_expr(first, last, db); 3777263363Semaste break; 3778263363Semaste case 'r': 3779263363Semaste db.names.push_back("throw"); 3780263363Semaste first += 2; 3781263363Semaste break; 3782263363Semaste case 'w': 3783263363Semaste first = parse_throw_expr(first, last, db); 3784263363Semaste break; 3785263363Semaste } 3786263363Semaste break; 3787263363Semaste case '1': 3788263363Semaste case '2': 3789263363Semaste case '3': 3790263363Semaste case '4': 3791263363Semaste case '5': 3792263363Semaste case '6': 3793263363Semaste case '7': 3794263363Semaste case '8': 3795263363Semaste case '9': 3796263363Semaste return parse_unresolved_name(first, last, db); 3797263363Semaste } 3798263363Semaste } 3799263363Semaste return first; 3800263363Semaste} 3801263363Semaste 3802263363Semaste// <template-arg> ::= <type> # type or template 3803263363Semaste// ::= X <expression> E # expression 3804263363Semaste// ::= <expr-primary> # simple expressions 3805263363Semaste// ::= J <template-arg>* E # argument pack 3806263363Semaste// ::= LZ <encoding> E # extension 3807263363Semaste 3808263363Semastetemplate <class C> 3809263363Semasteconst char* 3810263363Semasteparse_template_arg(const char* first, const char* last, C& db) 3811263363Semaste{ 3812263363Semaste if (first != last) 3813263363Semaste { 3814263363Semaste const char* t; 3815263363Semaste switch (*first) 3816263363Semaste { 3817263363Semaste case 'X': 3818263363Semaste t = parse_expression(first+1, last, db); 3819263363Semaste if (t != first+1) 3820263363Semaste { 3821263363Semaste if (t != last && *t == 'E') 3822263363Semaste first = t+1; 3823263363Semaste } 3824263363Semaste break; 3825263363Semaste case 'J': 3826263363Semaste t = first+1; 3827263363Semaste if (t == last) 3828263363Semaste return first; 3829263363Semaste while (*t != 'E') 3830263363Semaste { 3831263363Semaste const char* t1 = parse_template_arg(t, last, db); 3832263363Semaste if (t1 == t) 3833263363Semaste return first; 3834263363Semaste t = t1; 3835263363Semaste } 3836263363Semaste first = t+1; 3837263363Semaste break; 3838263363Semaste case 'L': 3839263363Semaste // <expr-primary> or LZ <encoding> E 3840263363Semaste if (first+1 != last && first[1] == 'Z') 3841263363Semaste { 3842263363Semaste t = parse_encoding(first+2, last, db); 3843263363Semaste if (t != first+2 && t != last && *t == 'E') 3844263363Semaste first = t+1; 3845263363Semaste } 3846263363Semaste else 3847263363Semaste first = parse_expr_primary(first, last, db); 3848263363Semaste break; 3849263363Semaste default: 3850263363Semaste // <type> 3851263363Semaste first = parse_type(first, last, db); 3852263363Semaste break; 3853263363Semaste } 3854263363Semaste } 3855263363Semaste return first; 3856263363Semaste} 3857263363Semaste 3858263363Semaste// <template-args> ::= I <template-arg>* E 3859263363Semaste// extension, the abi says <template-arg>+ 3860263363Semaste 3861263363Semastetemplate <class C> 3862263363Semasteconst char* 3863263363Semasteparse_template_args(const char* first, const char* last, C& db) 3864263363Semaste{ 3865263363Semaste if (last - first >= 2 && *first == 'I') 3866263363Semaste { 3867263363Semaste if (db.tag_templates) 3868263363Semaste db.template_param.back().clear(); 3869263363Semaste const char* t = first+1; 3870263363Semaste typename C::String args("<"); 3871263363Semaste while (*t != 'E') 3872263363Semaste { 3873263363Semaste if (db.tag_templates) 3874263363Semaste db.template_param.emplace_back(db.names.get_allocator()); 3875263363Semaste size_t k0 = db.names.size(); 3876263363Semaste const char* t1 = parse_template_arg(t, last, db); 3877263363Semaste size_t k1 = db.names.size(); 3878263363Semaste if (db.tag_templates) 3879263363Semaste db.template_param.pop_back(); 3880263363Semaste if (t1 == t || t1 == last) 3881263363Semaste return first; 3882263363Semaste if (db.tag_templates) 3883263363Semaste { 3884263363Semaste db.template_param.back().emplace_back(db.names.get_allocator()); 3885263363Semaste for (size_t k = k0; k < k1; ++k) 3886263363Semaste db.template_param.back().back().push_back(db.names[k]); 3887263363Semaste } 3888263363Semaste for (size_t k = k0; k < k1; ++k) 3889263363Semaste { 3890263363Semaste if (args.size() > 1) 3891263363Semaste args += ", "; 3892263363Semaste args += db.names[k].move_full(); 3893263363Semaste } 3894263363Semaste for (; k1 != k0; --k1) 3895263363Semaste db.names.pop_back(); 3896263363Semaste t = t1; 3897263363Semaste } 3898263363Semaste first = t + 1; 3899263363Semaste if (args.back() != '>') 3900263363Semaste args += ">"; 3901263363Semaste else 3902263363Semaste args += " >"; 3903263363Semaste db.names.push_back(std::move(args)); 3904263363Semaste 3905263363Semaste } 3906263363Semaste return first; 3907263363Semaste} 3908263363Semaste 3909263363Semaste// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E 3910263363Semaste// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E 3911263363Semaste// 3912263363Semaste// <prefix> ::= <prefix> <unqualified-name> 3913263363Semaste// ::= <template-prefix> <template-args> 3914263363Semaste// ::= <template-param> 3915263363Semaste// ::= <decltype> 3916263363Semaste// ::= # empty 3917263363Semaste// ::= <substitution> 3918263363Semaste// ::= <prefix> <data-member-prefix> 3919263363Semaste// extension ::= L 3920263363Semaste// 3921263363Semaste// <template-prefix> ::= <prefix> <template unqualified-name> 3922263363Semaste// ::= <template-param> 3923263363Semaste// ::= <substitution> 3924263363Semaste 3925263363Semastetemplate <class C> 3926263363Semasteconst char* 3927263363Semasteparse_nested_name(const char* first, const char* last, C& db) 3928263363Semaste{ 3929263363Semaste if (first != last && *first == 'N') 3930263363Semaste { 3931263363Semaste unsigned cv; 3932263363Semaste const char* t0 = parse_cv_qualifiers(first+1, last, cv); 3933263363Semaste if (t0 == last) 3934263363Semaste return first; 3935263363Semaste db.ref = 0; 3936263363Semaste if (*t0 == 'R') 3937263363Semaste { 3938263363Semaste db.ref = 1; 3939263363Semaste ++t0; 3940263363Semaste } 3941263363Semaste else if (*t0 == 'O') 3942263363Semaste { 3943263363Semaste db.ref = 2; 3944263363Semaste ++t0; 3945263363Semaste } 3946263363Semaste db.names.emplace_back(); 3947263363Semaste if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't') 3948263363Semaste { 3949263363Semaste t0 += 2; 3950263363Semaste db.names.back().first = "std"; 3951263363Semaste } 3952263363Semaste if (t0 == last) 3953263363Semaste { 3954263363Semaste db.names.pop_back(); 3955263363Semaste return first; 3956263363Semaste } 3957263363Semaste bool pop_subs = false; 3958263363Semaste while (*t0 != 'E') 3959263363Semaste { 3960263363Semaste const char* t1; 3961263363Semaste switch (*t0) 3962263363Semaste { 3963263363Semaste case 'S': 3964263363Semaste if (t0 + 1 != last && t0[1] == 't') 3965263363Semaste goto do_parse_unqualified_name; 3966263363Semaste t1 = parse_substitution(t0, last, db); 3967263363Semaste if (t1 != t0 && t1 != last) 3968263363Semaste { 3969263363Semaste auto name = db.names.back().move_full(); 3970263363Semaste db.names.pop_back(); 3971263363Semaste if (!db.names.back().first.empty()) 3972263363Semaste { 3973263363Semaste db.names.back().first += "::" + name; 3974263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 3975263363Semaste } 3976263363Semaste else 3977263363Semaste db.names.back().first = name; 3978263363Semaste pop_subs = true; 3979263363Semaste t0 = t1; 3980263363Semaste } 3981263363Semaste else 3982263363Semaste return first; 3983263363Semaste break; 3984263363Semaste case 'T': 3985263363Semaste t1 = parse_template_param(t0, last, db); 3986263363Semaste if (t1 != t0 && t1 != last) 3987263363Semaste { 3988263363Semaste auto name = db.names.back().move_full(); 3989263363Semaste db.names.pop_back(); 3990263363Semaste if (!db.names.back().first.empty()) 3991263363Semaste db.names.back().first += "::" + name; 3992263363Semaste else 3993263363Semaste db.names.back().first = name; 3994263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 3995263363Semaste pop_subs = true; 3996263363Semaste t0 = t1; 3997263363Semaste } 3998263363Semaste else 3999263363Semaste return first; 4000263363Semaste break; 4001263363Semaste case 'D': 4002263363Semaste if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T') 4003263363Semaste goto do_parse_unqualified_name; 4004263363Semaste t1 = parse_decltype(t0, last, db); 4005263363Semaste if (t1 != t0 && t1 != last) 4006263363Semaste { 4007263363Semaste auto name = db.names.back().move_full(); 4008263363Semaste db.names.pop_back(); 4009263363Semaste if (!db.names.back().first.empty()) 4010263363Semaste db.names.back().first += "::" + name; 4011263363Semaste else 4012263363Semaste db.names.back().first = name; 4013263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 4014263363Semaste pop_subs = true; 4015263363Semaste t0 = t1; 4016263363Semaste } 4017263363Semaste else 4018263363Semaste return first; 4019263363Semaste break; 4020263363Semaste case 'I': 4021263363Semaste t1 = parse_template_args(t0, last, db); 4022263363Semaste if (t1 != t0 && t1 != last) 4023263363Semaste { 4024263363Semaste auto name = db.names.back().move_full(); 4025263363Semaste db.names.pop_back(); 4026263363Semaste db.names.back().first += name; 4027263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 4028263363Semaste t0 = t1; 4029263363Semaste } 4030263363Semaste else 4031263363Semaste return first; 4032263363Semaste break; 4033263363Semaste case 'L': 4034263363Semaste if (++t0 == last) 4035263363Semaste return first; 4036263363Semaste break; 4037263363Semaste default: 4038263363Semaste do_parse_unqualified_name: 4039263363Semaste t1 = parse_unqualified_name(t0, last, db); 4040263363Semaste if (t1 != t0 && t1 != last) 4041263363Semaste { 4042263363Semaste auto name = db.names.back().move_full(); 4043263363Semaste db.names.pop_back(); 4044263363Semaste if (!db.names.back().first.empty()) 4045263363Semaste db.names.back().first += "::" + name; 4046263363Semaste else 4047263363Semaste db.names.back().first = name; 4048263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 4049263363Semaste pop_subs = true; 4050263363Semaste t0 = t1; 4051263363Semaste } 4052263363Semaste else 4053263363Semaste return first; 4054263363Semaste } 4055263363Semaste } 4056263363Semaste first = t0 + 1; 4057263363Semaste db.cv = cv; 4058263363Semaste if (pop_subs && !db.subs.empty()) 4059263363Semaste db.subs.pop_back(); 4060263363Semaste } 4061263363Semaste return first; 4062263363Semaste} 4063263363Semaste 4064263363Semaste// <discriminator> := _ <non-negative number> # when number < 10 4065263363Semaste// := __ <non-negative number> _ # when number >= 10 4066263363Semaste// extension := decimal-digit+ 4067263363Semaste 4068263363Semasteconst char* 4069263363Semasteparse_discriminator(const char* first, const char* last) 4070263363Semaste{ 4071263363Semaste // parse but ignore discriminator 4072263363Semaste if (first != last) 4073263363Semaste { 4074263363Semaste if (*first == '_') 4075263363Semaste { 4076263363Semaste const char* t1 = first+1; 4077263363Semaste if (t1 != last) 4078263363Semaste { 4079263363Semaste if (std::isdigit(*t1)) 4080263363Semaste first = t1+1; 4081263363Semaste else if (*t1 == '_') 4082263363Semaste { 4083263363Semaste for (++t1; t1 != last && std::isdigit(*t1); ++t1) 4084263363Semaste ; 4085263363Semaste if (t1 != last && *t1 == '_') 4086263363Semaste first = t1 + 1; 4087263363Semaste } 4088263363Semaste } 4089263363Semaste } 4090263363Semaste else if (std::isdigit(*first)) 4091263363Semaste { 4092263363Semaste const char* t1 = first+1; 4093263363Semaste for (; t1 != last && std::isdigit(*t1); ++t1) 4094263363Semaste ; 4095263363Semaste first = t1; 4096263363Semaste } 4097263363Semaste } 4098263363Semaste return first; 4099263363Semaste} 4100263363Semaste 4101263363Semaste// <local-name> := Z <function encoding> E <entity name> [<discriminator>] 4102263363Semaste// := Z <function encoding> E s [<discriminator>] 4103263363Semaste// := Z <function encoding> Ed [ <parameter number> ] _ <entity name> 4104263363Semaste 4105263363Semastetemplate <class C> 4106263363Semasteconst char* 4107263363Semasteparse_local_name(const char* first, const char* last, C& db) 4108263363Semaste{ 4109263363Semaste if (first != last && *first == 'Z') 4110263363Semaste { 4111263363Semaste const char* t = parse_encoding(first+1, last, db); 4112263363Semaste if (t != first+1 && t != last && *t == 'E' && ++t != last) 4113263363Semaste { 4114263363Semaste switch (*t) 4115263363Semaste { 4116263363Semaste case 's': 4117263363Semaste first = parse_discriminator(t+1, last); 4118269024Semaste if (db.names.empty()) 4119269024Semaste return first; 4120263363Semaste db.names.back().first.append("::string literal"); 4121263363Semaste break; 4122263363Semaste case 'd': 4123263363Semaste if (++t != last) 4124263363Semaste { 4125263363Semaste const char* t1 = parse_number(t, last); 4126263363Semaste if (t1 != last && *t1 == '_') 4127263363Semaste { 4128263363Semaste t = t1 + 1; 4129263363Semaste t1 = parse_name(t, last, db); 4130263363Semaste if (t1 != t) 4131263363Semaste { 4132269024Semaste if (db.names.size() < 2) 4133269024Semaste return first; 4134263363Semaste auto name = db.names.back().move_full(); 4135263363Semaste db.names.pop_back(); 4136263363Semaste db.names.back().first.append("::"); 4137263363Semaste db.names.back().first.append(name); 4138263363Semaste first = t1; 4139263363Semaste } 4140263363Semaste else 4141263363Semaste db.names.pop_back(); 4142263363Semaste } 4143263363Semaste } 4144263363Semaste break; 4145263363Semaste default: 4146263363Semaste { 4147263363Semaste const char* t1 = parse_name(t, last, db); 4148263363Semaste if (t1 != t) 4149263363Semaste { 4150263363Semaste // parse but ignore discriminator 4151263363Semaste first = parse_discriminator(t1, last); 4152269024Semaste if (db.names.size() < 2) 4153269024Semaste return first; 4154263363Semaste auto name = db.names.back().move_full(); 4155263363Semaste db.names.pop_back(); 4156263363Semaste db.names.back().first.append("::"); 4157263363Semaste db.names.back().first.append(name); 4158263363Semaste } 4159263363Semaste else 4160263363Semaste db.names.pop_back(); 4161263363Semaste } 4162263363Semaste break; 4163263363Semaste } 4164263363Semaste } 4165263363Semaste } 4166263363Semaste return first; 4167263363Semaste} 4168263363Semaste 4169263363Semaste// <name> ::= <nested-name> // N 4170263363Semaste// ::= <local-name> # See Scope Encoding below // Z 4171263363Semaste// ::= <unscoped-template-name> <template-args> 4172263363Semaste// ::= <unscoped-name> 4173263363Semaste 4174263363Semaste// <unscoped-template-name> ::= <unscoped-name> 4175263363Semaste// ::= <substitution> 4176263363Semaste 4177263363Semastetemplate <class C> 4178263363Semasteconst char* 4179263363Semasteparse_name(const char* first, const char* last, C& db) 4180263363Semaste{ 4181263363Semaste if (last - first >= 2) 4182263363Semaste { 4183263363Semaste const char* t0 = first; 4184263363Semaste // extension: ignore L here 4185263363Semaste if (*t0 == 'L') 4186263363Semaste ++t0; 4187263363Semaste switch (*t0) 4188263363Semaste { 4189263363Semaste case 'N': 4190263363Semaste { 4191263363Semaste const char* t1 = parse_nested_name(t0, last, db); 4192263363Semaste if (t1 != t0) 4193263363Semaste first = t1; 4194263363Semaste break; 4195263363Semaste } 4196263363Semaste case 'Z': 4197263363Semaste { 4198263363Semaste const char* t1 = parse_local_name(t0, last, db); 4199263363Semaste if (t1 != t0) 4200263363Semaste first = t1; 4201263363Semaste break; 4202263363Semaste } 4203263363Semaste default: 4204263363Semaste { 4205263363Semaste const char* t1 = parse_unscoped_name(t0, last, db); 4206263363Semaste if (t1 != t0) 4207263363Semaste { 4208263363Semaste if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args> 4209263363Semaste { 4210269024Semaste if (db.names.empty()) 4211269024Semaste return first; 4212263363Semaste db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator())); 4213263363Semaste t0 = t1; 4214263363Semaste t1 = parse_template_args(t0, last, db); 4215263363Semaste if (t1 != t0) 4216263363Semaste { 4217269024Semaste if (db.names.size() < 2) 4218269024Semaste return first; 4219263363Semaste auto tmp = db.names.back().move_full(); 4220263363Semaste db.names.pop_back(); 4221263363Semaste db.names.back().first += tmp; 4222263363Semaste first = t1; 4223263363Semaste } 4224263363Semaste } 4225263363Semaste else // <unscoped-name> 4226263363Semaste first = t1; 4227263363Semaste } 4228263363Semaste else 4229263363Semaste { // try <substitution> <template-args> 4230263363Semaste t1 = parse_substitution(t0, last, db); 4231263363Semaste if (t1 != t0 && t1 != last && *t1 == 'I') 4232263363Semaste { 4233263363Semaste t0 = t1; 4234263363Semaste t1 = parse_template_args(t0, last, db); 4235263363Semaste if (t1 != t0) 4236263363Semaste { 4237269024Semaste if (db.names.size() < 2) 4238269024Semaste return first; 4239263363Semaste auto tmp = db.names.back().move_full(); 4240263363Semaste db.names.pop_back(); 4241263363Semaste db.names.back().first += tmp; 4242263363Semaste first = t1; 4243263363Semaste } 4244263363Semaste } 4245263363Semaste } 4246263363Semaste break; 4247263363Semaste } 4248263363Semaste } 4249263363Semaste } 4250263363Semaste return first; 4251263363Semaste} 4252263363Semaste 4253263363Semaste// <call-offset> ::= h <nv-offset> _ 4254263363Semaste// ::= v <v-offset> _ 4255263363Semaste// 4256263363Semaste// <nv-offset> ::= <offset number> 4257263363Semaste// # non-virtual base override 4258263363Semaste// 4259263363Semaste// <v-offset> ::= <offset number> _ <virtual offset number> 4260263363Semaste// # virtual base override, with vcall offset 4261263363Semaste 4262263363Semasteconst char* 4263263363Semasteparse_call_offset(const char* first, const char* last) 4264263363Semaste{ 4265263363Semaste if (first != last) 4266263363Semaste { 4267263363Semaste switch (*first) 4268263363Semaste { 4269263363Semaste case 'h': 4270263363Semaste { 4271263363Semaste const char* t = parse_number(first + 1, last); 4272263363Semaste if (t != first + 1 && t != last && *t == '_') 4273263363Semaste first = t + 1; 4274263363Semaste } 4275263363Semaste break; 4276263363Semaste case 'v': 4277263363Semaste { 4278263363Semaste const char* t = parse_number(first + 1, last); 4279263363Semaste if (t != first + 1 && t != last && *t == '_') 4280263363Semaste { 4281263363Semaste const char* t2 = parse_number(++t, last); 4282263363Semaste if (t2 != t && t2 != last && *t2 == '_') 4283263363Semaste first = t2 + 1; 4284263363Semaste } 4285263363Semaste } 4286263363Semaste break; 4287263363Semaste } 4288263363Semaste } 4289263363Semaste return first; 4290263363Semaste} 4291263363Semaste 4292263363Semaste// <special-name> ::= TV <type> # virtual table 4293263363Semaste// ::= TT <type> # VTT structure (construction vtable index) 4294263363Semaste// ::= TI <type> # typeinfo structure 4295263363Semaste// ::= TS <type> # typeinfo name (null-terminated byte string) 4296263363Semaste// ::= Tc <call-offset> <call-offset> <base encoding> 4297263363Semaste// # base is the nominal target function of thunk 4298263363Semaste// # first call-offset is 'this' adjustment 4299263363Semaste// # second call-offset is result adjustment 4300263363Semaste// ::= T <call-offset> <base encoding> 4301263363Semaste// # base is the nominal target function of thunk 4302263363Semaste// ::= GV <object name> # Guard variable for one-time initialization 4303263363Semaste// # No <type> 4304263363Semaste// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 4305263363Semaste// extension ::= GR <object name> # reference temporary for object 4306263363Semaste 4307263363Semastetemplate <class C> 4308263363Semasteconst char* 4309263363Semasteparse_special_name(const char* first, const char* last, C& db) 4310263363Semaste{ 4311263363Semaste if (last - first > 2) 4312263363Semaste { 4313263363Semaste const char* t; 4314263363Semaste switch (*first) 4315263363Semaste { 4316263363Semaste case 'T': 4317263363Semaste switch (first[1]) 4318263363Semaste { 4319263363Semaste case 'V': 4320263363Semaste // TV <type> # virtual table 4321263363Semaste t = parse_type(first+2, last, db); 4322263363Semaste if (t != first+2) 4323263363Semaste { 4324269024Semaste if (db.names.empty()) 4325269024Semaste return first; 4326263363Semaste db.names.back().first.insert(0, "vtable for "); 4327263363Semaste first = t; 4328263363Semaste } 4329263363Semaste break; 4330263363Semaste case 'T': 4331263363Semaste // TT <type> # VTT structure (construction vtable index) 4332263363Semaste t = parse_type(first+2, last, db); 4333263363Semaste if (t != first+2) 4334263363Semaste { 4335269024Semaste if (db.names.empty()) 4336269024Semaste return first; 4337263363Semaste db.names.back().first.insert(0, "VTT for "); 4338263363Semaste first = t; 4339263363Semaste } 4340263363Semaste break; 4341263363Semaste case 'I': 4342263363Semaste // TI <type> # typeinfo structure 4343263363Semaste t = parse_type(first+2, last, db); 4344263363Semaste if (t != first+2) 4345263363Semaste { 4346269024Semaste if (db.names.empty()) 4347269024Semaste return first; 4348263363Semaste db.names.back().first.insert(0, "typeinfo for "); 4349263363Semaste first = t; 4350263363Semaste } 4351263363Semaste break; 4352263363Semaste case 'S': 4353263363Semaste // TS <type> # typeinfo name (null-terminated byte string) 4354263363Semaste t = parse_type(first+2, last, db); 4355263363Semaste if (t != first+2) 4356263363Semaste { 4357269024Semaste if (db.names.empty()) 4358269024Semaste return first; 4359263363Semaste db.names.back().first.insert(0, "typeinfo name for "); 4360263363Semaste first = t; 4361263363Semaste } 4362263363Semaste break; 4363263363Semaste case 'c': 4364263363Semaste // Tc <call-offset> <call-offset> <base encoding> 4365263363Semaste { 4366263363Semaste const char* t0 = parse_call_offset(first+2, last); 4367263363Semaste if (t0 == first+2) 4368263363Semaste break; 4369263363Semaste const char* t1 = parse_call_offset(t0, last); 4370263363Semaste if (t1 == t0) 4371263363Semaste break; 4372263363Semaste t = parse_encoding(t1, last, db); 4373263363Semaste if (t != t1) 4374263363Semaste { 4375269024Semaste if (db.names.empty()) 4376269024Semaste return first; 4377263363Semaste db.names.back().first.insert(0, "covariant return thunk to "); 4378263363Semaste first = t; 4379263363Semaste } 4380263363Semaste } 4381263363Semaste break; 4382263363Semaste case 'C': 4383263363Semaste // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 4384263363Semaste t = parse_type(first+2, last, db); 4385263363Semaste if (t != first+2) 4386263363Semaste { 4387263363Semaste const char* t0 = parse_number(t, last); 4388263363Semaste if (t0 != t && t0 != last && *t0 == '_') 4389263363Semaste { 4390263363Semaste const char* t1 = parse_type(++t0, last, db); 4391263363Semaste if (t1 != t0) 4392263363Semaste { 4393269024Semaste if (db.names.size() < 2) 4394269024Semaste return first; 4395263363Semaste auto left = db.names.back().move_full(); 4396263363Semaste db.names.pop_back(); 4397263363Semaste db.names.back().first = "construction vtable for " + 4398263363Semaste std::move(left) + "-in-" + 4399263363Semaste db.names.back().move_full(); 4400263363Semaste first = t1; 4401263363Semaste } 4402263363Semaste } 4403263363Semaste } 4404263363Semaste break; 4405263363Semaste default: 4406263363Semaste // T <call-offset> <base encoding> 4407263363Semaste { 4408263363Semaste const char* t0 = parse_call_offset(first+1, last); 4409263363Semaste if (t0 == first+1) 4410263363Semaste break; 4411263363Semaste t = parse_encoding(t0, last, db); 4412263363Semaste if (t != t0) 4413263363Semaste { 4414269024Semaste if (db.names.empty()) 4415269024Semaste return first; 4416263363Semaste if (first[2] == 'v') 4417263363Semaste { 4418263363Semaste db.names.back().first.insert(0, "virtual thunk to "); 4419263363Semaste first = t; 4420263363Semaste } 4421263363Semaste else 4422263363Semaste { 4423263363Semaste db.names.back().first.insert(0, "non-virtual thunk to "); 4424263363Semaste first = t; 4425263363Semaste } 4426263363Semaste } 4427263363Semaste } 4428263363Semaste break; 4429263363Semaste } 4430263363Semaste break; 4431263363Semaste case 'G': 4432263363Semaste switch (first[1]) 4433263363Semaste { 4434263363Semaste case 'V': 4435263363Semaste // GV <object name> # Guard variable for one-time initialization 4436263363Semaste t = parse_name(first+2, last, db); 4437263363Semaste if (t != first+2) 4438263363Semaste { 4439269024Semaste if (db.names.empty()) 4440269024Semaste return first; 4441263363Semaste db.names.back().first.insert(0, "guard variable for "); 4442263363Semaste first = t; 4443263363Semaste } 4444263363Semaste break; 4445263363Semaste case 'R': 4446263363Semaste // extension ::= GR <object name> # reference temporary for object 4447263363Semaste t = parse_name(first+2, last, db); 4448263363Semaste if (t != first+2) 4449263363Semaste { 4450269024Semaste if (db.names.empty()) 4451269024Semaste return first; 4452263363Semaste db.names.back().first.insert(0, "reference temporary for "); 4453263363Semaste first = t; 4454263363Semaste } 4455263363Semaste break; 4456263363Semaste } 4457263363Semaste break; 4458263363Semaste } 4459263363Semaste } 4460263363Semaste return first; 4461263363Semaste} 4462263363Semaste 4463269024Semastetemplate <class T> 4464269024Semasteclass save_value 4465269024Semaste{ 4466269024Semaste T& restore_; 4467269024Semaste T original_value_; 4468269024Semastepublic: 4469269024Semaste save_value(T& restore) 4470269024Semaste : restore_(restore), 4471269024Semaste original_value_(restore) 4472269024Semaste {} 4473269024Semaste 4474269024Semaste ~save_value() 4475269024Semaste { 4476269024Semaste restore_ = std::move(original_value_); 4477269024Semaste } 4478269024Semaste 4479269024Semaste save_value(const save_value&) = delete; 4480269024Semaste save_value& operator=(const save_value&) = delete; 4481269024Semaste}; 4482269024Semaste 4483263363Semaste// <encoding> ::= <function name> <bare-function-type> 4484263363Semaste// ::= <data name> 4485263363Semaste// ::= <special-name> 4486263363Semaste 4487263363Semastetemplate <class C> 4488263363Semasteconst char* 4489263363Semasteparse_encoding(const char* first, const char* last, C& db) 4490263363Semaste{ 4491263363Semaste if (first != last) 4492263363Semaste { 4493269024Semaste save_value<decltype(db.encoding_depth)> su(db.encoding_depth); 4494269024Semaste ++db.encoding_depth; 4495269024Semaste save_value<decltype(db.tag_templates)> sb(db.tag_templates); 4496269024Semaste if (db.encoding_depth > 1) 4497269024Semaste db.tag_templates = true; 4498263363Semaste switch (*first) 4499263363Semaste { 4500263363Semaste case 'G': 4501263363Semaste case 'T': 4502263363Semaste first = parse_special_name(first, last, db); 4503263363Semaste break; 4504263363Semaste default: 4505263363Semaste { 4506263363Semaste const char* t = parse_name(first, last, db); 4507263363Semaste unsigned cv = db.cv; 4508263363Semaste unsigned ref = db.ref; 4509263363Semaste if (t != first) 4510263363Semaste { 4511263363Semaste if (t != last && *t != 'E' && *t != '.') 4512263363Semaste { 4513269024Semaste save_value<bool> sb2(db.tag_templates); 4514263363Semaste db.tag_templates = false; 4515263363Semaste const char* t2; 4516263363Semaste typename C::String ret2; 4517269024Semaste if (db.names.empty()) 4518269024Semaste return first; 4519263363Semaste const typename C::String& nm = db.names.back().first; 4520269024Semaste if (nm.empty()) 4521269024Semaste return first; 4522263363Semaste if (!db.parsed_ctor_dtor_cv && nm.back() == '>' && nm[nm.size()-2] != '-' 4523263363Semaste && nm[nm.size()-2] != '>') 4524263363Semaste { 4525263363Semaste t2 = parse_type(t, last, db); 4526263363Semaste if (t2 == t) 4527263363Semaste return first; 4528269024Semaste if (db.names.size() < 2) 4529269024Semaste return first; 4530263363Semaste auto ret1 = std::move(db.names.back().first); 4531263363Semaste ret2 = std::move(db.names.back().second); 4532263363Semaste if (ret2.empty()) 4533263363Semaste ret1 += ' '; 4534263363Semaste db.names.pop_back(); 4535263363Semaste db.names.back().first.insert(0, ret1); 4536263363Semaste t = t2; 4537263363Semaste } 4538263363Semaste db.names.back().first += '('; 4539263363Semaste if (t != last && *t == 'v') 4540263363Semaste { 4541263363Semaste ++t; 4542263363Semaste } 4543263363Semaste else 4544263363Semaste { 4545263363Semaste bool first_arg = true; 4546263363Semaste while (true) 4547263363Semaste { 4548263363Semaste size_t k0 = db.names.size(); 4549263363Semaste t2 = parse_type(t, last, db); 4550263363Semaste size_t k1 = db.names.size(); 4551263363Semaste if (t2 == t) 4552263363Semaste break; 4553263363Semaste if (k1 > k0) 4554263363Semaste { 4555263363Semaste typename C::String tmp; 4556263363Semaste for (size_t k = k0; k < k1; ++k) 4557263363Semaste { 4558263363Semaste if (!tmp.empty()) 4559263363Semaste tmp += ", "; 4560263363Semaste tmp += db.names[k].move_full(); 4561263363Semaste } 4562263363Semaste for (size_t k = k0; k < k1; ++k) 4563263363Semaste db.names.pop_back(); 4564263363Semaste if (!tmp.empty()) 4565263363Semaste { 4566269024Semaste if (db.names.empty()) 4567269024Semaste return first; 4568263363Semaste if (!first_arg) 4569263363Semaste db.names.back().first += ", "; 4570263363Semaste else 4571263363Semaste first_arg = false; 4572263363Semaste db.names.back().first += tmp; 4573263363Semaste } 4574263363Semaste } 4575263363Semaste t = t2; 4576263363Semaste } 4577263363Semaste } 4578269024Semaste if (db.names.empty()) 4579269024Semaste return first; 4580263363Semaste db.names.back().first += ')'; 4581263363Semaste if (cv & 1) 4582263363Semaste db.names.back().first.append(" const"); 4583263363Semaste if (cv & 2) 4584263363Semaste db.names.back().first.append(" volatile"); 4585263363Semaste if (cv & 4) 4586263363Semaste db.names.back().first.append(" restrict"); 4587263363Semaste if (ref == 1) 4588263363Semaste db.names.back().first.append(" &"); 4589263363Semaste else if (ref == 2) 4590263363Semaste db.names.back().first.append(" &&"); 4591263363Semaste db.names.back().first += ret2; 4592263363Semaste first = t; 4593263363Semaste } 4594263363Semaste else 4595263363Semaste first = t; 4596263363Semaste } 4597263363Semaste break; 4598263363Semaste } 4599263363Semaste } 4600263363Semaste } 4601263363Semaste return first; 4602263363Semaste} 4603263363Semaste 4604263363Semaste// _block_invoke 4605263363Semaste// _block_invoke<decimal-digit>+ 4606263363Semaste// _block_invoke_<decimal-digit>+ 4607263363Semaste 4608263363Semastetemplate <class C> 4609263363Semasteconst char* 4610263363Semasteparse_block_invoke(const char* first, const char* last, C& db) 4611263363Semaste{ 4612263363Semaste if (last - first >= 13) 4613263363Semaste { 4614263363Semaste const char test[] = "_block_invoke"; 4615263363Semaste const char* t = first; 4616263363Semaste for (int i = 0; i < 13; ++i, ++t) 4617263363Semaste { 4618263363Semaste if (*t != test[i]) 4619263363Semaste return first; 4620263363Semaste } 4621263363Semaste if (t != last) 4622263363Semaste { 4623263363Semaste if (*t == '_') 4624263363Semaste { 4625263363Semaste // must have at least 1 decimal digit 4626263363Semaste if (++t == last || !std::isdigit(*t)) 4627263363Semaste return first; 4628263363Semaste ++t; 4629263363Semaste } 4630263363Semaste // parse zero or more digits 4631263363Semaste while (t != last && isdigit(*t)) 4632263363Semaste ++t; 4633263363Semaste } 4634269024Semaste if (db.names.empty()) 4635269024Semaste return first; 4636263363Semaste db.names.back().first.insert(0, "invocation function for block in "); 4637263363Semaste first = t; 4638263363Semaste } 4639263363Semaste return first; 4640263363Semaste} 4641263363Semaste 4642263363Semaste// extension 4643263363Semaste// <dot-suffix> := .<anything and everything> 4644263363Semaste 4645263363Semastetemplate <class C> 4646263363Semasteconst char* 4647263363Semasteparse_dot_suffix(const char* first, const char* last, C& db) 4648263363Semaste{ 4649263363Semaste if (first != last && *first == '.') 4650263363Semaste { 4651269024Semaste if (db.names.empty()) 4652269024Semaste return first; 4653263363Semaste db.names.back().first += " (" + typename C::String(first, last) + ")"; 4654263363Semaste first = last; 4655263363Semaste } 4656263363Semaste return first; 4657263363Semaste} 4658263363Semaste 4659263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke 4660263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+ 4661263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+ 4662263363Semaste// <mangled-name> ::= _Z<encoding> 4663263363Semaste// ::= <type> 4664263363Semaste 4665263363Semastetemplate <class C> 4666263363Semastevoid 4667263363Semastedemangle(const char* first, const char* last, C& db, int& status) 4668263363Semaste{ 4669263363Semaste if (first >= last) 4670263363Semaste { 4671263363Semaste status = invalid_mangled_name; 4672263363Semaste return; 4673263363Semaste } 4674263363Semaste if (*first == '_') 4675263363Semaste { 4676263363Semaste if (last - first >= 4) 4677263363Semaste { 4678263363Semaste if (first[1] == 'Z') 4679263363Semaste { 4680263363Semaste const char* t = parse_encoding(first+2, last, db); 4681263363Semaste if (t != first+2 && t != last && *t == '.') 4682263363Semaste t = parse_dot_suffix(t, last, db); 4683263363Semaste if (t != last) 4684263363Semaste status = invalid_mangled_name; 4685263363Semaste } 4686263363Semaste else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z') 4687263363Semaste { 4688263363Semaste const char* t = parse_encoding(first+4, last, db); 4689263363Semaste if (t != first+4 && t != last) 4690263363Semaste { 4691263363Semaste const char* t1 = parse_block_invoke(t, last, db); 4692263363Semaste if (t1 != last) 4693263363Semaste status = invalid_mangled_name; 4694263363Semaste } 4695263363Semaste else 4696263363Semaste status = invalid_mangled_name; 4697263363Semaste } 4698263363Semaste else 4699263363Semaste status = invalid_mangled_name; 4700263363Semaste } 4701263363Semaste else 4702263363Semaste status = invalid_mangled_name; 4703263363Semaste } 4704263363Semaste else 4705263363Semaste { 4706263363Semaste const char* t = parse_type(first, last, db); 4707263363Semaste if (t != last) 4708263363Semaste status = invalid_mangled_name; 4709263363Semaste } 4710263363Semaste if (status == success && db.names.empty()) 4711263363Semaste status = invalid_mangled_name; 4712263363Semaste} 4713263363Semaste 4714263363Semastetemplate <std::size_t N> 4715263363Semasteclass arena 4716263363Semaste{ 4717263363Semaste static const std::size_t alignment = 16; 4718263363Semaste alignas(alignment) char buf_[N]; 4719263363Semaste char* ptr_; 4720263363Semaste 4721263363Semaste std::size_t 4722263363Semaste align_up(std::size_t n) noexcept 4723263363Semaste {return n + (alignment-1) & ~(alignment-1);} 4724263363Semaste 4725263363Semaste bool 4726263363Semaste pointer_in_buffer(char* p) noexcept 4727263363Semaste {return buf_ <= p && p <= buf_ + N;} 4728263363Semaste 4729263363Semastepublic: 4730263363Semaste arena() noexcept : ptr_(buf_) {} 4731263363Semaste ~arena() {ptr_ = nullptr;} 4732263363Semaste arena(const arena&) = delete; 4733263363Semaste arena& operator=(const arena&) = delete; 4734263363Semaste 4735263363Semaste char* allocate(std::size_t n); 4736263363Semaste void deallocate(char* p, std::size_t n) noexcept; 4737263363Semaste 4738263363Semaste static constexpr std::size_t size() {return N;} 4739263363Semaste std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);} 4740263363Semaste void reset() {ptr_ = buf_;} 4741263363Semaste}; 4742263363Semaste 4743263363Semastetemplate <std::size_t N> 4744263363Semastechar* 4745263363Semastearena<N>::allocate(std::size_t n) 4746263363Semaste{ 4747263363Semaste n = align_up(n); 4748263363Semaste if (static_cast<std::size_t>(buf_ + N - ptr_) >= n) 4749263363Semaste { 4750263363Semaste char* r = ptr_; 4751263363Semaste ptr_ += n; 4752263363Semaste return r; 4753263363Semaste } 4754263363Semaste return static_cast<char*>(std::malloc(n)); 4755263363Semaste} 4756263363Semaste 4757263363Semastetemplate <std::size_t N> 4758263363Semastevoid 4759263363Semastearena<N>::deallocate(char* p, std::size_t n) noexcept 4760263363Semaste{ 4761263363Semaste if (pointer_in_buffer(p)) 4762263363Semaste { 4763263363Semaste n = align_up(n); 4764263363Semaste if (p + n == ptr_) 4765263363Semaste ptr_ = p; 4766263363Semaste } 4767263363Semaste else 4768263363Semaste std::free(p); 4769263363Semaste} 4770263363Semaste 4771263363Semastetemplate <class T, std::size_t N> 4772263363Semasteclass short_alloc 4773263363Semaste{ 4774263363Semaste arena<N>& a_; 4775263363Semastepublic: 4776263363Semaste typedef T value_type; 4777263363Semaste 4778263363Semastepublic: 4779263363Semaste template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;}; 4780263363Semaste 4781263363Semaste short_alloc(arena<N>& a) noexcept : a_(a) {} 4782263363Semaste template <class U> 4783263363Semaste short_alloc(const short_alloc<U, N>& a) noexcept 4784263363Semaste : a_(a.a_) {} 4785263363Semaste short_alloc(const short_alloc&) = default; 4786263363Semaste short_alloc& operator=(const short_alloc&) = delete; 4787263363Semaste 4788263363Semaste T* allocate(std::size_t n) 4789263363Semaste { 4790263363Semaste return reinterpret_cast<T*>(a_.allocate(n*sizeof(T))); 4791263363Semaste } 4792263363Semaste void deallocate(T* p, std::size_t n) noexcept 4793263363Semaste { 4794263363Semaste a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T)); 4795263363Semaste } 4796263363Semaste 4797263363Semaste template <class T1, std::size_t N1, class U, std::size_t M> 4798263363Semaste friend 4799263363Semaste bool 4800263363Semaste operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept; 4801263363Semaste 4802263363Semaste template <class U, std::size_t M> friend class short_alloc; 4803263363Semaste}; 4804263363Semaste 4805263363Semastetemplate <class T, std::size_t N, class U, std::size_t M> 4806263363Semasteinline 4807263363Semastebool 4808263363Semasteoperator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept 4809263363Semaste{ 4810263363Semaste return N == M && &x.a_ == &y.a_; 4811263363Semaste} 4812263363Semaste 4813263363Semastetemplate <class T, std::size_t N, class U, std::size_t M> 4814263363Semasteinline 4815263363Semastebool 4816263363Semasteoperator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept 4817263363Semaste{ 4818263363Semaste return !(x == y); 4819263363Semaste} 4820263363Semaste 4821263363Semastetemplate <class T> 4822263363Semasteclass malloc_alloc 4823263363Semaste{ 4824263363Semastepublic: 4825263363Semaste typedef T value_type; 4826263363Semaste 4827263363Semaste malloc_alloc() = default; 4828263363Semaste template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {} 4829263363Semaste 4830263363Semaste T* allocate(std::size_t n) 4831263363Semaste { 4832263363Semaste return static_cast<T*>(std::malloc(n*sizeof(T))); 4833263363Semaste } 4834263363Semaste void deallocate(T* p, std::size_t) noexcept 4835263363Semaste { 4836263363Semaste std::free(p); 4837263363Semaste } 4838263363Semaste}; 4839263363Semaste 4840263363Semastetemplate <class T, class U> 4841263363Semasteinline 4842263363Semastebool 4843263363Semasteoperator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept 4844263363Semaste{ 4845263363Semaste return true; 4846263363Semaste} 4847263363Semaste 4848263363Semastetemplate <class T, class U> 4849263363Semasteinline 4850263363Semastebool 4851263363Semasteoperator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept 4852263363Semaste{ 4853263363Semaste return !(x == y); 4854263363Semaste} 4855263363Semaste 4856263363Semasteconst size_t bs = 4 * 1024; 4857263363Semastetemplate <class T> using Alloc = short_alloc<T, bs>; 4858263363Semastetemplate <class T> using Vector = std::vector<T, Alloc<T>>; 4859263363Semasteusing String = std::basic_string<char, std::char_traits<char>, malloc_alloc<char>>; 4860263363Semaste 4861263363Semastestruct string_pair 4862263363Semaste{ 4863263363Semaste String first; 4864263363Semaste String second; 4865263363Semaste 4866263363Semaste string_pair() = default; 4867263363Semaste string_pair(String f) : first(std::move(f)) {} 4868263363Semaste string_pair(String f, String s) 4869263363Semaste : first(std::move(f)), second(std::move(s)) {} 4870263363Semaste template <size_t N> 4871263363Semaste string_pair(const char (&s)[N]) : first(s, N-1) {} 4872263363Semaste 4873263363Semaste size_t size() const {return first.size() + second.size();} 4874263363Semaste String full() const {return first + second;} 4875263363Semaste String move_full() {return std::move(first) + std::move(second);} 4876263363Semaste}; 4877263363Semaste 4878263363Semastestruct Db 4879263363Semaste{ 4880263363Semaste typedef String String; 4881263363Semaste typedef Vector<string_pair> sub_type; 4882263363Semaste typedef Vector<sub_type> template_param_type; 4883263363Semaste Vector<string_pair> names; 4884263363Semaste Vector<sub_type> subs; 4885263363Semaste Vector<template_param_type> template_param; 4886263363Semaste unsigned cv; 4887263363Semaste unsigned ref; 4888269024Semaste unsigned encoding_depth; 4889263363Semaste bool parsed_ctor_dtor_cv; 4890263363Semaste bool tag_templates; 4891263363Semaste bool fix_forward_references; 4892263363Semaste bool try_to_parse_template_args; 4893263363Semaste 4894263363Semaste template <size_t N> 4895263363Semaste Db(arena<N>& ar) : 4896263363Semaste names(ar), 4897263363Semaste subs(0, names, ar), 4898263363Semaste template_param(0, subs, ar) 4899263363Semaste {} 4900263363Semaste}; 4901263363Semaste 4902263363Semastechar* 4903263363Semaste__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status) 4904263363Semaste{ 4905263363Semaste if (mangled_name == nullptr || (buf != nullptr && n == nullptr)) 4906263363Semaste { 4907263363Semaste if (status) 4908263363Semaste *status = invalid_args; 4909263363Semaste return nullptr; 4910263363Semaste } 4911263363Semaste size_t internal_size = buf != nullptr ? *n : 0; 4912263363Semaste arena<bs> a; 4913263363Semaste Db db(a); 4914263363Semaste db.cv = 0; 4915263363Semaste db.ref = 0; 4916269024Semaste db.encoding_depth = 0; 4917263363Semaste db.parsed_ctor_dtor_cv = false; 4918263363Semaste db.tag_templates = true; 4919263363Semaste db.template_param.emplace_back(a); 4920263363Semaste db.fix_forward_references = false; 4921263363Semaste db.try_to_parse_template_args = true; 4922263363Semaste int internal_status = success; 4923263363Semaste size_t len = std::strlen(mangled_name); 4924263363Semaste demangle(mangled_name, mangled_name + len, db, 4925263363Semaste internal_status); 4926263363Semaste if (internal_status == success && db.fix_forward_references && 4927263363Semaste !db.template_param.empty() && !db.template_param.front().empty()) 4928263363Semaste { 4929263363Semaste db.fix_forward_references = false; 4930263363Semaste db.tag_templates = false; 4931263363Semaste db.names.clear(); 4932263363Semaste db.subs.clear(); 4933263363Semaste demangle(mangled_name, mangled_name + len, db, internal_status); 4934263363Semaste if (db.fix_forward_references) 4935263363Semaste internal_status = invalid_mangled_name; 4936263363Semaste } 4937263363Semaste if (internal_status == success) 4938263363Semaste { 4939263363Semaste size_t sz = db.names.back().size() + 1; 4940263363Semaste if (sz > internal_size) 4941263363Semaste { 4942263363Semaste char* newbuf = static_cast<char*>(std::realloc(buf, sz)); 4943263363Semaste if (newbuf == nullptr) 4944263363Semaste { 4945263363Semaste internal_status = memory_alloc_failure; 4946263363Semaste buf = nullptr; 4947263363Semaste } 4948263363Semaste else 4949263363Semaste { 4950263363Semaste buf = newbuf; 4951263363Semaste if (n != nullptr) 4952263363Semaste *n = sz; 4953263363Semaste } 4954263363Semaste } 4955263363Semaste if (buf != nullptr) 4956263363Semaste { 4957263363Semaste db.names.back().first += db.names.back().second; 4958263363Semaste std::memcpy(buf, db.names.back().first.data(), sz-1); 4959263363Semaste buf[sz-1] = char(0); 4960263363Semaste } 4961263363Semaste } 4962263363Semaste else 4963263363Semaste buf = nullptr; 4964263363Semaste if (status) 4965263363Semaste *status = internal_status; 4966263363Semaste return buf; 4967263363Semaste} 4968263363Semaste 4969269024Semaste} 4970263363Semaste#endif 4971263363Semaste 4972263363Semaste 4973254721Semaste#include "llvm/ADT/DenseMap.h" 4974254721Semaste 4975254721Semaste#include "lldb/Core/ConstString.h" 4976254721Semaste#include "lldb/Core/Mangled.h" 4977254721Semaste#include "lldb/Core/RegularExpression.h" 4978254721Semaste#include "lldb/Core/Stream.h" 4979254721Semaste#include "lldb/Core/Timer.h" 4980254721Semaste#include <ctype.h> 4981254721Semaste#include <string.h> 4982254721Semaste#include <stdlib.h> 4983254721Semaste 4984254721Semasteusing namespace lldb_private; 4985254721Semaste 4986254721Semastestatic inline bool 4987254721Semastecstring_is_mangled (const char *s) 4988254721Semaste{ 4989254721Semaste if (s) 4990254721Semaste return s[0] == '_' && s[1] == 'Z'; 4991254721Semaste return false; 4992254721Semaste} 4993254721Semaste 4994254721Semaste#pragma mark Mangled 4995254721Semaste//---------------------------------------------------------------------- 4996254721Semaste// Default constructor 4997254721Semaste//---------------------------------------------------------------------- 4998254721SemasteMangled::Mangled () : 4999254721Semaste m_mangled(), 5000254721Semaste m_demangled() 5001254721Semaste{ 5002254721Semaste} 5003254721Semaste 5004254721Semaste//---------------------------------------------------------------------- 5005254721Semaste// Constructor with an optional string and a boolean indicating if it is 5006254721Semaste// the mangled version. 5007254721Semaste//---------------------------------------------------------------------- 5008254721SemasteMangled::Mangled (const ConstString &s, bool mangled) : 5009254721Semaste m_mangled(), 5010254721Semaste m_demangled() 5011254721Semaste{ 5012254721Semaste if (s) 5013254721Semaste SetValue(s, mangled); 5014254721Semaste} 5015254721Semaste 5016254721SemasteMangled::Mangled (const ConstString &s) : 5017254721Semaste m_mangled(), 5018254721Semaste m_demangled() 5019254721Semaste{ 5020254721Semaste if (s) 5021254721Semaste SetValue(s); 5022254721Semaste} 5023254721Semaste 5024254721Semaste//---------------------------------------------------------------------- 5025254721Semaste// Destructor 5026254721Semaste//---------------------------------------------------------------------- 5027254721SemasteMangled::~Mangled () 5028254721Semaste{ 5029254721Semaste} 5030254721Semaste 5031254721Semaste//---------------------------------------------------------------------- 5032254721Semaste// Convert to pointer operator. This allows code to check any Mangled 5033254721Semaste// objects to see if they contain anything valid using code such as: 5034254721Semaste// 5035254721Semaste// Mangled mangled(...); 5036254721Semaste// if (mangled) 5037254721Semaste// { ... 5038254721Semaste//---------------------------------------------------------------------- 5039254721SemasteMangled::operator void* () const 5040254721Semaste{ 5041254721Semaste return (m_mangled) ? const_cast<Mangled*>(this) : NULL; 5042254721Semaste} 5043254721Semaste 5044254721Semaste//---------------------------------------------------------------------- 5045254721Semaste// Logical NOT operator. This allows code to check any Mangled 5046254721Semaste// objects to see if they are invalid using code such as: 5047254721Semaste// 5048254721Semaste// Mangled mangled(...); 5049254721Semaste// if (!file_spec) 5050254721Semaste// { ... 5051254721Semaste//---------------------------------------------------------------------- 5052254721Semastebool 5053254721SemasteMangled::operator! () const 5054254721Semaste{ 5055254721Semaste return !m_mangled; 5056254721Semaste} 5057254721Semaste 5058254721Semaste//---------------------------------------------------------------------- 5059254721Semaste// Clear the mangled and demangled values. 5060254721Semaste//---------------------------------------------------------------------- 5061254721Semastevoid 5062254721SemasteMangled::Clear () 5063254721Semaste{ 5064254721Semaste m_mangled.Clear(); 5065254721Semaste m_demangled.Clear(); 5066254721Semaste} 5067254721Semaste 5068254721Semaste 5069254721Semaste//---------------------------------------------------------------------- 5070254721Semaste// Compare the the string values. 5071254721Semaste//---------------------------------------------------------------------- 5072254721Semasteint 5073254721SemasteMangled::Compare (const Mangled& a, const Mangled& b) 5074254721Semaste{ 5075254721Semaste return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled)); 5076254721Semaste} 5077254721Semaste 5078254721Semaste 5079254721Semaste 5080254721Semaste//---------------------------------------------------------------------- 5081254721Semaste// Set the string value in this objects. If "mangled" is true, then 5082254721Semaste// the mangled named is set with the new value in "s", else the 5083254721Semaste// demangled name is set. 5084254721Semaste//---------------------------------------------------------------------- 5085254721Semastevoid 5086254721SemasteMangled::SetValue (const ConstString &s, bool mangled) 5087254721Semaste{ 5088254721Semaste if (s) 5089254721Semaste { 5090254721Semaste if (mangled) 5091254721Semaste { 5092254721Semaste m_demangled.Clear(); 5093254721Semaste m_mangled = s; 5094254721Semaste } 5095254721Semaste else 5096254721Semaste { 5097254721Semaste m_demangled = s; 5098254721Semaste m_mangled.Clear(); 5099254721Semaste } 5100254721Semaste } 5101254721Semaste else 5102254721Semaste { 5103254721Semaste m_demangled.Clear(); 5104254721Semaste m_mangled.Clear(); 5105254721Semaste } 5106254721Semaste} 5107254721Semaste 5108254721Semastevoid 5109254721SemasteMangled::SetValue (const ConstString &name) 5110254721Semaste{ 5111254721Semaste if (name) 5112254721Semaste { 5113254721Semaste if (cstring_is_mangled(name.GetCString())) 5114254721Semaste { 5115254721Semaste m_demangled.Clear(); 5116254721Semaste m_mangled = name; 5117254721Semaste } 5118254721Semaste else 5119254721Semaste { 5120254721Semaste m_demangled = name; 5121254721Semaste m_mangled.Clear(); 5122254721Semaste } 5123254721Semaste } 5124254721Semaste else 5125254721Semaste { 5126254721Semaste m_demangled.Clear(); 5127254721Semaste m_mangled.Clear(); 5128254721Semaste } 5129254721Semaste} 5130254721Semaste 5131254721Semaste 5132254721Semaste//---------------------------------------------------------------------- 5133254721Semaste// Generate the demangled name on demand using this accessor. Code in 5134254721Semaste// this class will need to use this accessor if it wishes to decode 5135254721Semaste// the demangled name. The result is cached and will be kept until a 5136254721Semaste// new string value is supplied to this object, or until the end of the 5137254721Semaste// object's lifetime. 5138254721Semaste//---------------------------------------------------------------------- 5139254721Semasteconst ConstString& 5140254721SemasteMangled::GetDemangledName () const 5141254721Semaste{ 5142254721Semaste // Check to make sure we have a valid mangled name and that we 5143254721Semaste // haven't already decoded our mangled name. 5144254721Semaste if (m_mangled && !m_demangled) 5145254721Semaste { 5146254721Semaste // We need to generate and cache the demangled name. 5147254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 5148254721Semaste "Mangled::GetDemangledName (m_mangled = %s)", 5149254721Semaste m_mangled.GetCString()); 5150254721Semaste 5151254721Semaste // Don't bother running anything that isn't mangled 5152254721Semaste const char *mangled_cstr = m_mangled.GetCString(); 5153254721Semaste if (cstring_is_mangled(mangled_cstr)) 5154254721Semaste { 5155254721Semaste if (!m_mangled.GetMangledCounterpart(m_demangled)) 5156254721Semaste { 5157254721Semaste // We didn't already mangle this name, demangle it and if all goes well 5158254721Semaste // add it to our map. 5159263363Semaste#ifdef LLDB_USE_BUILTIN_DEMANGLER 5160263363Semaste char *demangled_name = __cxa_demangle (mangled_cstr, NULL, NULL, NULL); 5161263367Semaste#elif defined(_MSC_VER) 5162263367Semaste // Cannot demangle on msvc. 5163263367Semaste char *demangled_name = nullptr; 5164263363Semaste#else 5165254721Semaste char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL); 5166263363Semaste#endif 5167254721Semaste 5168254721Semaste if (demangled_name) 5169254721Semaste { 5170254721Semaste m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); 5171254721Semaste free (demangled_name); 5172254721Semaste } 5173254721Semaste } 5174254721Semaste } 5175254721Semaste if (!m_demangled) 5176254721Semaste { 5177254721Semaste // Set the demangled string to the empty string to indicate we 5178254721Semaste // tried to parse it once and failed. 5179254721Semaste m_demangled.SetCString(""); 5180254721Semaste } 5181254721Semaste } 5182254721Semaste 5183254721Semaste return m_demangled; 5184254721Semaste} 5185254721Semaste 5186254721Semaste 5187254721Semastebool 5188254721SemasteMangled::NameMatches (const RegularExpression& regex) const 5189254721Semaste{ 5190254721Semaste if (m_mangled && regex.Execute (m_mangled.AsCString())) 5191254721Semaste return true; 5192254721Semaste 5193254721Semaste if (GetDemangledName() && regex.Execute (m_demangled.AsCString())) 5194254721Semaste return true; 5195254721Semaste return false; 5196254721Semaste} 5197254721Semaste 5198254721Semaste//---------------------------------------------------------------------- 5199254721Semaste// Get the demangled name if there is one, else return the mangled name. 5200254721Semaste//---------------------------------------------------------------------- 5201254721Semasteconst ConstString& 5202254721SemasteMangled::GetName (Mangled::NamePreference preference) const 5203254721Semaste{ 5204254721Semaste if (preference == ePreferDemangled) 5205254721Semaste { 5206254721Semaste // Call the accessor to make sure we get a demangled name in case 5207254721Semaste // it hasn't been demangled yet... 5208254721Semaste if (GetDemangledName()) 5209254721Semaste return m_demangled; 5210254721Semaste return m_mangled; 5211254721Semaste } 5212254721Semaste else 5213254721Semaste { 5214254721Semaste if (m_mangled) 5215254721Semaste return m_mangled; 5216254721Semaste return GetDemangledName(); 5217254721Semaste } 5218254721Semaste} 5219254721Semaste 5220254721Semaste//---------------------------------------------------------------------- 5221254721Semaste// Dump a Mangled object to stream "s". We don't force our 5222254721Semaste// demangled name to be computed currently (we don't use the accessor). 5223254721Semaste//---------------------------------------------------------------------- 5224254721Semastevoid 5225254721SemasteMangled::Dump (Stream *s) const 5226254721Semaste{ 5227254721Semaste if (m_mangled) 5228254721Semaste { 5229254721Semaste *s << ", mangled = " << m_mangled; 5230254721Semaste } 5231254721Semaste if (m_demangled) 5232254721Semaste { 5233254721Semaste const char * demangled = m_demangled.AsCString(); 5234254721Semaste s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>"); 5235254721Semaste } 5236254721Semaste} 5237254721Semaste 5238254721Semaste//---------------------------------------------------------------------- 5239254721Semaste// Dumps a debug version of this string with extra object and state 5240254721Semaste// information to stream "s". 5241254721Semaste//---------------------------------------------------------------------- 5242254721Semastevoid 5243254721SemasteMangled::DumpDebug (Stream *s) const 5244254721Semaste{ 5245254721Semaste s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this); 5246254721Semaste m_mangled.DumpDebug(s); 5247254721Semaste s->Printf(", demangled = "); 5248254721Semaste m_demangled.DumpDebug(s); 5249254721Semaste} 5250254721Semaste 5251254721Semaste//---------------------------------------------------------------------- 5252254721Semaste// Return the size in byte that this object takes in memory. The size 5253254721Semaste// includes the size of the objects it owns, and not the strings that 5254254721Semaste// it references because they are shared strings. 5255254721Semaste//---------------------------------------------------------------------- 5256254721Semastesize_t 5257254721SemasteMangled::MemorySize () const 5258254721Semaste{ 5259254721Semaste return m_mangled.MemorySize() + m_demangled.MemorySize(); 5260254721Semaste} 5261254721Semaste 5262254721Semaste//---------------------------------------------------------------------- 5263254721Semaste// Dump OBJ to the supplied stream S. 5264254721Semaste//---------------------------------------------------------------------- 5265254721SemasteStream& 5266254721Semasteoperator << (Stream& s, const Mangled& obj) 5267254721Semaste{ 5268254721Semaste if (obj.GetMangledName()) 5269254721Semaste s << "mangled = '" << obj.GetMangledName() << "'"; 5270254721Semaste 5271254721Semaste const ConstString& demangled = obj.GetDemangledName(); 5272254721Semaste if (demangled) 5273254721Semaste s << ", demangled = '" << demangled << '\''; 5274254721Semaste else 5275254721Semaste s << ", demangled = <error>"; 5276254721Semaste return s; 5277254721Semaste} 5278