aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Frontend/PrintPreprocessedOutput.cpp
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-07-31 10:44:12 +0100
committerIain Sandoe <iain@sandoe.co.uk>2022-03-28 07:38:22 +0100
commit85b1354098ba0a665fdd47204d0e53e63d09d9ab (patch)
treef285b11403f258c465f1c1fb04c250324905a0f6 /clang/lib/Frontend/PrintPreprocessedOutput.cpp
parentad57e10dbca2fdeff1448afc0aa1cf23d6df8736 (diff)
downloadllvm-85b1354098ba0a665fdd47204d0e53e63d09d9ab.zip
llvm-85b1354098ba0a665fdd47204d0e53e63d09d9ab.tar.gz
llvm-85b1354098ba0a665fdd47204d0e53e63d09d9ab.tar.bz2
[C++20][Modules][HU 5/5] Add fdirectives-only mode for preprocessing output.
When the -fdirectives-only option is used together with -E, the preprocessor output reflects evaluation of if/then/else directives. As such, it preserves defines and undefs of macros that are still live after such processing. The intent is that this output could be consumed as input to generate considered a C++20 header unit. We strip out any (unused) defines that come from built-in, built-in-file or command line; these are re-added when the preprocessed source is consumed. Differential Revision: https://reviews.llvm.org/D121099
Diffstat (limited to 'clang/lib/Frontend/PrintPreprocessedOutput.cpp')
-rw-r--r--clang/lib/Frontend/PrintPreprocessedOutput.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
index e2fc862..7737d04 100644
--- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -96,6 +96,7 @@ private:
bool UseLineDirectives;
bool IsFirstFileEntered;
bool MinimizeWhitespace;
+ bool DirectivesOnly;
Token PrevTok;
Token PrevPrevTok;
@@ -103,12 +104,13 @@ private:
public:
PrintPPOutputPPCallbacks(Preprocessor &pp, raw_ostream &os, bool lineMarkers,
bool defines, bool DumpIncludeDirectives,
- bool UseLineDirectives, bool MinimizeWhitespace)
+ bool UseLineDirectives, bool MinimizeWhitespace,
+ bool DirectivesOnly)
: PP(pp), SM(PP.getSourceManager()), ConcatInfo(PP), OS(os),
DisableLineMarkers(lineMarkers), DumpDefines(defines),
DumpIncludeDirectives(DumpIncludeDirectives),
UseLineDirectives(UseLineDirectives),
- MinimizeWhitespace(MinimizeWhitespace) {
+ MinimizeWhitespace(MinimizeWhitespace), DirectivesOnly(DirectivesOnly) {
CurLine = 0;
CurFilename += "<uninit>";
EmittedTokensOnThisLine = false;
@@ -467,12 +469,21 @@ void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, StringRef S) {
void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) {
const MacroInfo *MI = MD->getMacroInfo();
- // Only print out macro definitions in -dD mode.
- if (!DumpDefines ||
+ // Print out macro definitions in -dD mode and when we have -fdirectives-only
+ // for C++20 header units.
+ if ((!DumpDefines && !DirectivesOnly) ||
// Ignore __FILE__ etc.
- MI->isBuiltinMacro()) return;
+ MI->isBuiltinMacro())
+ return;
- MoveToLine(MI->getDefinitionLoc(), /*RequireStartOfLine=*/true);
+ SourceLocation DefLoc = MI->getDefinitionLoc();
+ if (DirectivesOnly && !MI->isUsed()) {
+ SourceManager &SM = PP.getSourceManager();
+ if (SM.isWrittenInBuiltinFile(DefLoc) ||
+ SM.isWrittenInCommandLineFile(DefLoc))
+ return;
+ }
+ MoveToLine(DefLoc, /*RequireStartOfLine=*/true);
PrintMacroDefinition(*MacroNameTok.getIdentifierInfo(), *MI, PP, OS);
setEmittedDirectiveOnThisLine();
}
@@ -480,8 +491,10 @@ void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
void PrintPPOutputPPCallbacks::MacroUndefined(const Token &MacroNameTok,
const MacroDefinition &MD,
const MacroDirective *Undef) {
- // Only print out macro definitions in -dD mode.
- if (!DumpDefines) return;
+ // Print out macro definitions in -dD mode and when we have -fdirectives-only
+ // for C++20 header units.
+ if (!DumpDefines && !DirectivesOnly)
+ return;
MoveToLine(MacroNameTok.getLocation(), /*RequireStartOfLine=*/true);
OS << "#undef " << MacroNameTok.getIdentifierInfo()->getName();
@@ -959,7 +972,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
PrintPPOutputPPCallbacks *Callbacks = new PrintPPOutputPPCallbacks(
PP, *OS, !Opts.ShowLineMarkers, Opts.ShowMacros,
Opts.ShowIncludeDirectives, Opts.UseLineDirectives,
- Opts.MinimizeWhitespace);
+ Opts.MinimizeWhitespace, Opts.DirectivesOnly);
// Expand macros in pragmas with -fms-extensions. The assumption is that
// the majority of pragmas in such a file will be Microsoft pragmas.
@@ -995,6 +1008,8 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
// After we have configured the preprocessor, enter the main file.
PP.EnterMainSourceFile();
+ if (Opts.DirectivesOnly)
+ PP.SetMacroExpansionOnlyInDirectives();
// Consume all of the tokens that come from the predefines buffer. Those
// should not be emitted into the output and are guaranteed to be at the