Page MenuHomePhabricator

[NFC] Refactor representation of materialized temporaries
ClosedPublic

Authored by Tyker on Oct 23 2019, 4:03 PM.

Diff Detail

Event Timeline

Tyker created this revision.Oct 23 2019, 4:03 PM
Herald added a reviewer: shafik. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
martong added inline comments.Oct 29 2019, 9:34 AM
clang/lib/AST/ASTImporter.cpp
7004

Could you please use GetImportedOrCreateDecl<MaterializeTemporaryDecl>(...) instead? We wrap every Decl creation in the ASTImporter so things that must be done right after creating a node is handled in one place.
Also, you can remove the next statement with MapImported.

7021

(An i is missing in MaterialzedDecl) And for consistency with the previous lines, perhaps it should be called as ToMaterializedDecl.

Thanks, I like this a lot.

There are a few more changes we'll need in addition to this before we can properly serialize APValues 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 LifetimeExtendedTemporaryDecls 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.

  1. Change the constant expression representation for a pointer or reference for a materialized temporary to refer to the temporary declaration instead.
  1. Change CodeGen / name mangling to operate on the new declaration node rather than MaterializedTemporaryExpr. (This will be needed once CodeGen starts seeing constant APValues 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.

clang/include/clang/AST/DeclCXX.h
3057

Since we should only use this for lifetime-extended temporaries, not for any materialized temporary, how about renaming to LifetimeExtendedTemporaryDecl?

3071

Clang coding convention puts the * on the right (please fix throughout the patch).

3101–3106

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.

clang/include/clang/AST/ExprCXX.h
4469–4471

This should live on the declaration, not here.

4516

Instead of the friend decl / direct member access, it would be cleaner to a children function to the declaration and call it from here.

clang/include/clang/AST/RecursiveASTVisitor.h
2125

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.

Tyker updated this revision to Diff 227454.Nov 1 2019, 8:51 AM
Tyker marked 8 inline comments as done.

fixed comments.

i will do the other changes later.

i also renamed MaterializeTemporaryExpr::GetTemporaryExpr to MaterializeTemporaryExpr::getSubExpr and change all uses of MaterializeTemporaryExpr::getTemporary to use it.
the renaming is for consistancy with other implicit nodes.

Tyker added a comment.Nov 13 2019, 9:57 AM
  1. Change the constant expression representation for a pointer or reference for a materialized temporary to refer to the temporary declaration instead.

I analyzed change 2 in this list and this require changing a very significant number of users many of them being implicit. and as far as I understand with the issue with duplication of MaterializeTemporaryExpr is solved by this patch + https://reviews.llvm.org/D70190. there can be multiple MaterializeTemporaryExpr but if they are equivalent they will all use the same LifetimeExtendedTemporaryDecl which contain all there internal state.

rsmith accepted this revision.Nov 13 2019, 11:17 AM

Thanks, looks good subject to some comment fixes + a tiny change to RecursiveASTVisitor.

clang/include/clang/AST/DeclCXX.h
3055

Typo: declartion -> declaration

3056

"a MaterializeTemporaryExpr."

We should probably also mention here that this only applies to MaterializeTemporaryExprs that are lifetime-extended.

3098

Start this comment by explaining what the function returns: "Retrieve the expression to which the temporary materialization conversion was applied."

"this" -> "This"

3099

Remove "that" here.

clang/include/clang/AST/RecursiveASTVisitor.h
1438

We should traverse the subexpression from here. (If someone directly starts a recursive visitation from the LifetimeExtendedTemporaryDecl, they should reach the subexpression.) ...

2642–2643

... and we should set ShouldVisitChildren = false; here because we already visited the children when visiting the LifetimeExtendedTemporaryDecl.

This revision is now accepted and ready to land.Nov 13 2019, 11:17 AM
Tyker updated this revision to Diff 229240.Nov 14 2019, 12:45 AM
Tyker marked 6 inline comments as done.

fixed comments.

clang/include/clang/AST/RecursiveASTVisitor.h
2642–2643

as far as i understanding, LifetimeExtendedTemporaryDecl is not listed in the childrens of MaterializeTemporaryExpr, it is not returned by MaterializeTemporaryExpr::children however the subexpression of MaterializeTemporaryExpr is listed in the children and need to be traversed. so i don't think this change is correct.

Tyker updated this revision to Diff 229242.Nov 14 2019, 12:51 AM
Tyker updated this revision to Diff 229694.Sat, Nov 16, 8:02 AM
This revision was automatically updated to reflect the committed changes.

This seems to have broken clangd tests e.g. http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/58189/steps/test-check-all/logs/stdio

FindExplicitReferences now finds duplicate refs to vector in

             void foo() {
-              for (int $0^x : $1^vector()) {
-                $2^x = 10;
+              for (int $0^x : $1^$2^vector()) {
+                $3^x = 10;
               }
             }

ninja check-clangd, or ninja ClangdTests && tools/clang/tools/extra/clangd/unittests/ClangdTests --gtest_filter=FindExplicitReferencesTest.All

I don't have much context on this code, @ilya-biryukov may be able to advise next week

Reverted in c9276fbfdf0c7caf1576b2 for now. Please watch the bots after landing things, and revert if something breaks and it takes you a while to fix.

Tyker updated this revision to Diff 229718.EditedSun, Nov 17, 4:36 AM

fixed the issue causing buildbot failure.

Herald added a project: Restricted Project. · View Herald Transcript