[cfe-dev] Doubts about constructor calls (and functional casts).

John McCall rjmccall at apple.com
Fri Mar 12 11:13:17 PST 2010


On Mar 12, 2010, at 11:00 AM, Anders Carlsson wrote:

> 
> On Mar 12, 2010, at 10:55 AM, John McCall wrote:
> 
>> 
>> On Feb 27, 2010, at 12:06 AM, Enea Zaffanella wrote:
>>> 
>>> But then I get to the following case
>>>    S s3 = S(3);
>>> for which I get the following AST:
>>> =============
>>>  (DeclStmt 0x1d5f430 <line:8:3, col:14>
>>>    0x1d5f1f0 "struct S s3 =
>>>      (ImplicitCastExpr 0x1d5f3f0 <col:10, col:13> 'struct S' 
>>> <ConstructorConversion>
>>>        (CXXConstructExpr 0x1d5f380 <col:10, col:13> 'struct S''void 
>>> (struct S const &)' elidable
>>>          (ImplicitCastExpr 0x1d5f340 <col:10, col:13> 'struct S const' 
>>> <NoOp>
>>>            (CXXFunctionalCastExpr 0x1d5f300 <col:10, col:13> 'struct 
>>> S' functional cast to struct S
>>>              (CXXConstructExpr 0x1d5f290 <col:10, col:12> 'struct 
>>> S''void (int)'
>>>                (IntegerLiteral 0x1d5f250 <col:12> 'int' 3))))))"
>>> =============
>>> 
>>> Here there are two things that I do not understand.
>>> 
>>> First, I cannot see why the result of the inner CXXConstructorExpr call 
>>> should be fed to a CXXFunctionalCastExpr. I may agree that the 
>>> initializer of s3 is a functional cast expression ... but then I would 
>>> expect that the argument of this functional cast is the integer literal, 
>>> not the struct S object returned by the constructor.
>>> In other words, to my eyes, the presence of the functional cast should 
>>> exclude the presence of the inner constructor call, or vice versa.
>>> Is my reasoning missing some important point?
>> 
>> 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.
>> 
> 
> Actually, it's not that strange :)
> 
> The CXXFunctionalCastExpr is just the syntactical representation, and the inner CXXConstructExpr has all the constructor information - which constructor to call, default arguments etc.


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.

That said, can you similarly justify this representation for conversion operators?  It looks like we get an extra, unelidable CXXConstructExpr.

struct S { S(unsigned); S(const S &value); };
struct T { operator S() const; };
void test() {
  T t;
  S x = S(t);
}

void test() (CompoundStmt 0x103618f20 </tmp/red.cpp:10:13, line:13:1>
  (DeclStmt 0x103618b60 <line:11:3, col:6>
    0x103618b10 "T t"
  (DeclStmt 0x103617d10 <line:12:3, col:13>
    0x103617080 "S x =
      (ImplicitCastExpr 0x103618ef0 <col:9, col:12> 'struct S' <ConstructorConversion>
        (CXXConstructExpr 0x103618ea0 <col:9, col:12> 'struct S''void (struct S const &)' elidable
          (ImplicitCastExpr 0x103618e70 <col:9, col:12> 'struct S const' <NoOp>
            (CXXFunctionalCastExpr 0x103618e30 <col:9, col:12> 'struct S' functional cast to struct S
              (CXXConstructExpr 0x103618de0 <col:9, col:11> 'struct S''void (struct S const &)'
                (ImplicitCastExpr 0x103618db0 <col:11> 'struct S const' <NoOp>
                  (ImplicitCastExpr 0x103618d80 <col:11> 'struct S' <UserDefinedConversion>
                    (CXXMemberCallExpr 0x103618d40 <col:11> 'struct S'
                      (MemberExpr 0x103618d00 <col:11, <invalid sloc>> 'struct S (void) const' .operator S 0x103618590
                        (ImplicitCastExpr 0x103618cd0 <col:11> 'struct T const' <NoOp> lvalue
                          (DeclRefExpr 0x103618be0 <col:11> 'struct T' Var='t' 0x103618b10)))))))))))")

John.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100312/24105cbc/attachment.html>


More information about the cfe-dev mailing list