rsmith added a comment.

Thanks, I like this a lot.

There are a few more changes we'll need in addition to this before we can 
properly serialize `APValue`s referring to such temporaries:

1. Merging during deserialization. For example, if we have

  inline int &&r = 123;

in two different modules, we should merge the two 
`LifetimeExtendedTemporaryDecl`s for the `123`. This will require making the 
decl derive from `Mergeable<...>` and adding a little logic to ASTReader to 
look up lifetime-extended declarations by their extending decl and mangling 
number.

2. Change the constant expression representation for a pointer or reference for 
a materialized temporary to refer to the temporary declaration instead.

3. Change CodeGen / name mangling to operate on the new declaration node rather 
than `MaterializedTemporaryExpr`. (This will be needed once `CodeGen` starts 
seeing constant `APValue`s referring to the new declaration nodes.)

I'm happy for the above to be done in a follow-up; as is, this change is a good 
refactoring and a basis for the above extensions.



================
Comment at: clang/include/clang/AST/DeclCXX.h:3057
+/// MaterializeTemporaryExpr
+class MaterializeTemporaryDecl final : public Decl {
+  friend class MaterializeTemporaryExpr;
----------------
Since we should only use this for lifetime-extended temporaries, not for any 
materialized temporary, how about renaming to `LifetimeExtendedTemporaryDecl`?


================
Comment at: clang/include/clang/AST/DeclCXX.h:3071
+
+  mutable APValue* Value = nullptr;
+
----------------
Clang coding convention puts the `*` on the right (please fix throughout the 
patch).


================
Comment at: clang/include/clang/AST/DeclCXX.h:3101-3106
+  Stmt* getStmtWithTemporary() {
+    return StmtWithTemporary;
+  }
+  const Stmt* getStmtWithTemporary() const {
+    return StmtWithTemporary;
+  }
----------------
We should expose this as an `Expr*` rather than a `Stmt*`, since it must always 
be an expression. Also maybe `getSubExpr()` or `getTemporaryExpr()` would be a 
better name?

Please include a comment here saying that this isn't necessarily the 
initializer of the temporary due to the C++98 delayed materialization rules, 
but that `skipRValueSubobjectAdjustments` can be used to find said initializer 
within the subexpression.


================
Comment at: clang/include/clang/AST/ExprCXX.h:4469-4471
+  /// Get the storage for the constant value of a materialized temporary
+  /// of static storage duration.
+  APValue *getOrCreateValue(ASTContext &Ctx, bool MayCreate) const;
----------------
This should live on the declaration, not here.


================
Comment at: clang/include/clang/AST/ExprCXX.h:4516
+    auto ES = State.get<MaterializeTemporaryDecl *>();
+    return child_range(&ES->StmtWithTemporary, &ES->StmtWithTemporary + 1);
   }
----------------
Instead of the friend decl / direct member access, it would be cleaner to a 
`children` function to the declaration and call it from here.


================
Comment at: clang/include/clang/AST/RecursiveASTVisitor.h:2125
+DEF_TRAVERSE_DECL(MaterializeTemporaryDecl, {
+  TRY_TO(TraverseDecl(D->getExtendingDecl()));
+  TRY_TO(TraverseStmt(D->getStmtWithTemporary()));
----------------
We should not traverse the extending declaration here; the temporary just has a 
backreference to the extending decl, it doesn't *contain* the extending decl.

Also, this is unreachable in normal circumstances. I think traversing the 
`MaterializeTemporaryExpr` should visit the lifetime-extended temporary 
declaration if there is one.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69360/new/

https://reviews.llvm.org/D69360



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to