Helped by Khronos focus of never supporting anything other than C and letting the community come up with tools.
So for years, before they started having a beating OpenCL was all about a C99 dialect with printf debugging.
SPIR and support for C++ came later as they were already taking a beating, trying to get up.
Apparently that is also the reason why Apple gave up on OpenCL, disagreements on how it should be going, after they gave 1.0 to Khronos.
Just compare Metal, a OOP API for GPUs, with Objective-C/Swift bindings, using a C++ dialect as shading language, a framework for data management, with Vulkan/OpenGL/OpenCL.
well, yeah. All of the opencl implementations were (and probably still are) awful. Other than requiring a lot of boilerplate, I found it adequate, essentially a clone of the the CUDA C driver API.
opencl 2 went into the weeds going full c++, but that all got rolled back with version 3.