Novice attempting to implement is_constant_evaluation trait

Hi clang experts,

I submitted a constexpr-related paper to the C++ standards committee about
6 months ago. To summarize the paper, I want to find a way to:

a. Allow constexpr code to have two implementations: one for constant
evaluation, and one for runtime evaluation.

b. I also wish for a way for a programmer to insist that a particular
constexpr function may only be used for constant evaluation. If the
constexpr function were to generate runtime code I want to be able
to generate a compile- or link-time error.

The full version of the paper can be found here:

Reception from the committee was somewhat chilly. But they said that if I
were to pursue the project, I should try Approach C: a trait.

Richard Smith kindly offered some additional advice about such a trait.
Here’s my interpretation of Richard’s suggestion:

o Create a nullary trait named

constexpr bool std::is_constant_evaluation().

It is not a template and it accepts no arguments.

o The return value of this trait depends on the context in which it
is called. If it is called in a situation that requires compile-time
evaluation of a value, then it returns true. One such situation
occurs when a variable that is declared constexpr is evaluated. Another
such situation is when an Integer Constant Expression (ICE) is required.
Yet another such situation is when a static_assert is evaluated. There
may be other similar situations as well.

o Under all other situations, the trait returns false.

Such a trait could be used with a conditional in a constexpr function to
select between a compile-time or a run-time implementation.

I’m attempting to implement such a trait in clang. I want an implementation
for two reasons:

a. I want to make sure that the trait will meet my requirements.

b. If I submit a follow-on paper to the C++ standard committee, I would
like that paper to be based on experience with an implementation.

I am not a compiler person, but I’m game to try hacking clang. I’ve
made an initial attempt at an implementation. I feel like my initial
attempt, adding a new unary trait to clang (and always passing void), is not
going well. I’ve created a new unary trait that always returns false with
surprisingly little damage to the clang code base. But I haven’t yet figured
out how to examine the context so I know when to return true. It also
appears that clang caches the trait result. So, even if I solved the context
problem, once the trait is evaluated it would always return the same value,
regardless of each new context.

So I’m asking for guidance.

Suggestions? Thanks in advance.

Scott Schurr