[clang] 0c42d87 - [clang][cli] Generate and round-trip preprocessor options
Jan Svoboda via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 8 00:35:04 PST 2021
Author: Jan Svoboda
Date: 2021-02-08T09:34:55+01:00
New Revision: 0c42d87ea8e01f369d9cced7427a5ee0cca7574b
URL: https://github.com/llvm/llvm-project/commit/0c42d87ea8e01f369d9cced7427a5ee0cca7574b
DIFF: https://github.com/llvm/llvm-project/commit/0c42d87ea8e01f369d9cced7427a5ee0cca7574b.diff
LOG: [clang][cli] Generate and round-trip preprocessor options
This patch implements generation of remaining preprocessor options and tests it by performing parse-generate-parse round trip.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D95366
Added:
Modified:
clang/include/clang/Driver/Options.td
clang/lib/Frontend/CompilerInvocation.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index cbd501ca2a74..49071a4c56d9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -258,7 +258,7 @@ class CodeGenOpts<string base>
class HeaderSearchOpts<string base>
: KeyPathAndMacro<"HeaderSearchOpts->", base, "HEADER_SEARCH_"> {}
class PreprocessorOpts<string base>
- : KeyPathAndMacro<"PreprocessorOpts->", base> {}
+ : KeyPathAndMacro<"PreprocessorOpts->", base, "PREPROCESSOR_"> {}
class FileSystemOpts<string base>
: KeyPathAndMacro<"FileSystemOpts.", base> {}
class AnalyzerOpts<string base>
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index f93f10cf0988..8743da2b80ca 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3122,9 +3122,96 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
llvm_unreachable("invalid frontend action");
}
-static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
- DiagnosticsEngine &Diags,
- frontend::ActionKind Action) {
+static void GeneratePreprocessorArgs(PreprocessorOptions &Opts,
+ SmallVectorImpl<const char *> &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_VALUE, \
+ IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \
+ MERGER, TABLE_INDEX)
+#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);
@@ -3195,6 +3282,48 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
// "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<PreprocessorOptions>();
+
+ auto Parse = [Action](CompilerInvocation &Res, ArgList &Args,
+ DiagnosticsEngine &Diags) {
+ return ParsePreprocessorArgsImpl(Res.getPreprocessorOpts(), Args, Diags,
+ Action, Res.getFrontendOpts());
+ };
+
+ auto Generate = [&Args](CompilerInvocation &Res,
+ SmallVectorImpl<const char *> &GeneratedArgs,
+ CompilerInvocation::StringAllocator SA) {
+ GeneratePreprocessorArgs(Res.getPreprocessorOpts(), GeneratedArgs, SA,
+ *Res.getLangOpts(), Res.getFrontendOpts(),
+ Res.getCodeGenOpts());
+ // The ParsePreprocessorArgs function queries the -fcf-protection option,
+ // which means that it won't be directly copied during argument generation.
+ // The GeneratePreprocessorArgs function isn't responsible for generating it
+ // either. This would cause -fcf-protection to get forgotten during
+ // round-trip and the __CET__ macros wouldn't get deduced during second call
+ // to ParsePreprocessorArgs. Let's fix this by generating -fcf-protection
+ // here.
+ // TODO: Remove this once we're doing one big round-trip instead of many
+ // small ones.
+ if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ))
+ GenerateArg(GeneratedArgs, OPT_fcf_protection_EQ, A->getValue(), SA);
+ };
+
+ auto Swap = [&DummyOpts](CompilerInvocation &Res) {
+ std::swap(Res.PreprocessorOpts, DummyOpts);
+ };
+
+ return RoundTrip(Parse, Generate, Swap, Res, Args, Diags,
+ "PreprocessorOptions");
}
static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
@@ -3322,8 +3451,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
!LangOpts.Sanitize.has(SanitizerKind::Memory) &&
!LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
- ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
- Res.getFrontendOpts().ProgramAction);
+ ParsePreprocessorArgs(Res, Res.getPreprocessorOpts(), Args, Diags,
+ Res.getFrontendOpts().ProgramAction,
+ Res.getFrontendOpts());
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), Args,
Res.getFrontendOpts().ProgramAction);
@@ -3483,6 +3613,8 @@ void CompilerInvocation::generateCC1CommandLine(
#undef DIAG_OPTION_WITH_MARSHALLING
#undef OPTION_WITH_MARSHALLING
+ GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts,
+ FrontendOpts, CodeGenOpts);
GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA);
GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA);
GenerateLangArgs(*LangOpts, Args, SA);
More information about the cfe-commits
mailing list