14#include "llvm/ADT/SmallString.h"
15#include "llvm/Support/JSON.h"
16#include "llvm/Support/raw_ostream.h"
22 raw_ostream *OutputFile;
24 unsigned CurrentIncludeDepth;
25 bool HasProcessedPredefines;
32 HeaderIncludesCallback(
const Preprocessor *PP,
bool ShowAllHeaders_,
33 raw_ostream *OutputFile_,
35 bool OwnsOutputFile_,
bool ShowDepth_,
bool MSStyle_)
36 :
SM(PP->getSourceManager()), OutputFile(OutputFile_), DepOpts(DepOpts),
37 CurrentIncludeDepth(0), HasProcessedPredefines(
false),
38 OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_),
39 ShowDepth(ShowDepth_), MSStyle(MSStyle_) {}
41 ~HeaderIncludesCallback()
override {
46 HeaderIncludesCallback(
const HeaderIncludesCallback &) =
delete;
47 HeaderIncludesCallback &operator=(
const HeaderIncludesCallback &) =
delete;
64 return (HasProcessedPredefines ||
65 (ShowAllHeaders && CurrentIncludeDepth > 2));
79class HeaderIncludesJSONCallback :
public PPCallbacks {
81 raw_ostream *OutputFile;
86 HeaderIncludesJSONCallback(
const Preprocessor *PP, raw_ostream *OutputFile_,
88 :
SM(PP->getSourceManager()), OutputFile(OutputFile_),
89 OwnsOutputFile(OwnsOutputFile_) {}
91 ~HeaderIncludesJSONCallback()
override {
96 HeaderIncludesJSONCallback(
const HeaderIncludesJSONCallback &) =
delete;
97 HeaderIncludesJSONCallback &
98 operator=(
const HeaderIncludesJSONCallback &) =
delete;
112 bool ShowDepth,
unsigned CurrentIncludeDepth,
121 Msg +=
"Note: including file:";
125 for (
unsigned i = 1; i != CurrentIncludeDepth; ++i)
126 Msg += MSStyle ?
' ' :
'.';
140 bool ShowAllHeaders, StringRef OutputPath,
141 bool ShowDepth,
bool MSStyle) {
142 raw_ostream *OutputFile = &llvm::errs();
143 bool OwnsOutputFile =
false;
149 llvm_unreachable(
"Invalid destination for /showIncludes output!");
150 case ShowIncludesDestination::Stderr:
151 OutputFile = &llvm::errs();
153 case ShowIncludesDestination::Stdout:
154 OutputFile = &llvm::outs();
160 if (!OutputPath.empty()) {
162 llvm::raw_fd_ostream *OS =
new llvm::raw_fd_ostream(
163 OutputPath.str(), EC,
164 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
172 OwnsOutputFile =
true;
178 llvm_unreachable(
"unexpected header format kind");
181 "header filtering is currently always disabled when output format is"
188 for (
const auto &Header : DepOpts.
ExtraDeps)
191 &PP, ShowAllHeaders, OutputFile, DepOpts, OwnsOutputFile, ShowDepth,
197 "only-direct-system is the only option for filtering");
199 &PP, OutputFile, OwnsOutputFile));
206 FileChangeReason Reason,
217 ++CurrentIncludeDepth;
219 if (CurrentIncludeDepth)
220 --CurrentIncludeDepth;
224 if (CurrentIncludeDepth == 1 && !HasProcessedPredefines)
225 HasProcessedPredefines =
true;
232 if (!ShouldShowHeader(NewFileType))
235 unsigned IncludeDepth = CurrentIncludeDepth;
236 if (!HasProcessedPredefines)
242 UserLoc.
getFilename() != StringRef(
"<command line>")) {
248void HeaderIncludesCallback::FileSkipped(
const FileEntryRef &SkippedFile,
const
258 CurrentIncludeDepth + 1, MSStyle);
261void HeaderIncludesJSONCallback::EndOfMainFile() {
264 SM.getFileManager().makeAbsolutePath(MainFile);
267 llvm::raw_string_ostream OS(Str);
268 llvm::json::OStream
JOS(OS);
270 JOS.attribute(
"source", MainFile.c_str());
271 JOS.attributeArray(
"includes", [&] {
272 llvm::StringSet<> SeenHeaders;
273 for (const std::string &H : IncludedHeaders)
274 if (SeenHeaders.insert(H).second)
280 if (OutputFile->get_kind() == raw_ostream::OStreamKind::OK_FDStream) {
281 llvm::raw_fd_ostream *FDS =
static_cast<llvm::raw_fd_ostream *
>(OutputFile);
282 if (
auto L = FDS->lock())
296void HeaderIncludesJSONCallback::FileChanged(
310 UserLoc.
getFilename() != StringRef(
"<command line>"))
314void HeaderIncludesJSONCallback::FileSkipped(
320 IncludedHeaders.push_back(SkippedFile.
getName().str());
llvm::json::OStream & JOS
llvm::MachO::FileType FileType
Defines the clang::Preprocessor interface.
Defines the SourceManager interface.
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
ShowIncludesDestination ShowIncludesDest
Destination of cl.exe style /showIncludes info.
HeaderIncludeFormatKind HeaderIncludeFormat
The format of header information.
HeaderIncludeFilteringKind HeaderIncludeFiltering
Determine whether header information should be filtered.
unsigned ShowSkippedHeaderIncludes
With ShowHeaderIncludes, show also includes that were skipped due to the "include guard optimizatio...
std::vector< std::pair< std::string, ExtraDepKind > > ExtraDeps
A list of extra dependencies (filename and kind) to be used for every target.
unsigned IncludeSystemHeaders
Include system header dependencies.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getName() const
The name of this FileEntry.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
static std::string Stringify(StringRef Str, bool Charify=false)
Stringify - Convert the specified string into a C string by i) escaping '\' and " characters and ii) ...
This interface provides a way to observe the actions of the preprocessor as it does its thing.
virtual void EndOfMainFile()
Callback invoked when the end of the main file is reached.
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID=FileID())
Callback invoked whenever a source file is entered or exited.
virtual void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType)
Callback invoked whenever a source file is skipped as the result of header guard optimization.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
DiagnosticsEngine & getDiagnostics() const
Represents an unpacked "presumed" location which can be presented to the user.
const char * getFilename() const
Return the presumed filename of this location.
bool isInvalid() const
Return true if this object is invalid or uninitialized.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
bool isSystem(CharacteristicKind CK)
Determine whether a file / directory characteristic is for system code.
The JSON file list parser is used to communicate input to InstallAPI.
@ HIFIL_Only_Direct_System
void AttachHeaderIncludeGen(Preprocessor &PP, const DependencyOutputOptions &DepOpts, bool ShowAllHeaders=false, StringRef OutputPath={}, bool ShowDepth=true, bool MSStyle=false)
AttachHeaderIncludeGen - Create a header include list generator, and attach it to the given preproces...