Open bernhardmgruber opened 4 months ago
I have been thinking about get_body(info func) -> info
for a while now, and the implementation seems extremely difficult. If the function is only declared, we would have no answer (fine). If the function's body is available, an implementation would either need to retain the token streams of the body for all functions in case they are requested, or reparse the function body upon request. The latter is really expensive because it requires reparsing the entire translation unit to reconstruct the necessary state. But it's solvable. But bugs me recently, are important functions. What if I want to reflect on a function made available by importing a module? No source is available, maybe some form of AST or implementation-specific intermediate representation. We likely don't want to expose that and we probably cannot turn this representation back into a token stream portably.
Hi! @andralex asked me to review this paper, so here are some textual suggestions and the following feedback:
inject_function
prefix seems a rather arbitrary choice. I think this needs more explanation for this design choice.set_body(info func, info token_seq)
, and aget_body(info func) -> info
declare_function
is not a good name, because calling it does not declare a function in the program yet. This only happens later upon injection.declare_function
: are tokens sufficient? Don't we also need the scope where the function is declared in? Where do expressions naming variables and types for e.g. function default arguments or return type resolve to? I could imagine this being not easily implementable. Am I allowed to use::foo::bar::f
as function name in the token stream? We cannot delay these questions until injection time, since we may want to reflect these properties again before injection happens. Alternatively, we kill this function and carry around plain token stream, as done in P3294.set_qualified_name
move a function from one namespace to another? what happens if both namespaces have an equally named type that is used as return value of the function? Does it still refer to the old entities. What if I move the function from one class into another, where certain members are no longer accessible?friend
is classified with the access modifiers. I would separate friendship from access modifiers.set_attributes
. Adding and removing of attributes should be done on the vector returned fromattributes(info)
, so those APIs could be dropped.is_pure
andset_pure
to something likeis_pure_virtual
etc. to not grab the namepure
in case something like__attribute__((pure))
is ever standardizedset_deleted(info)
seems to miss a bool parameter and a string for the message.null_object<T>
: I would have expected the proposal to contain an implementation of said class to show that the proposed APIs are sufficient