2023-07-26 11:21:20 -07:00
|
|
|
// This is the non-bootstraped version of the ESpecifier. This will be obsolete once bootstrap is stress tested.
|
|
|
|
|
|
|
|
namespace ESpecifier
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Note: The following are handled separately:
|
|
|
|
attributes
|
|
|
|
alignas
|
|
|
|
*/
|
|
|
|
|
|
|
|
# define Define_Specifiers \
|
|
|
|
Entry( Invalid, INVALID ) \
|
|
|
|
Entry( Consteval, consteval ) \
|
|
|
|
Entry( Constexpr, constexpr ) \
|
|
|
|
Entry( Constinit, constinit ) \
|
|
|
|
Entry( Explicit, explicit ) \
|
|
|
|
Entry( External_Linkage, extern ) \
|
|
|
|
Entry( Global, global ) \
|
|
|
|
Entry( Inline, inline ) \
|
|
|
|
Entry( Internal_Linkage, internal ) \
|
|
|
|
Entry( Local_Persist, local_persist ) \
|
|
|
|
Entry( Mutable, mutable ) \
|
2023-08-02 09:39:35 -07:00
|
|
|
Entry( NeverInline, neverinline ) \
|
2023-07-26 11:21:20 -07:00
|
|
|
Entry( Ptr, * ) \
|
|
|
|
Entry( Ref, & ) \
|
|
|
|
Entry( Register, register ) \
|
|
|
|
Entry( RValue, && ) \
|
|
|
|
Entry( Static, static ) \
|
|
|
|
Entry( Thread_Local, thread_local ) \
|
|
|
|
Entry( Volatile, volatile ) \
|
|
|
|
Entry( Virtual, virtual ) \
|
|
|
|
Entry( Const, const ) \
|
|
|
|
Entry( Final, final ) \
|
2023-08-07 00:10:45 -07:00
|
|
|
Entry( Override, override ) \
|
|
|
|
Entry( Pure, = 0 )
|
2023-07-26 11:21:20 -07:00
|
|
|
|
|
|
|
enum Type : u32
|
|
|
|
{
|
|
|
|
# define Entry( Specifier, Code ) Specifier,
|
|
|
|
Define_Specifiers
|
|
|
|
# undef Entry
|
|
|
|
|
2023-07-27 14:12:58 -07:00
|
|
|
NumSpecifiers,
|
2023-07-26 11:21:20 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
inline
|
|
|
|
bool is_trailing( Type specifier )
|
|
|
|
{
|
|
|
|
return specifier > Virtual;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Specifier to string
|
|
|
|
inline
|
|
|
|
StrC to_str( Type specifier )
|
|
|
|
{
|
|
|
|
local_persist
|
2023-07-27 14:12:58 -07:00
|
|
|
StrC lookup[ NumSpecifiers ] = {
|
2023-07-26 11:21:20 -07:00
|
|
|
# pragma push_macro( "global" )
|
|
|
|
# pragma push_macro( "internal" )
|
|
|
|
# pragma push_macro( "local_persist" )
|
2023-08-02 09:39:35 -07:00
|
|
|
# pragma push_macro( "neverinline" )
|
2023-07-26 11:21:20 -07:00
|
|
|
# undef global
|
|
|
|
# undef internal
|
|
|
|
# undef local_persist
|
2023-08-02 09:39:35 -07:00
|
|
|
# undef neverinline
|
2023-07-26 11:21:20 -07:00
|
|
|
|
|
|
|
# define Entry( Spec_, Code_ ) { sizeof(stringize(Code_)), stringize(Code_) },
|
|
|
|
Define_Specifiers
|
|
|
|
# undef Entry
|
|
|
|
|
|
|
|
# pragma pop_macro( "global" )
|
|
|
|
# pragma pop_macro( "internal" )
|
|
|
|
# pragma pop_macro( "local_persist" )
|
2023-08-02 09:39:35 -07:00
|
|
|
# pragma pop_macro( "neverinline" )
|
2023-07-26 11:21:20 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
return lookup[ specifier ];
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
Type to_type( StrC str )
|
|
|
|
{
|
|
|
|
local_persist
|
2023-07-27 14:12:58 -07:00
|
|
|
u32 keymap[ NumSpecifiers ];
|
2023-07-26 11:21:20 -07:00
|
|
|
do_once_start
|
2023-07-27 14:12:58 -07:00
|
|
|
for ( u32 index = 0; index < NumSpecifiers; index++ )
|
2023-07-26 11:21:20 -07:00
|
|
|
{
|
|
|
|
StrC enum_str = to_str( (Type)index );
|
|
|
|
|
|
|
|
// We subtract 1 to remove the null terminator
|
|
|
|
// This is because the tokens lexed are not null terminated.
|
|
|
|
keymap[index] = crc32( enum_str.Ptr, enum_str.Len - 1);
|
|
|
|
}
|
|
|
|
do_once_end
|
|
|
|
|
|
|
|
u32 hash = crc32( str.Ptr, str.Len );
|
|
|
|
|
2023-07-27 14:12:58 -07:00
|
|
|
for ( u32 index = 0; index < NumSpecifiers; index++ )
|
2023-07-26 11:21:20 -07:00
|
|
|
{
|
|
|
|
if ( keymap[index] == hash )
|
|
|
|
return (Type)index;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
# undef Define_Specifiers
|
|
|
|
}
|
|
|
|
using SpecifierT = ESpecifier::Type;
|
2023-08-03 08:01:43 -07:00
|
|
|
|