llvm.org GIT mirror llvm / 4d940e7
[demangler] Support for reference collapsing llvm.org/PR38323 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@338138 91177308-0d34-0410-b5e6-96231b3b80d8 Erik Pilkington 1 year, 3 months ago
1 changed file(s) with 60 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
2121 #include
2222 #include
2323 #include
24 #include
2425 #include
2526
26
2727 namespace {
28
29
3028 // Base class of all AST nodes. The AST is built by the parser, then is
3129 // traversed by the printLeft/Right functions to produce a demangled string.
3230 class Node {
4442 KEnableIfAttr,
4543 KObjCProtoName,
4644 KPointerType,
47 KLValueReferenceType,
48 KRValueReferenceType,
45 KReferenceType,
4946 KPointerToMemberType,
5047 KArrayType,
5148 KFunctionType,
126123 virtual bool hasArraySlow(OutputStream &) const { return false; }
127124 virtual bool hasFunctionSlow(OutputStream &) const { return false; }
128125
126 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
127 // get at a node that actually represents some concrete syntax.
128 virtual const Node *getSyntaxNode(OutputStream &) const {
129 return this;
130 }
131
129132 void print(OutputStream &S) const {
130133 printLeft(S);
131134 if (RHSComponentCache != Cache::No)
436439 }
437440 };
438441
439 class LValueReferenceType final : public Node {
442 enum class ReferenceKind {
443 LValue,
444 RValue,
445 };
446
447 // Represents either a LValue or an RValue reference type.
448 class ReferenceType : public Node {
440449 const Node *Pointee;
441
442 public:
443 LValueReferenceType(Node *Pointee_)
444 : Node(KLValueReferenceType, Pointee_->RHSComponentCache),
445 Pointee(Pointee_) {}
450 ReferenceKind RK;
451
452 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
453 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
454 // other combination collapses to a lvalue ref.
455 std::pair collapse(OutputStream &S) const {
456 auto SoFar = std::make_pair(RK, Pointee);
457 for (;;) {
458 const Node *SN = SoFar.second->getSyntaxNode(S);
459 if (SN->getKind() != KReferenceType)
460 break;
461 auto *RT = static_cast(SN);
462 SoFar.second = RT->Pointee;
463 SoFar.first = std::min(SoFar.first, RT->RK);
464 }
465 return SoFar;
466 }
467
468 public:
469 ReferenceType(Node *Pointee_, ReferenceKind RK_)
470 : Node(KReferenceType, Pointee_->RHSComponentCache),
471 Pointee(Pointee_), RK(RK_) {}
446472
447473 bool hasRHSComponentSlow(OutputStream &S) const override {
448474 return Pointee->hasRHSComponent(S);
449475 }
450476
451477 void printLeft(OutputStream &s) const override {
452 Pointee->printLeft(s);
453 if (Pointee->hasArray(s))
478 std::pair Collapsed = collapse(s);
479 Collapsed.second->printLeft(s);
480 if (Collapsed.second->hasArray(s))
454481 s += " ";
455 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
456 s += "(&";
457 else
458 s += "&";
482 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
483 s += "(";
484
485 s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
459486 }
460487 void printRight(OutputStream &s) const override {
461 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
488 std::pair Collapsed = collapse(s);
489 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
462490 s += ")";
463 Pointee->printRight(s);
464 }
465 };
466
467 class RValueReferenceType final : public Node {
468 const Node *Pointee;
469
470 public:
471 RValueReferenceType(Node *Pointee_)
472 : Node(KRValueReferenceType, Pointee_->RHSComponentCache),
473 Pointee(Pointee_) {}
474
475 bool hasRHSComponentSlow(OutputStream &S) const override {
476 return Pointee->hasRHSComponent(S);
477 }
478
479 void printLeft(OutputStream &s) const override {
480 Pointee->printLeft(s);
481 if (Pointee->hasArray(s))
482 s += " ";
483 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
484 s += "(&&";
485 else
486 s += "&&";
487 }
488
489 void printRight(OutputStream &s) const override {
490 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
491 s += ")";
492 Pointee->printRight(s);
491 Collapsed.second->printRight(s);
493492 }
494493 };
495494
908907 size_t Idx = S.CurrentPackIndex;
909908 return Idx < Data.size() && Data[Idx]->hasFunction(S);
910909 }
910 const Node *getSyntaxNode(OutputStream &S) const override {
911 initializePackExpansion(S);
912 size_t Idx = S.CurrentPackIndex;
913 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this;
914 }
911915
912916 void printLeft(OutputStream &S) const override {
913917 initializePackExpansion(S);
10341038 return false;
10351039 SwapAndRestore SavePrinting(Printing, true);
10361040 return Ref->hasFunction(S);
1041 }
1042 const Node *getSyntaxNode(OutputStream &S) const override {
1043 if (Printing)
1044 return this;
1045 SwapAndRestore SavePrinting(Printing, true);
1046 return Ref->getSyntaxNode(S);
10371047 }
10381048
10391049 void printLeft(OutputStream &S) const override {
34333443 Node *Ref = parseType();
34343444 if (Ref == nullptr)
34353445 return nullptr;
3436 Result = make<LValueReferenceType>(Ref);
3446 Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
34373447 break;
34383448 }
34393449 // ::= O # r-value reference (C++11)
34423452 Node *Ref = parseType();
34433453 if (Ref == nullptr)
34443454 return nullptr;
3445 Result = makeValueReferenceType>(Ref);
3455 Result = makeeferenceType>(Ref, ReferenceKind::RValue);
34463456 break;
34473457 }
34483458 // ::= C # complex pair (C99)