jansvoboda11 updated this revision to Diff 312785. jansvoboda11 added a comment.
Rebase, add tests Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D84674/new/ https://reviews.llvm.org/D84674 Files: 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
Index: llvm/utils/TableGen/OptParserEmitter.cpp =================================================================== --- llvm/utils/TableGen/OptParserEmitter.cpp +++ llvm/utils/TableGen/OptParserEmitter.cpp @@ -71,6 +71,7 @@ StringRef NormalizedValuesScope; StringRef ImpliedCheck; StringRef ImpliedValue; + StringRef ShouldParse; StringRef Normalizer; StringRef Denormalizer; StringRef ValueMerger; @@ -102,6 +103,8 @@ 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 @@ 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"); Index: llvm/include/llvm/Option/OptParser.td =================================================================== --- llvm/include/llvm/Option/OptParser.td +++ llvm/include/llvm/Option/OptParser.td @@ -101,6 +101,7 @@ code DefaultValue = ?; code ImpliedValue = ?; code ImpliedCheck = "false"; + code ShouldParse = "true"; bit ShouldAlwaysEmit = false; code NormalizerRetTy = ?; code NormalizedValuesScope = ""; @@ -193,6 +194,7 @@ class IsNegative { code Normalizer = "normalizeSimpleNegativeFlag"; } +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; } Index: clang/unittests/Frontend/CompilerInvocationTest.cpp =================================================================== --- clang/unittests/Frontend/CompilerInvocationTest.cpp +++ clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -19,6 +19,7 @@ using ::testing::Contains; using ::testing::StrEq; +using ::testing::HasSubstr; namespace { class CommandLineTest : public ::testing::Test { @@ -408,6 +409,68 @@ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("legacy")))); } +// 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"))); +} + // Tree of boolean options that can be (directly or transitively) implied by // their parent: // Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2273,23 +2273,6 @@ } 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); @@ -2997,16 +2980,17 @@ 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" @@ -3259,9 +3243,9 @@ // 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 || \ Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -4091,7 +4091,9 @@ 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits