MaskRay / ccls

C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting
Apache License 2.0
3.73k stars 254 forks source link

__COUNTER__ macro not handled properly across #include boundaries #885

Open JoshMcguigan opened 2 years ago

JoshMcguigan commented 2 years ago

Observed behavior

Describe what happened. Any aids you can include (that you think could be relevant) are a tremendous help.

// foo.h

#define CONCAT_IMPL(x, y) x##y
#define MACRO_CONCAT(x, y) CONCAT_IMPL(x, y)

#define FOO typedef int MACRO_CONCAT(foo_, __COUNTER__)

FOO; // defines foo_0
FOO; // defines foo_1
// 01-01.c

#include "foo.h"

FOO; // should define foo 2
FOO; // should define foo 3

foo_0 a;
foo_1 b;
foo_2 c;
foo_3 d;

int main() {
    return 0;
}

error

ccls reports unknown type name foo_2 and unknown type name foo_3.

Expected behavior

No errors should be reported. ccls should recognize types foo_2 and foo_3, by processing the __COUNTER__ macro in the same way as clang:

$ clang 01-01.c -E 
# 1 "01-01.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 348 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "01-01.c" 2
# 1 "./foo.h" 1

typedef int foo_0;
typedef int foo_1;
# 2 "01-01.c" 2

typedef int foo_2;
typedef int foo_3;

foo_0 a;
foo_1 b;
foo_2 c;
foo_3 d;

int main() {
 return 0;
}

Steps to reproduce

  1. Copy the c and h file above into a directory and start ccls
  2. Select foo_2 to see the diagnostic

System information