Sunday, June 26, 2022

[FIXED] how to solve: error: global qualification of class name is invalid before '{' token

Issue

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?


Solution

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.



Answered By - jpx
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.