[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())) {