[Sema] Tweak diagnostic logic so suppress-in-header logic works in tools too.

Certain idioms are ignored by -Wunused in header files only.
The current "is a header" check assumes that if headers are the main file, we're
building a PCH or a module or something. However in tools we may be parsing the
header in its own right, but still want to treat it as a header.

Fixes https://github.com/clangd/vscode-clangd/issues/360

Differential Revision: https://reviews.llvm.org/D129642
This commit is contained in:
Sam McCall 2022-07-13 16:27:36 +02:00
parent 605035bf45
commit ac31781759
2 changed files with 18 additions and 1 deletions

View File

@ -54,6 +54,9 @@ using ::testing::UnorderedElementsAre;
return Field(&Diag::Fixes, UnorderedElementsAre(FixMatcher1, FixMatcher2));
}
::testing::Matcher<const Diag &> withID(unsigned ID) {
return Field(&Diag::ID, ID);
}
::testing::Matcher<const Diag &>
withNote(::testing::Matcher<Note> NoteMatcher) {
return Field(&Diag::Notes, ElementsAre(NoteMatcher));
@ -1869,6 +1872,20 @@ TEST(DiagnosticsTest, FixItFromHeader) {
"'int' to 'int *' for 1st argument; take the address of "
"the argument with &")))));
}
TEST(DiagnosticsTest, UnusedInHeader) {
// Clang diagnoses unused static inline functions outside headers.
auto TU = TestTU::withCode("static inline void foo(void) {}");
TU.ExtraArgs.push_back("-Wunused-function");
TU.Filename = "test.c";
EXPECT_THAT(*TU.build().getDiagnostics(),
ElementsAre(withID(diag::warn_unused_function)));
// Sema should recognize a *.h file open in clangd as a header.
// https://github.com/clangd/vscode-clangd/issues/360
TU.Filename = "test.h";
EXPECT_THAT(*TU.build().getDiagnostics(), IsEmpty());
}
} // namespace
} // namespace clangd
} // namespace clang

View File

@ -1855,7 +1855,7 @@ bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) {
// FIXME: This needs to be refactored; some other isInMainFile users want
// these semantics.
static bool isMainFileLoc(const Sema &S, SourceLocation Loc) {
if (S.TUKind != TU_Complete)
if (S.TUKind != TU_Complete || S.getLangOpts().IsHeaderFile)
return false;
return S.SourceMgr.isInMainFile(Loc);
}