(preproc_def
    "#define" @context
    name: (_) @name) @item

(preproc_function_def
    "#define" @context
    name: (_) @name
    parameters: (preproc_params
        "(" @context
        ")" @context)) @item

(namespace_definition
    "inline"? @context
    "namespace" @context
    name: (_) @name) @item

(type_definition
    "typedef" @context
    declarator: (_) @name) @item

(struct_specifier
    "struct" @context
    name: (_) @name) @item

(class_specifier
    "class" @context
    name: (_) @name) @item

(enum_specifier
    "enum" @context
    [
        "class"
        "struct"
    ]? @context
    name: (_) @name) @item

(union_specifier
    "union" @context
    name: (_) @name) @item

(enumerator
    name: (_) @name) @item

(concept_definition
    "concept" @context
    name: (_) @name) @item

(declaration
    [
        (storage_class_specifier)
        (type_qualifier)
    ]* @context
    type: (_) @context
    declarator: [
        ; The declaration may define multiple variables, using @item on the
        ; declarator so that they get distinct ranges.
        (init_declarator
            declarator: (_) @item @name)
        (identifier) @item @name
    ] @item)

(function_definition
    [
        (storage_class_specifier)
        (type_qualifier)
    ]* @context
    type: (_)? @context
    declarator: [
        (function_declarator
            declarator: (_) @name
            parameters: (parameter_list
                "(" @context
                ")" @context))
        (pointer_declarator
            "*" @context
            declarator: (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
        (pointer_declarator
            "*" @context
            declarator: (pointer_declarator
                "*" @context
                declarator: (function_declarator
                    declarator: (_) @name
                    parameters: (parameter_list
                        "(" @context
                        ")" @context))))
        (reference_declarator
            ["&" "&&"] @context
            (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
    ]
    (type_qualifier)? @context) @item

(declaration
    [
        (storage_class_specifier)
        (type_qualifier)
    ]* @context
    type: (_)? @context
    declarator: [
        (field_identifier) @name
        (pointer_declarator
            "*" @context
            declarator: (field_identifier) @name)
        (function_declarator
            declarator: (_) @name
            parameters: (parameter_list
                "(" @context
                ")" @context))
        (pointer_declarator
            "*" @context
            declarator: (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
        (pointer_declarator
            "*" @context
            declarator: (pointer_declarator
                "*" @context
                declarator: (function_declarator
                    declarator: (_) @name
                    parameters: (parameter_list
                        "(" @context
                        ")" @context))))
        (reference_declarator
            ["&" "&&"] @context
            (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
    ]
    (type_qualifier)? @context) @item

(field_declaration
    [
        (storage_class_specifier)
        (type_qualifier)
    ]* @context
    type: (_) @context
    declarator: [
        (field_identifier) @name
        (pointer_declarator
            "*" @context
            declarator: (field_identifier) @name)
        (function_declarator
            declarator: (_) @name
            parameters: (parameter_list
                "(" @context
                ")" @context))
        (pointer_declarator
            "*" @context
            declarator: (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
        (pointer_declarator
            "*" @context
            declarator: (pointer_declarator
                "*" @context
                declarator: (function_declarator
                    declarator: (_) @name
                    parameters: (parameter_list
                        "(" @context
                        ")" @context))))
        (reference_declarator
            ["&" "&&"] @context
            (function_declarator
                declarator: (_) @name
                parameters: (parameter_list
                    "(" @context
                    ")" @context)))
    ; Fields declarations may define multiple fields, and so @item is on the
    ; declarator so they each get distinct ranges.
    ] @item
    (type_qualifier)? @context)

(comment) @annotation
