/// output (e.g., -E).
class PreprocessorOutputOptions {
public:
- unsigned ShowCPP : 1; ///< Print normal preprocessed output.
- unsigned ShowMacros : 1; ///< Print macro definitions.
- unsigned ShowLineMarkers : 1; ///< Show #line markers.
- unsigned ShowComments : 1; ///< Show comments.
- unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+ unsigned ShowCPP : 1; ///< Print normal preprocessed output.
+ unsigned ShowComments : 1; ///< Show comments.
+ unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H).
+ unsigned ShowLineMarkers : 1; ///< Show #line markers.
+ unsigned ShowMacroComments : 1; ///< Show comments, even in macros.
+ unsigned ShowMacros : 1; ///< Print macro definitions.
public:
PreprocessorOutputOptions() {
ShowCPP = 1;
- ShowMacros = 0;
- ShowLineMarkers = 1;
ShowComments = 0;
+ ShowHeaderIncludes = 0;
+ ShowLineMarkers = 1;
ShowMacroComments = 0;
+ ShowMacros = 0;
}
};
else if (!Opts.ShowCPP && Opts.ShowMacros)
Res.push_back("-dM");
+ if (Opts.ShowHeaderIncludes)
+ Res.push_back("-H");
if (!Opts.ShowLineMarkers)
Res.push_back("-P");
if (Opts.ShowComments)
ArgList &Args) {
using namespace cc1options;
Opts.ShowCPP = !Args.hasArg(OPT_dM);
- Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
- Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
Opts.ShowComments = Args.hasArg(OPT_C);
+ Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
+ Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
Opts.ShowMacroComments = Args.hasArg(OPT_CC);
+ Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
}
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
llvm::raw_ostream &OS;
private:
unsigned CurLine;
+
+ /// The current include nesting level, used by header include dumping (-H).
+ unsigned CurrentIncludeDepth;
+
bool EmittedTokensOnThisLine;
bool EmittedMacroOnThisLine;
SrcMgr::CharacteristicKind FileType;
bool Initialized;
bool DisableLineMarkers;
bool DumpDefines;
+ bool DumpHeaderIncludes;
bool UseLineDirective;
+ bool HasProcessedPredefines;
public:
PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
- bool lineMarkers, bool defines)
+ bool lineMarkers, bool defines, bool headers)
: PP(pp), SM(PP.getSourceManager()),
ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
- DumpDefines(defines) {
- CurLine = 0;
+ DumpDefines(defines), DumpHeaderIncludes(headers) {
+ CurLine = CurrentIncludeDepth = 0;
CurFilename += "<uninit>";
EmittedTokensOnThisLine = false;
EmittedMacroOnThisLine = false;
FileType = SrcMgr::C_User;
Initialized = false;
+ HasProcessedPredefines = false;
// If we're in microsoft mode, use normal #line instead of line markers.
UseLineDirective = PP.getLangOptions().Microsoft;
PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
unsigned NewLine = UserLoc.getLine();
-
+
if (Reason == PPCallbacks::EnterFile) {
SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
if (IncludeLoc.isValid())
// directive and emits a bunch of spaces that aren't needed. Emulate this
// strange behavior.
}
+
+ // Adjust the current include depth.
+ if (Reason == PPCallbacks::EnterFile) {
+ ++CurrentIncludeDepth;
+ } else {
+ if (CurrentIncludeDepth)
+ --CurrentIncludeDepth;
+
+ // We track when we are done with the predefines by watching for the first
+ // place where we drop back to a nesting depth of 0.
+ if (CurrentIncludeDepth == 0 && !HasProcessedPredefines)
+ HasProcessedPredefines = true;
+ }
CurLine = NewLine;
- if (DisableLineMarkers) return;
-
CurFilename.clear();
CurFilename += UserLoc.getFilename();
Lexer::Stringify(CurFilename);
FileType = NewFileType;
+ // Dump the header include information, if enabled and we are past the
+ // predefines buffer.
+ if (DumpHeaderIncludes && HasProcessedPredefines &&
+ Reason == PPCallbacks::EnterFile) {
+ llvm::SmallString<256> Msg;
+ llvm::raw_svector_ostream OS(Msg);
+ for (unsigned i = 0; i != CurrentIncludeDepth; ++i)
+ OS << '.';
+ OS << ' ' << CurFilename << '\n';
+ llvm::errs() << OS.str();
+ }
+
+ if (DisableLineMarkers) return;
+
if (!Initialized) {
WriteLineInfo(CurLine);
Initialized = true;
PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
- Opts.ShowMacros);
+ Opts.ShowMacros, Opts.ShowHeaderIncludes);
PP.AddPragmaHandler(new UnknownPragmaHandler("#pragma", Callbacks));
PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
Callbacks));