Author: epilk
Date: Mon Feb 12 16:15:56 2018
New Revision: 324970

URL: http://llvm.org/viewvc/llvm-project?rev=324970&view=rev
Log:
[demangler] Support for initializer lists and designated initializers.

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=324970&r1=324969&r2=324970&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Mon Feb 12 16:15:56 2018
@@ -198,6 +198,8 @@ public:
     KUnnamedTypeName,
     KLambdaTypeName,
     KExpr,
+    KBracedExpr,
+    KBracedRangeExpr,
   };
 
   static constexpr unsigned NoParameterPack =
@@ -1322,7 +1324,7 @@ public:
 // -- Expression Nodes --
 
 struct Expr : public Node {
-  Expr() : Node(KExpr) {}
+  Expr(Kind K = KExpr) : Node(K) {}
 };
 
 class BinaryExpr : public Expr {
@@ -1623,6 +1625,70 @@ public:
   }
 };
 
+class InitListExpr : public Expr {
+  Node *Ty;
+  NodeArray Inits;
+public:
+  InitListExpr(Node *Ty_, NodeArray Inits_)
+      : Ty(Ty_), Inits(Inits_) {
+    if (Ty)
+      ParameterPackSize = Ty->ParameterPackSize;
+    for (Node *I : Inits)
+      ParameterPackSize = std::min(I->ParameterPackSize, ParameterPackSize);
+  }
+
+  void printLeft(OutputStream &S) const override {
+    if (Ty)
+      Ty->print(S);
+    S += '{';
+    Inits.printWithComma(S);
+    S += '}';
+  }
+};
+
+class BracedExpr : public Expr {
+  Node *Elem;
+  Node *Init;
+  bool IsArray;
+public:
+  BracedExpr(Node *Elem_, Node *Init_, bool IsArray_)
+      : Expr(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
+
+  void printLeft(OutputStream &S) const override {
+    if (IsArray) {
+      S += '[';
+      Elem->print(S);
+      S += ']';
+    } else {
+      S += '.';
+      Elem->print(S);
+    }
+    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
+      S += " = ";
+    Init->print(S);
+  }
+};
+
+class BracedRangeExpr : public Expr {
+  Node *First;
+  Node *Last;
+  Node *Init;
+public:
+  BracedRangeExpr(Node *First_, Node *Last_, Node *Init_)
+      : Expr(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
+
+  void printLeft(OutputStream &S) const override {
+    S += '[';
+    First->print(S);
+    S += " ... ";
+    Last->print(S);
+    S += ']';
+    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
+      S += " = ";
+    Init->print(S);
+  }
+};
+
 class ThrowExpr : public Expr {
   const Node *Op;
 
@@ -1985,6 +2051,7 @@ struct Db {
   Node *parseFunctionParam();
   Node *parseNewExpr();
   Node *parseConversionExpr();
+  Node *parseBracedExpr();
 
   /// Parse the <type> production.
   Node *parseType();
@@ -2070,6 +2137,7 @@ const char *parse_name(const char *first
 const char *parse_template_args(const char *first, const char *last, Db &db);
 const char *parse_template_param(const char *, const char *, Db &);
 const char *parse_operator_name(const char *first, const char *last, Db &db);
+const char *parse_source_name(const char *, const char *, Db &);
 const char *parse_unqualified_name(const char *first, const char *last, Db 
&db);
 const char *parse_decltype(const char *first, const char *last, Db &db);
 const char *parse_unresolved_name(const char *, const char *, Db &);
@@ -2870,6 +2938,51 @@ Node *Db::parseExprPrimary() {
   }
 }
 
+// <braced-expression> ::= <expression>
+//                     ::= di <field source-name> <braced-expression>    # 
.name = expr
+//                     ::= dx <index expression> <braced-expression>     # 
[expr] = expr
+//                     ::= dX <range begin expression> <range end expression> 
<braced-expression>
+Node *Db::parseBracedExpr() {
+  if (look() == 'd') {
+    switch (look(1)) {
+    case 'i': {
+      First += 2;
+      Node *Field = legacyParse<parse_source_name>();
+      if (Field == nullptr)
+        return nullptr;
+      Node *Init = parseBracedExpr();
+      if (Init == nullptr)
+        return nullptr;
+      return make<BracedExpr>(Field, Init, /*isArray=*/false);
+    }
+    case 'x': {
+      First += 2;
+      Node *Index = parseExpr();
+      if (Index == nullptr)
+        return nullptr;
+      Node *Init = parseBracedExpr();
+      if (Init == nullptr)
+        return nullptr;
+      return make<BracedExpr>(Index, Init, /*isArray=*/true);
+    }
+    case 'X': {
+      First += 2;
+      Node *RangeBegin = parseExpr();
+      if (RangeBegin == nullptr)
+        return nullptr;
+      Node *RangeEnd = parseExpr();
+      if (RangeEnd == nullptr)
+        return nullptr;
+      Node *Init = parseBracedExpr();
+      if (Init == nullptr)
+        return nullptr;
+      return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
+    }
+    }
+  }
+  return parseExpr();
+}
+
 // <expression> ::= <unary operator-name> <expression>
 //              ::= <binary operator-name> <expression> <expression>
 //              ::= <ternary operator-name> <expression> <expression> 
<expression>
@@ -3079,7 +3192,8 @@ Node *Db::parseExpr() {
     }
     return nullptr;
   case 'i':
-    if (First[1] == 'x') {
+    switch (First[1]) {
+    case 'x': {
       First += 2;
       Node *Base = parseExpr();
       if (Base == nullptr)
@@ -3089,6 +3203,18 @@ Node *Db::parseExpr() {
         return Index;
       return make<ArraySubscriptExpr>(Base, Index);
     }
+    case 'l': {
+      First += 2;
+      size_t InitsBegin = Names.size();
+      while (!consumeIf('E')) {
+        Node *E = parseBracedExpr();
+        if (E == nullptr)
+          return nullptr;
+        Names.push_back(E);
+      }
+      return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
+    }
+    }
     return nullptr;
   case 'l':
     switch (First[1]) {
@@ -3310,6 +3436,20 @@ Node *Db::parseExpr() {
         return Ty;
       return make<EnclosingExpr>("typeid (", Ty, ")");
     }
+    case 'l': {
+      First += 2;
+      Node *Ty = parseType();
+      if (Ty == nullptr)
+        return nullptr;
+      size_t InitsBegin = Names.size();
+      while (!consumeIf('E')) {
+        Node *E = parseBracedExpr();
+        if (E == nullptr)
+          return nullptr;
+        Names.push_back(E);
+      }
+      return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
+    }
     case 'r':
       First += 2;
       return make<NameType>("throw");

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=324970&r1=324969&r2=324970&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Mon Feb 12 16:15:56 2018
@@ -29663,6 +29663,33 @@ const char* cases[][2] =
     {"_ZN6test471fINS_1SEEEvPTsNT_1cE", "void test47::f<test47::S>(struct 
test47::S::c*)"},
     {"_ZN6test481fINS_1SEEEvPTuNT_1uE", "void test48::f<test48::S>(union 
test48::S::u*)"},
     {"_ZN6test451fINS_1SEEEvPTeNT_1eE", "void test45::f<test45::S>(enum 
test45::S::e*)"},
+
+    // Initializer list expressions
+    {"_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE", "void 
test4::tf2<test4::X>(decltype(new test4::X({1})))"},
+    {"_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_", 
"decltype((test7::A{1, 2}) , ((int)())) test7::fA1<int>(int)"},
+    {"_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_", 
"decltype(((test7::A)({1, 2})) , ((int)())) test7::fA2<int>(int)"},
+    {"_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_", 
"decltype((test7::B{1, 2}) , ((int)())) test7::fB1<int>(int)"},
+    {"_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_", 
"decltype(((test7::B)({1, 2})) , ((int)())) test7::fB2<int>(int)"},
+    {"_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_", 
"decltype((test7::C{{1, 2}}) , ((int)())) test7::fC1<int>(int)"},
+    {"_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_", 
"decltype(((test7::C)({1, 2})) , ((int)())) test7::fC2<int>(int)"},
+    {"_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_", 
"decltype((test7::D{test7::b}) , ((int)())) test7::fD1<int>(int)"},
+    {"_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_", 
"decltype((test7::E{1, 2}) , ((int)())) test7::fE1<int>(int)"},
+    {"_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_", 
"decltype(((test7::E)({1, 2})) , ((int)())) test7::fE2<int>(int)"},
+    {"_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_", 
"decltype((test7::F{{1, 2}}) , ((int)())) test7::fF1<int>(int)"},
+    {"_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_", 
"decltype(((test7::F)({1, 2})) , ((int)())) test7::fF2<int>(int)"},
+    {"_ZN5test73fT1IiEEDTtlT_EES1_", "decltype(int{}) test7::fT1<int>(int)"},
+    {"_ZN5test73fT3IiEEDTtlT_Li1EEES1_", "decltype(int{1}) 
test7::fT3<int>(int)"},
+    {"_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_", "decltype(test7::B{1, 2}) 
test7::fT5<test7::B>(test7::B)"},
+    {"_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_", "decltype(test7::A{{}}) 
test7::fT7<test7::A>(test7::A)"},
+    {"_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_", "decltype((test7::A)({})) 
test7::fT8<test7::A>(test7::A)"},
+    {"_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_", "decltype(test7::A{{1}}) 
test7::fT9<test7::A>(test7::A)"},
+    {"_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_", "decltype((test7::A)({1})) 
test7::fTA<test7::A>(test7::A)"},
+    {"_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_", "decltype(test7::C{{1, 
2}}) test7::fTB<test7::C>(test7::C)"},
+    {"_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_", "decltype((test7::C)({1, 
2})) test7::fTC<test7::C>(test7::C)"},
+
+    // Designated init expressions
+    {"_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE", 
"void 
designated_init::f<designated_init::A>(decltype(designated_init::A{.a.b[3][1 
... 4] = 9}))"},
+    {"_Z1fIXtl1Xdi1adi1bdxLi3ELi1EEEE", "f<X{.a.b[3] = 1}>"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29798,33 +29825,6 @@ const char *xfail_cases[] = {
 
     // FIXME: Why does clang generate the "cp" expr?
     "_ZN5test11bIsEEDTcp3foocvT__EEES1_",
-
-    // Initializer list expressions:
-    "_ZN5test43tf2INS_1XEEEvDTnw_T_piilLi1EEEE",
-    "_ZN5test43tf3INS_1XEEEvDTnw_T_ilLi1EEE",
-    "_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_",
-    "_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_",
-    "_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_",
-    "_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_",
-    "_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_",
-    "_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_",
-    "_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_",
-    "_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_",
-    "_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_",
-    "_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_",
-    "_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_",
-    "_ZN5test73fT1IiEEDTtlT_EES1_",
-    "_ZN5test73fT3IiEEDTtlT_Li1EEES1_",
-    "_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_",
-    "_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_",
-    "_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_",
-    "_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_",
-    "_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_",
-    "_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_",
-    "_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_",
-
-    // Designated init expressions
-    "_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE",
 };
 
 const size_t num_xfails = sizeof(xfail_cases) / sizeof(xfail_cases[0]);


_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to