From b34d69b9292534c1c574f168f0ac10aea652adca Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 2 Feb 2011 21:11:31 +0000 Subject: [PATCH] Frontend: Add -header-include-file option, for allowing saving header include information to a file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124750 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/CC1Options.td | 6 ++- .../clang/Frontend/DependencyOutputOptions.h | 8 +++- lib/Frontend/CompilerInstance.cpp | 6 +++ lib/Frontend/CompilerInvocation.cpp | 5 +++ lib/Frontend/HeaderIncludeGen.cpp | 37 +++++++++++++++---- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index fd9bec0661..813ee5bcc3 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -196,6 +196,10 @@ def dependency_file : Separate<"-dependency-file">, HelpText<"Filename (or -) to write dependency output to">; def sys_header_deps : Flag<"-sys-header-deps">, HelpText<"Include system headers in dependency output">; +def header_include_file : Separate<"-header-include-file">, + HelpText<"Filename (or -) to write header include output to">; +def H : Flag<"-H">, + HelpText<"Show header includes and nesting depth">; def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">; def MT : Separate<"-MT">, HelpText<"Specify target for dependency">; def MP : Flag<"-MP">, @@ -600,8 +604,6 @@ def dM : Flag<"-dM">, HelpText<"Print macro definitions in -E mode instead of normal output">; def dD : Flag<"-dD">, HelpText<"Print macro definitions in -E mode in addition to normal output">; -def H : Flag<"-H">, - HelpText<"Show header includes and nesting depth">; //===----------------------------------------------------------------------===// // OpenCL Options diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h index a812ded6c9..35aa6c6aac 100644 --- a/include/clang/Frontend/DependencyOutputOptions.h +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -20,7 +20,7 @@ namespace clang { class DependencyOutputOptions { public: unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies. - unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H). + unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H). unsigned UsePhonyTargets : 1; ///< Include phony targets for each /// dependency, which can avoid some 'make' /// problems. @@ -28,6 +28,12 @@ public: /// The file to write dependency output to. std::string OutputFile; + /// The file to write header include output to. This is orthogonal to + /// ShowHeaderIncludes (-H) and will include headers mentioned in the + /// predefines buffer. If the output file is "-", output will be sent to + /// stderr. + std::string HeaderIncludeOutputFile; + /// A list of names to use as the targets in the dependency file; this list /// must contain at least one entry. std::vector Targets; diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index dea698d593..92aed39b5c 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -210,6 +210,12 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags, // Handle generating header include information, if requested. if (DepOpts.ShowHeaderIncludes) AttachHeaderIncludeGen(*PP); + if (!DepOpts.HeaderIncludeOutputFile.empty()) { + llvm::StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; + if (OutputPath == "-") + OutputPath = ""; + AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath); + } return PP; } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 1869049cbc..c2fe7d3f4d 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -222,6 +222,10 @@ static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts, Res.push_back("-sys-header-deps"); if (Opts.ShowHeaderIncludes) Res.push_back("-H"); + if (!Opts.HeaderIncludeOutputFile.empty()) { + Res.push_back("-header-include-file"); + Res.push_back(Opts.HeaderIncludeOutputFile); + } if (Opts.UsePhonyTargets) Res.push_back("-MP"); if (!Opts.OutputFile.empty()) { @@ -961,6 +965,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); Opts.UsePhonyTargets = Args.hasArg(OPT_MP); Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); + Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); } static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp index 480a97dd10..0d478d7065 100644 --- a/lib/Frontend/HeaderIncludeGen.cpp +++ b/lib/Frontend/HeaderIncludeGen.cpp @@ -10,19 +10,29 @@ #include "clang/Frontend/Utils.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Preprocessor.h" +#include using namespace clang; namespace { class HeaderIncludesCallback : public PPCallbacks { SourceManager &SM; + FILE *OutputFile; unsigned CurrentIncludeDepth; - bool ShowAllHeaders; bool HasProcessedPredefines; + bool OwnsOutputFile; + bool ShowAllHeaders; public: - HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_) - : SM(PP->getSourceManager()), CurrentIncludeDepth(0), - ShowAllHeaders(ShowAllHeaders_), HasProcessedPredefines(false) {} + HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_, + FILE *OutputFile_, bool OwnsOutputFile_) + : SM(PP->getSourceManager()), OutputFile(OutputFile_), + CurrentIncludeDepth(0), HasProcessedPredefines(false), + OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_) {} + + ~HeaderIncludesCallback() { + if (OwnsOutputFile) + fclose(OutputFile); + } virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType); @@ -31,7 +41,20 @@ public: void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders, llvm::StringRef OutputPath) { - PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders)); + FILE *OutputFile; + bool OwnsOutputFile; + + // Open the output file, if used. + if (OutputPath.empty()) { + OutputFile = stderr; + OwnsOutputFile = false; + } else { + OutputFile = fopen(OutputPath.str().c_str(), "a"); + OwnsOutputFile = true; + } + + PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders, + OutputFile, OwnsOutputFile)); } void HeaderIncludesCallback::FileChanged(SourceLocation Loc, @@ -42,7 +65,7 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, PresumedLoc UserLoc = SM.getPresumedLoc(Loc); if (UserLoc.isInvalid()) return; - + // Adjust the current include depth. if (Reason == PPCallbacks::EnterFile) { ++CurrentIncludeDepth; @@ -76,7 +99,7 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc, Msg += Filename; Msg += '\n'; - llvm::errs() << Msg; + fwrite(Msg.data(), Msg.size(), 1, OutputFile); } } -- 2.40.0