tree-sitter / tree-sitter-cpp

C++ grammar for tree-sitter
MIT License
262 stars 85 forks source link

bug: No highlight with `#define`d 'extern "C" {' #249

Closed h3xOo closed 5 months ago

h3xOo 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

I am using neovim with latest nvim-treesitter and updated parsers and clangd. I have bug with the following code

#ifdef __cplusplus
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS   }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif

__BEGIN_DECLS
typedef int foo;
__END_DECLS

Right now typedef int is white (as it has no highlight), but when I add semicolon before it, highlight appears again (like ; typedef int foo;).

Steps To Reproduce/Bad Parse Tree

Tree from neovim :InspectTree

(preproc_ifdef) ; [1:1 - 7:6]
 name: (identifier) ; [1:8 - 18]
 (preproc_def) ; [2:1 - 3:0]
  name: (identifier) ; [2:9 - 21]
  value: (preproc_arg) ; [2:23 - 34]
   (linkage_specification) ; [2:23 - 34]
    value: (string_literal) ; [2:30 - 32]
     (string_content) ; [2:31 - 31]
    body: (declaration_list) ; [2:34 - 34]
 (preproc_def) ; [3:1 - 4:0]
  name: (identifier) ; [3:9 - 19]
  value: (preproc_arg) ; [3:23 - 23]
   (ERROR) ; [3:23 - 23]
 alternative: (preproc_else) ; [4:1 - 7:0]
  (preproc_def) ; [5:1 - 6:0]
   name: (identifier) ; [5:9 - 21]
  (preproc_def) ; [6:1 - 7:0]
   name: (identifier) ; [6:9 - 19]
(declaration) ; [9:1 - 10:16]
 type: (type_identifier) ; [9:1 - 13]
 declarator: (identifier) ; [10:1 - 7]
 (ERROR) ; [10:9 - 15]
  (identifier) ; [10:9 - 11]
  (identifier) ; [10:13 - 15]
(type_identifier) ; [11:1 - 11]

Expected Behavior/Parse Tree

typedef int would be highlighted (colored). Here's tree with ;typedef int foo;

(preproc_ifdef) ; [1:1 - 7:6]
 name: (identifier) ; [1:8 - 18]
 (preproc_def) ; [2:1 - 3:0]
  name: (identifier) ; [2:9 - 21]
  value: (preproc_arg) ; [2:23 - 34]
   (linkage_specification) ; [2:23 - 34]
    value: (string_literal) ; [2:30 - 32]
     (string_content) ; [2:31 - 31]
    body: (declaration_list) ; [2:34 - 34]
 (preproc_def) ; [3:1 - 4:0]
  name: (identifier) ; [3:9 - 19]
  value: (preproc_arg) ; [3:23 - 23]
   (ERROR) ; [3:23 - 23]
 alternative: (preproc_else) ; [4:1 - 7:0]
  (preproc_def) ; [5:1 - 6:0]
   name: (identifier) ; [5:9 - 21]
  (preproc_def) ; [6:1 - 7:0]
   name: (identifier) ; [6:9 - 19]
(expression_statement) ; [9:1 - 10:1]
 (identifier) ; [9:1 - 13]
(type_definition) ; [10:2 - 17]
 type: (primitive_type) ; [10:10 - 12]
 declarator: (type_identifier) ; [10:14 - 16]
(type_identifier) ; [11:1 - 11]

Repro

#ifdef __cplusplus
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS   }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif

__BEGIN_DECLS
typedef int foo;
__END_DECLS
amaanq commented 5 months ago

yeah macros just cannot be parsed well since tree-sitter does not have semantic info about the code