<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=text/html;charset=iso-8859-1 http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.7601.17785"></HEAD>
<BODY style="PADDING-LEFT: 10px; PADDING-RIGHT: 10px; PADDING-TOP: 15px" 
id=MailContainerBody leftMargin=0 topMargin=0 CanvasTabStop="true" 
name="Compose message area">
<DIV><FONT size=2 face=Consolas>On Friday, May 18, 2012 9:13 PM, Richard Smith 
wrote:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> OK. The first thing you need to be aware of 
is that 'folded<BR>> to a constant' is not the same as 'evaluated as a 
constant<BR>> expression'. The former case just means "take an 
expression,<BR>> and use any tricks we know to reduce it to a 
compile-time<BR>> constant". The latter means following the relevant 
language<BR>> standards, which is a nebulous affair [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Firstly, thank you for such a detailed 
reply.  I have read it through now several times to be sure I understand 
everything!</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>From what you say, just to be sure I do 
understand, the range of expressions that can be "folded" is a super-set of 
those "evaluated to a constant expression" in C++11 terms, which is 
in turn a super-set of those which are "integer constant expressions" 
of C++98 / C.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>So, what I am looking for is the first thing, 
i.e. to use "any tricks we know" to reduce an expression to a compile-time 
constant, which should mean, as an example, any calls to functions should be 
eliminated.  If they cannot be, then by extension the expression cannot be 
folded, and the compiler should at this point stop with an error message to that 
effect.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>As I mentioned in my post to Jonathan Sauer (<A 
title="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html STRG + Klicken, um Verknüpfung zu folgen" 
href="http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html">http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-May/021554.html</A>), 
one such use case for this is to limit the possibility of using what may be 
necessarily-inefficient compile-time algorithms accidentally in a run-time 
environment.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> Additionally, the set of things we can fold 
is slightly<BR>> different in the different languages. Anyway, the point 
is,<BR>> outside of C++11, we don't really have an implemented,<BR>> 
checkable notion of 'constant expression' other than<BR>> 'integer constant 
expression'.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Doesn't Expr::EvaluateAsRValue(...) fill 
this criteria?</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> For what it's worth, if you want something 
which folds<BR>> expressions, I think you can already build that 
[...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Unfortunately, I couldn't get your suggestion to 
work in my tests.  Here's some sample code:</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>struct assert_foldable_t { int arr[1]; 
};<BR>#define fold(X) (__builtin_constant_p(1)?(X):(X))<BR>#define ignore(X) 
((int)!(X))<BR>#define assert_foldable(X) ((void)(struct 
assert_foldable_t){.arr[ignore(fold(X))]=1})<BR>#define builtin_fold(X) 
(assert_foldable(X),fold(X))</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>constexpr double X() {<BR>    
return 5.0;<BR>}</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>int main() {<BR>    double i = 
builtin_fold(12.0 / X());<BR>    printf("%f\n", 
i);<BR>    return 0;<BR>}</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>It does at least stop compilation if the 
expression is not foldable, but it doesn't produce code as though I had written 
"double i = 2.4" which is what my aim is (I checked the output using -S 
-emit-llvm).</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>I also liked your solution using lambdas (I'd 
actually considered a similar solution before), although as you say, it won't 
work outside a C++11 environment.  Also, you can't use it to assign to a 
constexpr variable so it can't be used as a generic solution, although this 
is in this case a minor thing.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> If you want to add a new builtin for this, 
you should<BR>> search through the codebase to find the places where<BR>> 
builtins are currently handled, and add the relevant<BR>> support for your 
builtin there. [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Thank you for the pointers; I will have a nose 
around and see what I can do!  The way I have been approaching it so far is 
to use Parser::ParseAssignmentExpression then Expr::EvaluateAsRValue which 
returns an APValue which is the constant I'm looking for.  If any of these 
steps fail, I can generate some diagnostics and stop.  Next, my 
understanding and maybe you can confirm whether I'm right, is that I need 
to then turn my APValue into an Expr object.  There doesn't seem to be 
a direct function available for doing this, but I could use IntegerLiteral 
or FloatingLiteral for these types, and extract Expr directly from APValue if it 
is an LValue type.  Other APValue types may be more 
difficult, but its a starting point.  Is this the best route to take, do 
you think?</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>> However, I think a better feature (and one 
which I would<BR>> definitely support pushing into trunk clang) would be 
an<BR>> attribute which can be applied to declarations (maybe<BR>> 
[[clang::const_init]]) [...]</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>I agree that I can certainly see an advantage to 
this feature.  I'll have a look into this too.</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Thanks again,</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV><FONT size=2 face=Consolas>Andy</FONT></DIV>
<DIV><FONT size=2 face=Consolas></FONT> </DIV>
<DIV> </DIV></BODY></HTML>