Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide support for C functional macros #3

Open
Slabity opened this issue Nov 9, 2016 · 25 comments
Open

Provide support for C functional macros #3

Slabity opened this issue Nov 9, 2016 · 25 comments

Comments

@Slabity
Copy link

Slabity commented Nov 9, 2016

Currently, cexpr cannot produce values that use functional macros to calculate. It would be very useful if cexpr supported them.

@jethrogb
Copy link
Owner

jethrogb commented Nov 9, 2016

cexpr support is almost trivial, assuming these functional macros evaluate into proper expressions. If this is useful I can implement it. Note however that you must indicate to cexpr whether you'd be parsing a functional macro or a regular macro, because there is no way to distinguish between the two at the token level.

@Slabity
Copy link
Author

Slabity commented Nov 9, 2016

there is no way to distinguish between the two at the token level.

How so?

@jethrogb
Copy link
Owner

jethrogb commented Nov 9, 2016

Both of

m(a) -1
m (a) -1

are

[
  Identifier("m"),
  Punctuation("("),
  Identifier("a"),
  Punctuation(")"),
  Punctuation("-"),
  Literal("1")
]

@Slabity
Copy link
Author

Slabity commented Nov 9, 2016

Could there be a Whitespace token to differentiate the two?

@jethrogb
Copy link
Owner

jethrogb commented Nov 9, 2016

Possibly. But you need a lexer that generates those tokens. Clang does not.

@emilio
Copy link
Collaborator

emilio commented Jun 16, 2017

Hi, @jethrogb, would it be fine to give you a boolean that tells whether the current macro definition is function-like?

Clang has an API for that (clang_Cursor_isMacroFunctionLike), and it'd solve some bindgen issues like rust-lang/rust-bindgen#753

@jethrogb
Copy link
Owner

jethrogb commented Jun 16, 2017

Yes that would work. cexpr just needs to know whether it's parsing a functional or regular macro. I can probably look at this on Sunday.

Note: clang_Cursor_isMacroFunctionLike was introduced relatively recently and is e.g. not available on Ubuntu 16.04.

Also notably, clang_Cursor_Evaluate was introduced in the same commit, but I think it's not as powerful as cexpr.

@emilio
Copy link
Collaborator

emilio commented Jun 16, 2017

Right both are libclang 3.9+. But nicely enough bindgen loads libclang at runtime so can detect which functions are available, so it'd be nice to start using them when available.

@nicokoch
Copy link

Any update on this? :)

@jethrogb
Copy link
Owner

It was too hot to do any work ;) Next weekend... Or feel free to pick it up yourself before then.

@Slabity
Copy link
Author

Slabity commented Jul 8, 2017

@jethrogb Any update?

@jethrogb
Copy link
Owner

jethrogb commented Jul 9, 2017

Was going to do this this morning, but got distracted by 0ea1367 and 4fdd26b

@jethrogb
Copy link
Owner

jethrogb commented Jul 11, 2017

Parsing functional macro declarations is now supported in fe05507.

I suppose you'd also like to evaluate them if they're used as part of a another macro definition? Because of token-pasting, stringizing and non-reentrant evaluation, that's not super easy. Reference: https://www.mirbsd.org/htman/i386/manINFO/cppinternals.html
http://port70.net/~nsz/c/c89/c89-draft.html#3.8.3
https://superb-dca2.dl.sourceforge.net/project/mcpp/mcpp/V.2.7.2/mcpp-summary-272.pdf
http://c0x.coding-guidelines.com/6.10.3.pdf
http://c0x.coding-guidelines.com/6.10.3.1.pdf

@emilio
Copy link
Collaborator

emilio commented Jul 12, 2017

Awesome!

Yeah, I think having support to resolve a macro inside other macro is what can make it useful for Bindgen... Otherwise there isn't much utility on it... I think the most usual request is for simple macros that resolve to numeric types, for which there shouldn't be any token-pasting issue I guess? Something like:

