[PATCH] D141226: [clangd] support expanding `decltype(expr)`
Sam McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 11 07:11:09 PST 2023
sammccall added a comment.
Thanks for doing this!
There are a couple of separate logical changes here - I don't think it's a problem per se, but it does mean it takes a bit longer to get the good + obvious stuff reviewed and landed.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExpandDeducedType.cpp:57
+std::string ExpandDeducedType::title() const {
+ return IsAutoType ? "Expand auto type" : "Expand decltype";
+}
----------------
Maybe "Replace with deduced type" would be clearer for both cases?
Then we don't need to track IsAutoType.
(I have no objection with spending a bit of code to provide better text, but given that the cursor is either on top of "auto" or "decltype" I don't think we're actually adding anything by echoing it back)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExpandDeducedType.cpp:119
+ if (auto DTTL = TypeNode->getAs<DecltypeTypeLoc>()) {
+ if (!isDeducedAsLambda(Node, DTTL.getBeginLoc()))
+ Range = DTTL.getSourceRange();
----------------
isDeducedAsLambda is detecting the specific pattern `auto x = [&} { ... };`, which doesn't occur with decltype.
On the other hand I suspect the `DecltypeTypeLoc` for `decltype(some_lambda)` doesn't suffer from the same issue as the `AutoTypeLoc` in a declaration, and we can simply call getUnderlyingType().
So I think you can simply factor out `isLambda(QualType)` from `isDeducedAsLambda`, and call `isLambda(DTTL.getType()->getUnderlyingType())` here.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExpandDeducedType.cpp:139
- // if it's a lambda expression, return an error message
- if (isa<RecordType>(*DeducedType) &&
- cast<RecordType>(*DeducedType)->getDecl()->isLambda()) {
- return error("Could not expand type of lambda expression");
+ // we shouldn't replace a dependent type, e.g.
+ // template <class T>
----------------
why not? replacing this with `T` seems perfectly reasonable.
(The fact that we don't do this with `auto t = T{}` is just because we're hitting a limitation of clang's AST)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExpandDeducedType.cpp:149
+ // int arr[10];
+ // decltype(auto) foobar = arr;
+ // ^^^^^^^^^^^^^^ is `int[10]`
----------------
these are unrelated to the decltype change (`decltype(auto)` is an AutoType rather than a DecltypeType and already works/has this bug today).
In future it's best to split unrelated changes into different patches/a patch sequence, though this is simple enough it's probably OK.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExpandDeducedType.cpp:151
+ // ^^^^^^^^^^^^^^ is `int[10]`
+ if ((*DeducedType)->isArrayType())
+ return error("Could not expand type of array");
----------------
the commonality between these cases you're excluding (and the function types below) is that they use C-style declarator syntax that may have chunks following the declarator-id. Specifically:
- array, function, and paren types always have chunks following the declarator
- pointer and reference types compose inside-out so their pointee types may contain trailing chunks
If we want to make some attempt to detect more cases, we should pull out a function here and do it properly, something like: `bool hasTrailingChunks(QualType)` which calls recursively for pointertype etc.
But there's a cheaper way: when we call `printType()` below, we can optionally specify the declarator-id. Then we can simply check whether it's at the end of the string:
```
std::string PrettyDeclarator = printType(..., "DECLARATOR_ID");
llvm::StringRef PrettyType = PrettyDeclarator;
if (!PrettyType.consume_back("DECLARATOR_ID"))
return error("could not expand non-contiguous type {0}", PrettyType);
PrettyType = PrettyType.rtrim();
```
This feels slightly hacky, but it's direct and simple and we shouldn't miss a case.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D141226/new/
https://reviews.llvm.org/D141226
More information about the cfe-commits
mailing list