2

I'm trying to build https://android.googlesource.com/device/generic/vulkan-cereal but have run into an error that seems to only happen with GCC (v8.3 is what I have to work with).

There are related questions, but I still don't understand what's going on well enough to fix the issue:

The code:

https://android.googlesource.com/device/generic/vulkan-cereal/+/refs/heads/master/stream-servers/vulkan/vk_fn_info.h

#define REGISTER_VK_FN_INFO(coreName, allNames)                 \
    struct coreName;                                            \
    template <>                                                 \
    struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {       \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
                    ("vkGetPhysicalDeviceProperties2KHR", "vkGetPhysicalDeviceProperties2"))

The Error:

vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:31:57: error: global qualification of class name is invalid before '{' token
     struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {       \
                                                         ^

/vulkan-cereal/stream-servers/vulkan/vk_fn_info.h:36:1: note: in expansion of macro 'REGISTER_VK_FN_INFO'
 REGISTER_VK_FN_INFO(GetPhysicalDeviceProperties2,
 ^~~~~~~~~~~~~~~~~~~

What can I do to get this to build?

jpx
  • 123
  • 2
  • 9
  • `typedef ::vk_util::vk_fn_info V;` Then define own macros with `::vk_util::vk_fn_info` replaced by V – QuentinUK Feb 26 '22 at 00:39
  • unfortunately, that doesn't appear to work: `error: 'vk_fn_info' in namespace 'vk_util' does not name a type typedef ::vk_util::vk_fn_info V;` – jpx Feb 26 '22 at 05:39
  • That should be `namespace V = ::vk_util::vk_fn_info;` – QuentinUK Feb 26 '22 at 08:08
  • I played around with it a bit, but couldn't get past: ```error: declaration of 'struct vk_util::vk_fn_info::GetVkFnInfo' in namespace 'vk_util::vk_fn_info' which does not enclose 'VK_FN_INFO' struct VK_FN_INFO::GetVkFnInfo {``` – jpx Feb 26 '22 at 15:21
  • https://godbolt.org/z/95GqoP7qG (uncomment the commented out bit) – QuentinUK Feb 26 '22 at 18:11
  • damn... think there is a way to make it work with GCC8.3? This repros my issue: https://godbolt.org/z/qGEhE5Moj – jpx Feb 28 '22 at 15:44

1 Answers1

1

The global qualifier is the two colons at the front:

struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
       ^^

But the answer was to remove all qualifiers:

struct ::vk_util::vk_fn_info::GetVkFnInfo<coreName> {
       ^^^^^^^^^^^^^^^^^^^^^^^

So it becomes:

#define REGISTER_VK_FN_INFO(coreName, allNames)                 \
    struct coreName;                                            \
    template <>                                                 \
    struct GetVkFnInfo<coreName> {                              \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

The trick was that this revealed knock-on errors caused by the macro being improperly used outside the namespaces in another file:

vk_util_unittest.cpp:28:25: error: expected constructor, destructor, or type conversion before '(' token
 REGISTER_VK_FN_INFO_TEST(GfxstreamTestFunc, ("vkGfxstreamTestFunc", "vkGfxstreamTestFuncGOOGLE",

The final change required fixing the namespaces in vk_util_unittest.cpp so that they matched the ones in vk_fn_info.h

As an alternative, I found that the macro could be used outside the namespace as long as it was fully qualified (excluding the invalid global qualification):

#define REGISTER_VK_FN_INFO_EXTERN(coreName, allNames)          \
    struct coreName;                                            \
    template <>                                                 \
    struct vk_util::vk_fn_info::GetVkFnInfo<coreName> {         \
        static constexpr auto names = std::make_tuple allNames; \
        using type = PFN_vk##coreName;                          \
    };

But this prevented it from being used within the namespace. Two separate macros would be needed to satisfy use within and without the namespace.

jpx
  • 123
  • 2
  • 9