[cfe-dev] better way to test for explicit C++ constructor?

John McCall rjmccall at apple.com
Wed Dec 12 15:13:53 PST 2012


On Dec 12, 2012, at 3:07 PM, Peeter Joot <peeter.joot at gmail.com> wrote:
> I can get as far as finding the CXXConstructExpr like you mention (using code from Eli's reply) :
> 
>    bool VisitVarDecl( VarDecl * var )
>    {
>       Expr * Init = var->getInit() ;
>       bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal() ;
>       QualType type = var->getType();
>       ASTContext & Context = ci.getASTContext() ;
>       QualType baseType = Context.getBaseElementType( type ) ;
> 
>       if (!var->getDeclContext()->isDependentContext() && Init && !Init->isValueDependent())
>       {
>          if (IsGlobal && !var->isConstexpr() &&
>               !Init->isConstantInitializer(Context, baseType->isReferenceType()))
>          {
>             if ( const CXXConstructExpr * r = dyn_cast<CXXConstructExpr>( Init ) )
>             {
>                cout << "found global CXXConstructExpr" << endl ;
>             }
>          }
>       }
> 
>       return true ;
>    }
> 
> How do I walk over the initializers in that constructor?  I'd tried:
> 
>                for ( CXXConstructExpr::const_arg_iterator b = r->arg_begin(), e = r->arg_end() ;
>                      b != e ; ++b )
> 
> but this appears to be wrong, and results in an empty iteration.

Those are the arguments passed to the constructor.

1.  Look at the constructor: getConstructor().
2.  Check whether it's a implicitly-defined default constructor: isDefaultConstructor(), isImplicitlyDefined().  If not, you've found your problem right there.
3.  Iterate over the initializers: init_begin(), init_end().
4.  I believe the expression for each initializer should always be a CXXConstructExpr.  Recurse.

John.



More information about the cfe-dev mailing list