forked from OSchip/llvm-project
[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
This commit is contained in:
parent
ba62ebc48e
commit
7dd6068899
|
@ -122,6 +122,17 @@ public:
|
|||
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;
|
||||
|
|
|
@ -226,6 +226,24 @@ public:
|
|||
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()) {
|
||||
|
|
|
@ -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"(
|
||||
|
|
Loading…
Reference in New Issue