[PATCH] D116377: [libTooling] Adds more support for constructing object access expressions.
Dmitri Gribenko via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 17 01:52:55 PST 2022
gribozavr2 accepted this revision.
gribozavr2 added inline comments.
This revision is now accepted and ready to land.
================
Comment at: clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp:78
+ returns(qualType(references(type()))))));
+ const auto SmartPointer = qualType(hasDeclaration(
+ cxxRecordDecl(anyOf(KnownSmartPointer, QuacksLikeASmartPointer))));
----------------
asoffer wrote:
> I think std::optional satisfies these requirements but should not be considered a smart-pointer.
Are you objecting to naming, or to this code handling optionals and smart pointers in the same way at all?
An optional is not a pointer, however it has few semantic differences from `std::unique_ptr` that are relevant here (whether the object is heap-allocated or not is not relevant for building an access expression). So I think this code should handle optionals and other value wrappers like `llvm::Expected` and `absl::StatusOr`.
================
Comment at: clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp:221-222
+ isSmartPointerType(E->getType(), Context)) {
+ // Strip off any operator->. This can only occur inside an actual arrow
+ // member access, so we treat it as equivalent to an actual object
+ // expression.
----------------
================
Comment at: clang/lib/Tooling/Transformer/SourceCodeBuilders.cpp:234
+ if (const auto *Operand = isSmartDereference(*E, Context)) {
+ // `buildDot` already handles the built-in dereference operator, so we
+ // only need to catch overloaded `operator*`.
----------------
================
Comment at: clang/unittests/Tooling/SourceCodeBuildersTest.cpp:141
+ std::string Snippet = "std::unique_ptr<int> P; P;";
+ auto StmtMatch = matchStmt(Snippet, expr(hasType(qualType().bind("ty"))));
+ ASSERT_TRUE(StmtMatch) << "Snippet: " << Snippet;
----------------
There are actually two expressions in the snippet above, one is the `DeclRefExpr` in `P;`, but the other is the `CXXConstructExpr` in `std::unique_ptr<int> P;`. Both have the same type, so it makes no difference which one we find, but the snippet deliberately having `P;` makes it look like we specifically want the `DeclRefExpr`. I'd suggest changing the matcher to `declRefExpr()` for clarity. Same in tests below.
================
Comment at: clang/unittests/Tooling/SourceCodeBuildersTest.cpp:373
+TEST(SourceCodeBuildersTest, BuildAccessSmartPointer) {
+ testBuilder(buildAccess, "Smart x; x;", "x->");
+}
----------------
This is a case where the old APIs provided the user with a choice, but the new API does not. If the user wanted to call a method on the smart pointer itself (e.g., `reset()`), they could have used `buildDot` to get `x.`.
IDK if it is an important use case, but I thought I'd mention it, since the new API is not 100% equivalent to the ones that it replaces.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D116377/new/
https://reviews.llvm.org/D116377
More information about the cfe-commits
mailing list