aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2014-04-26 00:14:00 +0000
committerNick Lewycky <nicholas@mxc.ca>2014-04-26 00:14:00 +0000
commit7129bf266e51bfcfac5d5aebe27a16e4e9b1972b (patch)
treea4d3eae18d27ab8295a936a6d886255396eb546f
parent34e86037931c687336f9ad0583020d865d6150d1 (diff)
downloadclang_35a-7129bf266e51bfcfac5d5aebe27a16e4e9b1972b.tar.gz
Add mangling for attribute enable_if. The demangling patch for libcxxabi is still in review.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207296 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ItaniumMangle.cpp19
-rw-r--r--test/CodeGenCXX/enable_if.cpp20
2 files changed, 39 insertions, 0 deletions
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index bb7de2f080..0e332a6f2d 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -456,6 +456,25 @@ void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
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.
+ for (AttrVec::const_reverse_iterator I = FD->getAttrs().rbegin(),
+ E = FD->getAttrs().rend();
+ I != E; ++I) {
+ EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
+ if (!EIA)
+ continue;
+ 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:
diff --git a/test/CodeGenCXX/enable_if.cpp b/test/CodeGenCXX/enable_if.cpp
new file mode 100644
index 0000000000..00c55c7749
--- /dev/null
+++ b/test/CodeGenCXX/enable_if.cpp
@@ -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>;