diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2019-06-03 22:59:17 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2019-06-03 22:59:17 +0000 |
| commit | 6e2d36b60b401a0fd5a25f8eb98cddfd3a7b92b4 (patch) | |
| tree | 852ca7da741315e7c7fa68bd08b31d81ab7bb015 /clang/lib/Frontend | |
| parent | 1f8030630be6c5b75c4c2a1edf7658472ff9c0c1 (diff) | |
| download | bcm5719-llvm-6e2d36b60b401a0fd5a25f8eb98cddfd3a7b92b4.tar.gz bcm5719-llvm-6e2d36b60b401a0fd5a25f8eb98cddfd3a7b92b4.zip | |
Add clang source minimizer that reduces source to directives
that might affect the dependency list for a compilation
This commit introduces a dependency directives source minimizer to clang
that minimizes header and source files to the minimum necessary preprocessor
directives for evaluating includes. It reduces the source down to #define, #include,
The source minimizer works by lexing the input with a custom fast lexer that recognizes
the preprocessor directives it cares about, and emitting those directives in the minimized source.
It ignores source code, comments, and normalizes whitespace. It gives up and fails if seems
any directives that it doesn't recognize as valid (e.g. #define 0).
In addition to the source minimizer this patch adds a
-print-dependency-directives-minimized-source CC1 option that allows you to invoke the minimizer
from clang directly.
Differential Revision: https://reviews.llvm.org/D55463
llvm-svn: 362459
Diffstat (limited to 'clang/lib/Frontend')
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 33 |
2 files changed, 37 insertions, 1 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 717278c0861..7ac58ae4da4 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1696,6 +1696,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::MigrateSource; break; case OPT_Eonly: Opts.ProgramAction = frontend::RunPreprocessorOnly; break; + case OPT_print_dependency_directives_minimized_source: + Opts.ProgramAction = + frontend::PrintDependencyDirectivesSourceMinimizerOutput; + break; } } @@ -3116,6 +3120,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::PrintPreprocessedInput: case frontend::RewriteMacros: case frontend::RunPreprocessorOnly: + case frontend::PrintDependencyDirectivesSourceMinimizerOutput: return true; } llvm_unreachable("invalid frontend action"); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 9e863235457..7d54d665146 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -14,6 +14,7 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/Utils.h" +#include "clang/Lex/DependencyDirectivesSourceMinimizer.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" @@ -23,8 +24,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" #include <memory> #include <system_error> @@ -908,3 +909,33 @@ void DumpCompilerOptionsAction::ExecuteAction() { OS << "}"; } + +void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + SourceManager &SM = CI.getPreprocessor().getSourceManager(); + const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID()); + + llvm::SmallString<1024> Output; + llvm::SmallVector<minimize_source_to_dependency_directives::Token, 32> Toks; + if (minimizeSourceToDependencyDirectives( + FromFile->getBuffer(), Output, Toks, &CI.getDiagnostics(), + SM.getLocForStartOfFile(SM.getMainFileID()))) { + assert(CI.getDiagnostics().hasErrorOccurred() && + "no errors reported for failure"); + + // Preprocess the source when verifying the diagnostics to capture the + // 'expected' comments. + if (CI.getDiagnosticOpts().VerifyDiagnostics) { + // Make sure we don't emit new diagnostics! + CI.getDiagnostics().setSuppressAllDiagnostics(); + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + PP.EnterMainSourceFile(); + Token Tok; + do { + PP.Lex(Tok); + } while (Tok.isNot(tok::eof)); + } + return; + } + llvm::outs() << Output; +} |

