Comments (11)
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.
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.
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. Example:
#if _WIN32
#include <windows.h>
void foo(DWORD param); // DWORD is declared in windows.h
#endif
Running the above translation on any other platform than windows will fail to compile if the branch is analyzed.
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?
from dstep.
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.
The first thing seems possible, the second not so much.
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.
Good point. Hmm, I believe we could go quite far by explicitly handling such cases (e.g. using knowledge of what windows.h
is).
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?
Yes, 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.
It 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).
After some thinking I believe at first I'll try to solve the problem without complicating that thin wrapper.
from dstep.
It 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).
This should be avoided.
After some thinking I believe at first I'll try to solve the problem without complicating that thin wrapper.
Sounds like a good idea.
from dstep.
This should be avoided.
I suppose it will be hard to avoid. The only API that libclang provides is clang_getSkippedRanges, but it isn't enough : (. Ideally I would like to have a cursor (or equivalent) for every preprocessor directive...
from dstep.
Why do you think intermixing Cursors from different TUs would be a bad idea?
from dstep.
I suppose it will be hard to avoid. The only API that libclang provides is clang_getSkippedRanges, but it isn't enough : (. Ideally I would like to have a cursor (or equivalent) for every preprocessor directive...
I'm not sure if you would like to go the route but there's always the possibility to contribute to libclang by extending the API if we need to.
I found this [1] which looks interesting. Unfortunately it looks like it never got any attention.
[1] http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20120326/055612.html
from dstep.
Why do you think intermixing Cursors from different TUs would be a bad idea?
An example:
Let a
be from main translation unit and represents a struct A;
and then let b
be from another translation unit (e.g. ifdef-block, the same file) and represents another struct A;
. Then I want to check if the struct they refer too is the same
Cursor a = ...;
Cursor b = ...;
if (a.canonical == b.canonical) // clang_getCanonicalType
{
...
}
I suppose it won't work as libclang doesn't see a connection between the cursors. There are plenty of similar problems.
from dstep.
Hmm, I see the problem.
from dstep.
I'm not sure if you would like to go the route but there's always the possibility to contribute to libclang by extending the API if we need to.
I considered it, but the road to contribute something to llvm is quite steep (not so easy as making fork and pull req on github : ( ).
I found this [1] which looks interesting. Unfortunately it looks like it never got any attention.
I've already implemented it in the most recent PR (by parsing tokenized directive...).
The libclang has quite good API to access #defines
. The real problem are conditional directives.
from dstep.
I considered it, but the road to contribute something to llvm is quite steep (not so easy as making fork and pull req on github)
They're considering moving the project to git 😃. But yeah, that's a good point. Perhaps there's a good reason why they don't provide access to that.
If one would have access to both branches of a preprocessor if statement would might also get errors like duplicated symbols.
from dstep.
They're considering moving the project to git 😃.
Nice to hear that.
If one would have access to both branches of a preprocessor if statement would might also get errors like duplicated symbols.
Right.
from dstep.
Related Issues (20)
- Pointer arithmetic and parentheses elision
- Dstep + bindbc HOT 1
- `--normalize-modules` insert underscore in the module decl but not in the filename
- typedef function prototypes don't retain arguments HOT 5
- dub run failure - ld cannot find @linker_flags.txt HOT 4
- doc error:
- Missing import HOT 2
- Unhandled type kind objCTypeParam HOT 2
- const T arr[] gets converted to imcompatible const(T) *arr instead of a warning HOT 2
- Improper output when importing core.stdc.limits HOT 1
- Rename enum members can create invalid enum names HOT 1
- API macro erased but should be extern(System) HOT 2
- /usr/include/cuda_runtime_api.h ==> d: Error: undefined identifier `cudaError_t` HOT 6
- Assertion Failure when defining a cast from int to function pointer
- Unhandled type kind objCObject when trying to bind Foundation.framework on macOS
- enh? add enum alias (as dpp do) HOT 1
- unknown type name 'size_t' HOT 1
- `--alias-enum-members=true` shouldn't affect global anonymous enums
- Unnecessary leading dot in alias
- Add support for adding public imports
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dstep.