tree-sitter / tree-sitter-c

C grammar for tree-sitter
MIT License
225 stars 100 forks source link

bug: Microsoft calling convention grammar incorrect #192

Closed cdacamar closed 6 months ago

cdacamar commented 6 months ago

Did you check existing issues?

Tree-Sitter CLI Version, if relevant (output of tree-sitter --version)

No response

Describe the bug

The Microsoft calling convention is grammatically attached to the declarator, not to the function definition before any decl-specifiers as observed in the grammar:

https://github.com/tree-sitter/tree-sitter-c/blob/df6ac34d5eb1dccfac8f2a9011a8491300818d7c/grammar.js#L230-L235

Steps To Reproduce/Bad Parse Tree

  1. tree-sitter playground with C code below
  2. Output:
[translation_unit](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [7, 0]
  [function_definition](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [0, 22]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [0, 0] - [0, 4]
    [ERROR](https://tree-sitter.github.io/tree-sitter/playground#) [0, 5] - [0, 14]
      [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 5] - [0, 14]
    declarator: [function_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [0, 15] - [0, 18]
      declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [0, 15] - [0, 16]
      parameters: [parameter_list](https://tree-sitter.github.io/tree-sitter/playground#) [0, 16] - [0, 18]
    body: [compound_statement](https://tree-sitter.github.io/tree-sitter/playground#) [0, 19] - [0, 22]
  [function_definition](https://tree-sitter.github.io/tree-sitter/playground#) [1, 0] - [1, 24]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [1, 0] - [1, 4]
    declarator: [function_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [1, 5] - [1, 20]
      declarator: [parenthesized_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [1, 5] - [1, 18]
        [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 6] - [1, 15]
        [ERROR](https://tree-sitter.github.io/tree-sitter/playground#) [1, 16] - [1, 17]
          [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [1, 16] - [1, 17]
      parameters: [parameter_list](https://tree-sitter.github.io/tree-sitter/playground#) [1, 18] - [1, 20]
    body: [compound_statement](https://tree-sitter.github.io/tree-sitter/playground#) [1, 21] - [1, 24]
  [declaration](https://tree-sitter.github.io/tree-sitter/playground#) [3, 0] - [3, 14]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [3, 0] - [3, 4]
    declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [3, 5] - [3, 14]
    [MISSING ;](https://tree-sitter.github.io/tree-sitter/playground#) [3, 14] - [3, 14]
  [expression_statement](https://tree-sitter.github.io/tree-sitter/playground#) [3, 15] - [3, 19]
    [call_expression](https://tree-sitter.github.io/tree-sitter/playground#) [3, 15] - [3, 18]
      function: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [3, 15] - [3, 16]
      arguments: [argument_list](https://tree-sitter.github.io/tree-sitter/playground#) [3, 16] - [3, 18]
  [declaration](https://tree-sitter.github.io/tree-sitter/playground#) [4, 0] - [4, 21]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [4, 0] - [4, 4]
    declarator: [parenthesized_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [4, 5] - [4, 20]
      [ERROR](https://tree-sitter.github.io/tree-sitter/playground#) [4, 6] - [4, 15]
        [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [4, 6] - [4, 15]
      [function_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [4, 16] - [4, 19]
        declarator: [identifier](https://tree-sitter.github.io/tree-sitter/playground#) [4, 16] - [4, 17]
        parameters: [parameter_list](https://tree-sitter.github.io/tree-sitter/playground#) [4, 17] - [4, 19]
  [type_definition](https://tree-sitter.github.io/tree-sitter/playground#) [6, 0] - [6, 30]
    type: [primitive_type](https://tree-sitter.github.io/tree-sitter/playground#) [6, 8] - [6, 12]
    declarator: [function_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [6, 12] - [6, 29]
      declarator: [parenthesized_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [6, 12] - [6, 27]
        [ERROR](https://tree-sitter.github.io/tree-sitter/playground#) [6, 13] - [6, 22]
          [type_identifier](https://tree-sitter.github.io/tree-sitter/playground#) [6, 13] - [6, 22]
        [pointer_declarator](https://tree-sitter.github.io/tree-sitter/playground#) [6, 23] - [6, 26]
          declarator: [type_identifier](https://tree-sitter.github.io/tree-sitter/playground#) [6, 24] - [6, 26]
      parameters: [parameter_list](https://tree-sitter.github.io/tree-sitter/playground#) [6, 27] - [6, 29]

Expected Behavior/Parse Tree

On each declarator, the ms_call_modifier is attached.

Repro

void __stdcall f() { }
void (__stdcall g)() { }

void __stdcall h();
void (__stdcall j());

typedef void(__stdcall *fp)();