[PATCH] D95366: [clang][cli] Generate and round-trip preprocessor options
This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG0c42d87ea8e0: [clang][cli] Generate and round-trip preprocessor options (authored by jansvoboda11). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95366/new/ https://reviews.llvm.org/D95366 Files: clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp Index: clang/lib/Frontend/CompilerInvocation.cpp === --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3122,9 +3122,96 @@ llvm_unreachable("invalid frontend action"); } -static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, - DiagnosticsEngine &Diags, - frontend::ActionKind Action) { +static void GeneratePreprocessorArgs(PreprocessorOptions &Opts, + SmallVectorImpl &Args, + CompilerInvocation::StringAllocator SA, + const LangOptions &LangOpts, + const FrontendOptions &FrontendOpts, + const CodeGenOptions &CodeGenOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING( \ +PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,\ +HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ +DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ +MERGER, EXTRACTOR, TABLE_INDEX)\ + GENERATE_OPTION_WITH_MARSHALLING(\ + Args, SA, KIND, FLAGS, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE,\ + IMPLIED_CHECK, IMPLIED_VALUE, DENORMALIZER, EXTRACTOR, TABLE_INDEX) +#include "clang/Driver/Options.inc" +#undef PREPROCESSOR_OPTION_WITH_MARSHALLING + + if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate) +GenerateArg(Args, OPT_pch_through_hdrstop_use, SA); + + for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) +GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); + + for (const auto &MP : Opts.MacroPrefixMap) +GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); + + if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false)) +GenerateArg(Args, OPT_preamble_bytes_EQ, +Twine(Opts.PrecompiledPreambleBytes.first) + "," + +(Opts.PrecompiledPreambleBytes.second ? "1" : "0"), +SA); + + for (const auto &M : Opts.Macros) { +// Don't generate __CET__ macro definitions. They are implied by the +// -fcf-protection option that is generated elsewhere. +if (M.first == "__CET__=1" && !M.second && +!CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn && +!CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn && +CodeGenOpts.CFProtectionBranch) + continue; + +GenerateArg(Args, M.second ? OPT_U : OPT_D, M.first, SA); + } + + for (const auto &I : Opts.Includes) { +// Don't generate OpenCL includes. They are implied by other flags that are +// generated elsewhere. +if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader && +((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") || + I == "opencl-c.h")) + continue; + +GenerateArg(Args, OPT_include, I, SA); + } + + for (const auto &CI : Opts.ChainedIncludes) +GenerateArg(Args, OPT_chain_include, CI, SA); + + for (const auto &RF : Opts.RemappedFiles) +GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA); + + // Don't handle LexEditorPlaceholders. It is implied by the action that is + // generated elsewhere. +} + +static bool ParsePreprocessorArgsImpl(PreprocessorOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags, + frontend::ActionKind Action, + const FrontendOptions &FrontendOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + bool Success = true; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING( \ +PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,\ +HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ +DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ +MERGER, EXTRACTOR, TABLE_INDEX)\ + PARSE_OP
[PATCH] D95366: [clang][cli] Generate and round-trip preprocessor options
jansvoboda11 updated this revision to Diff 320344. jansvoboda11 added a comment. Rebase, rename parse function Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95366/new/ https://reviews.llvm.org/D95366 Files: clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp Index: clang/lib/Frontend/CompilerInvocation.cpp === --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3100,9 +3100,96 @@ llvm_unreachable("invalid frontend action"); } -static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, - DiagnosticsEngine &Diags, - frontend::ActionKind Action) { +static void GeneratePreprocessorArgs(PreprocessorOptions &Opts, + SmallVectorImpl &Args, + CompilerInvocation::StringAllocator SA, + const LangOptions &LangOpts, + const FrontendOptions &FrontendOpts, + const CodeGenOptions &CodeGenOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING( \ +PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,\ +HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ +DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ +MERGER, EXTRACTOR, TABLE_INDEX)\ + GENERATE_OPTION_WITH_MARSHALLING(\ + Args, SA, KIND, FLAGS, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE,\ + IMPLIED_CHECK, IMPLIED_VALUE, DENORMALIZER, EXTRACTOR, TABLE_INDEX) +#include "clang/Driver/Options.inc" +#undef PREPROCESSOR_OPTION_WITH_MARSHALLING + + if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate) +GenerateArg(Args, OPT_pch_through_hdrstop_use, SA); + + for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) +GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); + + for (const auto &MP : Opts.MacroPrefixMap) +GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); + + if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false)) +GenerateArg(Args, OPT_preamble_bytes_EQ, +Twine(Opts.PrecompiledPreambleBytes.first) + "," + +(Opts.PrecompiledPreambleBytes.second ? "1" : "0"), +SA); + + for (const auto &M : Opts.Macros) { +// Don't generate __CET__ macro definitions. They are implied by the +// -fcf-protection option that is generated elsewhere. +if (M.first == "__CET__=1" && !M.second && +!CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn && +!CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn && +CodeGenOpts.CFProtectionBranch) + continue; + +GenerateArg(Args, M.second ? OPT_U : OPT_D, M.first, SA); + } + + for (const auto &I : Opts.Includes) { +// Don't generate OpenCL includes. They are implied by other flags that are +// generated elsewhere. +if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader && +((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") || + I == "opencl-c.h")) + continue; + +GenerateArg(Args, OPT_include, I, SA); + } + + for (const auto &CI : Opts.ChainedIncludes) +GenerateArg(Args, OPT_chain_include, CI, SA); + + for (const auto &RF : Opts.RemappedFiles) +GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA); + + // Don't handle LexEditorPlaceholders. It is implied by the action that is + // generated elsewhere. +} + +static bool ParsePreprocessorArgsImpl(PreprocessorOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags, + frontend::ActionKind Action, + const FrontendOptions &FrontendOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + bool Success = true; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING( \ +PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,\ +HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \ +DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \ +MERGER, EXTRACTOR, TABLE_INDEX)\ + PARSE_OPTION_WITH_MARSHALLING(Args, Diags, Success, ID, FLAGS, PARAM,\ +SHOULD_PARSE, KEYPATH, DEFAULT_VA
[PATCH] D95366: [clang][cli] Generate and round-trip preprocessor options
jansvoboda11 updated this revision to Diff 320119. jansvoboda11 edited the summary of this revision. jansvoboda11 added a comment. Rename variable Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95366/new/ https://reviews.llvm.org/D95366 Files: clang/include/clang/Driver/Options.td clang/lib/Frontend/CompilerInvocation.cpp Index: clang/lib/Frontend/CompilerInvocation.cpp === --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3053,9 +3053,83 @@ llvm_unreachable("invalid frontend action"); } -static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, +static void GeneratePreprocessorArgs(PreprocessorOptions &Opts, + SmallVectorImpl &Args, + CompilerInvocation::StringAllocator SA, + const LangOptions &LangOpts, + const FrontendOptions &FrontendOpts, + const CodeGenOptions &CodeGenOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \ + GENERATE_OPTION_WITH_MARSHALLING(Args, SA, NO_PREFIX, __VA_ARGS__) +#include "clang/Driver/Options.inc" +#undef PREPROCESSOR_OPTION_WITH_MARSHALLING + + if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate) +GenerateArg(Args, OPT_pch_through_hdrstop_use, SA); + + for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) +GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); + + for (const auto &MP : Opts.MacroPrefixMap) +GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); + + if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false)) +GenerateArg(Args, OPT_preamble_bytes_EQ, +Twine(Opts.PrecompiledPreambleBytes.first) + "," + +(Opts.PrecompiledPreambleBytes.second ? "1" : "0"), +SA); + + for (const auto &M : Opts.Macros) { +// Don't generate __CET__ macro definitions. They are implied by the +// -fcf-protection option that is generated elsewhere. +if (M.first == "__CET__=1" && !M.second && +!CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn && +!CodeGenOpts.CFProtectionBranch) + continue; +if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn && +CodeGenOpts.CFProtectionBranch) + continue; + +GenerateArg(Args, M.second ? OPT_U : OPT_D, M.first, SA); + } + + for (const auto &I : Opts.Includes) { +// Don't generate OpenCL includes. They are implied by other flags that are +// generated elsewhere. +if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader && +((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") || + I == "opencl-c.h")) + continue; + +GenerateArg(Args, OPT_include, I, SA); + } + + for (const auto &CI : Opts.ChainedIncludes) +GenerateArg(Args, OPT_chain_include, CI, SA); + + for (const auto &RF : Opts.RemappedFiles) +GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA); + + // Don't handle LexEditorPlaceholders. It is implied by the action that is + // generated elsewhere. +} + +static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, - frontend::ActionKind Action) { + frontend::ActionKind Action, + const FrontendOptions &FrontendOpts) { + PreprocessorOptions *PreprocessorOpts = &Opts; + bool Success = true; + +#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \ + PARSE_OPTION_WITH_MARSHALLING(Args, Diags, Success, NO_PREFIX, __VA_ARGS__) +#include "clang/Driver/Options.inc" +#undef PREPROCESSOR_OPTION_WITH_MARSHALLING + Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) || Args.hasArg(OPT_pch_through_hdrstop_use); @@ -3126,6 +3200,48 @@ // "editor placeholder in source file" error in PP only mode. if (isStrictlyPreprocessorAction(Action)) Opts.LexEditorPlaceholders = false; + + return Success; +} + +static bool ParsePreprocessorArgs(CompilerInvocation &Res, + PreprocessorOptions &Opts, ArgList &Args, + DiagnosticsEngine &Diags, + frontend::ActionKind Action, + FrontendOptions &FrontendOpts) { + auto DummyOpts = std::make_shared(); + + auto Parse = [Action](CompilerInvocation &Res, ArgList &Args, +DiagnosticsEngine &Diags) { +return ::ParseP
[PATCH] D95366: [clang][cli] Generate and round-trip preprocessor options
jansvoboda11 added inline comments. Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3093 + +static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, dexonsmith wrote: > Can we name this differently, so it's obvious which is being called without > looking at the argument list? I suggest `ParsePreprocessorArgsImpl` for this > one, since it's doing the actual parsing. I thought about it and decided to keep it the same. We'd be renaming it back to `ParsePreprocessorArgs` in a few weeks, when we round-trip the whole CompilerInvocation at once and the need for the fine-grained interposed functions disappears. Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3215-3216 + + return RoundTrip(Parse, Generate, Swap, Res, Args, Diags, + "PreprocessorOptions"); } dexonsmith wrote: > Have you considered just defining the lambdas inline in the call to > `RoundTrip`? I'm fine either way, but the way clang-format tends to clean > this up seems pretty readable to me, and the names don't really add much > value since they match the functions being called. Up to you. In this case, where one of the lambdas contains a long comment, I suggest keeping it separate. It's easier to read that way. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95366/new/ https://reviews.llvm.org/D95366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D95366: [clang][cli] Generate and round-trip preprocessor options
dexonsmith accepted this revision. dexonsmith added a comment. This revision is now accepted and ready to land. LGTM. Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3093 + +static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, Can we name this differently, so it's obvious which is being called without looking at the argument list? I suggest `ParsePreprocessorArgsImpl` for this one, since it's doing the actual parsing. Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3215-3216 + + return RoundTrip(Parse, Generate, Swap, Res, Args, Diags, + "PreprocessorOptions"); } Have you considered just defining the lambdas inline in the call to `RoundTrip`? I'm fine either way, but the way clang-format tends to clean this up seems pretty readable to me, and the names don't really add much value since they match the functions being called. Up to you. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95366/new/ https://reviews.llvm.org/D95366 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits