[libcxxabi] r328462 - [demangler] Support for clang's enable_if attribute.

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 25 15:49:16 PDT 2018


Author: epilk
Date: Sun Mar 25 15:49:16 2018
New Revision: 328462

URL: http://llvm.org/viewvc/llvm-project?rev=328462&view=rev
Log:
[demangler] Support for clang's enable_if attribute.

Fixes PR33569.

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=328462&r1=328461&r2=328462&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_demangle.cpp (original)
+++ libcxxabi/trunk/src/cxa_demangle.cpp Sun Mar 25 15:49:16 2018
@@ -9,7 +9,6 @@
 
 // FIXME: (possibly) incomplete list of features that clang mangles that this
 // file does not yet support:
-//   - enable_if attribute
 //   - C++ modules TS
 //   - All C++14 and C++17 features
 
@@ -168,6 +167,7 @@ public:
     KElaboratedTypeSpefType,
     KNameType,
     KAbiTagAttr,
+    KEnableIfAttr,
     KObjCProtoName,
     KPointerType,
     KLValueReferenceType,
@@ -486,6 +486,19 @@ public:
   }
 };
 
+class EnableIfAttr : public Node {
+  NodeArray Conditions;
+public:
+  EnableIfAttr(NodeArray Conditions_)
+      : Node(KEnableIfAttr), Conditions(Conditions_) {}
+
+  void printLeft(OutputStream &S) const override {
+    S += " [enable_if:";
+    Conditions.printWithComma(S);
+    S += ']';
+  }
+};
+
 class ObjCProtoName : public Node {
   Node *Ty;
   StringView Protocol;
@@ -812,17 +825,18 @@ class FunctionEncoding final : public No
   const Node *Ret;
   const Node *Name;
   NodeArray Params;
+  Node *Attrs;
   Qualifiers CVQuals;
   FunctionRefQual RefQual;
 
 public:
   FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_,
-                   Qualifiers CVQuals_, FunctionRefQual RefQual_)
+                   Node *Attrs_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
       : Node(KFunctionEncoding, NoParameterPack,
              /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
              /*FunctionCache=*/Cache::Yes),
-        Ret(Ret_), Name(Name_), Params(Params_), CVQuals(CVQuals_),
-        RefQual(RefQual_) {
+        Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
+        CVQuals(CVQuals_), RefQual(RefQual_) {
     for (Node *P : Params)
       ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
     if (Ret)
@@ -861,6 +875,9 @@ public:
       S += " &";
     else if (RefQual == FrefQualRValue)
       S += " &&";
+
+    if (Attrs != nullptr)
+      Attrs->print(S);
   }
 };
 
@@ -4480,6 +4497,18 @@ Node *Db::parseEncoding() {
 
   TagTemplates = false;
 
+  Node *Attrs = nullptr;
+  if (consumeIf("Ua9enable_ifI")) {
+    size_t BeforeArgs = Names.size();
+    while (!consumeIf('E')) {
+      Node *Arg = parseTemplateArg();
+      if (Arg == nullptr)
+        return nullptr;
+      Names.push_back(Arg);
+    }
+    Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
+  }
+
   Node *ReturnType = nullptr;
   if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
     ReturnType = parseType();
@@ -4489,7 +4518,7 @@ Node *Db::parseEncoding() {
 
   if (consumeIf('v'))
     return make<FunctionEncoding>(ReturnType, Name, NodeArray(),
-                                  NameInfo.CVQualifiers,
+                                  Attrs, NameInfo.CVQualifiers,
                                   NameInfo.ReferenceQualifier);
 
   size_t ParamsBegin = Names.size();
@@ -4502,7 +4531,7 @@ Node *Db::parseEncoding() {
 
   return make<FunctionEncoding>(ReturnType, Name,
                                 popTrailingNodeArray(ParamsBegin),
-                                NameInfo.CVQualifiers,
+                                Attrs, NameInfo.CVQualifiers,
                                 NameInfo.ReferenceQualifier);
 }
 

Modified: libcxxabi/trunk/test/test_demangle.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/test_demangle.pass.cpp?rev=328462&r1=328461&r2=328462&view=diff
==============================================================================
--- libcxxabi/trunk/test/test_demangle.pass.cpp (original)
+++ libcxxabi/trunk/test/test_demangle.pass.cpp Sun Mar 25 15:49:16 2018
@@ -29727,6 +29727,11 @@ const char* cases[][2] =
     {"_ZGR1bIvE2_", "reference temporary for b<void>"},
 
     {"_ZZ18test_assign_throwsI20small_throws_on_copyLb0EEvvENKUlRNSt3__13anyEOT_E_clIRS0_EEDaS3_S5_", "auto void test_assign_throws<small_throws_on_copy, false>()::'lambda'(std::__1::any&, auto&&)::operator()<small_throws_on_copy&>(std::__1::any&, auto&&) const"},
+
+    // enable_if attributes:
+    {"_Z1fUa9enable_ifIXLi1EEEv", "f() [enable_if:1]"},
+    {"_ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi", "test4<double>::f(int) [enable_if:(fp) == (1), (fp0) == (2)]"},
+    {"_Z3quxUa9enable_ifIXLi1EEXL_Z9TRUEFACTSEEEi", "qux(int) [enable_if:1, TRUEFACTS]"},
 };
 
 const unsigned N = sizeof(cases) / sizeof(cases[0]);
@@ -29856,7 +29861,6 @@ void test_invalid_cases()
 }
 
 const char *xfail_cases[] = {
-    "_Z1fUa9enable_ifIXLi1EEEv", // enable_if attribute
     "_ZW6FooBarE2f3v", // C++ modules TS
 
     // FIXME: Why does clang generate the "cp" expr?




More information about the cfe-commits mailing list