[RFC] Experimental C++ support (#331)

This change adds experimental support for C++ via Clang's
OpenCL C++ mode.

In that mode Clang uses OpenCL's generic address space for
a number of things so I've just added it to
clspv::AddressSpace to align clspv's internal convention
with what Clang does a bit better.

This currently has to be used with -inline-entry-points to
maximise the chances that all traces of generic address
space will have been removed before passes that don't
support it. I have another change that plugs LLVM's address
space inference pass and enables quite a bit more code to be
compiled (and the use of the generic address space generally)
but it requires a couple of minor changes to LLVM.

Kernel function overloads are forbidden in the FrontendPlugin
with a custom diagnostic message. Kernel function names
are demangled before the descriptor map creation and the
absence of overload guarantees name unicity.

Signed-off-by: Kévin Petit <kpet@free.fr>
diff --git a/lib/FrontendPlugin.cpp b/lib/FrontendPlugin.cpp
index 1d08153..ddbfc8e 100644
--- a/lib/FrontendPlugin.cpp
+++ b/lib/FrontendPlugin.cpp
@@ -24,6 +24,8 @@
 
 #include "FrontendPlugin.h"
 
+#include <unordered_set>
+
 using namespace clang;
 
 namespace {
@@ -54,6 +56,7 @@
     CustomDiagnosticLocationInfo = 13,
     CustomDiagnosticSSBOUnalignedArray = 14,
     CustomDiagnosticSSBOUnalignedStruct = 15,
+    CustomDiagnosticOverloadedKernel = 16,
     CustomDiagnosticTotal
   };
   std::vector<unsigned> CustomDiagnosticsIDMap;
@@ -332,6 +335,7 @@
   };
 
   DeclVisitor Visitor;
+  std::unordered_set<std::string> Kernels;
 
 public:
   explicit ExtraValidationConsumer(CompilerInstance &Instance,
@@ -403,6 +407,9 @@
         DE.getCustomDiagID(DiagnosticsEngine::Error,
                            "in a SSBO, structs must be aligned to their "
                            "largest element alignment");
+    CustomDiagnosticsIDMap[CustomDiagnosticOverloadedKernel] =
+        DE.getCustomDiagID(DiagnosticsEngine::Error,
+                           "kernel functions can't be overloaded");
   }
 
   virtual bool HandleTopLevelDecl(DeclGroupRef DG) override {
@@ -425,6 +432,15 @@
             }
           }
 
+          if (is_opencl_kernel) {
+            if (Kernels.count(FD->getName()) != 0) {
+              auto srcRange = FD->getSourceRange();
+              Report(CustomDiagnosticOverloadedKernel, srcRange, srcRange);
+            } else {
+              Kernels.insert(FD->getName());
+            }
+          }
+
           for (auto *P : FD->parameters()) {
             auto type = P->getType();
             if (!IsSupportedType(P->getOriginalType(), P->getSourceRange())) {