{"action":"created","issue":{"url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/65","repository_url":"https://api.github.com/repos/jacob-carlborg/dstep","labels_url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/65/labels{/name}","comments_url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/65/comments","events_url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/65/events","html_url":"https://github.com/jacob-carlborg/dstep/issues/65","id":157986371,"number":65,"title":"Handling advanced pre-processor macros.","user":{"login":"ciechowoj","id":7858228,"avatar_url":"https://avatars.githubusercontent.com/u/7858228?v=3","gravatar_id":"","url":"https://api.github.com/users/ciechowoj","html_url":"https://github.com/ciechowoj","followers_url":"https://api.github.com/users/ciechowoj/followers","following_url":"https://api.github.com/users/ciechowoj/following{/other_user}","gists_url":"https://api.github.com/users/ciechowoj/gists{/gist_id}","starred_url":"https://api.github.com/users/ciechowoj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ciechowoj/subscriptions","organizations_url":"https://api.github.com/users/ciechowoj/orgs","repos_url":"https://api.github.com/users/ciechowoj/repos","events_url":"https://api.github.com/users/ciechowoj/events{/privacy}","received_events_url":"https://api.github.com/users/ciechowoj/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-06-01T19:21:50Z","updated_at":"2016-06-08T17:22:13Z","closed_at":null,"body":"I'm wondering how to handle 'advanced' pre-processor stuff. I have two problems. The first problem is libclang only parses an active branch of pre-processor condition. E.g. \r\n\r\n```C\r\n#define FOO\r\n\r\n#ifdef FOO\r\n// This will appear in AST.\r\n#else\r\n// This won't appear in AST.\r\n#endif\r\n```\r\n\r\nI suppose it isn't possible to implement translation of pre-processor that handles all possible cases, but most common cases should be doable. The only idea I have is to load the content of file we are translating and parse macros manually (possibly using clang to parse the code *inside* ifdefs) to some AST form, suitable for further processing. This should be perfectly doable. The next problem is a design/implementation one.\r\n\r\nCurrently there is a thin wrapper around c libclang API. I think it would be nice if pre-processor information (that we extract from file) are available through the same API. What I propose is to extend the classes (structs) like `Cursor`, `SourceLocation`, `Token` etc. in a way that they can contain data created by the user of the thin wrapper (currently an instances of that structs can only be created by libclang). Then, one could iterate through AST containing all the information in a transparent way, without worrying if the data comes from libclang or from the pre-processor parser. For example I would like `Cursor` to have a constructor that allows to create an instance of it from user-supplied data. E.g.\r\n\r\n```D\r\nstruct Cursor\r\n{\r\n    this(string spelling, CXCursorKind kind, SourceRange, ...);\r\n\r\n    /+ ... +/\r\n}\r\n```\r\nAn alternative would be to add separate API and then interleave them in actual translator code, however it seems to be messy.\r\n\r\nWhat do you think about it?"},"comment":{"url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/comments/224664799","html_url":"https://github.com/jacob-carlborg/dstep/issues/65#issuecomment-224664799","issue_url":"https://api.github.com/repos/jacob-carlborg/dstep/issues/65","id":224664799,"user":{"login":"ciechowoj","id":7858228,"avatar_url":"https://avatars.githubusercontent.com/u/7858228?v=3","gravatar_id":"","url":"https://api.github.com/users/ciechowoj","html_url":"https://github.com/ciechowoj","followers_url":"https://api.github.com/users/ciechowoj/followers","following_url":"https://api.github.com/users/ciechowoj/following{/other_user}","gists_url":"https://api.github.com/users/ciechowoj/gists{/gist_id}","starred_url":"https://api.github.com/users/ciechowoj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ciechowoj/subscriptions","organizations_url":"https://api.github.com/users/ciechowoj/orgs","repos_url":"https://api.github.com/users/ciechowoj/repos","events_url":"https://api.github.com/users/ciechowoj/events{/privacy}","received_events_url":"https://api.github.com/users/ciechowoj/received_events","type":"User","site_admin":false},"created_at":"2016-06-08T17:22:13Z","updated_at":"2016-06-08T17:22:13Z","body":"> I would hope it's possible to using libclang to lex the file to get the tokens of the branch that is not compiled. Then run the tokens through libclang again to do the full parsing and analyze.\r\n\r\nThe first thing seems possible, the second not so much.\r\n\r\n> There's a problem regardless which method is used. You might get compile errors if you're trying to analyze the branch that is normally not analyzed.\r\n\r\nGood point. Hmm, I believe we could go quite far by explicitly handling such cases (e.g. using knowledge of what `windows.h` is).\r\n\r\n> As far as the design. At some point you need to run libclang on the source code/tokens and the wrapper types can be created like today. Or am I missing something?\r\n\r\nYes, this would be the case, if `libclang` is capable of it. But, the problem is that to parse that `#ifdef`-blocks, even in isolation, one would need to create a new `TranslationUnit` and currently `Cursor`s and other stuff are bound to particular translation unit and intermixing `Cursor`s from different TUs would be a bad idea, so wrapper types cannot be used in current shape.\r\n\r\nIt is still a problem if I wanted to parse those blocks by some other way (writing own parser to handle most common cases, I don't know currently).\r\n\r\nAfter some thinking I believe at first I'll try to solve the problem without complicating that thin wrapper. \r\n"}}
{"actor":{"display_login":"ciechowoj"}}