<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">> How do I walk over the initializers in that constructor?  I'd tried:<br>
</div></blockquote><div>[snip] </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im"></div>
1.  Look at the constructor: getConstructor().<br>2.  Check whether it's a implicitly-defined default constructor: isDefaultConstructor(), isImplicitlyDefined().  If not, you've found your problem right there.<br>
3.  Iterate over the initializers: init_begin(), init_end().<br>4.  I believe the expression for each initializer should always be a CXXConstructExpr.  Recurse.<br></blockquote></div><br clear="all"><div>With the tips supplied, I was able to cobble together the global detection and the initializer iteration portions of above.  Each initializer turns out to be a CXXCtorInitializer, but the CXXConstructExpr can be found from that:<div>
<br></div></div><div><div>   void recurseOverConstructorDecls( CXXConstructorDecl * c, string subobject )</div><div>   {</div><div>      for ( CXXConstructorDecl::init_iterator b = c->init_begin(), e = c->init_end() ;</div>
<div>            b != e ; ++b )</div><div>      {</div><div>         CXXCtorInitializer *    i        = *b ;</div><div>         FieldDecl *             f        = i->getMember() ;</div><div>         Expr *                  Init     = i->getInit() ;</div>
<div>         string                  subfield = subMemberString( subobject, f->getName().str() ) ;</div><div><br></div><div>         if ( const CXXConstructExpr * r = dyn_cast<CXXConstructExpr>( Init ) )</div><div>
         {</div><div>            CXXConstructorDecl * cInner = r->getConstructor() ;</div><div><br></div><div>            if ( !cInner->isImplicitlyDefined() )</div><div>            {</div><div>               cout << "!implicit: " << subfield << endl ;</div>
<div>            }</div><div><br></div><div>            recurseOverConstructorDecls( cInner, subfield ) ;</div><div>         }</div><div>      }</div><div>   }</div><div><br></div><div>   bool VisitVarDecl( VarDecl * var )</div>
<div>   {</div><div>      // modified from Eli's email "Here's the code used to implement -Wglobal-constructor:"</div><div>      Expr *         Init     = var->getInit() ;</div><div>      bool           IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal() ;</div>
<div>      QualType       type     = var->getType();</div><div>      QualType       baseType = context.getBaseElementType( type ) ;</div><div><br></div><div>      if ( !var->getDeclContext()->isDependentContext() && Init && !Init->isValueDependent() )</div>
<div>      {</div><div>         if ( IsGlobal && !var->isConstexpr() &&</div><div>              !Init->isConstantInitializer( context, baseType->isReferenceType() ) )</div><div>         {</div><div>
            if ( const CXXConstructExpr * r = dyn_cast<CXXConstructExpr>( Init ) )</div><div>            {</div><div>               CXXConstructorDecl * c = r->getConstructor() ;</div><div><br></div><div>               recurseOverConstructorDecls( c, var->getName().str() ) ;</div>
<div>            }</div><div>         }</div><div>      }</div><div><br></div><div>      return true ;</div><div>   }</div></div><div><br></div><div>However, on the following sample: </div><div><br></div><div><div>    struct withConstructor</div>
<div>    {</div><div>       int x ;</div><div><br></div><div>       withConstructor() : x(3) {}</div><div>    } ;</div><div><br></div><div>    struct noConstructor</div><div>    {</div><div>       int x ;</div><div>    } ;</div>
<div><br></div><div>    struct krcb</div><div>    {</div><div>       noConstructor     noCons ;</div><div>       withConstructor   withCons;</div><div>    } ;</div><div><br></div><div>    krcb k ;</div></div><div><br></div>
<div><div><div>I get:</div></div><div><br></div><div><div><div>    !implicit: k.noCons</div><div>    !implicit: k.withCons</div></div></div><div><br></div><div>despite the fact that the type noConstructor is POD.  It appears that checking for the non trivial constructor isn't really what the isImplicitlyDefined() function does. Calling isDefaultConstructor() doesn't help since my explicit constructor is also a default constructor, but is also non-trivial.  How can I additionally narrow this down?</div>
<div><br></div><div>Alternately, if there was a way to lookup the CXXRecordDecl that's associated with the FieldDecl, then the functions like hasUserDeclaredConstructor() could be called.  However, I'm not sure how to find this RecordDecl from any of the types available from the init expression.</div>
<div class="gmail_extra"><br>-- <br>Peeter<br>
</div></div>