Skip to content

Failure to expand certain multi-line macros properly #195

@devshgraphicsprogramming

Description

Hi, I have the following piece of code

#define alignof(expr) ::nbl::hlsl::alignment_of<__decltype(expr)>::value

// shoudl really return a std::type_info like struct or something, but no `constexpr` and unsure whether its possible to have a `const static SomeStruct` makes it hard to do...
#define typeid(expr) (::nbl::hlsl::impl::typeid_t<__decltype(expr)>::value)

#define NBL_REGISTER_OBJ_TYPE(T, A) namespace nbl { namespace hlsl { \
    namespace impl { template<> struct typeid_t<T> : integral_constant<uint32_t,__COUNTER__> {}; } \ 
    template<> struct alignment_of<T> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<const T> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<typename impl::add_lvalue_reference<T>::type> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<typename impl::add_lvalue_reference<const T>::type> : integral_constant<uint32_t,A> {}; \
}}

// TODO: find out how to do it such that we don't get duplicate definition if we use two function identifiers with same signature
#define NBL_REGISTER_FUN_TYPE(fn) namespace nbl { namespace hlsl { template<> struct typeid_t<__decltype(fn)> : integral_constant<uint32_t,__COUNTER__> {}; }}
// TODO: ideally we'd like to call NBL_REGISTER_FUN_TYPE under the hood, but we can't right now. Also we have a bigger problem, the passing of the function identifier as the second template parameter doesn't work :(
/*
template<> \
struct function_info<__decltype(fn),fn> \
{ \
    using type = __decltype(fn); \
    static const uint32_t address = __COUNTER__; \
}; \
}}}}
*/

// builtins

#define NBL_REGISTER_MATRICES(T, A) \
    NBL_REGISTER_OBJ_TYPE(T, A) \
    NBL_REGISTER_OBJ_TYPE(T ## x4, A) \
    NBL_REGISTER_OBJ_TYPE(T ## x3, A) \
    NBL_REGISTER_OBJ_TYPE(T ## x2, A) \

#define NBL_REGISTER_TYPES_FOR_SCALAR(T) \
    NBL_REGISTER_OBJ_TYPE(T, sizeof(T)) \
    NBL_REGISTER_OBJ_TYPE(T ## 1, sizeof(T)) \
    NBL_REGISTER_MATRICES(T ## 2, sizeof(T)) \
    NBL_REGISTER_MATRICES(T ## 3, sizeof(T)) \
    NBL_REGISTER_MATRICES(T ## 4, sizeof(T))

NBL_REGISTER_TYPES_FOR_SCALAR(int16_t)
NBL_REGISTER_TYPES_FOR_SCALAR(int32_t)
NBL_REGISTER_TYPES_FOR_SCALAR(int64_t)

NBL_REGISTER_TYPES_FOR_SCALAR(uint16_t)
NBL_REGISTER_TYPES_FOR_SCALAR(uint32_t)
NBL_REGISTER_TYPES_FOR_SCALAR(uint64_t)

NBL_REGISTER_TYPES_FOR_SCALAR(bool)

NBL_REGISTER_TYPES_FOR_SCALAR(float16_t)
NBL_REGISTER_TYPES_FOR_SCALAR(float32_t)
NBL_REGISTER_TYPES_FOR_SCALAR(float64_t)

#undef NBL_REGISTER_MATRICES
#undef NBL_REGISTER_TYPES_FOR_SCALAR

Wave leaves a piece of NBL_REGISTER_OBJ_TYPE behind.

The output should be: good.txt

I got this instead: bad.txt

Changing the definition of NBL_REGISTER_OBJ_TYPE to:

#define NBL_IMPL_SPECIALIZE_TYPE_ID(T) namespace impl { template<> struct typeid_t<T> : integral_constant<uint32_t,__COUNTER__> {}; }

#define NBL_REGISTER_OBJ_TYPE(T,A) namespace nbl { namespace hlsl { NBL_IMPL_SPECIALIZE_TYPE_ID(T) \
    template<> struct alignment_of<T> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<const T> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<typename impl::add_lvalue_reference<T>::type> : integral_constant<uint32_t,A> {}; \
    template<> struct alignment_of<typename impl::add_lvalue_reference<const T>::type> : integral_constant<uint32_t,A> {}; \
}}

fixes the problem

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions