[PATCH] D66647: [clangd] DefineInline action apply logic with fully qualified names
Ilya Biryukov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 4 01:42:38 PDT 2019
ilya-biryukov added inline comments.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:68
+// Lexes from end of \p FD until it finds a semicolon.
+llvm::Optional<SourceLocation> getSemiColonForDecl(const FunctionDecl *FD) {
----------------
"Lexes" is probably a not very relevant implementation detail.
I'd say this function probably doesn't need a comment, it's clear what it does from its name.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:169
+ tooling::Replacements Replacements;
+ std::string Failure;
+ findExplicitReferences(FD->getBody(), [&](ReferenceLoc Ref) {
----------------
NIT: Maybe store `Error` directly?
It would communicate the intent of the variable more clearly.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:175
+ // qualifier.
+ if (Ref.Qualifier.hasQualifier())
+ return;
----------------
NIT: IIUC, this could be simply `if (Ref.Qualifier)`
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:182
+
+ // All Targets should be in the same nested name scope, so we can safely
+ // chose any one of them.
----------------
As discussed before, `Targets` can actually come from different scopes, e.g. from ADL.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:183
+ // All Targets should be in the same nested name scope, so we can safely
+ // chose any one of them.
+ const NamedDecl *ND = Ref.Targets.front();
----------------
It just occurred to me that this is a really bad idea. I **think** the order of items in `Targets` is non-deterministic.
Could we instead try to check if all scopes are the same and only qualify in that case?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:196
+
+ std::string Qualifier = printNamespaceScope(*ND->getDeclContext());
+ if (auto Err = Replacements.add(
----------------
You would want to use `ND->printNestedNameSpecifier()` instead to avoid printing inline namespaces:
```
namespace std { inline namespace v1 {
struct vector {};
}}
```
^-- I believe the current code would print `std::v1::` for `vector` and we want `std::`.
Could you add this example to tests too?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:199
+ tooling::Replacement(SM, Ref.NameLoc, 0, Qualifier))) {
+ Failure = llvm::formatv("Failed to add qualifier: {0}",
+ llvm::fmt_consume(std::move(Err)));
----------------
Maybe return a generic error in the end instead of the last error?
Something like `createStringError(..., "Failed to compute qualifiers, see errors in the logs for more details")`.
Should be a better UX for anyone who tries to explore what went wrong.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:223
+
+/// Generates Replacements for changing parameter names in \p Dest to be the
+/// same as in \p Source.
----------------
NIT: mention that both function parameters and template parameters are updated here.
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:226
+llvm::Expected<tooling::Replacements>
+renameParameters(const FunctionDecl *Dest, const FunctionDecl *Source) {
+ const SourceManager &SM = Dest->getASTContext().getSourceManager();
----------------
This does not rename any references to those parameters, right?
E.g.
```
template <class T> void foo(T x);
template <class U> void foo(U x) {}
```
would turn into
```
template <class U> void foo(T x);
```
right?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66647/new/
https://reviews.llvm.org/D66647
More information about the cfe-commits
mailing list