GabrielDosReis/ipr

Should ipr::New distinguish between braced-init vs paren-init initializer (and more)?

Closed this issue · 2 comments

Currently ipr::New is defined as:

   // This node represents a new-expression:
   //    ::_opt new new-placement_opt new-type-id new-initializer_opt
   //    ::_opt new new-placement_opt ( type-id ) new-initializer_opt
   struct New : Category<new_cat, Classic> { 
      virtual Optional<Expr_list> placement() const = 0;
      virtual const Type& allocated_type() const = 0;
      virtual Optional<Expr_list> initializer() const = 0;
   };

Thus both: new T{1,2,3} and new T(1,2,3) will have the same ipr representation

The same issue is present with ordinary declaration of variables or data members.

We chatted about various flavors of initializers.

// A x = y;       // copy-init from whater 
// A x = {xxxx }; // copy-list-init
// A x(1,2,3);    // direct-init via parens
// A x{1,2,3};    // direct-init via braces

Tentatively we would like to have two new ipr nodes (better names TBD)

    struct Copy_init : Unary<Category<copy_init_cat, Classic>, const Expr&>
    {
      Location location();
      const Expr& expr() { return operand(); }
    }

    struct DelimitedPair 
    {
       enum class Kind { Braced, Parens };

       Location_span span;
       Kind kind;     
    };

    struct Delimited_expr_list : Binary<Category<delimited_expr_list_cat>, Classic>, 
        const Expr_list&, 
        const DelimitedPair>

    // initializer = Delimited_expr_list (1,2,3) {1,2,3}
    // copy-init " = expr";

Note that these new nodes are classic expression and implementation would refer to a chosen constructor.

Other comments:

We might no longer need Initializer_list (Delimited_expr_list can subsume its name)
The only use of Expr_list in the IPR that is not a parenthesized list is in

       struct Ctor_body : Binary<Category<ctor_body_cat, Stmt>,
                             const Expr_list&, const Block&> {

Datum second operand should be Delimited_expr_list, not Expr_list

       struct Datum : Binary<Category<datum_cat, Classic>,
                          const Type&, 
                          const <del>Expr_list</del><ins>Delimited_expr_list&</ins> > {

Same for the operator new:

      struct New : Category<new_cat, Classic> { 
         virtual Optional<Expr_list> placement() const = 0;
         virtual const Type& allocated_type() const = 0;
         virtual Optional<<del>Expr_list</del><ins>Delimited_expr_list&</ins> > initializer() const = 0;
      };