// SPDX-License-Identifier: LGPL-2.1-or-later
#ifndef RCC_KEYWORD_IDS_H
#define RCC_KEYWORD_IDS_H

#include <stddef.h>

// keyword_entry.flags
enum {
    KW_NONE = 0,
    KW_CONTROL = 1 << 0,
    KW_STORAGE = 1 << 1,
    KW_QUAL = 1 << 2,
    KW_TYPE = 1 << 3,
    KW_ATTR = 1 << 4,
    KW_BUILTIN = 1 << 5,
    KW_ATOMIC = 1 << 6,
    KW_SYNC = 1 << 7,
    KW_PREPROC = 1 << 8,
    KW_ASM = 1 << 9,
    KW_SPECIAL = 1 << 10,
    KW_MODE = 1 << 11,
};

// keyword_entry.id
enum {
    ID_NONE = 0,
    ID_IF,
    ID_ELSE,
    ID_WHILE,
    ID_DO,
    ID_FOR,
    ID_SWITCH,
    ID_CASE,
    ID_DEFAULT,
    ID_BREAK,
    ID_CONTINUE,
    ID_RETURN,
    ID_GOTO,
    ID_TYPEDEF,
    ID_EXTERN,
    ID_STATIC,
    ID_INLINE,
    ID___INLINE,
    ID___INLINE__,
    ID_REGISTER,
    ID_AUTO,
    ID_CONSTEXPR,
    ID___AUTO_TYPE,
    ID___THREAD,
    ID__THREAD_LOCAL,
    ID_THREAD_LOCAL,
    ID_CONST,
    ID___CONST,
    ID___CONST__,
    ID_VOLATILE,
    ID___VOLATILE,
    ID___VOLATILE__,
    ID_RESTRICT,
    ID___RESTRICT,
    ID___RESTRICT__,
    ID__ATOMIC,
    ID_INT,
    ID_CHAR,
    ID_VOID,
    ID_FLOAT,
    ID_DOUBLE,
    ID___INT128,
    ID___INT64,
    ID__BOOL,
    ID__BITINT,
    ID__COMPLEX,
    ID___COMPLEX__,
    ID__DECIMAL32,
    ID__DECIMAL64,
    ID__DECIMAL128,
    ID__FLOAT16,
    ID__FLOAT32,
    ID__FLOAT32X,
    ID__FLOAT64,
    ID__FLOAT64X,
    ID__FLOAT128,
    ID_TYPEOF,
    ID_TYPEOF_UNQUAL,
    ID___TYPEOF_UNQUAL,
    ID___TYPEOF_UNQUAL__,
    ID___TYPEOF,
    ID___TYPEOF__,
    ID_STRUCT,
    ID_UNION,
    ID_ENUM,
    ID_SIGNED,
    ID___SIGNED,
    ID___SIGNED__,
    ID_UNSIGNED,
    ID_SHORT,
    ID_LONG,
    ID___ATTRIBUTE,
    ID___ATTRIBUTE__,
    ID___DECLSPEC,
    ID_ALIAS,
    ID___ALIAS__,
    ID_ALIGNED,
    ID___ALIGNED__,
    ID_CLEANUP,
    ID___CLEANUP__,
    ID_CONSTRUCTOR,
    ID___CONSTRUCTOR__,
    ID_DESTRUCTOR,
    ID___DESTRUCTOR__,
    ID_GCC_STRUCT,
    ID_MS_STRUCT,
    ID_MODE,
    ID___MODE__,
    ID_PACKED,
    ID___PACKED__,
    ID_WEAK,
    ID___CDECL,
    ID___STDCALL,
    ID___FASTCALL,
    ID___THISCALL,
    ID___VECTORCALL,
    ID_QI,
    ID_HI,
    ID_SI,
    ID_DI,
    ID__ALIGNAS,
    ID_ALIGNAS,
    ID__ALIGNOF,
    ID_ALIGNOF,
    ID___ALIGNOF,
    ID___ALIGNOF__,
    ID__GENERIC,
    ID__PRAGMA,
    ID_SIZEOF,
    ID___FUNCTION__,
    ID___PRETTY_FUNCTION__,
    ID___FUNC__,
    ID___HAS_INCLUDE,
    ID___HAS_INCLUDE_NEXT,
    ID___LABEL__,
    ID___ASM,
    ID___ASM__,
    ID_ASM,
    ID_STATIC_ASSERT,
    ID__STATIC_ASSERT,
    ID_NULLPTR,
    ID__,
    ID_NULL,
    ID___RETBUF,
    ID_DEFINE,
    ID_UNDEF,
    ID_INCLUDE,
    ID_IFDEF,
    ID_IFNDEF,
    ID_ELIF,
    ID_ENDIF,
    ID_PRAGMA,
    ID_ONCE,
    ID_PACK,
    ID_PUSH,
    ID_POP,
    ID_PUSH_MACRO,
    ID_POP_MACRO,
    ID_UNICODE,
    ID_DEFINED,
    ID_ABS,
    ID_LABS,
    ID_LLABS,
    ID_ALLOCA,
    ID_PRINTF,
    ID_FPRINTF,
    ID_VPRINTF,
    ID_VFPRINTF,
    ID_PUTS,
    ID_FPUTS,
    ID_SPRINTF,
    ID_SNPRINTF,
    ID_SCANF,
    ID_FSCANF,
    ID_SSCANF,
    ID_MEMSET,
    ID_MEMCPY,
    ID_MEMCMP,
    ID_STRLEN,
    ID_STRCMP,
    ID_STRCHR,
    ID___BUILTIN_ABS,
    ID___BUILTIN_ADD_OVERFLOW,
    ID___BUILTIN_APPLY,
    ID___BUILTIN_APPLY_ARGS,
    ID___BUILTIN_BSWAP16,
    ID___BUILTIN_BSWAP32,
    ID___BUILTIN_BSWAP64,
    ID___BUILTIN_CHOOSE_EXPR,
    ID___BUILTIN_CLASSIFY_TYPE,
    ID___BUILTIN_CLRSB,
    ID___BUILTIN_CLRSBL,
    ID___BUILTIN_CLRSBLL,
    ID___BUILTIN_CLZ,
    ID___BUILTIN_CLZL,
    ID___BUILTIN_CLZLL,
    ID___BUILTIN_CONSTANT_P,
    ID___BUILTIN_COPYSIGN,
    ID___BUILTIN_COPYSIGNF,
    ID___BUILTIN_COPYSIGNL,
    ID___BUILTIN_CTZ,
    ID___BUILTIN_CTZL,
    ID___BUILTIN_CTZLL,
    ID___BUILTIN_FFS,
    ID___BUILTIN_FFSL,
    ID___BUILTIN_FFSLL,
    ID___BUILTIN_FPCLASSIFY,
    ID___BUILTIN_FPCLASSIFYF,
    ID___BUILTIN_FPCLASSIFYL,
    ID___BUILTIN_FRAME_ADDRESS,
    ID___BUILTIN_ISINF,
    ID___BUILTIN_ISINFF,
    ID___BUILTIN_ISINFL,
    ID___BUILTIN_ISFINITE,
    ID___BUILTIN_ISFINITEF,
    ID___BUILTIN_ISFINITEL,
    ID___BUILTIN_ISNORMAL,
    ID___BUILTIN_ISNORMALF,
    ID___BUILTIN_ISNORMALL,
    ID___BUILTIN_LABS,
    ID___BUILTIN_LLABS,
    ID___BUILTIN_LONGJMP,
    ID___BUILTIN_MEMCMP,
    ID___BUILTIN_MEMCPY,
    ID___BUILTIN_MEMSET,
    ID___BUILTIN_MUL_OVERFLOW,
    ID___BUILTIN_MUL_OVERFLOW_P,
    ID___BUILTIN_OFFSETOF,
    ID___BUILTIN_PARITY,
    ID___BUILTIN_PARITYL,
    ID___BUILTIN_PARITYLL,
    ID___BUILTIN_POPCOUNT,
    ID___BUILTIN_POPCOUNTL,
    ID___BUILTIN_POPCOUNTLL,
    ID___BUILTIN_PREFETCH,
    ID___BUILTIN_RETURN,
    ID___BUILTIN_RETURN_ADDRESS,
    ID___BUILTIN_SETJMP,
    ID___BUILTIN_SIGNBIT,
    ID___BUILTIN_SIGNBITF,
    ID___BUILTIN_SIGNBITL,
    ID___BUILTIN_STRCHR,
    ID___BUILTIN_STRCMP,
    ID___BUILTIN_STRLEN,
    ID___BUILTIN_SUB_OVERFLOW,
    ID___BUILTIN_TYPES_COMPATIBLE_P,
    ID___BUILTIN_VA_ARG,
    ID___BUILTIN_VA_ARG_PACK,
    ID___BUILTIN_VA_ARG_PACK_LEN,
    ID___BUILTIN_VA_COPY,
    ID___BUILTIN_VA_END,
    ID___BUILTIN_VA_START,
    ID___ATOMIC_ADD_FETCH,
    ID___ATOMIC_AND_FETCH,
    ID___ATOMIC_CLEAR,
    ID___ATOMIC_COMPARE_EXCHANGE,
    ID___ATOMIC_COMPARE_EXCHANGE_N,
    ID___ATOMIC_EXCHANGE,
    ID___ATOMIC_EXCHANGE_N,
    ID___ATOMIC_FETCH_ADD,
    ID___ATOMIC_FETCH_AND,
    ID___ATOMIC_FETCH_NAND,
    ID___ATOMIC_FETCH_OR,
    ID___ATOMIC_FETCH_SUB,
    ID___ATOMIC_FETCH_XOR,
    ID___ATOMIC_IS_LOCK_FREE,
    ID___ATOMIC_LOAD,
    ID___ATOMIC_LOAD_N,
    ID___ATOMIC_NAND_FETCH,
    ID___ATOMIC_OR_FETCH,
    ID___ATOMIC_SIGNAL_FENCE,
    ID___ATOMIC_STORE,
    ID___ATOMIC_STORE_N,
    ID___ATOMIC_SUB_FETCH,
    ID___ATOMIC_TEST_AND_SET,
    ID___ATOMIC_THREAD_FENCE,
    ID___ATOMIC_XOR_FETCH,
    ID___SYNC_BOOL_COMPARE_AND_SWAP,
    ID___SYNC_FETCH_AND_ADD,
    ID___SYNC_FETCH_AND_AND,
    ID___SYNC_FETCH_AND_NAND,
    ID___SYNC_FETCH_AND_OR,
    ID___SYNC_FETCH_AND_SUB,
    ID___SYNC_FETCH_AND_XOR,
    ID___SYNC_LOCK_RELEASE,
    ID___SYNC_LOCK_TEST_AND_SET,
    ID___SYNC_SYNCHRONIZE,
    ID___SYNC_VAL_COMPARE_AND_SWAP,
    ID___PRINTF_CHK,
    ID___VPRINTF_CHK,
    ID___FPRINTF_CHK,
    ID___VFPRINTF_CHK,
    KW_COUNT
};

extern char *kw_canon[KW_COUNT + 1];
extern unsigned kw_flags[KW_COUNT + 1];

struct keyword_entry;

const struct keyword_entry *keyword_lookup(const char *str, size_t len);
int keyword_id(const char *str, size_t len, char **interned_out);
char *keyword_interned(const char *str, size_t len);
void init_keywords(void);

#endif
