[llvm] 77db83a - [clang][cli] Allow users to specify a conditional to prevent parsing options with MarshallingInfo
Jan Svoboda via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 7 01:02:35 PST 2021
Author: Jan Svoboda
Date: 2021-01-07T10:01:49+01:00
New Revision: 77db83ae997767400ffcbe0101f8ee867ebaa111
URL: https://github.com/llvm/llvm-project/commit/77db83ae997767400ffcbe0101f8ee867ebaa111
DIFF: https://github.com/llvm/llvm-project/commit/77db83ae997767400ffcbe0101f8ee867ebaa111.diff
LOG: [clang][cli] Allow users to specify a conditional to prevent parsing options with MarshallingInfo
Depends on D84189 & D93540.
Reviewed By: Bigcheese
Differential Revision: https://reviews.llvm.org/D84674
Added:
Modified:
clang/include/clang/Driver/Options.td
clang/lib/Frontend/CompilerInvocation.cpp
clang/unittests/Frontend/CompilerInvocationTest.cpp
llvm/include/llvm/Option/OptParser.td
llvm/utils/TableGen/OptParserEmitter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 428c14a7d9bb..33b5cd09004e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4091,7 +4091,9 @@ defm sycl : BoolOption<"sycl",
BothFlags<[CoreOption], " SYCL kernels compilation for device">, "f">,
Group<sycl_Group>;
def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>, Flags<[CC1Option, NoArgumentUnused, CoreOption]>,
- HelpText<"SYCL language standard to compile for.">, Values<"2017, 121, 1.2.1, sycl-1.2.1">;
+ HelpText<"SYCL language standard to compile for.">, Values<"2017,121,1.2.1,sycl-1.2.1">,
+ NormalizedValues<["SYCL_2017", "SYCL_2017", "SYCL_2017", "SYCL_2017"]>, NormalizedValuesScope<"LangOptions">,
+ MarshallingInfoString<"LangOpts->SYCLVersion", "SYCL_None">, ShouldParseIf<fsycl.KeyPath>, AutoNormalizeEnum;
//===----------------------------------------------------------------------===//
// FlangOption and FC1 Options
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 57027cea5659..962f72963cd2 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2282,23 +2282,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
}
Opts.SYCLIsDevice = Opts.SYCL && Args.hasArg(options::OPT_fsycl_is_device);
- if (Opts.SYCL) {
- // -sycl-std applies to any SYCL source, not only those containing kernels,
- // but also those using the SYCL API
- if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) {
- Opts.setSYCLVersion(
- llvm::StringSwitch<LangOptions::SYCLMajorVersion>(A->getValue())
- .Cases("2017", "1.2.1", "121", "sycl-1.2.1",
- LangOptions::SYCL_2017)
- .Default(LangOptions::SYCL_None));
-
- if (Opts.getSYCLVersion() == LangOptions::SYCL_None) {
- // User has passed an invalid value to the flag, this is an error
- Diags.Report(diag::err_drv_invalid_value)
- << A->getAsString(Args) << A->getValue();
- }
- }
- }
llvm::Triple T(TargetOpts.Triple);
CompilerInvocation::setLangDefaults(Opts, IK, T, PPOpts, LangStd);
@@ -3003,16 +2986,17 @@ bool CompilerInvocation::parseSimpleArgs(const ArgList &Args,
DiagnosticsEngine &Diags) {
#define OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
- IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
- TABLE_INDEX) \
+ HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
+ DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
+ MERGER, EXTRACTOR, TABLE_INDEX) \
if ((FLAGS)&options::CC1Option) { \
this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \
if (IMPLIED_CHECK) \
this->KEYPATH = MERGER(this->KEYPATH, IMPLIED_VALUE); \
- if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \
- this->KEYPATH = MERGER( \
- this->KEYPATH, static_cast<decltype(this->KEYPATH)>(*MaybeValue)); \
+ if (SHOULD_PARSE) \
+ if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \
+ this->KEYPATH = MERGER( \
+ this->KEYPATH, static_cast<decltype(this->KEYPATH)>(*MaybeValue)); \
}
#include "clang/Driver/Options.inc"
@@ -3265,9 +3249,9 @@ void CompilerInvocation::generateCC1CommandLine(
// with lifetime extension of the reference.
#define OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
- IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
- TABLE_INDEX) \
+ HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
+ DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
+ MERGER, EXTRACTOR, TABLE_INDEX) \
if ((FLAGS)&options::CC1Option) { \
[&](const auto &Extracted) { \
if (ALWAYS_EMIT || \
diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp
index 8960e263df11..89d9c88cc604 100644
--- a/clang/unittests/Frontend/CompilerInvocationTest.cpp
+++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp
@@ -448,6 +448,68 @@ TEST_F(CommandLineTest, StringVectorMultiple) {
ASSERT_EQ(count(GeneratedArgs, StringRef("-fmodule-map-file=b")), 1);
}
+// A flag that should be parsed only if a condition is met.
+
+TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagNotPresent) {
+ const char *Args[] = {""};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_FALSE(Invocation.getLangOpts()->SYCL);
+ ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl"))));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
+}
+
+TEST_F(CommandLineTest, ConditionalParsingIfFalseFlagPresent) {
+ const char *Args[] = {"-sycl-std=2017"};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_FALSE(Invocation.getLangOpts()->SYCL);
+ ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fsycl"))));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
+}
+
+TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagNotPresent) {
+ const char *Args[] = {"-fsycl"};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_TRUE(Invocation.getLangOpts()->SYCL);
+ ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_None);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl")));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(HasSubstr("-sycl-std="))));
+}
+
+TEST_F(CommandLineTest, ConditionalParsingIfTrueFlagPresent) {
+ const char *Args[] = {"-fsycl", "-sycl-std=2017"};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_TRUE(Invocation.getLangOpts()->SYCL);
+ ASSERT_EQ(Invocation.getLangOpts()->getSYCLVersion(), LangOptions::SYCL_2017);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fsycl")));
+ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-sycl-std=2017")));
+}
+
// Wide integer option.
TEST_F(CommandLineTest, WideIntegerHighValue) {
diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td
index e1139d6c02fa..17cdb159e3f7 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -101,6 +101,7 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
code DefaultValue = ?;
code ImpliedValue = ?;
code ImpliedCheck = "false";
+ code ShouldParse = "true";
bit ShouldAlwaysEmit = false;
code NormalizerRetTy = ?;
code NormalizedValuesScope = "";
@@ -202,6 +203,7 @@ class MarshallingInfoBooleanFlag<code keypath, code defaultvalue, code value, co
// Mixins for additional marshalling attributes.
+class ShouldParseIf<code condition> { code ShouldParse = condition; }
class AlwaysEmit { bit ShouldAlwaysEmit = true; }
class Normalizer<code normalizer> { code Normalizer = normalizer; }
class Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp
index a08a837e5e70..2869ff60777c 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -71,6 +71,7 @@ class MarshallingInfo {
StringRef NormalizedValuesScope;
StringRef ImpliedCheck;
StringRef ImpliedValue;
+ StringRef ShouldParse;
StringRef Normalizer;
StringRef Denormalizer;
StringRef ValueMerger;
@@ -102,6 +103,8 @@ struct SimpleEnumValueTable {
void emit(raw_ostream &OS) const {
write_cstring(OS, StringRef(getOptionSpelling(R)));
OS << ", ";
+ OS << ShouldParse;
+ OS << ", ";
OS << ShouldAlwaysEmit;
OS << ", ";
OS << KeyPath;
@@ -167,6 +170,7 @@ static MarshallingInfo createMarshallingInfo(const Record &R) {
Ret.ImpliedValue =
R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret.DefaultValue);
+ Ret.ShouldParse = R.getValueAsString("ShouldParse");
Ret.Normalizer = R.getValueAsString("Normalizer");
Ret.Denormalizer = R.getValueAsString("Denormalizer");
Ret.ValueMerger = R.getValueAsString("ValueMerger");
More information about the llvm-commits
mailing list