From afc8bfe838c88bfa38877d403a994d94e60096f0 Mon Sep 17 00:00:00 2001
From: Philippe Virouleau <philippe.44@gmail.com>
Date: Thu, 5 Apr 2018 17:10:14 +0200
Subject: [PATCH] Remove lambdas with parameters inside omp pragmas

Clang seems to be confused by the lambda parameters: it tries to capture it and emit code for it whereas it shouldn't, resulting in an internal error.
---
 Src/Adaptive/FAdaptiveTask.hpp        | 21 ++++---------------
 Src/Adaptive/FNode.hpp                | 18 +++++++++++++++++
 Src/Components/FBasicCell.hpp         | 20 ++++++++++++++++++
 Src/Core/FFmmAlgorithmSectionTask.hpp | 29 +++++++++------------------
 Src/Core/FFmmAlgorithmTask.hpp        | 19 ++++++++----------
 5 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/Src/Adaptive/FAdaptiveTask.hpp b/Src/Adaptive/FAdaptiveTask.hpp
index e75c74c97..c4d5befaa 100644
--- a/Src/Adaptive/FAdaptiveTask.hpp
+++ b/Src/Adaptive/FAdaptiveTask.hpp
@@ -333,18 +333,12 @@ public:
                 std::array<multipole_t*, node_t::child_count> child_multipoles {};
                 std::transform(std::begin(node->getChildren()), std::end(node->getChildren()),
                                child_multipoles.begin(),
-                               [](node_t* n) {
-                                   return n == nullptr ? nullptr
-                                       : &(n->getData()->getMultipoleData());
-                               });
+                               node_t::template getMultipoleDataFromNode<node_t, multipole_t>);
 
                 std::array<symbolic_data_t*, node_t::child_count> child_symbolics {};
                 std::transform(std::begin(node->getChildren()), std::end(node->getChildren()),
                                child_symbolics.begin(),
-                               [](node_t* n) {
-                                   return n == nullptr ? nullptr
-                                       : &(n->getSymbolicData());
-                               });
+                               node_t::template getSymbolicData<node_t, symbolic_data_t>);
 
             // Call kernel module
                 this->_kernels[thread_num]->M2M(
@@ -863,18 +857,11 @@ public:
                 std::array<local_expansion_t*, node_t::child_count> child_local_expansions {};
                 std::transform(std::begin(node->getChildren()), std::end(node->getChildren()),
                                child_local_expansions.begin(),
-                               [](node_t* n) {
-                                   return n == nullptr ? nullptr
-                                       : &(n->getData()->getLocalExpansionData());
-                               });
-
+                               node_t::template getLocalExpansionDataFromNode<node_t, local_expansion_t>);
                 std::array<symbolic_data_t*, node_t::child_count> child_symbolics {};
                 std::transform(std::begin(node->getChildren()), std::end(node->getChildren()),
                                child_symbolics.begin(),
-                               [](node_t* n) {
-                                   return n == nullptr ? nullptr
-                                       : &(n->getSymbolicData());
-                               });
+                               node_t::template getSymbolicDataFromNode<node_t, symbolic_data_t>);
 
                 this->_kernels[thread_num]->L2L(
                     &(node->getData()->getLocalExpansionData()),
diff --git a/Src/Adaptive/FNode.hpp b/Src/Adaptive/FNode.hpp
index d7e06f4df..5abcad6ea 100644
--- a/Src/Adaptive/FNode.hpp
+++ b/Src/Adaptive/FNode.hpp
@@ -983,6 +983,24 @@ private:
             inria::make_index_sequence<std::tuple_size<Tuple>::value - Dim>{});
     }
 
+    template<typename Node, typename Multipole>
+    static Multipole *getMultipoleDataFromNode(Node *n) {
+        return n == nullptr ? nullptr
+            : &(n->getData()->getMultipoleData());
+    }
+
+    template<typename Node, typename SymbolicData>
+    static SymbolicData *getSymbolicDataFromNode(Node *n) {
+        return n == nullptr ? nullptr
+            : &(n->getSymbolicData());
+    }
+
+    template<typename Node, typename LocalExpansion>
+    static LocalExpansion *getLocalExpansionDataFromNode(Node *n) {
+        return n == nullptr ? nullptr
+            : &(n->getData()->getLocalExpansionData());
+    }
+
     /**
      * \brief Reinsert particle in tree after spliting a container
      *
diff --git a/Src/Components/FBasicCell.hpp b/Src/Components/FBasicCell.hpp
index cd01cc673..c8f2fd2d6 100644
--- a/Src/Components/FBasicCell.hpp
+++ b/Src/Components/FBasicCell.hpp
@@ -91,6 +91,26 @@ public:
     /** Do nothing */
     void resetToInitialState(){
     }
+
+    template<typename CellClass, typename Multipole>
+    static Multipole *getMultipoleDataFromCell(CellClass *c) {
+        return c == nullptr ? nullptr
+            : &(c->getMultipoleData());
+    }
+
+    template<typename CellClass, typename LocalExpansion>
+    static LocalExpansion *getLocalExpansionDataFromCell(CellClass *c) {
+        return c == nullptr ? nullptr
+            : &(c->getLocalExpansionData());
+    }
+
+    // FIXME: see Src/Core/FFmmAlgorithmSectionTask.hpp for usage
+    // This is applied via std::transform to an array of data.
+    // It doesn't seem to do anything, but I may be missing something.
+    template<typename CellClass>
+    static CellClass *noop(CellClass *c) {
+        return c;
+    }
 };
 
 
