Generated AST for implicit CXXConstructorDecl

Hello all,

I’m using libTooling to generate the AST of a given program (that will later be translated to our own internal AST), and I just found this odd CXXConstructorDecl for the following program:

class X

{

public:

X() {};

char str[20][20][230];

};

int main(void)

{

X x;

X x1 = x;

return 0;

}

The implicit constructor for X is:

CXXConstructorDecl 0x3959fd0 line:3:7 col:7 implicit used X ‘void (const class X &) throw()’ inline

-ParmVarDecl 0x395a110 col:7 col:7 used ‘const class X &’
-CXXCtorInitializer Field 0x3908c48 ‘str’ ‘char [20][20][230]’
-ImplicitCastExpr 0x395a6e8 <col:7> 'char' <LValueToRValue> -ArraySubscriptExpr 0x395a6c0 col:7 ‘const char’ lvalue

-ImplicitCastExpr 0x395a6a8 col:7 ‘const char *’
`-ArraySubscriptExpr 0x395a560 col:7 ‘char const[230]’ lvalue

-ImplicitCastExpr 0x395a548 col:7 ‘char const (*)[230]’
`-ArraySubscriptExpr 0x395a400 col:7 ‘char const[20][230]’ lvalue

-ImplicitCastExpr 0x395a3e8 col:7 ‘char const (*)[20][230]’
-MemberExpr 0x395a298 <col:7> 'char const[20][20][230]' lvalue .str 0x3908c48 -DeclRefExpr 0x395a270 col:7 ‘const class X’ lvalue ParmVar 0x395a110 ‘’ ‘const class X &’
-ImplicitCastExpr 0x395a368 <col:7> 'unsigned int' <LValueToRValue> -DeclRefExpr 0x395a340 col:7 ‘unsigned int’ lvalue Var 0x395a2e0 ‘__i0’ ‘unsigned int’
-ImplicitCastExpr 0x395a4c0 <col:7> 'unsigned int' <LValueToRValue> -DeclRefExpr 0x395a498 col:7 ‘unsigned int’ lvalue Var 0x395a438 ‘__i1’ ‘unsigned int’
-ImplicitCastExpr 0x395a620 <col:7> 'unsigned int' <LValueToRValue> -DeclRefExpr 0x395a5f8 col:7 ‘unsigned int’ lvalue Var 0x395a598 ‘__i2’ ‘unsigned int’
`-CompoundStmt 0x395a748 col:7

Which should look this (I think):

X(const X& ref) : str(ref.str[__i0][__i1][__i2]) {}

Or maybe:

X(const X& ref) { str(ref.str[__i0][__i1][__i2]); }

(None of the above is compiled)
(If we call emit-llvm, it’s translated into a memcpy)

Anyway, there are a few things missing on this AST, in my opinion:

  1. No VarDecl for __i0, __i1, __i2.
  2. No loop to iterate and copy the array elements (a call to memcpy would be good as well, but I don’t expect that clang will generate that).

Does anyone knows if I can generate the AST with the varDecls and the loop? I found a method on SemaDeclCXX that seems to build a loop, it’s called buildSingleCopyAssignRecursively. It’s called by buildSingleCopyAssign, that even tries to build a memcpy.

Am I out of luck and will have to go through all the implicit generated CXXConstructorDecls and build a loop myself or is there an alternative?

Thank you,

I almost forgot:

I know that we can get the VarDecl from the DeclRef (by using getDecl() or getFoundDecl()). What I meant by “if I can generate the AST with the varDecls” was actually an AST with the explicit VarDecls of __i0, __i1, etc.

Thank you,

I almost forgot:

I know that we can get the VarDecl from the DeclRef (by using getDecl() or
getFoundDecl()). What I meant by "if I can generate the AST with the
varDecls" was actually an AST with the explicit VarDecls of __i0, __i1,
etc.

The VarDecls are in the AST, you can access them by calling
getArrayIndices() on the CXXCtorInitializer.