Repository navigation
[PARSE BUG]: various type aliases (C array, struct, function) #83
Copy link
Copy link
Open
Description
Problem description
It seems that the new style of alias declarations are not completely implemented.
The equivalent typedefs are working as expected.
I provide below a short program which works under compiler explorer, but is not parsed correctly (I took the declaration part into the demo)
#include <iostream>
using namespace std;
// --------------- begin to be placed into the parser demo
using aType = int[4];
using fType = void(int);
using lType = struct {int x;int y;int z;int t;};
using sType = struct l{int x;int y;int z;int t;};
using vType = union {int x;int y;int z;int t;};
using uType = union v{int x;int y;int z;int t;};
using arefType = int(&)[4];
using frefType = int(&)(int);
using lrefType = struct {int x;int y;int z;int t;}&;
using srefType = struct l/*{int x;int y;int z;int t;}*/&;
using vrefType = union {int x;int y;int z;int t;}&;
using urefType = union v/*{int x;int y;int z;int t;}*/&;
using aptrType = int(*)[4];
using fptrType = int(*)(int);
using lptrType = struct {int x;int y;int z;int t;}*;
using sptrType = struct l/*{int x;int y;int z;int t;}*/*;
using vptrType = union {int x;int y;int z;int t;}*;
using uptrType = union v/*{int x;int y;int z;int t;}*/*;
typedef int(aType1)[4];
typedef void(fType1)(int);
typedef struct {int x;int y;int z;int t;} lType1;
typedef struct l/*{int x;int y;int z;int t;}*/ sType1;
typedef union {int x;int y;int z;int t;} vType1;
typedef union v/*{int x;int y;int z;int t;}*/ uType1;
typedef int(&arefType1)[4];
typedef int(&frefType1)(int);
typedef struct {int x;int y;int z;int t;}& lrefType1;
typedef struct l/*{int x;int y;int z;int t;}*/& srefType1;
typedef union {int x;int y;int z;int t;}& vrefType1;
typedef union v/*{int x;int y;int z;int t;}*/& urefType1;
typedef int(*aptrType1)[4];
typedef int(*fptrType1)(int);
typedef struct {int x;int y;int z;int t;}* lptrType1;
typedef struct l/*{int x;int y;int z;int t;}*/* sptrType1;
typedef union {int x;int y;int z;int t;}* vptrType1;
typedef union v/*{int x;int y;int z;int t;}*/* uptrType1;
// --------------- end to be placed into the parser demo
int f(int x)
{
return x;
}
int main(int argc, char* argv[])
{
aType x{0,1,2,3};
cout << x[1] << endl;
static_assert(is_same<aType, aType1>::value, "wrong");
static_assert(is_same<decltype(x[1]), int&>::value, "wrong");
arefType x2 = x;
cout << x2[2] << endl;
static_assert(is_same<arefType, arefType1>::value, "wrong");
static_assert(is_same<decltype(x2[2]), int&>::value, "wrong");
aptrType x3 = &x;
cout << (*x3)[3] << endl;
static_assert(is_same<aptrType, aptrType1>::value, "wrong");
static_assert(is_same<decltype((*x3)[3]), int&>::value, "wrong");
static_assert(is_same<arefType, aType&>::value, "wrong");
static_assert(is_same<aptrType, aType*>::value, "wrong");
//---------------------------------
cout << f(1) << endl;
static_assert(is_same<fType, fType1>::value, "wrong");
static_assert(is_same<decltype(f(1)), int>::value, "wrong");
frefType ff2 = f;
cout << ff2(2) << endl;
static_assert(is_same<frefType, frefType1>::value, "wrong");
static_assert(is_same<decltype(ff2(2)), int>::value, "wrong");
fptrType ff3 = f;
cout << ff3(3) << endl;
static_assert(is_same<fptrType, fptrType1>::value, "wrong");
static_assert(is_same<decltype(ff3(3)), int>::value, "wrong");
static_assert(is_same<frefType, decltype(f)&>::value, "wrong");
static_assert(is_same<fptrType, decltype(f)*>::value, "wrong");
//---------------------------------
sType s{0,1,2,3};
cout << s.y << endl;
static_assert(is_same<sType, sType1>::value, "wrong");
static_assert(is_same<decltype(s.y), int>::value, "wrong");
srefType s2 = s;
cout << s2.z << endl;
static_assert(is_same<srefType, srefType1>::value, "wrong");
static_assert(is_same<decltype(s2.z), int>::value, "wrong");
sptrType s3 = &s;
cout << s3->t << endl;
static_assert(is_same<sptrType, sptrType1>::value, "wrong");
static_assert(is_same<decltype(s3->t), int>::value, "wrong");
static_assert(is_same<srefType, sType&>::value, "wrong");
static_assert(is_same<sptrType, sType*>::value, "wrong");
//anon structs are different types
static_assert(!is_same<lrefType, lType&>::value, "wrong");
static_assert(!is_same<lptrType, lType*>::value, "wrong");
//---------------------------------
uType u; u.y=1;
cout << u.y << endl;
static_assert(is_same<sType, sType1>::value, "wrong");
static_assert(is_same<decltype(s.y), int>::value, "wrong");
urefType u2 = u; u.z=2;
cout << u2.z << endl;
static_assert(is_same<urefType, urefType1>::value, "wrong");
static_assert(is_same<decltype(u2.z), int>::value, "wrong");
uptrType u3 = &u; u.t=3;
cout << u3->t << endl;
static_assert(is_same<uptrType, uptrType1>::value, "wrong");
static_assert(is_same<decltype(u3->t), int>::value, "wrong");
static_assert(is_same<urefType, uType&>::value, "wrong");
static_assert(is_same<uptrType, uType*>::value, "wrong");
//anon unions are different types
static_assert(!is_same<vrefType, vType&>::value, "wrong");
static_assert(!is_same<vptrType, vType*>::value, "wrong");
return 0;
}
C++ code that can't be parsed correctly (please double-check that https://robotpy.github.io/cxxheaderparser/ has the same error)
//these all fail to be parsed, the typedef equivalents are correctly parsed.
using aType = int[4];
using fType = void(int);
using lType = struct {int x;int y;int z;int t;};
using sType = struct l{int x;int y;int z;int t;};
using vType = union {int x;int y;int z;int t;};
using uType = union v{int x;int y;int z;int t;};
using lrefType = struct {int x;int y;int z;int t;}&;
using vrefType = union {int x;int y;int z;int t;}&;
using lptrType = struct {int x;int y;int z;int t;}*;
using vptrType = union {int x;int y;int z;int t;}*;
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
virtuald commentedon Nov 15, 2023
How are you intending to use the parsed data? If you just need it to parse then this should be straightforward to do, but I note that the way I implemented typedefs is a bit annoying to actually use the data.
scherno2000 commentedon Nov 16, 2023
I would use them to generate some kind of documentation. (I would generate a json file, and then I would use the json in my program as the source).
It would be OK for me analogous to the way the typedefs are implemented as it contains all of the necessary data.
Basically what I need is equivalent to be possible to reconstruct the original alias declaration considering also the enclosing context (namespace scope, class scope), based on the the parsed data (I would use the generated json for this purpose).
virtuald commentedon Nov 20, 2023
I looked at this briefly the other night and it's slightly more involved than I thought it would be, and my time is a bit limited at the moment.