<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Mar 12, 2010, at 11:00 AM, Anders Carlsson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Mar 12, 2010, at 10:55 AM, John McCall wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br>On Feb 27, 2010, at 12:06 AM, Enea Zaffanella wrote:<br><blockquote type="cite"><font class="Apple-style-span" color="#144FAE"><br></font></blockquote><blockquote type="cite">But then I get to the following case<br></blockquote><blockquote type="cite">    S s3 = S(3);<br></blockquote><blockquote type="cite">for which I get the following AST:<br></blockquote><blockquote type="cite">=============<br></blockquote><blockquote type="cite">  (DeclStmt 0x1d5f430 <line:8:3, col:14><br></blockquote><blockquote type="cite">    0x1d5f1f0 "struct S s3 =<br></blockquote><blockquote type="cite">      (ImplicitCastExpr 0x1d5f3f0 <col:10, col:13> 'struct S' <br></blockquote><blockquote type="cite"><ConstructorConversion><br></blockquote><blockquote type="cite">        (CXXConstructExpr 0x1d5f380 <col:10, col:13> 'struct S''void <br></blockquote><blockquote type="cite">(struct S const &)' elidable<br></blockquote><blockquote type="cite">          (ImplicitCastExpr 0x1d5f340 <col:10, col:13> 'struct S const' <br></blockquote><blockquote type="cite"><NoOp><br></blockquote><blockquote type="cite">            (CXXFunctionalCastExpr 0x1d5f300 <col:10, col:13> 'struct <br></blockquote><blockquote type="cite">S' functional cast to struct S<br></blockquote><blockquote type="cite">              (CXXConstructExpr 0x1d5f290 <col:10, col:12> 'struct <br></blockquote><blockquote type="cite">S''void (int)'<br></blockquote><blockquote type="cite">                (IntegerLiteral 0x1d5f250 <col:12> 'int' 3))))))"<br></blockquote><blockquote type="cite">=============<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Here there are two things that I do not understand.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">First, I cannot see why the result of the inner CXXConstructorExpr call <br></blockquote><blockquote type="cite">should be fed to a CXXFunctionalCastExpr. I may agree that the <br></blockquote><blockquote type="cite">initializer of s3 is a functional cast expression ... but then I would <br></blockquote><blockquote type="cite">expect that the argument of this functional cast is the integer literal, <br></blockquote><blockquote type="cite">not the struct S object returned by the constructor.<br></blockquote><blockquote type="cite">In other words, to my eyes, the presence of the functional cast should <br></blockquote><blockquote type="cite">exclude the presence of the inner constructor call, or vice versa.<br></blockquote><blockquote type="cite">Is my reasoning missing some important point?<br></blockquote><br>This is a strange representation, and it looks even stranger when the functional cast is actually invoking a user-defined conversion.  CodeGen aggressively elides the constructor calls (in most cases; I don't enough about that corner of the standard to know if it's missing legal elisions), so it's just an internal-representation issue rather than also being a performance issue.  Still, it's not a good representation, and if the elision optimization is disabled (which is a supported configuration, I think) it might mean we make too many copies.<br><br></div></blockquote><div><br></div>Actually, it's not that strange :)</div><div><br></div><div>The CXXFunctionalCastExpr is just the syntactical representation, and the inner CXXConstructExpr has all the constructor information - which constructor to call, default arguments etc.</div></div></blockquote></div><div><br></div>Okay, so you're saying that a CXXFunctionalCastExpr always contains a CastExpr as its immediate sub-expressions, and that that CastExpr is what actually conveys the semantics of the cast?  I'm not thrilled with that, but it's probably better than duplicating the cast logic N times over.<div><br></div><div>That said, can you similarly justify this representation for conversion operators?  It looks like we get an extra, unelidable CXXConstructExpr.<br><div><br></div><div><div>struct S { S(unsigned); S(const S &value); };</div><div>struct T { operator S() const; };</div><div>void test() {</div><div>  T t;</div><div>  S x = S(t);</div><div>}</div><div><br></div><div><div>void test() (CompoundStmt 0x103618f20 </tmp/red.cpp:10:13, line:13:1></div><div>  (DeclStmt 0x103618b60 <line:11:3, col:6></div><div>    0x103618b10 "T t"</div><div>  (DeclStmt 0x103617d10 <line:12:3, col:13></div><div>    0x103617080 "S x =</div><div>      (ImplicitCastExpr 0x103618ef0 <col:9, col:12> 'struct S' <ConstructorConversion></div><div>        (CXXConstructExpr 0x103618ea0 <col:9, col:12> 'struct S''void (struct S const &)' elidable</div><div>          (ImplicitCastExpr 0x103618e70 <col:9, col:12> 'struct S const' <NoOp></div><div>            (CXXFunctionalCastExpr 0x103618e30 <col:9, col:12> 'struct S' functional cast to struct S</div><div>              (CXXConstructExpr 0x103618de0 <col:9, col:11> 'struct S''void (struct S const &)'</div><div>                (ImplicitCastExpr 0x103618db0 <col:11> 'struct S const' <NoOp></div><div>                  (ImplicitCastExpr 0x103618d80 <col:11> 'struct S' <UserDefinedConversion></div><div>                    (CXXMemberCallExpr 0x103618d40 <col:11> 'struct S'</div><div>                      (MemberExpr 0x103618d00 <col:11, <invalid sloc>> 'struct S (void) const' .operator S 0x103618590</div><div>                        (ImplicitCastExpr 0x103618cd0 <col:11> 'struct T const' <NoOp> lvalue</div><div>                          (DeclRefExpr 0x103618be0 <col:11> 'struct T' Var='t' 0x103618b10)))))))))))")</div><div><br></div><div>John.</div></div></div></div></body></html>