diff --git a/clang-tools-extra/clangd/SourceCode.cpp b/clang-tools-extra/clangd/SourceCode.cpp index 0432097b434882..c6279177eba99b 100644 --- a/clang-tools-extra/clangd/SourceCode.cpp +++ b/clang-tools-extra/clangd/SourceCode.cpp @@ -633,6 +633,12 @@ std::vector collectIdentifierRanges(llvm::StringRef Identifier, return Ranges; } +bool isKeyword(llvm::StringRef NewName, const LangOptions &LangOpts) { + // Keywords are initialized in constructor. + clang::IdentifierTable KeywordsTable(LangOpts); + return KeywordsTable.find(NewName) != KeywordsTable.end(); +} + namespace { struct NamespaceEvent { enum { diff --git a/clang-tools-extra/clangd/SourceCode.h b/clang-tools-extra/clangd/SourceCode.h index 128f985a526642..be78e2f86436cd 100644 --- a/clang-tools-extra/clangd/SourceCode.h +++ b/clang-tools-extra/clangd/SourceCode.h @@ -248,6 +248,10 @@ struct SpelledWord { const LangOptions &LangOpts); }; +/// Return true if the \p TokenName is in the list of reversed keywords of the +/// language. +bool isKeyword(llvm::StringRef TokenName, const LangOptions &LangOpts); + /// Heuristically determine namespaces visible at a point, without parsing Code. /// This considers using-directives and enclosing namespace-declarations that /// are visible (and not obfuscated) in the file itself (not headers). diff --git a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp index 9c3ae4df51ff1e..c05515f2c094f5 100644 --- a/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp +++ b/clang-tools-extra/clangd/unittests/SourceCodeTests.cpp @@ -789,6 +789,19 @@ TEST(SourceCodeTests, isHeaderFile) { EXPECT_TRUE(isHeaderFile("header.h", LangOpts)); } +TEST(SourceCodeTests, isKeywords) { + LangOptions LangOpts; + LangOpts.CPlusPlus20 = true; + EXPECT_TRUE(isKeyword("int", LangOpts)); + EXPECT_TRUE(isKeyword("return", LangOpts)); + EXPECT_TRUE(isKeyword("co_await", LangOpts)); + + // these are identifiers (not keywords!) with special meaning in some + // contexts. + EXPECT_FALSE(isKeyword("final", LangOpts)); + EXPECT_FALSE(isKeyword("override", LangOpts)); +} + } // namespace } // namespace clangd } // namespace clang