Author: Daniele Castagna Date: 2021-04-12T13:15:14-07:00 New Revision: 7dd60688992526bb7ee0c7846e9abd591fc3e297
URL: https://github.com/llvm/llvm-project/commit/7dd60688992526bb7ee0c7846e9abd591fc3e297 DIFF: https://github.com/llvm/llvm-project/commit/7dd60688992526bb7ee0c7846e9abd591fc3e297.diff LOG: [clang-rename] Handle designated initializers. clang Tooling, and more specifically Refactoring/Rename, have support code to extract source locations given a Unified Symbol Resolution set. This support code is used by clang-rename and other tools that might not be in the tree. Currently field designated initializer are not supported. So, renaming S::a to S::b in this code: S s = { .a = 10 }; will not extract the field designated initializer for a (the 'a' after the dot). This patch adds support for field designated initialized to RecursiveSymbolVisitor and RenameLocFinder that is used in createRenameAtomicChanges. Differential Revision: https://reviews.llvm.org/D100310 Added: Modified: clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp clang/unittests/Rename/RenameClassTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h index c0f995d85c14c..63d46abc20347 100644 --- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h +++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -122,6 +122,17 @@ class RecursiveSymbolVisitor return BaseType::TraverseNestedNameSpecifierLoc(NNS); } + bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) { + for (const DesignatedInitExpr::Designator &D : E->designators()) { + if (D.isFieldDesignator() && D.getField()) { + const FieldDecl *Decl = D.getField(); + if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc())) + return false; + } + } + return true; + } + private: const SourceManager &SM; const LangOptions &LangOpts; diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp index 6a08c7fd52475..aecfffcbef1fa 100644 --- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp @@ -226,6 +226,24 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> { return true; } + bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) { + for (const DesignatedInitExpr::Designator &D : E->designators()) { + if (D.isFieldDesignator() && D.getField()) { + const FieldDecl *Decl = D.getField(); + if (isInUSRSet(Decl)) { + auto StartLoc = D.getFieldLoc(); + auto EndLoc = D.getFieldLoc(); + RenameInfos.push_back({StartLoc, EndLoc, + /*FromDecl=*/nullptr, + /*Context=*/nullptr, + /*Specifier=*/nullptr, + /*IgnorePrefixQualifiers=*/true}); + } + } + } + return true; + } + bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) { // Fix the constructor initializer when renaming class members. for (const auto *Initializer : CD->inits()) { diff --git a/clang/unittests/Rename/RenameClassTest.cpp b/clang/unittests/Rename/RenameClassTest.cpp index 1c00ad7912e73..1b008987a16d3 100644 --- a/clang/unittests/Rename/RenameClassTest.cpp +++ b/clang/unittests/Rename/RenameClassTest.cpp @@ -780,6 +780,27 @@ TEST_F(RenameClassTest, UsingAlias) { CompareSnippets(Expected, After); } +TEST_F(ClangRenameTest, FieldDesignatedInitializers) { + std::string Before = R"( + struct S { + int a; + }; + void foo() { + S s = { .a = 10 }; + s.a = 20; + })"; + std::string Expected = R"( + struct S { + int b; + }; + void foo() { + S s = { .b = 10 }; + s.b = 20; + })"; + std::string After = runClangRenameOnCode(Before, "S::a", "S::b"); + CompareSnippets(Expected, After); +} + // FIXME: investigate why the test fails when adding a new USR to the USRSet. TEST_F(ClangRenameTest, DISABLED_NestedTemplates) { std::string Before = R"( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits