Currently, there are separate codepaths for constant and non-constant
expressions. This is not a good thing: it means a lot of code
duplication. My idea is that with a bit of tweaking,
ScalarExprEmitter can be made usable for constant expressions as well
as non-constant expressions.
ScalarExprEmitter normally works with Value*'s. However, it does most
of its actual work through an LLVMFoldingBuilder. Because of this,
expressions that are constant can be sent through ScalarExprEmitter,
then cast to a Constant* at the end; any constant expression should
end up as a Constant*. In this way, the existing code for expression
generation can be used with little modification.
The primary issue with this approach is that a lot of the existing
code in ScalarExprEmitter depends on having a CodeGenFunction;
however, the functions that would be useful for constant expressions
don't have any fundamental dependencies on CodeGenFunction, although
many have dependencies nonetheless.
Attached is a patch to clean out most of the unnecessary uses of CGF
from ScalarExprEmitter, which is the first step to implementing this
approach. This patch shouldn't cause any behavior changes; it's just
shifting code around to do things directly instead of calling through
The next step is to add a boolean member ExprIsConst, and when it is
true, block off all the remaining uses of CGF with assertions (for
cases that shouldn't be reachable in constant expressions) and
warnings (for cases that should work, but need to be refactored).
After that, CGF can be changed to a possibly-null pointer, and with
that, ScalarExprEmitter can be used for constant expression
generation. That said, it will need some fixes to avoid regressions;
ScalarExprEmitter has some bugs that don't exist in ConstExprEmitter.
Note that it's intentional that there's both a boolean and a
possibly-null pointer; in some cases, a constant expression inside of
a function is allowed to refer to the address of a static local
variable, and that address isn't accessible without a CGF.
cgexprclean.txt (14.7 KB)