[libcxxabi] r318874 - [demangler] Support for abi_tag attribute

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 22 12:38:22 PST 2017


Author: epilk
Date: Wed Nov 22 12:38:22 2017
New Revision: 318874

URL: http://llvm.org/viewvc/llvm-project?rev=318874&view=rev
Log:
[demangler] Support for abi_tag attribute

Differential revision: https://reviews.llvm.org/D40279

Modified:
    libcxxabi/trunk/src/cxa_demangle.cpp
    libcxxabi/trunk/test/test_demangle.pass.cpp

Modified: libcxxabi/trunk/src/cxa_demangle.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp?rev=318874&r1=318873&r2=318874&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Wed Nov 22 12:38:22 2017
@@ -184,6 +184,7 @@ public:
     KConversionOperatorType,
     KPostfixQualifiedType,
     KNameType,
+    KAbiTagAttr,
     KObjCProtoName,
     KPointerType,
     KLValueReferenceType,
@@ -390,6 +391,21 @@ public:
   void printLeft(OutputStream &s) const override { s += Name; }
 };
 
+class AbiTagAttr final : public Node {
+  const Node* Base;
+  StringView Tag;
+public:
+  AbiTagAttr(const Node* Base_, StringView Tag_)
+      : Node(KAbiTagAttr), Base(Base_), Tag(Tag_) {}
+
+  void printLeft(OutputStream &S) const override {
+    Base->printLeft(S);
+    S += "[abi:";
+    S += Tag;
+    S += "]";
+  }
+};
+
 class ObjCProtoName : public Node {
   Node *Ty;
   Node *Protocol;
@@ -1801,10 +1817,9 @@ parse_floating_number(const char* first,
     return first;
 }
 
-// <source-name> ::= <positive length number> <identifier>
-
+// <positive length number> ::= [0-9]*
 const char*
-parse_source_name(const char* first, const char* last, Db& db)
+parse_positive_integer(const char* first, const char* last, size_t* out)
 {
     if (first != last)
     {
@@ -1819,15 +1834,53 @@ parse_source_name(const char* first, con
                 if (++t == last)
                     return first;
             }
-            if (static_cast<size_t>(last - t) >= n)
-            {
-                StringView r(t, t + n);
-                if (r.substr(0, 10) == "_GLOBAL__N")
-                    db.Names.push_back(db.make<NameType>("(anonymous namespace)"));
-                else
-                    db.Names.push_back(db.make<NameType>(r));
-                first = t + n;
-            }
+            *out = n;
+            first = t;
+        }
+    }
+    return first;
+}
+
+// extension
+// <abi-tag-seq> ::= <abi-tag>*
+// <abi-tag>     ::= B <positive length number> <identifier>
+const char*
+parse_abi_tag_seq(const char* first, const char* last, Db& db)
+{
+    while (first != last && *first == 'B' && first+1 != last)
+    {
+        size_t length;
+        const char* t = parse_positive_integer(first+1, last, &length);
+        if (t == first+1)
+            return first;
+        if (static_cast<size_t>(last - t) < length || db.Names.empty())
+            return first;
+        db.Names.back() = db.make<AbiTagAttr>(
+            db.Names.back(), StringView(t, t + length));
+        first = t + length;
+    }
+    return first;
+}
+
+// <source-name> ::= <positive length number> <identifier> [<abi-tag-seq>]
+const char*
+parse_source_name(const char* first, const char* last, Db& db)
+{
+    if (first != last)
+    {
+        size_t length;
+        const char* t = parse_positive_integer(first, last, &length);
+        if (t == first)
+            return first;
+        if (static_cast<size_t>(last - t) >= length)
+        {
+            StringView r(t, t + length);
+            if (r.substr(0, 10) == "_GLOBAL__N")
+                db.Names.push_back(db.make<NameType>("(anonymous namespace)"));
+            else
+                db.Names.push_back(db.make<NameType>(r));
+            first = t + length;
+            first = parse_abi_tag_seq(first, last, db);
         }
     }
     return first;
@@ -3763,10 +3816,11 @@ parse_type(const char* first, const char
 //                   ::= rs    # >>            
 //                   ::= rS    # >>=           
 //                   ::= v <digit> <source-name>        # vendor extended operator
-
+//   extension       ::= <operator-name> <abi-tag-seq>
 const char*
 parse_operator_name(const char* first, const char* last, Db& db)
 {
+    const char* original_first = first;
     if (last - first >= 2)
     {
         switch (first[0])
@@ -4063,6 +4117,10 @@ parse_operator_name(const char* first, c
             break;
         }
     }
+
+    if (original_first != first)
+        first = parse_abi_tag_seq(first, last, db);
+
     return first;
 }
 
@@ -4299,7 +4357,7 @@ Node* maybe_change_special_sub_name(Node
 //                  ::= D1    # complete object destructor
 //                  ::= D2    # base object destructor
 //   extension      ::= D5    # ?
-
+//   extension      ::= <ctor-dtor-name> <abi-tag-seq>
 const char*
 parse_ctor_dtor_name(const char* first, const char* last, Db& db)
 {
@@ -4321,6 +4379,7 @@ parse_ctor_dtor_name(const char* first,
                 db.Names.push_back(
                     db.make<CtorDtorName>(db.Names.back(), false));
                 first += 2;
+                first = parse_abi_tag_seq(first, last, db);
                 db.ParsedCtorDtorCV = true;
                 break;
             }
@@ -4337,6 +4396,7 @@ parse_ctor_dtor_name(const char* first,
                 db.Names.push_back(
                     db.make<CtorDtorName>(db.Names.back(), true));
                 first += 2;
+                first = parse_abi_tag_seq(first, last, db);
                 db.ParsedCtorDtorCV = true;
                 break;
             }
@@ -4346,13 +4406,12 @@ parse_ctor_dtor_name(const char* first,
     return first;
 }
 
-// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
+// <unnamed-type-name> ::= Ut [<nonnegative number>] _ [<abi-tag-seq>]
 //                     ::= <closure-type-name>
 // 
 // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _ 
 // 
 // <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
-
 const char*
 parse_unnamed_type_name(const char* first, const char* last, Db& db)
 {
@@ -4379,6 +4438,7 @@ parse_unnamed_type_name(const char* firs
                 return first;
             db.Names.push_back(db.make<UnnamedTypeName>(count));
             first = t0 + 1;
+            first = parse_abi_tag_seq(first, last, db);
           }
             break;
         case 'l':

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=318874&r1=318873&r2=318874&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Wed Nov 22 12:38:22 2017
@@ -29605,6 +29605,12 @@ const char* cases[][2] =
     {"_ZTW1x", "thread-local wrapper routine for x"},
     {"_ZTHN3fooE", "thread-local initialization routine for foo"},
     {"_Z4algoIJiiiEEvZ1gEUlT_E_", "void algo<int, int, int>(g::'lambda'(int, int, int))"},
+    // attribute abi_tag
+    {"_Z1fB3foov", "f[abi:foo]()"},
+    {"_Z1fB3fooB3barv", "f[abi:foo][abi:bar]()"},
+    {"_ZN1SB5outer1fB5innerEv", "S[abi:outer]::f[abi:inner]()"},
+    {"_ZN1SC2B8ctor_tagEv", "S::S[abi:ctor_tag]()"},
+    {"_ZplB4MERP1SS_", "operator+[abi:MERP](S, S)"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);




More information about the cfe-commits mailing list