10 #include "clang/AST/ASTContext.h"
11 #include "clang/Lex/Preprocessor.h"
18 class SuspiciousIncludePPCallbacks :
public PPCallbacks {
20 explicit SuspiciousIncludePPCallbacks(SuspiciousIncludeCheck &Check,
21 const SourceManager &SM,
23 : Check(Check),
PP(
PP) {}
25 void InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
27 CharSourceRange FilenameRange,
const FileEntry *File,
28 StringRef SearchPath, StringRef RelativePath,
29 const Module *Imported,
30 SrcMgr::CharacteristicKind FileType)
override;
33 SuspiciousIncludeCheck &Check;
41 RawStringHeaderFileExtensions(Options.getLocalOrGlobal(
43 RawStringImplementationFileExtensions(Options.getLocalOrGlobal(
44 "ImplementationFileExtensions",
49 llvm::errs() <<
"Invalid implementation file extension: "
50 << RawStringImplementationFileExtensions <<
"\n";
56 llvm::errs() <<
"Invalid header file extension: "
57 << RawStringHeaderFileExtensions <<
"\n";
63 RawStringImplementationFileExtensions);
64 Options.
store(Opts,
"HeaderFileExtensions", RawStringHeaderFileExtensions);
68 const SourceManager &SM, Preprocessor *
PP, Preprocessor *ModuleExpanderPP) {
70 ::std::make_unique<SuspiciousIncludePPCallbacks>(*
this, SM,
PP));
73 void SuspiciousIncludePPCallbacks::InclusionDirective(
74 SourceLocation HashLoc,
const Token &IncludeTok, StringRef
FileName,
75 bool IsAngled, CharSourceRange FilenameRange,
const FileEntry *File,
76 StringRef SearchPath, StringRef RelativePath,
const Module *Imported,
77 SrcMgr::CharacteristicKind FileType) {
78 if (IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import)
81 SourceLocation DiagLoc = FilenameRange.getBegin().getLocWithOffset(1);
83 const Optional<StringRef> IFE =
88 Check.
diag(DiagLoc,
"suspicious #%0 of file with '%1' extension")
89 << IncludeTok.getIdentifierInfo()->getName() << *IFE;
91 for (
const auto &HFE : Check.HeaderFileExtensions) {
92 SmallString<128> GuessedFileName(
FileName);
93 llvm::sys::path::replace_extension(GuessedFileName,
94 (HFE.size() ?
"." :
"") + HFE);
96 const DirectoryLookup *CurDir;
97 Optional<FileEntryRef> File =
98 PP->LookupFile(DiagLoc, GuessedFileName,
IsAngled,
nullptr,
nullptr,
99 CurDir,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
101 Check.
diag(DiagLoc,
"did you mean to include '%0'?", DiagnosticIDs::Note)