[llvm] r338138 - [demangler] Support for reference collapsing

Erik Pilkington via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 27 10:27:41 PDT 2018


Author: epilk
Date: Fri Jul 27 10:27:40 2018
New Revision: 338138

URL: http://llvm.org/viewvc/llvm-project?rev=338138&view=rev
Log:
[demangler] Support for reference collapsing

llvm.org/PR38323

Modified:
    llvm/trunk/lib/Demangle/ItaniumDemangle.cpp

Modified: llvm/trunk/lib/Demangle/ItaniumDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/ItaniumDemangle.cpp?rev=338138&r1=338137&r2=338138&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/ItaniumDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/ItaniumDemangle.cpp Fri Jul 27 10:27:40 2018
@@ -22,12 +22,10 @@
 #include <cstdlib>
 #include <cstring>
 #include <numeric>
+#include <utility>
 #include <vector>
 
-
 namespace {
-
-
 // Base class of all AST nodes. The AST is built by the parser, then is
 // traversed by the printLeft/Right functions to produce a demangled string.
 class Node {
@@ -45,8 +43,7 @@ public:
     KEnableIfAttr,
     KObjCProtoName,
     KPointerType,
-    KLValueReferenceType,
-    KRValueReferenceType,
+    KReferenceType,
     KPointerToMemberType,
     KArrayType,
     KFunctionType,
@@ -127,6 +124,12 @@ public:
   virtual bool hasArraySlow(OutputStream &) const { return false; }
   virtual bool hasFunctionSlow(OutputStream &) const { return false; }
 
+  // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
+  // get at a node that actually represents some concrete syntax.
+  virtual const Node *getSyntaxNode(OutputStream &) const {
+    return this;
+  }
+
   void print(OutputStream &S) const {
     printLeft(S);
     if (RHSComponentCache != Cache::No)
@@ -437,60 +440,56 @@ public:
   }
 };
 
-class LValueReferenceType final : public Node {
-  const Node *Pointee;
-
-public:
-  LValueReferenceType(Node *Pointee_)
-      : Node(KLValueReferenceType, Pointee_->RHSComponentCache),
-        Pointee(Pointee_) {}
-
-  bool hasRHSComponentSlow(OutputStream &S) const override {
-    return Pointee->hasRHSComponent(S);
-  }
-
-  void printLeft(OutputStream &s) const override {
-    Pointee->printLeft(s);
-    if (Pointee->hasArray(s))
-      s += " ";
-    if (Pointee->hasArray(s) || Pointee->hasFunction(s))
-      s += "(&";
-    else
-      s += "&";
-  }
-  void printRight(OutputStream &s) const override {
-    if (Pointee->hasArray(s) || Pointee->hasFunction(s))
-      s += ")";
-    Pointee->printRight(s);
-  }
+enum class ReferenceKind {
+  LValue,
+  RValue,
 };
 
-class RValueReferenceType final : public Node {
+// Represents either a LValue or an RValue reference type.
+class ReferenceType : public Node {
   const Node *Pointee;
+  ReferenceKind RK;
+
+  // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
+  // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
+  // other combination collapses to a lvalue ref.
+  std::pair<ReferenceKind, const Node *> collapse(OutputStream &S) const {
+    auto SoFar = std::make_pair(RK, Pointee);
+    for (;;) {
+      const Node *SN = SoFar.second->getSyntaxNode(S);
+      if (SN->getKind() != KReferenceType)
+        break;
+      auto *RT = static_cast<const ReferenceType *>(SN);
+      SoFar.second = RT->Pointee;
+      SoFar.first = std::min(SoFar.first, RT->RK);
+    }
+    return SoFar;
+  }
 
 public:
-  RValueReferenceType(Node *Pointee_)
-      : Node(KRValueReferenceType, Pointee_->RHSComponentCache),
-        Pointee(Pointee_) {}
+  ReferenceType(Node *Pointee_, ReferenceKind RK_)
+      : Node(KReferenceType, Pointee_->RHSComponentCache),
+        Pointee(Pointee_), RK(RK_) {}
 
   bool hasRHSComponentSlow(OutputStream &S) const override {
     return Pointee->hasRHSComponent(S);
   }
 
   void printLeft(OutputStream &s) const override {
-    Pointee->printLeft(s);
-    if (Pointee->hasArray(s))
+    std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
+    Collapsed.second->printLeft(s);
+    if (Collapsed.second->hasArray(s))
       s += " ";
-    if (Pointee->hasArray(s) || Pointee->hasFunction(s))
-      s += "(&&";
-    else
-      s += "&&";
-  }
+    if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
+      s += "(";
 
+    s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
+  }
   void printRight(OutputStream &s) const override {
-    if (Pointee->hasArray(s) || Pointee->hasFunction(s))
+    std::pair<ReferenceKind, const Node *> Collapsed = collapse(s);
+    if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s))
       s += ")";
-    Pointee->printRight(s);
+    Collapsed.second->printRight(s);
   }
 };
 
@@ -909,6 +908,11 @@ public:
     size_t Idx = S.CurrentPackIndex;
     return Idx < Data.size() && Data[Idx]->hasFunction(S);
   }
+  const Node *getSyntaxNode(OutputStream &S) const override {
+    initializePackExpansion(S);
+    size_t Idx = S.CurrentPackIndex;
+    return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this;
+  }
 
   void printLeft(OutputStream &S) const override {
     initializePackExpansion(S);
@@ -1036,6 +1040,12 @@ struct ForwardTemplateReference : Node {
     SwapAndRestore<bool> SavePrinting(Printing, true);
     return Ref->hasFunction(S);
   }
+  const Node *getSyntaxNode(OutputStream &S) const override {
+    if (Printing)
+      return this;
+    SwapAndRestore<bool> SavePrinting(Printing, true);
+    return Ref->getSyntaxNode(S);
+  }
 
   void printLeft(OutputStream &S) const override {
     if (Printing)
@@ -3434,7 +3444,7 @@ Node *Db::parseType() {
     Node *Ref = parseType();
     if (Ref == nullptr)
       return nullptr;
-    Result = make<LValueReferenceType>(Ref);
+    Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
     break;
   }
   //             ::= O <type>        # r-value reference (C++11)
@@ -3443,7 +3453,7 @@ Node *Db::parseType() {
     Node *Ref = parseType();
     if (Ref == nullptr)
       return nullptr;
-    Result = make<RValueReferenceType>(Ref);
+    Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
     break;
   }
   //             ::= C <type>        # complex pair (C99)




More information about the llvm-commits mailing list