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 {
64class HeaderIncludesJSONCallback :
public PPCallbacks {
66 raw_ostream *OutputFile;
71 HeaderIncludesJSONCallback(
const Preprocessor *PP, raw_ostream *OutputFile_,
73 :
SM(PP->getSourceManager()), OutputFile(OutputFile_),
74 OwnsOutputFile(OwnsOutputFile_) {}
76 ~HeaderIncludesJSONCallback()
override {
93 bool ShowDepth,
unsigned CurrentIncludeDepth,
102 Msg +=
"Note: including file:";
106 for (
unsigned i = 1; i != CurrentIncludeDepth; ++i)
107 Msg += MSStyle ?
' ' :
'.';
121 bool ShowAllHeaders, StringRef OutputPath,
122 bool ShowDepth,
bool MSStyle) {
123 raw_ostream *OutputFile = &llvm::errs();
124 bool OwnsOutputFile =
false;
130 llvm_unreachable(
"Invalid destination for /showIncludes output!");
131 case ShowIncludesDestination::Stderr:
132 OutputFile = &llvm::errs();
134 case ShowIncludesDestination::Stdout:
135 OutputFile = &llvm::outs();
141 if (!OutputPath.empty()) {
143 llvm::raw_fd_ostream *OS =
new llvm::raw_fd_ostream(
144 OutputPath.str(), EC,
145 llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);
153 OwnsOutputFile =
true;
159 llvm_unreachable(
"unexpected header format kind");
162 "header filtering is currently always disabled when output format is"
169 for (
const auto &Header : DepOpts.
ExtraDeps)
172 &PP, ShowAllHeaders, OutputFile, DepOpts, OwnsOutputFile, ShowDepth,
178 "only-direct-system is the only option for filtering");
180 &PP, OutputFile, OwnsOutputFile));
187 FileChangeReason Reason,
198 ++CurrentIncludeDepth;
200 if (CurrentIncludeDepth)
201 --CurrentIncludeDepth;
205 if (CurrentIncludeDepth == 1 && !HasProcessedPredefines) {
208 ShowDepth, 2, MSStyle);
210 HasProcessedPredefines =
true;
220 bool ShowHeader = (HasProcessedPredefines ||
221 (ShowAllHeaders && CurrentIncludeDepth > 2));
222 unsigned IncludeDepth = CurrentIncludeDepth;
223 if (!HasProcessedPredefines)
237 UserLoc.
getFilename() != StringRef(
"<command line>")) {
243void HeaderIncludesCallback::FileSkipped(
const FileEntryRef &SkippedFile,
const
253 CurrentIncludeDepth + 1, MSStyle);
256void HeaderIncludesJSONCallback::EndOfMainFile() {
257 const FileEntry *FE =
SM.getFileEntryForID(
SM.getMainFileID());
259 SM.getFileManager().makeAbsolutePath(MainFile);
262 llvm::raw_string_ostream
OS(Str);
263 llvm::json::OStream JOS(OS);
265 JOS.attribute(
"source", MainFile.c_str());
266 JOS.attributeArray(
"includes", [&] {
267 llvm::StringSet<> SeenHeaders;
268 for (const std::string &H : IncludedHeaders)
269 if (SeenHeaders.insert(H).second)
275 if (OutputFile->get_kind() == raw_ostream::OStreamKind::OK_FDStream) {
276 llvm::raw_fd_ostream *FDS =
static_cast<llvm::raw_fd_ostream *
>(OutputFile);
277 if (
auto L = FDS->lock())
291void HeaderIncludesJSONCallback::FileChanged(
305 UserLoc.
getFilename() != StringRef(
"<command line>"))
309void HeaderIncludesJSONCallback::FileSkipped(
315 IncludedHeaders.push_back(SkippedFile.
getName().str());
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.
std::string ShowIncludesPretendHeader
In /showIncludes mode, pretend the main TU is a header with this name.
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.
Cached information about one file (either on disk or in the virtual file system).
StringRef getName() const
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.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ 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...