diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -117,8 +117,8 @@ if (D.Severity < DiagnosticsEngine::Level::Error) return false; - const SourceLocation &DiagLoc = Info.getLocation(); const SourceManager &SM = Info.getSourceManager(); + const SourceLocation &DiagLoc = SM.getExpansionLoc(Info.getLocation()); SourceLocation IncludeInMainFile; auto GetIncludeLoc = [&SM](SourceLocation SLoc) { return SM.getIncludeLoc(SM.getFileID(SLoc)); diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp --- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp +++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp @@ -941,7 +941,7 @@ WithNote(Diag(Header.range(), "error occurred here"))))); } -TEST(IgnoreDiags, FromNonWrittenSources) { +TEST(DiagsInHeaders, FromNonWrittenSources) { Annotations Main(R"cpp( #include [["a.h"]] void foo() {})cpp"); @@ -951,7 +951,11 @@ TestTU TU = TestTU::withCode(Main.code()); TU.AdditionalFiles = {{"a.h", Header.code()}}; TU.ExtraArgs = {"-DFOO=NOOO"}; - EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre(AllOf( + Diag(Main.range(), + "in included file: use of undeclared identifier 'NOOO'"), + WithNote(Diag(Header.range(), "error occurred here"))))); } TEST(IgnoreDiags, FromNonWrittenInclude) { @@ -963,6 +967,40 @@ EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre()); } +TEST(DiagsInHeaders, ErrorFromMacroExpansion) { + Annotations Main(R"cpp( + void bar() { + int fo; + #include [["a.h"]] + })cpp"); + Annotations Header(R"cpp( + #define X foo + X;)cpp"); + TestTU TU = TestTU::withCode(Main.code()); + TU.AdditionalFiles = {{"a.h", Header.code()}}; + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre( + Diag(Main.range(), "in included file: use of undeclared " + "identifier 'foo'; did you mean 'fo'?"))); +} + +TEST(DiagsInHeaders, ErrorFromMacroArgument) { + Annotations Main(R"cpp( + void bar() { + int fo; + #include [["a.h"]] + })cpp"); + Annotations Header(R"cpp( + #define X(arg) arg + X(foo);)cpp"); + TestTU TU = TestTU::withCode(Main.code()); + TU.AdditionalFiles = {{"a.h", Header.code()}}; + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre( + Diag(Main.range(), "in included file: use of undeclared " + "identifier 'foo'; did you mean 'fo'?"))); +} + } // namespace } // namespace clangd