#define MY_FLAG(i) (1 << (i))

#define MY_VAR_1 MY_FLAG(1)
#define MY_VAR_2 MY_FLAG(2)
#define MY_VAR_3 MY_FLAG(3)

Supporting that would be quite nice IMO.

@jethrogb
Copy link
Owner

jethrogb commented Jul 16, 2017

I've investigated this further and I think best results would be obtained with a mostly-implemented mostly-compliant C preprocessor. The preprocessor is completely separate from the expression evaluation implemented by this crate. The preprocessor would basically take a macro replacement list and fully expand the list of tokens which could then be evaluated by cexpr. There are a couple of options:

  1. Figure out how to leverage Clang's preprocessor. I looked into this but the C API doesn't seem to have anything. There's clang_Cursor_Evaluate which could do both jobs but it has some limitations, for example it doesn't distinguish chars from ints. The C++ API might be useful according to this StackOverflow post but that's an unstable API with no dynamic libraries.
  2. Incorporate a stand-alone preprocessor such as mcpp.
  3. Write one in Rust.

@jethrogb
Copy link
Owner

No. We already do that.

@photoszzt
Copy link

Directly calling clang -E isn't an option?

@Slabity
Copy link
Author

Slabity commented Feb 28, 2018

Any progress on this? It's still impossible to use the _IO family of macros.

I use to be able to hack around this by rebinding them as constants, but this no longer works for some reason.

@Slabity
Copy link
Author

Slabity commented Mar 7, 2018

Pinging @jethrogb - Anything I can do to help fix this?

@jethrogb
Copy link
Owner

jethrogb commented Mar 7, 2018

@Slabity Yes, the next steps are described in #3 (comment)

@gnzlbg
Copy link

gnzlbg commented Dec 10, 2018

So an mpi-sys crate needs to expose constants that are implemented slightly differently by the different MPI implementations, for example, see MPI_REQUEST_NULL in:

 #define MPI_REQUEST_NULL   ((MPI_Request)0x2c000000)
#define MPI_REQUEST_NULL OMPI_PREDEFINED_GLOBAL(MPI_Request, ompi_request_null)

it would be great if rust-bindgen could import these as consts, instead of as static mut.

@pvdrz
Copy link

pvdrz commented Feb 23, 2023

I've investigated this further and I think best results would be obtained with a mostly-implemented mostly-compliant C preprocessor. The preprocessor is completely separate from the expression evaluation implemented by this crate. The preprocessor would basically take a macro replacement list and fully expand the list of tokens which could then be evaluated by cexpr. There are a couple of options:

1. Figure out how to leverage Clang's preprocessor. I looked into this but the C API doesn't seem to have anything. There's clang_Cursor_Evaluate which could do both jobs but it has some limitations, for example it doesn't distinguish `char`s from `int`s. The C++ API might be useful according to [this StackOverflow post](https://stackoverflow.com/questions/39529480/is-there-a-way-to-get-source-code-with-macro-expanded-using-clang-api) but that's an unstable API with no dynamic libraries.

2. Incorporate a stand-alone preprocessor such as [mcpp](http://mcpp.sourceforge.net/).

3. Write one in Rust.

👋 I'm writing a C preprocessor from scratch and I'd like to know what kind of API do you have in mind for the expansion. Would you pass the preprocessing directive defining the macro and the tokens where the macro is supposed to be expanded?

@photoszzt
Copy link

Before writing a new one, what's missing from the mcpp? Is it just hard to use in Rust?

@pvdrz
Copy link

pvdrz commented Feb 24, 2023

Well you'd have to write rust bindings for mcpp by hand (or using bindgen but we would have to see if bindgen can generate valid rust bindings for all the items). At the same time the project seems to be unmaintained, the last release was in 2008 and the last update to their sourceforge was 2013. It could be fine as they are C99 compliant but who knows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants