Skip to content

Add -fkeep-system-includes modifier for -E #67684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions clang/docs/CommandGuide/clang.rst
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,21 @@ Preprocessor Options

Do not search clang's builtin directory for include files.

.. option:: -fkeep-system-includes

Usable only with :option:`-E`. Do not copy the preprocessed content of
"system" headers to the output; instead, preserve the #include directive.
This can greatly reduce the volume of text produced by :option:`-E` which
can be helpful when trying to produce a "small" reproduceable test case.

This option does not guarantee reproduceability, however. If the including
source defines preprocessor symbols that influence the behavior of system
headers (for example, ``_XOPEN_SOURCE``) the operation of :option:`-E` will
remove that definition and thus can change the semantics of the included
header. Also, using a different version of the system headers (especially a
different version of the STL) may result in different behavior. Always verify
the preprocessed file by compiling it separately.


ENVIRONMENT
-----------
Expand Down
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ New Compiler Flags
Since enabling the verifier adds a non-trivial cost of a few percent impact on
build times, it's disabled by default, unless your LLVM distribution itself is
compiled with runtime checks enabled.
* ``-fkeep-system-includes`` modifies the behavior of the ``-E`` option,
preserving ``#include`` directives for "system" headers instead of copying
the preprocessed text to the output. This can greatly reduce the size of the
preprocessed output, which can be helpful when trying to reduce a test case.

Deprecated Compiler Flags
-------------------------
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ def err_drv_invalid_Xopenmp_target_with_args : Error<
"invalid -Xopenmp-target argument: '%0', options requiring arguments are unsupported">;
def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">;
def err_drv_minws_unsupported_input_type : Error<
"'-fminimize-whitespace' invalid for input of type %0">;
def err_drv_opt_unsupported_input_type : Error<
"'%0' invalid for input of type %1">;
def err_drv_amdgpu_ieee_without_no_honor_nans : Error<
"invalid argument '-mno-amdgpu-ieee' only allowed with relaxed NaN handling">;
def err_drv_argument_not_allowed_with : Error<
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,17 @@ defm minimize_whitespace : BoolFOption<"minimize-whitespace",
"whitespace such that two files with only formatting changes are "
"equal.\n\nOnly valid with -E on C-like inputs and incompatible "
"with -traditional-cpp.">, NegFlag<SetFalse>>;
defm keep_system_includes : BoolFOption<"keep-system-includes",
PreprocessorOutputOpts<"KeepSystemIncludes">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Instead of expanding system headers when emitting preprocessor "
"output, preserve the #include directive. Useful when producing "
"preprocessed output for test case reduction. May produce incorrect "
"output if preprocessor symbols that control the included content "
"(e.g. _XOPEN_SOURCE) are defined in the including source file. The "
"portability of the resulting source to other compilation environments "
"is not guaranteed.\n\nOnly valid with -E.">,
NegFlag<SetFalse>>;

def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Frontend/PreprocessorOutputOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class PreprocessorOutputOptions {
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.
unsigned KeepSystemIncludes : 1; ///< Do not expand system headers.

public:
PreprocessorOutputOptions() {
Expand All @@ -40,6 +41,7 @@ class PreprocessorOutputOptions {
RewriteImports = 0;
MinimizeWhitespace = 0;
DirectivesOnly = 0;
KeepSystemIncludes = 0;
}
};

Expand Down
18 changes: 15 additions & 3 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ using namespace llvm::opt;
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(clang::driver::options::OPT_C, options::OPT_CC,
options::OPT_fminimize_whitespace,
options::OPT_fno_minimize_whitespace)) {
options::OPT_fno_minimize_whitespace,
options::OPT_fkeep_system_includes,
options::OPT_fno_keep_system_includes)) {
if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
!Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
Expand Down Expand Up @@ -6717,11 +6719,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_minimize_whitespace, false)) {
types::ID InputType = Inputs[0].getType();
if (!isDerivedFromC(InputType))
D.Diag(diag::err_drv_minws_unsupported_input_type)
<< types::getTypeName(InputType);
D.Diag(diag::err_drv_opt_unsupported_input_type)
<< "-fminimize-whitespace" << types::getTypeName(InputType);
CmdArgs.push_back("-fminimize-whitespace");
}

// -fno-keep-system-includes is default.
if (Args.hasFlag(options::OPT_fkeep_system_includes,
options::OPT_fno_keep_system_includes, false)) {
types::ID InputType = Inputs[0].getType();
if (!isDerivedFromC(InputType))
D.Diag(diag::err_drv_opt_unsupported_input_type)
<< "-fkeep-system-includes" << types::getTypeName(InputType);
CmdArgs.push_back("-fkeep-system-includes");
}

// -fms-extensions=0 is default.
if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
IsWindowsMSVC))
Expand Down
Loading