Detect if a CXXConstructExpr is implicit

In the following code:

A(A const&a);

voidf(A a);

voidg() {
A a;
f(a); // 1
f(2); // 2

The generated AST contains nodes about object construction that are implicit (the copy constructor for 1, the conversion then the copy constructor for 2).

 >\-CallExpr <line:12:5, col:8> 'void'
 > >\-ImplicitCastExpr <col:5> 'void \(\*\)\(A\)' <FunctionToPointerDecay>
 > > \`\-DeclRefExpr <col:5> 'void \(A\)' lvalue Function 0x55c42589b208 'f' 'void \(A\)'
 > \`\-CXXConstructExpr <col:7> 'A' 'void \(const A &\)'
 >   \`\-ImplicitCastExpr <col:7> 'const A' lvalue <NoOp>
 >     \`\-DeclRefExpr <col:7> 'A' lvalue Var 0x55c42589b3c8 'a' 'A'
 \`\-ExprWithCleanups <line:13:5, col:8> 'void'
   \`\-CallExpr <col:5, col:8> 'void'
     >\-ImplicitCastExpr <col:5> 'void \(\*\)\(A\)' <FunctionToPointerDecay>
     > \`\-DeclRefExpr <col:5> 'void \(A\)' lvalue Function 0x55c42589b208 'f' 'void \(A\)'
     \`\-CXXConstructExpr <col:7> 'A' 'void \(const A &\)' elidable
       \`\-MaterializeTemporaryExpr <col:7> 'const A' lvalue
         \`\-ImplicitCastExpr <col:7> 'const A' <NoOp>
           \`\-ImplicitCastExpr <col:7> 'A' <ConstructorConversion>
             \`\-CXXConstructExpr <col:7> 'A' 'void \(int\)'
               \`\-IntegerLiteral <col:7> 'int' 2

Do you know if there is a way to detect that these constructions are implicit (as opposed to constructions written as the type name followed by initialization?)

Thank you!

If you look at the AST for the record decl, there is a bunch of flags in the DefinitionData of interest:

-CXXRecordDecl <line:1:1, line:6:1> line:1:7 referenced class A
>-DefinitionData empty standard_layout has_user_declared_ctor
> >-DefaultConstructor exists non_trivial user_provided
> >defaulted_is_constexpr -CopyConstructor non_trivial user_declared
> >has_const_param implicit_has_const_param -MoveConstructor
> >-CopyAssignment trivial has_const_param needs_implicit
> >implicit_has_const_param -MoveAssignment

See "user_provided" and "user_declared". I'm not sure what the difference between those two is however.

Unless I'm mistaken, those notions apply to CXXContructorDecl, not to CXXConstructExpr. A user declared copy constructor may or may not be called implicitely.

Ah, I see. I got lost in the pronoun game :slight_smile:

None that I'm aware of, and I don't see anything promising here:

Perhaps someone with more knowledge of this can elaborate better.

If it's useful, I have plans to upstream changes such that you can print and AST-match on code like this while eliding invisible AST nodes. See: