On 03/09/2014 11:01 AM, David Majnemer wrote:
Your std::remove_if would be more concise if it used a lambda instead
of IsNotEnableIfAttr.

Done. Also added another test case to the mangling tests.

Nick

On Sun Mar 09 2014 at 10:30:45 AM, Nick Lewycky <[email protected]
<mailto:[email protected]>> wrote:

    The attached mangle-enable_if-1.patch adds a mangling for
    __attribute__((enable_if(expr, string-literal))) to clang.

    demangle-enable_if-1.patch adds support to libcxxabi's demangler. This
    patch I'm not very confident in. libcxxabi's cxa_demangle lacks comments
    and assertions, leaving its design criteria a mystery. I think the
    functions return 'first' in case of error. I added a vector<> inside the
    demangler, I don't know whether that's OK because it means doing
    allocation. I don't know what the two strings in the pair in db.names
    are for, but the first one appears to be the demangling so I put it
    there. I don't understand what the members in 'db' are for, since they
    aren't commented (db.tag_templates?). The code is cargo culted from
    parse_template_args and simplified down by making wild assumptions
    (db.tag_templates is always false!) and constant folding.

    Also the demangler seems pretty buggy. It wraps expressions in extra
    parentheses which don't correspond to pi .. E expressions (if you were
    to remangle it, you'd get the extra pi .. E). A mangling for "&function"
    ends up demangling "&(function())" which has different semantic meaning.
       I'm assuming these problems are pre-existing. While "_Z3foo"
    demangles
    to "foo" and "_Z3foov" demangles to "foo()", the same things with an
    attribute demangle to include parens. For example, "_Z3fooUa3bar" and
    "_Z3fooUa3barv" both demangle to "foo() __attribute__((bar))", never
    "foo __attribute__((bar))".

    Finally, I've never even compiled the change to the tests. I have tested
    those exact manglings and seen what cxa_demangle does to them, but it
    was easier to write a standalone tool than to deal with "testit".

    Please review!

    Nick
    _________________________________________________
    cfe-commits mailing list
    [email protected] <mailto:[email protected]>
    http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-commits
    <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits>


Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp	(revision 203417)
+++ lib/AST/ItaniumMangle.cpp	(working copy)
@@ -453,6 +453,27 @@
   if (!Context.shouldMangleDeclName(FD))
     return;
 
+  if (FD->hasAttr<EnableIfAttr>()) {
+    FunctionTypeDepthState saved = FunctionTypeDepth.push();
+    Out << "Ua9enable_ifI";
+    // FIXME: specific_attr_iterator iterates in reverse order. Fix that and use
+    // it here.
+    AttrVec Attrs = FD->getAttrs();
+    AttrVec::iterator E = std::remove_if(Attrs.begin(), Attrs.end(),
+                                         [&](Attr *A) -> bool {
+                                           return !isa<EnableIfAttr>(A);
+                                         });
+    std::reverse(Attrs.begin(), E);
+    for (AttrVec::iterator I = Attrs.begin(); I != E; ++I) {
+      EnableIfAttr *EIA = cast<EnableIfAttr>(*I);
+      Out << 'X';
+      mangleExpression(EIA->getCond());
+      Out << 'E';
+    }
+    Out << 'E';
+    FunctionTypeDepth.pop(saved);
+  }
+
   // Whether the mangling of a function type includes the return type depends on
   // the context and the nature of the function. The rules for deciding whether
   // the return type is included are:
Index: test/CodeGenCXX/enable_if.cpp
===================================================================
--- test/CodeGenCXX/enable_if.cpp	(revision 0)
+++ test/CodeGenCXX/enable_if.cpp	(working copy)
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu| FileCheck %s
+// Test itanium mangling for attribute enable_if
+
+// CHECK: _Z5test1Ua9enable_ifIXeqfL0p_Li1EEEi
+void test1(int i) __attribute__((enable_if(i == 1, ""))) {}
+
+void ext();
+// CHECK: _Z5test2Ua9enable_ifIXneadL_Z3extvELi0EEEi
+void test2(int i) __attribute__((enable_if(&ext != 0, ""))) {}
+
+// CHECK: _Z5test3Ua9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEii
+void test3(int i, int j) __attribute__((enable_if(i == 1, ""), enable_if(j == 2, ""))) {}
+
+// CHECK: _ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi
+template <typename T>
+class test4 {
+  virtual void f(int i, int j) __attribute__((enable_if(i == 1, ""))) __attribute__((enable_if(j == 2, "")));
+};
+
+template class test4<double>;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to