[cfe-dev] C++ constructors/destructors/temporaries AST changes

Anders Carlsson andersca at mac.com
Fri May 29 14:37:37 PDT 2009


Hi,

currently we have a CXXConstructExpr node that represents a call to a  
constructor, and mapping the result to a variable. This can be a  
temporary variable.

For example, assuming we have a class type 'T':

class T { T(); };

then

T t;

is represented as

(VarDecl 'x' Type=T,
    Init = CXXConstruct("x", "T::T()")

and

T();

is represented (more or less) as

(CXXConstruct("temp", "T::T()");

where temp is a CXXTempVarDecl.

However, this means that there is no way to bind an already existing  
variable to a temporary (and have its destructor be called at the  
right time, consider)

T f();

{ f(); }

where we want to bind the return value of f to a temporary so that it  
will be destroyed at the right time.

To solve this, I propose that we split up the CXXConstructExpr node in  
two, one that actually calls the constructor, and one that binds it to  
a temporary. I currently call this node CXXBindTemporaryExpr.

With this new node

T t;

would be represented in the same way as before (with the exception  
that CXXConstruct doesn't know about "x". So

(VarDecl 'x' Type=T,
    Init = CXXConstruct("T::T()")

and

T();

would be represented as

(CXXBindTemporary "sometemp" (CXXConstruct("T::T()")))

and finally,

f();

would be represented as

(CXXBindTemporaryExpr "sometemp" (Call("f"));

Another example that's possible/easier now is

return T();

which would be represented as

(ReturnStmt (CXXConstruct("T::T()")).

I also noticed when working on this that CXXTempVarDecl is way  
overkill for just representing a temporary in the AST - In fact, we  
don't need it to be a VarDecl or a Decl at all! All we need to know is  
which destructor to call, so a CXXTemporary could just be something like

/// CXXTemporary - Represents a C++ temporary.
class CXXTemporary {
   CXXDestructorDecl *Destructor;

   CXXTemporary(CXXDestructorDecl *destructor)
     : Destructor(destructor) { }

public:
   static CXXTemporary *Create(ASTContext &C, CXXDestructorDecl  
*Destructor);
};

(and CXXExprWithTemporaries would store an array of CXXTemporary  
pointers, instead of an array of CXXTempVarDecl pointers).

I have a patch that implements this, and I think it's a step forward  
in terms of expressiveness in the AST, but I'd love to hear what other  
people think about it.

Anders




More information about the cfe-dev mailing list