diff --git a/Src/Core/FFmmAlgorithmSectionTask.hpp b/Src/Core/FFmmAlgorithmSectionTask.hpp
index 88b6ed4e2..9332fbb57 100644
--- a/Src/Core/FFmmAlgorithmSectionTask.hpp
+++ b/Src/Core/FFmmAlgorithmSectionTask.hpp
@@ -18,6 +18,8 @@
 #include "../Containers/FOctree.hpp"
 #include "../Containers/FVector.hpp"
 
+#include "Components/FBasicCell.hpp"
+
 #include "FCoreCommon.hpp"
 #include "FP2PExclusion.hpp"
 
@@ -217,13 +219,10 @@ protected:
                     CellClass** children = octreeIterator.getCurrentChildren();
                     std::array<const multipole_t*, 8> child_multipoles;
                     std::transform(children, children+8, child_multipoles.begin(),
-                                   [](CellClass* c) {
-                                       return (c == nullptr ? nullptr
-                                               : &(c->getMultipoleData()));
-                                   });
+                                   FBasicCell::getMultipoleDataFromCell<const CellClass, const multipole_t>);
                     std::array<const symbolic_data_t*, 8> child_symbolics;
                     std::transform(children, children+8, child_symbolics.begin(),
-                                   [](CellClass* c) {return c;});
+                                   FBasicCell::noop<const CellClass>);
                     kernels[omp_get_thread_num()]->M2M(parent_multipole,
                                                        parent_symbolic,
                                                        child_multipoles.data(),
@@ -294,13 +293,10 @@ protected:
                             = octreeIterator.getCurrentCell();
                         std::array<const multipole_t*, 342> neighbor_multipoles;
                         std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
-                                       [](const CellClass* c) {
-                                           return (c == nullptr ? nullptr
-                                                   : &(c->getMultipoleData()));
-                                       });
+                                       FBasicCell::getMultipoleDataFromCell<const CellClass, const multipole_t>);
                         std::array<const symbolic_data_t*, 342> neighbor_symbolics;
                         std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
-                                       [](const CellClass* c) {return c;});
+                                       FBasicCell::noop<const CellClass>);
 
                         kernels[omp_get_thread_num()]->M2L(
                             target_local_exp,
@@ -365,13 +361,10 @@ protected:
                             = octreeIterator.getCurrentCell();
                         std::array<const multipole_t*, 342> neighbor_multipoles;
                         std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
-                                       [](const CellClass* c) {
-                                           return (c == nullptr ? nullptr
-                                                   : &(c->getMultipoleData()));
-                                       });
+                                       FBasicCell::getMultipoleDataFromCell<const CellClass, const multipole_t>);
                         std::array<const symbolic_data_t*, 342> neighbor_symbolics;
                         std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
-                                       [](const CellClass* c) {return c;});
+                                       FBasicCell::noop<const CellClass>);
 
                         kernels[omp_get_thread_num()]->M2L(
                             target_local_exp,
@@ -427,12 +420,10 @@ protected:
                     CellClass** children = octreeIterator.getCurrentChildren();
                     std::array<local_expansion_t*, 8> child_local_expansions;
                     std::transform(children, children+8, child_local_expansions.begin(),
-                                   [](CellClass* c) {return (c == nullptr ? nullptr
-                                                             : &(c->getLocalExpansionData()));
-                                   });
+                                   FBasicCell::getLocalExpansionDataFromCell<CellClass, local_expansion_t>);
                     std::array<symbolic_data_t*, 8> child_symbolics;
                     std::transform(children, children+8, child_symbolics.begin(),
-                                   [](CellClass* c) {return c;});
+                                   FBasicCell::noop<CellClass>);
                     kernels[omp_get_thread_num()]->L2L(
                         parent_local_exp,
                         parent_symbolic,
diff --git a/Src/Core/FFmmAlgorithmTask.hpp b/Src/Core/FFmmAlgorithmTask.hpp
index a30ad3173..7c6f0ead7 100644
--- a/Src/Core/FFmmAlgorithmTask.hpp
+++ b/Src/Core/FFmmAlgorithmTask.hpp
@@ -7,18 +7,18 @@
 
 #include <omp.h>
 
-#include "../Utils/FGlobal.hpp"
-#include "../Utils/FAssert.hpp"
-#include "Utils/FLog.hpp"
-#include "Utils/FEnv.hpp"
 #include "Utils/FAlgorithmTimers.hpp"
-
+#include "Utils/FAssert.hpp"
+#include "Utils/FEnv.hpp"
+#include "Utils/FGlobal.hpp"
+#include "Utils/FLog.hpp"
 #include "Utils/FTic.hpp"
-#include "Utils/FAlgorithmTimers.hpp"
 
 #include "Containers/FOctree.hpp"
 #include "Containers/FVector.hpp"
 
+#include "Components/FBasicCell.hpp"
+
 #include "FCoreCommon.hpp"
 #include "FP2PExclusion.hpp"
 
@@ -374,13 +374,10 @@ protected:
                                     = octreeIterator.getCurrentCell();
                                 std::array<const multipole_t*, 342> neighbor_multipoles;
                                 std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
-                                               [](const CellClass* c) {
-                                                   return (c == nullptr ? nullptr
-                                                           : &(c->getMultipoleData()));
-                                               });
+                                               FBasicCell::getMultipoleDataFromCell<const CellClass, const multipole_t>);
                                 std::array<const symbolic_data_t*, 342> neighbor_symbolics;
                                 std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
-                                               [](const CellClass* c) {return c;});
+                                               FBasicCell::noop<const CellClass>);
 
                                 kernels[omp_get_thread_num()]->M2L(
                                     target_local_exp,
-- 
GitLab