{"action":"created","issue":{"url":"https://api.github.com/repos/facebook/CParser/issues/1","labels_url":"https://api.github.com/repos/facebook/CParser/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/facebook/CParser/issues/1/comments","events_url":"https://api.github.com/repos/facebook/CParser/issues/1/events","html_url":"https://github.com/facebook/CParser/issues/1","id":109242365,"number":1,"title":"Tagless enum redeclared","user":{"login":"millerlogic","id":6836420,"avatar_url":"https://avatars.githubusercontent.com/u/6836420?v=3","gravatar_id":"","url":"https://api.github.com/users/millerlogic","html_url":"https://github.com/millerlogic","followers_url":"https://api.github.com/users/millerlogic/followers","following_url":"https://api.github.com/users/millerlogic/following{/other_user}","gists_url":"https://api.github.com/users/millerlogic/gists{/gist_id}","starred_url":"https://api.github.com/users/millerlogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/millerlogic/subscriptions","organizations_url":"https://api.github.com/users/millerlogic/orgs","repos_url":"https://api.github.com/users/millerlogic/repos","events_url":"https://api.github.com/users/millerlogic/events{/privacy}","received_events_url":"https://api.github.com/users/millerlogic/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"leonbottou","id":612213,"avatar_url":"https://avatars.githubusercontent.com/u/612213?v=3","gravatar_id":"","url":"https://api.github.com/users/leonbottou","html_url":"https://github.com/leonbottou","followers_url":"https://api.github.com/users/leonbottou/followers","following_url":"https://api.github.com/users/leonbottou/following{/other_user}","gists_url":"https://api.github.com/users/leonbottou/gists{/gist_id}","starred_url":"https://api.github.com/users/leonbottou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leonbottou/subscriptions","organizations_url":"https://api.github.com/users/leonbottou/orgs","repos_url":"https://api.github.com/users/leonbottou/repos","events_url":"https://api.github.com/users/leonbottou/events{/privacy}","received_events_url":"https://api.github.com/users/leonbottou/received_events","type":"User","site_admin":false},"milestone":null,"comments":2,"created_at":"2015-10-01T07:08:15Z","updated_at":"2015-10-01T11:30:59Z","closed_at":null,"body":"I'm using CParser to do some source code transformations. I ran into an issue with code like the following:\r\n```c\r\ntypedef enum { A, B } One, Two;\r\n```\r\n\r\nWhat happens is that because the enum has no tag name, One and Two get fully redeclared like the following:\r\n```c\r\ntypedef enum{A,B}One;\r\ntypedef enum{A,B}Two;\r\n```\r\nso the names A and B have a collision and it breaks the source.\r\n\r\nI worked around this in parseEnum by generating a dummy tag name when a name isn't present, but I suspect there may be a better solution. The same issue may happen with struct and union, but the fix might not be that simple when considering anonymous structs."},"comment":{"url":"https://api.github.com/repos/facebook/CParser/issues/comments/144702203","html_url":"https://github.com/facebook/CParser/issues/1#issuecomment-144702203","issue_url":"https://api.github.com/repos/facebook/CParser/issues/1","id":144702203,"user":{"login":"leonbottou","id":612213,"avatar_url":"https://avatars.githubusercontent.com/u/612213?v=3","gravatar_id":"","url":"https://api.github.com/users/leonbottou","html_url":"https://github.com/leonbottou","followers_url":"https://api.github.com/users/leonbottou/followers","following_url":"https://api.github.com/users/leonbottou/following{/other_user}","gists_url":"https://api.github.com/users/leonbottou/gists{/gist_id}","starred_url":"https://api.github.com/users/leonbottou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leonbottou/subscriptions","organizations_url":"https://api.github.com/users/leonbottou/orgs","repos_url":"https://api.github.com/users/leonbottou/repos","events_url":"https://api.github.com/users/leonbottou/events{/privacy}","received_events_url":"https://api.github.com/users/leonbottou/received_events","type":"User","site_admin":false},"created_at":"2015-10-01T11:30:59Z","updated_at":"2015-10-01T11:30:59Z","body":"Correction. Only the second excerpt (two typedefs) gives you a name collision in cparser (as well as in gcc and clang).  On the other hand, A single typedef with two names gives:\r\n```\r\n+--------------------------\r\n| Definition{init={..},sclass=\"[enum]\",where=\"tst.c:2\",type=Qualified{_enum={..},const=true,t=Type{n=\"int\"}},name=\"A\",intval=1}\r\n| [enum] const int A = 1\r\n+--------------------------\r\n| Definition{init={..},sclass=\"[enum]\",where=\"tst.c:2\",type=Qualified{_enum={..},const=true,t=Type{n=\"int\"}},name=\"B\",intval=2}\r\n| [enum] const int B = 2\r\n+--------------------------\r\n| TypeDef{sclass=\"typedef\",where=\"tst.c:2\",type=Enum{Pair{\"A\"},Pair{\"B\"}},name=\"One\"}\r\n| typedef enum{A,B}One\r\n+--------------------------\r\n| TypeDef{sclass=\"typedef\",where=\"tst.c:2\",type=Enum{Pair{\"A\"},Pair{\"B\"}},name=\"Two\"}\r\n| typedef enum{A,B}Two\r\n+--------------------------\r\n```\r\nwhich is correct in terms of parsing.\r\n\r\nI guess that what happens is that you generate code based on this information and repeat the enum declaration, which causes a name collision when you run the c compiler on the generated code.  One way to deal with this would be remark that the two <type=> in the tagged tables refer to the same type. So if you set a field name <tag=xxxx> in the first enum when you see it, the tag will also appear in the second enum, and you'll know it is the same.\r\n\r\nOn the one hand, the lcdecl output is correct because this is what the parsed code says (One and Two are defined to be the same anonymous enum type, not defined to be a same tagged enum type). On the other hand, I can see that this forces some clumsiness when generating code.   \r\n\r\nMaybe an option to invent tags for all anonymous types would help?\r\n"}}