Skip to content

Commit be8ef3d

Browse files
authored
[include-cleaner] Respect language when tracking IWYU pragmas on stdlib headers (llvm#152142)
In absence we were associating all the IWYU pragmas with C++ versions of stdlib headers, which would result in false negatives when querying them from a C source file.
1 parent 16766b3 commit be8ef3d

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

clang-tools-extra/include-cleaner/lib/Record.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/Basic/FileEntry.h"
1515
#include "clang/Basic/FileManager.h"
1616
#include "clang/Basic/LLVM.h"
17+
#include "clang/Basic/LangOptions.h"
1718
#include "clang/Basic/SourceLocation.h"
1819
#include "clang/Basic/SourceManager.h"
1920
#include "clang/Basic/Specifiers.h"
@@ -179,8 +180,10 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
179180
RecordPragma(const CompilerInstance &CI, PragmaIncludes *Out)
180181
: RecordPragma(CI.getPreprocessor(), Out) {}
181182
RecordPragma(const Preprocessor &P, PragmaIncludes *Out)
182-
: SM(P.getSourceManager()), HeaderInfo(P.getHeaderSearchInfo()), Out(Out),
183-
Arena(std::make_shared<llvm::BumpPtrAllocator>()),
183+
: SM(P.getSourceManager()), HeaderInfo(P.getHeaderSearchInfo()),
184+
L(P.getLangOpts().CPlusPlus ? tooling::stdlib::Lang::CXX
185+
: tooling::stdlib::Lang::C),
186+
Out(Out), Arena(std::make_shared<llvm::BumpPtrAllocator>()),
184187
UniqueStrings(*Arena),
185188
MainFileStem(llvm::sys::path::stem(
186189
SM.getNonBuiltinFilenameForID(SM.getMainFileID()).value_or(""))) {}
@@ -224,7 +227,7 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
224227
std::optional<Header> IncludedHeader;
225228
if (IsAngled)
226229
if (auto StandardHeader =
227-
tooling::stdlib::Header::named("<" + FileName.str() + ">")) {
230+
tooling::stdlib::Header::named("<" + FileName.str() + ">", L)) {
228231
IncludedHeader = *StandardHeader;
229232
}
230233
if (!IncludedHeader && File)
@@ -363,6 +366,7 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
363366
bool InMainFile = false;
364367
const SourceManager &SM;
365368
const HeaderSearch &HeaderInfo;
369+
const tooling::stdlib::Lang L;
366370
PragmaIncludes *Out;
367371
std::shared_ptr<llvm::BumpPtrAllocator> Arena;
368372
/// Intern table for strings. Contents are on the arena.

clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "clang/Frontend/FrontendActions.h"
1919
#include "clang/Frontend/FrontendOptions.h"
2020
#include "clang/Serialization/PCHContainerOperations.h"
21+
#include "clang/Testing/CommandLineArgs.h"
2122
#include "clang/Testing/TestAST.h"
2223
#include "clang/Tooling/Inclusions/StandardLibrary.h"
2324
#include "llvm/ADT/ArrayRef.h"
@@ -514,6 +515,26 @@ TEST_F(PragmaIncludeTest, IWYUExportForStandardHeaders) {
514515
testing::UnorderedElementsAre(FileNamed("export.h")));
515516
}
516517

518+
TEST_F(PragmaIncludeTest, IWYUExportForStandardHeadersRespectsLang) {
519+
Inputs.Code = R"cpp(
520+
#include "export.h"
521+
)cpp";
522+
Inputs.Language = TestLanguage::Lang_C99;
523+
Inputs.ExtraFiles["export.h"] = R"cpp(
524+
#include <stdlib.h> // IWYU pragma: export
525+
)cpp";
526+
Inputs.ExtraFiles["stdlib.h"] = "";
527+
Inputs.ExtraArgs = {"-isystem."};
528+
TestAST Processed = build();
529+
auto &FM = Processed.fileManager();
530+
EXPECT_THAT(PI.getExporters(*tooling::stdlib::Header::named(
531+
"<stdlib.h>", tooling::stdlib::Lang::C),
532+
FM),
533+
testing::UnorderedElementsAre(FileNamed("export.h")));
534+
EXPECT_THAT(PI.getExporters(llvm::cantFail(FM.getFileRef("stdlib.h")), FM),
535+
testing::UnorderedElementsAre(FileNamed("export.h")));
536+
}
537+
517538
TEST_F(PragmaIncludeTest, IWYUExportBlock) {
518539
Inputs.Code = R"cpp(// Line 1
519540
#include "normal.h"

0 commit comments

Comments
 (0)