iains updated this revision to Diff 416850.
iains added a comment.
rebased.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D121099/new/
https://reviews.llvm.org/D121099
Files:
clang/include/clang/Driver/Options.td
clang/include/clang/Frontend/PreprocessorOutputOptions.h
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Frontend/PrintPreprocessedOutput.cpp
clang/test/Modules/cxx20-hu-06.cpp
Index: clang/test/Modules/cxx20-hu-06.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/cxx20-hu-06.cpp
@@ -0,0 +1,68 @@
+// Test check that consuming -E -fdirectives-only output produces the expected
+// header unit.
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+// RUN: cd %t
+
+// RUN: %clang_cc1 -std=c++20 -E -fdirectives-only -xc++-user-header hu-01.h \
+// RUN: -o hu-01.iih
+
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit \
+// RUN: -xc++-user-header-cpp-output hu-01.iih -o hu-01.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header hu-02.h \
+// RUN: -DFOO -fmodule-file=hu-01.pcm -o hu-02.pcm -Rmodule-import 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-IMP %s -DTDIR=%t
+
+//--- hu-01.h
+#ifndef __GUARD
+#define __GUARD
+
+int baz(int);
+#define FORTYTWO 42
+
+#define SHOULD_NOT_BE_DEFINED -1
+#undef SHOULD_NOT_BE_DEFINED
+
+#endif // __GUARD
+// expected-no-diagnostics
+
+//--- hu-02.h
+export import "hu-01.h";
+#if !defined(FORTYTWO) || FORTYTWO != 42
+#error FORTYTWO missing in hu-02
+#endif
+
+#ifndef __GUARD
+#error __GUARD missing in hu-02
+#endif
+
+#ifdef SHOULD_NOT_BE_DEFINED
+#error SHOULD_NOT_BE_DEFINED is visible
+#endif
+
+// Make sure that we have not discarded macros from the builtin file.
+#ifndef __cplusplus
+#error we dropped a defined macro
+#endif
+
+#define KAP 6174
+
+#ifdef FOO
+#define FOO_BRANCH(X) (X) + 1
+inline int foo(int x) {
+ if (x == FORTYTWO)
+ return FOO_BRANCH(x);
+ return FORTYTWO;
+}
+#else
+#define BAR_BRANCH(X) (X) + 2
+inline int bar(int x) {
+ if (x == FORTYTWO)
+ return BAR_BRANCH(x);
+ return FORTYTWO;
+}
+#endif
+// CHECK-IMP: remark: importing module './hu-01.h' from 'hu-01.pcm'
Index: clang/lib/Frontend/PrintPreprocessedOutput.cpp
===================================================================
--- clang/lib/Frontend/PrintPreprocessedOutput.cpp
+++ clang/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -96,6 +96,7 @@
bool UseLineDirectives;
bool IsFirstFileEntered;
bool MinimizeWhitespace;
+ bool DirectivesOnly;
Token PrevTok;
Token PrevPrevTok;
@@ -103,12 +104,13 @@
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::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::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 @@
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 @@
// 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
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -4413,6 +4413,8 @@
GenerateArg(Args, OPT_dM, SA);
if (!Generate_dM && Opts.ShowMacros)
GenerateArg(Args, OPT_dD, SA);
+ if (Opts.DirectivesOnly)
+ GenerateArg(Args, OPT_fdirectives_only, SA);
}
static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
@@ -4435,6 +4437,7 @@
Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
+ Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
return Diags.getNumErrors() == NumErrorsBefore;
}
Index: clang/include/clang/Frontend/PreprocessorOutputOptions.h
===================================================================
--- clang/include/clang/Frontend/PreprocessorOutputOptions.h
+++ clang/include/clang/Frontend/PreprocessorOutputOptions.h
@@ -25,6 +25,7 @@
unsigned RewriteIncludes : 1; ///< Preprocess include directives only.
unsigned RewriteImports : 1; ///< Include contents of transitively-imported modules.
unsigned MinimizeWhitespace : 1; ///< Ignore whitespace from input.
+ unsigned DirectivesOnly : 1; ///< Process directives but do not expand macros.
public:
PreprocessorOutputOptions() {
@@ -38,6 +39,7 @@
RewriteIncludes = 0;
RewriteImports = 0;
MinimizeWhitespace = 0;
+ DirectivesOnly = 0;
}
};
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -1871,6 +1871,8 @@
PreprocessorOutputOpts<"RewriteIncludes">, DefaultFalse,
PosFlag<SetTrue, [CC1Option]>, NegFlag<SetFalse>>;
+defm directives_only : OptInCC1FFlag<"directives-only", "">;
+
defm delete_null_pointer_checks : BoolFOption<"delete-null-pointer-checks",
CodeGenOpts<"NullPointerIsValid">, DefaultFalse,
NegFlag<SetTrue, [CC1Option], "Do not treat usage of null pointers as undefined behavior">,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits