diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index e0bfd120c1b0..19f33a40f889 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1105,14 +1105,19 @@ void loadMainFilePreambleMacros(const Preprocessor &PP, ExternalPreprocessorSource *PreambleMacros = PP.getExternalSource(); // As we have the names of the macros, we can look up their IdentifierInfo // and then use this to load just the macros we want. + const auto &ITable = PP.getIdentifierTable(); IdentifierInfoLookup *PreambleIdentifiers = - PP.getIdentifierTable().getExternalIdentifierLookup(); + ITable.getExternalIdentifierLookup(); + if (!PreambleIdentifiers || !PreambleMacros) return; - for (const auto &MacroName : Preamble.Macros.Names) + for (const auto &MacroName : Preamble.Macros.Names) { + if (ITable.find(MacroName.getKey()) != ITable.end()) + continue; if (auto *II = PreambleIdentifiers->get(MacroName.getKey())) if (II->isOutOfDate()) PreambleMacros->updateOutOfDateIdentifier(*II); + } } // Invokes Sema code completion on a file. diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index a57ae49f9159..e4e56f2b5e38 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -3139,6 +3139,15 @@ TEST(CompletionTest, FunctionArgsExist) { Kind(CompletionItemKind::Constructor)))); } +TEST(CompletionTest, NoCrashDueToMacroOrdering) { + EXPECT_THAT(completions(R"cpp( + #define ECHO(X) X + #define ECHO2(X) ECHO(X) + int finish_preamble = EC^HO(2);)cpp") + .Completions, + UnorderedElementsAre(Labeled("ECHO(X)"), Labeled("ECHO2(X)"))); +} + } // namespace } // namespace clangd } // namespace clang