llvm.org GIT mirror llvm / 97b215a
Port libcxxabi r344607 into llvm Summary: The original commit message was: This uses CRTP (for performance reasons) to allow a user the override demangler functions to implement custom parsing logic. The motivation for this is LLDB, which needs to occasionaly modify the mangled names. One such instance is already implemented via the TypeCallback member, but this is very specific functionality which does not help with any other use case. Currently we have a use case for modifying the constructor flavours, which would require adding another callback. This approach does not scale. With CRTP, the user (LLDB) can override any function it needs without any special support from the demangler library. After LLDB is ported to use this instead of the TypeCallback mechanism, the callback can be removed. The only difference here is the addition of a unit test which exercises the CRTP mechanism to override a function in the parser. Reviewers: erik.pilkington, rsmith, EricWF Subscribers: mgorny, kristina, llvm-commits Differential Revision: https://reviews.llvm.org/D53300 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@344703 91177308-0d34-0410-b5e6-96231b3b80d8 Pavel Labath 10 months ago
5 changed file(s) with 422 addition(s) and 305 deletion(s). Raw diff Collapse all Expand all
21332133 }
21342134 };
21352135
2136 template
2137 struct Db {
2136 template struct AbstractManglingParser {
21382137 const char *First;
21392138 const char *Last;
21402139
21662165
21672166 Alloc ASTAllocator;
21682167
2169 Db(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
2168 AbstractManglingParser(const char *First_, const char *Last_)
2169 : First(First_), Last(Last_) {}
2170
2171 Derived &getDerived() { return static_cast(*this); }
21702172
21712173 void reset(const char *First_, const char *Last_) {
21722174 First = First_;
22732275 FunctionRefQual ReferenceQualifier = FrefQualNone;
22742276 size_t ForwardTemplateRefsBegin;
22752277
2276 NameState(Db *Enclosing)
2278 NameState(AbstractManglingParser *Enclosing)
22772279 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
22782280 };
22792281
23232325 //
23242326 // ::=
23252327 // ::=
2326 template Node *Db::parseName(NameState *State) {
2328 template
2329 Node *AbstractManglingParser::parseName(NameState *State) {
23272330 consumeIf('L'); // extension
23282331
23292332 if (look() == 'N')
2330 return parseNestedName(State);
2333 return getDerived().parseNestedName(State);
23312334 if (look() == 'Z')
2332 return parseLocalName(State);
2335 return getDerived().parseLocalName(State);
23332336
23342337 // ::=
23352338 if (look() == 'S' && look(1) != 't') {
2336 Node *S = parseSubstitution();
2339 Node *S = getDerived().parseSubstitution();
23372340 if (S == nullptr)
23382341 return nullptr;
23392342 if (look() != 'I')
23402343 return nullptr;
2341 Node *TA = parseTemplateArgs(State != nullptr);
2344 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
23422345 if (TA == nullptr)
23432346 return nullptr;
23442347 if (State) State->EndsWithTemplateArgs = true;
23452348 return make(S, TA);
23462349 }
23472350
2348 Node *N = parseUnscopedName(State);
2351 Node *N = getDerived().parseUnscopedName(State);
23492352 if (N == nullptr)
23502353 return nullptr;
23512354 // ::=
23522355 if (look() == 'I') {
23532356 Subs.push_back(N);
2354 Node *TA = parseTemplateArgs(State != nullptr);
2357 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
23552358 if (TA == nullptr)
23562359 return nullptr;
23572360 if (State) State->EndsWithTemplateArgs = true;
23642367 // := Z E []
23652368 // := Z E s []
23662369 // := Z Ed [ ] _
2367 template Node *Db::parseLocalName(NameState *State) {
2370 template
2371 Node *AbstractManglingParser::parseLocalName(NameState *State) {
23682372 if (!consumeIf('Z'))
23692373 return nullptr;
2370 Node *Encoding = parseEncoding();
2374 Node *Encoding = getDerived().parseEncoding();
23712375 if (Encoding == nullptr || !consumeIf('E'))
23722376 return nullptr;
23732377
23832387 parseNumber(true);
23842388 if (!consumeIf('_'))
23852389 return nullptr;
2386 Node *N = parseName(State);
2390 Node *N = getDerived().parseName(State);
23872391 if (N == nullptr)
23882392 return nullptr;
23892393 return make(Encoding, N);
23902394 }
23912395
2392 Node *Entity = parseName(State);
2396 Node *Entity = getDerived().parseName(State);
23932397 if (Entity == nullptr)
23942398 return nullptr;
23952399 First = parse_discriminator(First, Last);
23992403 // ::=
24002404 // ::= St # ::std::
24012405 // extension ::= StL
2402 template Node *Db::parseUnscopedName(NameState *State) {
2403 if (consumeIf("StL") || consumeIf("St")) {
2404 Node *R = parseUnqualifiedName(State);
2405 if (R == nullptr)
2406 return nullptr;
2407 return make(R);
2408 }
2409 return parseUnqualifiedName(State);
2406 template
2407 Node *
2408 AbstractManglingParser::parseUnscopedName(NameState *State) {
2409 if (consumeIf("StL") || consumeIf("St")) {
2410 Node *R = getDerived().parseUnqualifiedName(State);
2411 if (R == nullptr)
2412 return nullptr;
2413 return make(R);
2414 }
2415 return getDerived().parseUnqualifiedName(State);
24102416 }
24112417
24122418 // ::= [abi-tags]
24142420 // ::=
24152421 // ::=
24162422 // ::= DC + E # structured binding declaration
2417 template
2418 Node *Db::parseUnqualifiedName(NameState *State) {
2423 template
2424 Node *
2425 AbstractManglingParser::parseUnqualifiedName(NameState *State) {
24192426 // s are special-cased in parseNestedName().
24202427 Node *Result;
24212428 if (look() == 'U')
2422 Result = parseUnnamedTypeName(State);
2429 Result = getDerived().parseUnnamedTypeName(State);
24232430 else if (look() >= '1' && look() <= '9')
2424 Result = parseSourceName(State);
2431 Result = getDerived().parseSourceName(State);
24252432 else if (consumeIf("DC")) {
24262433 size_t BindingsBegin = Names.size();
24272434 do {
2428 Node *Binding = parseSourceName(State);
2435 Node *Binding = getDerived().parseSourceName(State);
24292436 if (Binding == nullptr)
24302437 return nullptr;
24312438 Names.push_back(Binding);
24322439 } while (!consumeIf('E'));
24332440 Result = make(popTrailingNodeArray(BindingsBegin));
24342441 } else
2435 Result = parseOperatorName(State);
2442 Result = getDerived().parseOperatorName(State);
24362443 if (Result != nullptr)
2437 Result = parseAbiTags(Result);
2444 Result = getDerived().parseAbiTags(Result);
24382445 return Result;
24392446 }
24402447
24442451 // ::= Ul E [ ] _
24452452 //
24462453 // ::= + # Parameter types or "v" if the lambda has no parameters
2447 template Node *Db::parseUnnamedTypeName(NameState *) {
2454 template
2455 Node *
2456 AbstractManglingParser::parseUnnamedTypeName(NameState *) {
24482457 if (consumeIf("Ut")) {
24492458 StringView Count = parseNumber();
24502459 if (!consumeIf('_'))
24572466 if (!consumeIf("vE")) {
24582467 size_t ParamsBegin = Names.size();
24592468 do {
2460 Node *P = parseType();
2469 Node *P = getDerived().parseType();
24612470 if (P == nullptr)
24622471 return nullptr;
24632472 Names.push_back(P);
24732482 }
24742483
24752484 // ::=
2476 template Node *Db::parseSourceName(NameState *) {
2485 template
2486 Node *AbstractManglingParser::parseSourceName(NameState *) {
24772487 size_t Length = 0;
24782488 if (parsePositiveInteger(&Length))
24792489 return nullptr;
25372547 // ::= rS # >>=
25382548 // ::= ss # <=> C++2a
25392549 // ::= v # vendor extended operator
2540 template Node *Db::parseOperatorName(NameState *State) {
2550 template
2551 Node *
2552 AbstractManglingParser::parseOperatorName(NameState *State) {
25412553 switch (look()) {
25422554 case 'a':
25432555 switch (look(1)) {
25772589 SwapAndRestore SavePermit(PermitForwardTemplateReferences,
25782590 PermitForwardTemplateReferences ||
25792591 State != nullptr);
2580 Node* Ty = parseType();
2592 Node *Ty = getDerived().parseType();
25812593 if (Ty == nullptr)
25822594 return nullptr;
25832595 if (State) State->CtorDtorConversion = true;
26412653 // ::= li # operator ""
26422654 case 'i': {
26432655 First += 2;
2644 Node *SN = parseSourceName(State);
2656 Node *SN = getDerived().parseSourceName(State);
26452657 if (SN == nullptr)
26462658 return nullptr;
26472659 return make(SN);
27622774 case 'v':
27632775 if (std::isdigit(look(1))) {
27642776 First += 2;
2765 Node *SN = parseSourceName(State);
2777 Node *SN = getDerived().parseSourceName(State);
27662778 if (SN == nullptr)
27672779 return nullptr;
27682780 return make(SN);
27802792 // ::= D1 # complete object destructor
27812793 // ::= D2 # base object destructor
27822794 // extension ::= D5 # ?
2783 template
2784 Node *Db::parseCtorDtorName(Node *&SoFar, NameState *State) {
2795 template
2796 Node *
2797 AbstractManglingParser::parseCtorDtorName(Node *&SoFar,
2798 NameState *State) {
27852799 if (SoFar->getKind() == Node::KSpecialSubstitution) {
27862800 auto SSK = static_cast(SoFar)->SSK;
27872801 switch (SSK) {
28052819 ++First;
28062820 if (State) State->CtorDtorConversion = true;
28072821 if (IsInherited) {
2808 if (parseName(State) == nullptr)
2822 if (getDerived().parseName(State) == nullptr)
28092823 return nullptr;
28102824 }
28112825 return make(SoFar, false, Variant);
28392853 // ::=