robertoraggi / cplusplus

A compiler front end for the C++ language
https://robertoraggi.github.io/cplusplus/
MIT License
122 stars 12 forks source link

expected a declaration #306

Open mingodad opened 9 months ago

mingodad commented 9 months ago

While testing cxx with https://c9x.me/qscm/data/qscm.c I found that cxx get lost with this extracted test (heavy on macros):

typedef long V;

#define L(n) L_(n, E)
#define A a_(E)
#define B(x,y) (E=C(x,E), B_(y, &E))
#define F(n) C((V)f##n, E)
#define Z1(f) Zn(f, 0)
#define Z(f,a) Zn(f, C(a,0))
#define Z3(f,a,b) Zn(f, C(a,C(b,0)))
#define Z4(f,a,b,c) Zn(f, C(a,C(b,C(c,0))))
#define J return
#define D(x,y) V f##x(V E){J y;}

int putchar(int c) {return 0;}
int getchar() {return 0;}
V malloc(long) {return 0;}

V C(V a,V d){return 0;}
V a_(V x){J*(V*)x;}
V d_(V x){J*((V*)x+1);}
V B_(V x,V *e){*e=d_(*e);J x;}
V L_(V n,V e){while(--n)e=d_(e);J a_(e);}
V Zn(V x,V a){return 0;}

D(g,*(char *)A)
D(s,*(char *)L(2)=A)
D(n,(V)malloc(A))
D(c,C(L(2),A))
D(a,a_(A))
D(d,d_(A))
D(i,getchar())
D(o,putchar(A))
#define X(x) (V)&(V[2]){(V)f##x}

V qget=X(g);
g++ -fsyntax-only test-qscm-macro.cpp
//no errors
cxx test-qscm-macro.cpp
test-qscm-macro.cpp:33:24: expected a declaration
#define X(x) (V)&(V[2]){(V)f##x}
                       ^
test-qscm-macro.cpp:33:25: expected a declaration
#define X(x) (V)&(V[2]){(V)f##x}
                        ^
test-qscm-macro.cpp:33:27: expected a declaration
#define X(x) (V)&(V[2]){(V)f##x}
                          ^
test-qscm-macro.cpp:33:32: expected a declaration
#define X(x) (V)&(V[2]){(V)f##x}
                               ^
robertoraggi commented 9 months ago

I believe the snippet is using the C compound literals e.g. stuff like auto v = (int[2]){1,2}; or (struct point){10,20}. They are standard in C but not in C++. It is yet another gcc/clang extension, I will make sure to add support for it, thanks for the report.

mingodad commented 9 months ago

If you do so maybe also add the offsetof macro/builtin with it Lua can be parsed defining -DLUA_USE_JUMPTABLE=0 because although cxx somehow has defined macros that identify it as gcc compatible it doesn't accept it:

/*
** By default, use jump tables in the main interpreter loop on gcc
** and compatible compilers.
*/
#if !defined(LUA_USE_JUMPTABLE)
#if defined(__GNUC__)
#define LUA_USE_JUMPTABLE   1
#else
#define LUA_USE_JUMPTABLE   0
#endif
#endif
...
tatic const void *const disptab[NUM_OPCODES] = {
&&L_OP_MOVE,
&&L_OP_LOADI,
&&L_OP_LOADF,
...

sqlite3 has this:

#ifndef __builtin_offsetof
#define __builtin_offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD))
#endif