Currently, Chapel support extern renaming for functions as shown:
extern "foo_in_c" proc foo_in_chapel(): c_int;
writeln(foo_in_chapel()); // will generate a call to foo_in_c
This is useful for cases when a C function name conflicts with reserved keywords in Chapel. However, this does not account for all cases, such as variables or struct fields.
Today, these other cases can be worked around by writing a C function to provide a getter/setter for the variable or field, but it is fairly cumbersome (especially in the fields case).
It would be nice to generalize extern, so that one can do something like this:
extern var "label" _label: c_int;
writeln(_label); // I can now use this variable in Chapel without keyword-conflicts.
Context: I encountered this when wrapping libsvm, which contains several keyword-conflicts as field names.
I have a feeling this would be really simple to do if you want a pointer.
I'll take it.
if you want a pointer.
I'll take it.
as in, I'll take that pointer!
Search compiler/parser/chapel.ypp for TEXTERN opt_ident_or_string. Such rules are ones that permit an optional identifier or string to follow an extern keyword. That identifier or string is then stored into the cname field of the Symbol class used to represent the symbol being declared (e.g., the external record name). cname is the C/codegen name for the symbol whereas name is its name in Chapel. So in extern "foo_in_c" proc foo_in_chapel(...) the FnSymbol (function symbol) representing this declaration would store "foo_in_chapel" in its name field and "foo_in_c" in its cname field.
Next search for the opt_config: rule (which supplies the extern keyword for variable declarations) and the use just above it of the TVAR token (corresponding to the var keyword). Your approach would be to add an opt_ident_or_string to the TEXTERN case, and propagate its string up to where the symbol is built in the TVAR case.
Something that's occurring to me belatedly that might've been clear to you: I was going to say that your string looks like it's in the wrong place to me in your example above -- after the var keyword rather than before it. But I'm also realizing that since the TVAR keyword permits multiple variables to be declared, that creates problems with our current placement of the extern name right after the extern keyword, suggesting maybe it should appear on a per-var basis. I think I'd actually take the approach of keeping the external name in the same place as in other extern declaration contexts for consistency (and because I think it "reads" more clearly) and disallow such statements to declare more than one variable.
There are other basics to working in the parser that you may need help with (e.g., what does $$ mean, what does $2 mean), but we can help you through those if it's not obvious (it's quick to learn).
@ben-albrecht : This is becoming a more important issue due to the Fortran interop work. so I've moved it into the backlog. I'm guessing you don't have a start on it, but wanted to check before someone else picks it up.
I'm guessing you don't have a start on it, but wanted to check before someone else picks it up.
I have not started this.
I've got a branch that implements this, but PR #11746 needs to be reviewed and merged first.
Thanks @bradcray !