diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -120,6 +120,9 @@ UsedOutsideFile, // for within-file rename only. UnsupportedSymbol, AmbiguousSymbol, + + // name validation. + RenameToKeywords, }; llvm::Optional renameable(const NamedDecl &RenameDecl, @@ -208,6 +211,8 @@ return "symbol is not a supported kind (e.g. namespace, macro)"; case ReasonToReject::AmbiguousSymbol: return "there are multiple symbols at the given location"; + case ReasonToReject::RenameToKeywords: + return "symbol is renamed to a reserved keyword"; } llvm_unreachable("unhandled reason kind"); }; @@ -471,6 +476,10 @@ return makeError(ReasonToReject::NoSymbolFound); if (DeclsUnderCursor.size() > 1) return makeError(ReasonToReject::AmbiguousSymbol); + // Empty name is legal -- this allows rename API to return all occurrences + // even the name is unknown. + if (!RInputs.NewName.empty() && isKeyword(RInputs.NewName, AST.getLangOpts())) + return makeError(ReasonToReject::RenameToKeywords); const auto &RenameDecl = llvm::cast(*(*DeclsUnderCursor.begin())->getCanonicalDecl()); diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -516,6 +516,7 @@ const char* ErrorMessage; // null if no error bool IsHeaderFile; const SymbolIndex *Index; + llvm::StringRef NewName = "DummyName"; }; TestTU OtherFile = TestTU::withCode("Outside s; auto ss = &foo;"); const char *CommonHeader = R"cpp( @@ -542,6 +543,11 @@ )cpp", nullptr, HeaderFile, Index}, + {R"cpp( + void ^f(); + )cpp", + "keyword", HeaderFile, Index, "return"}, + {R"cpp(// disallow -- symbol is indexable and has other refs in index. void f() { Out^side s; @@ -639,7 +645,7 @@ TU.ExtraArgs.push_back("-xobjective-c++-header"); } auto AST = TU.build(); - llvm::StringRef NewName = "dummyNewName"; + llvm::StringRef NewName = Case.NewName; auto Results = rename({T.point(), NewName, AST, testPath(TU.Filename), Case.Index}); bool WantRename = true;