Tips on implementing n3972 (std::source_context)?

I'm interested in implementing n3972[1] (std::source_context), but before I start delving too deep into it, I wanted to see if others had thought any about it. I do have some experience hacking on clang, but only in the parser (and it was years ago, anyway).

The paper suggests implementing std::source_context as a pointer to some implementation-defined static object to make copying faster. Since it's a literal type, I assume this means the static objects will have to be generated during compilation, but that's a part of clang I haven't look at at all.

There's also the question of getting the SourceLocation of the invocation, but that seems more tractable for me. Still, if anyone has ideas about how to implement this, I'd be happy to hear them.

- Jim

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3972.pdf

I'm interested in implementing n3972[1] (std::source_context), but before
I start delving too deep into it, I wanted to see if others had thought any
about it. I do have some experience hacking on clang, but only in the
parser (and it was years ago, anyway).

The paper suggests implementing std::source_context as a pointer to some
implementation-defined static object to make copying faster. Since it's a
literal type, I assume this means the static objects will have to be
generated during compilation, but that's a part of clang I haven't look at
at all.

If we ignore the 'static objects' part for a moment, here's one way to
approach this:

Add a new Expr kind representing the construction of a source_context
object.
Create one of these Exprs whenever you default-initialize an object of type
std::source_context.
In IR generation, this Expr would fill in the fields of the class with the
relevant [1] source location information.
In the constant expression evaluator, this Expr would likewise fill in the
fields of the evaluated object.

Another approach would be to add a builtin function for each piece of
information you want to determine, and implement the source_context
constructor as

  source_context(const char *file = __builtin_file(), unsigned int line =
__builtin_line(), /*...*/);

... which would make the constant expression evaluation easier, and give
you IR generation for free (because IR generation evaluates builtins as
constants whenever possible). It'd also remove the need to hardcode a
source_context representation. But the calling function name is a bit
difficult to model this way, and it doesn't extend nicely to a static
context object, so the first approach is probably better.

If you want a static object for each source_context object, emitting such a
global constant from IR generation shouldn't be hard. Constant expression
evaluation would be a bit trickier; you would need to invent a way of
representing the static object as an APValue. Usually we use the Expr* as
the handle to the complete object in similar cases (for instance, this is
how we represent the result of typeid), but you can't do that here, because
the expression means different things depending on the default arguments
you followed to reach it, so you may need to add a new flavour of APValue.

There's also the question of getting the SourceLocation of the invocation,

but that seems more tractable for me.

This would require tracking the location of the outermost CXXDefaultArgExpr
you're evaluating / emitting code for, but that seems relatively
straightforward.