diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -231,6 +231,12 @@ // FIXME: skip tokens inside macros for now. return; + // Non top level decls that are included from a header are not filtered by + // topLevelDecls. (example: method declarations being included from another + // file for a class) from another file) + if (!SM.isWrittenInMainFile(Loc)) + return; + auto R = getTokenRange(SM, Ctx.getLangOpts(), Loc); if (!R) { // R should always have a value, if it doesn't something is very wrong. diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -51,9 +51,16 @@ return ExpectedTokens; } -void checkHighlightings(llvm::StringRef Code) { +// AdditionalFiles are key-value-pair that are included in the TU where the key +// is the filename and the value is the code for the file. +void checkHighlightings(llvm::StringRef Code, + std::vector> + AdditionalFiles = {}) { Annotations Test(Code); - auto AST = TestTU::withCode(Test.code()).build(); + auto TU = TestTU::withCode(Test.code()); + for (auto File : AdditionalFiles) + TU.AdditionalFiles.insert({File.first, File.second}); + auto AST = TU.build(); std::vector ActualTokens = getSemanticHighlightings(AST); EXPECT_THAT(ActualTokens, getExpectedTokens(Test)) << Code; } @@ -321,6 +328,17 @@ for (const auto &TestCase : TestCases) { checkHighlightings(TestCase); } + + checkHighlightings(R"cpp( + class $Class[[A]] { + #include "imp.h" + }; + #endif + )cpp", + {{"imp.h", R"cpp( + int someMethod(); + void otherMethod(); + )cpp"}}); } TEST(SemanticHighlighting, GeneratesHighlightsWhenFileChange) {