diff --git a/flang/include/flang/Common/enum-class.h b/flang/include/flang/Common/enum-class.h index 41575d45091a8..0635a0c85be05 100644 --- a/flang/include/flang/Common/enum-class.h +++ b/flang/include/flang/Common/enum-class.h @@ -18,8 +18,8 @@ #define FORTRAN_COMMON_ENUM_CLASS_H_ #include -#include - +#include +#include namespace Fortran::common { constexpr std::size_t CountEnumNames(const char *p) { @@ -62,11 +62,19 @@ constexpr std::array EnumNames(const char *p) { enum class NAME { __VA_ARGS__ }; \ [[maybe_unused]] static constexpr std::size_t NAME##_enumSize{ \ ::Fortran::common::CountEnumNames(#__VA_ARGS__)}; \ + [[maybe_unused]] static constexpr std::array NAME##_names{ \ + ::Fortran::common::EnumNames(#__VA_ARGS__)}; \ + [[maybe_unused]] static inline std::size_t EnumToInt(NAME e) { \ + return static_cast(e); \ + } \ [[maybe_unused]] static inline std::string_view EnumToString(NAME e) { \ - static const constexpr auto names{ \ - ::Fortran::common::EnumNames(#__VA_ARGS__)}; \ - return names[static_cast(e)]; \ + return NAME##_names[static_cast(e)]; \ + } \ + [[maybe_unused]] inline void ForEach##NAME(std::function f) { \ + for (std::size_t i{0}; i < NAME##_enumSize; ++i) { \ + f(static_cast(i)); \ + } \ } - } // namespace Fortran::common #endif // FORTRAN_COMMON_ENUM_CLASS_H_ diff --git a/flang/include/flang/Common/optional.h b/flang/include/flang/Common/optional.h index c7c81f40cc8c8..72991111be577 100644 --- a/flang/include/flang/Common/optional.h +++ b/flang/include/flang/Common/optional.h @@ -28,7 +28,6 @@ #include "api-attrs.h" #include -#include #if !defined(STD_OPTIONAL_UNSUPPORTED) && \ (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__) diff --git a/flang/include/flang/Support/Fortran-features.h b/flang/include/flang/Support/Fortran-features.h index 79eaf56bdec11..3f6d825e2b66c 100644 --- a/flang/include/flang/Support/Fortran-features.h +++ b/flang/include/flang/Support/Fortran-features.h @@ -11,8 +11,7 @@ #include "Fortran.h" #include "flang/Common/enum-set.h" -#include "flang/Common/idioms.h" -#include +#include #include namespace Fortran::common { @@ -83,9 +82,6 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable, using LanguageFeatures = EnumSet; using UsageWarnings = EnumSet; -std::optional FindLanguageFeature(const char *); -std::optional FindUsageWarning(const char *); - class LanguageFeatureControl { public: LanguageFeatureControl(); @@ -98,8 +94,10 @@ class LanguageFeatureControl { void EnableWarning(UsageWarning w, bool yes = true) { warnUsage_.set(w, yes); } - void WarnOnAllNonstandard(bool yes = true) { warnAllLanguage_ = yes; } - void WarnOnAllUsage(bool yes = true) { warnAllUsage_ = yes; } + void WarnOnAllNonstandard(bool yes = true); + bool IsWarnOnAllNonstandard() const { return warnAllLanguage_; } + void WarnOnAllUsage(bool yes = true); + bool IsWarnOnAllUsage() const { return warnAllUsage_; } void DisableAllNonstandardWarnings() { warnAllLanguage_ = false; warnLanguage_.clear(); @@ -108,26 +106,59 @@ class LanguageFeatureControl { warnAllUsage_ = false; warnUsage_.clear(); } - + void DisableAllWarnings() { + disableAllWarnings_ = true; + DisableAllNonstandardWarnings(); + DisableAllUsageWarnings(); + } + bool AreWarningsDisabled() const { return disableAllWarnings_; } bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); } - bool ShouldWarn(LanguageFeature f) const { - return (warnAllLanguage_ && f != LanguageFeature::OpenMP && - f != LanguageFeature::OpenACC && f != LanguageFeature::CUDA) || - warnLanguage_.test(f); + bool ShouldWarn(LanguageFeature f) const { return warnLanguage_.test(f); } + bool ShouldWarn(UsageWarning w) const { return warnUsage_.test(w); } + // Cli options + // Take a string from the Cli and apply it to the LanguageFeatureControl. + // Return true if the option was recognized (and hence applied). + bool ApplyCliOption(std::string input); + // The add and replace functions are not currently used but are provided + // to allow a flexible many-to-one mapping from Cli spellings to enum values. + // Taking a string by value because the functions own this string after the + // call. + void AddAlternativeCliSpelling(LanguageFeature f, std::string input) { + cliOptions_.insert({input, {f}}); } - bool ShouldWarn(UsageWarning w) const { - return warnAllUsage_ || warnUsage_.test(w); + void AddAlternativeCliSpelling(UsageWarning w, std::string input) { + cliOptions_.insert({input, {w}}); } + void ReplaceCliCanonicalSpelling(LanguageFeature f, std::string input); + void ReplaceCliCanonicalSpelling(UsageWarning w, std::string input); + std::string_view getDefaultCliSpelling(LanguageFeature f) const { + return languageFeatureCliCanonicalSpelling_[EnumToInt(f)]; + }; + std::string_view getDefaultCliSpelling(UsageWarning w) const { + return usageWarningCliCanonicalSpelling_[EnumToInt(w)]; + }; // Return all spellings of operators names, depending on features enabled std::vector GetNames(LogicalOperator) const; std::vector GetNames(RelationalOperator) const; private: + // Map from Cli syntax of language features and usage warnings to their enum + // values. + std::unordered_map> + cliOptions_; + // These two arrays map the enum values to their cannonical Cli spellings. + // Since each of the CanonicalSpelling is a string in the domain of the map + // above we just use a view of the string instead of another copy. + std::array + languageFeatureCliCanonicalSpelling_; + std::array + usageWarningCliCanonicalSpelling_; LanguageFeatures disable_; LanguageFeatures warnLanguage_; bool warnAllLanguage_{false}; UsageWarnings warnUsage_; bool warnAllUsage_{false}; + bool disableAllWarnings_{false}; }; } // namespace Fortran::common #endif // FORTRAN_SUPPORT_FORTRAN_FEATURES_H_ diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 89aaee9f13853..4e1f00954226c 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -20,11 +20,9 @@ #include "flang/Support/Version.h" #include "flang/Tools/TargetSetup.h" #include "flang/Version.inc" -#include "clang/Basic/AllDiagnostics.h" #include "clang/Basic/DiagnosticDriver.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/Driver.h" -#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptionUtils.h" #include "clang/Driver/Options.h" #include "llvm/ADT/StringRef.h" @@ -35,7 +33,6 @@ #include "llvm/Option/OptTable.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/FileUtilities.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" @@ -985,10 +982,23 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args, /// Parses all diagnostics related arguments and populates the variables /// options accordingly. Returns false if new errors are generated. +/// FC1 driver entry point for parsing diagnostic arguments. static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args, clang::DiagnosticsEngine &diags) { unsigned numErrorsBefore = diags.getNumErrors(); + auto &features{res.getFrontendOpts().features}; + // The order of these flags (-pedantic -W -w) is important and is + // chosen to match clang's behavior. + + // -pedantic + if (args.hasArg(clang::driver::options::OPT_pedantic)) { + features.WarnOnAllNonstandard(); + features.WarnOnAllUsage(); + res.setEnableConformanceChecks(); + res.setEnableUsageChecks(); + } + // -Werror option // TODO: Currently throws a Diagnostic for anything other than -W, // this has to change when other -W's are supported. @@ -998,22 +1008,26 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args, for (const auto &wArg : wArgs) { if (wArg == "error") { res.setWarnAsErr(true); - } else { - const unsigned diagID = - diags.getCustomDiagID(clang::DiagnosticsEngine::Error, - "Only `-Werror` is supported currently."); - diags.Report(diagID); + // -W(no-) + } else if (!features.ApplyCliOption(wArg)) { + const unsigned diagID = diags.getCustomDiagID( + clang::DiagnosticsEngine::Error, "Unknown diagnostic option: -W%0"); + diags.Report(diagID) << wArg; } } } - // Default to off for `flang -fc1`. - res.getFrontendOpts().showColors = - parseShowColorsArgs(args, /*defaultDiagColor=*/false); - - // Honor color diagnostics. - res.getDiagnosticOpts().ShowColors = res.getFrontendOpts().showColors; + // -w + if (args.hasArg(clang::driver::options::OPT_w)) { + features.DisableAllWarnings(); + res.setDisableWarnings(); + } + // Default to off for `flang -fc1`. + bool showColors{parseShowColorsArgs(args, false)}; + diags.getDiagnosticOptions().ShowColors = showColors; + res.getDiagnosticOpts().ShowColors = showColors; + res.getFrontendOpts().showColors = showColors; return diags.getNumErrors() == numErrorsBefore; } @@ -1088,16 +1102,6 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, Fortran::common::LanguageFeature::OpenACC); } - // -pedantic - if (args.hasArg(clang::driver::options::OPT_pedantic)) { - res.setEnableConformanceChecks(); - res.setEnableUsageChecks(); - } - - // -w - if (args.hasArg(clang::driver::options::OPT_w)) - res.setDisableWarnings(); - // -std=f2018 // TODO: Set proper options when more fortran standards // are supported. @@ -1106,6 +1110,7 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args, // We only allow f2018 as the given standard if (standard == "f2018") { res.setEnableConformanceChecks(); + res.getFrontendOpts().features.WarnOnAllNonstandard(); } else { const unsigned diagID = diags.getCustomDiagID(clang::DiagnosticsEngine::Error, @@ -1712,16 +1717,7 @@ void CompilerInvocation::setFortranOpts() { if (frontendOptions.needProvenanceRangeToCharBlockMappings) fortranOptions.needProvenanceRangeToCharBlockMappings = true; - if (getEnableConformanceChecks()) - fortranOptions.features.WarnOnAllNonstandard(); - - if (getEnableUsageChecks()) - fortranOptions.features.WarnOnAllUsage(); - - if (getDisableWarnings()) { - fortranOptions.features.DisableAllNonstandardWarnings(); - fortranOptions.features.DisableAllUsageWarnings(); - } + fortranOptions.features = frontendOptions.features; } std::unique_ptr diff --git a/flang/lib/Support/Fortran-features.cpp b/flang/lib/Support/Fortran-features.cpp index bee8984102b82..08ded173de513 100644 --- a/flang/lib/Support/Fortran-features.cpp +++ b/flang/lib/Support/Fortran-features.cpp @@ -8,11 +8,68 @@ #include "flang/Support/Fortran-features.h" #include "flang/Common/idioms.h" +#include "flang/Parser/characters.h" #include "flang/Support/Fortran.h" +#include +#include namespace Fortran::common { +static std::vector SplitCamelCase(std::string_view x) { + std::vector result; + // NB, we start at 1 because the first character is never a word boundary. + size_t xSize{x.size()}, wordStart{0}, wordEnd{1}; + for (; wordEnd < xSize; ++wordEnd) { + // Identify when wordEnd is at the start of a new word. + if ((!parser::IsUpperCaseLetter(x[wordEnd - 1]) && + parser::IsUpperCaseLetter(x[wordEnd])) || + // ACCUsage => ACC-Usage, CComment => C-Comment, etc. + (parser::IsUpperCaseLetter(x[wordEnd]) && wordEnd + 1 < xSize && + parser::IsLowerCaseLetter(x[wordEnd + 1]))) { + result.push_back(x.substr(wordStart, wordEnd - wordStart)); + wordStart = wordEnd; + } + } + // We went one past the end of the last word. + result.push_back(x.substr(wordStart, wordEnd - wordStart)); + return result; +} + +// Namespace for helper functions for parsing Cli options used instead of static +// so that there can be unit tests for this function. +namespace details { +std::string CamelCaseToLowerCaseHyphenated(std::string_view x) { + std::vector words{SplitCamelCase(x)}; + std::string result{}; + result.reserve(x.size() + words.size() + 1); + for (size_t i{0}; i < words.size(); ++i) { + std::string word{parser::ToLowerCaseLetters(words[i])}; + result += i == 0 ? "" : "-"; + result += word; + } + return result; +} +} // namespace details + LanguageFeatureControl::LanguageFeatureControl() { + // Initialize the bidirectional maps with the default spellings. + cliOptions_.reserve(LanguageFeature_enumSize + UsageWarning_enumSize); + ForEachLanguageFeature([&](auto feature) { + std::string_view name{Fortran::common::EnumToString(feature)}; + std::string cliOption{details::CamelCaseToLowerCaseHyphenated(name)}; + cliOptions_.insert({cliOption, {feature}}); + languageFeatureCliCanonicalSpelling_[EnumToInt(feature)] = + std::string_view{cliOption}; + }); + + ForEachUsageWarning([&](auto warning) { + std::string_view name{Fortran::common::EnumToString(warning)}; + std::string cliOption{details::CamelCaseToLowerCaseHyphenated(name)}; + cliOptions_.insert({cliOption, {warning}}); + usageWarningCliCanonicalSpelling_[EnumToInt(warning)] = + std::string_view{cliOption}; + }); + // These features must be explicitly enabled by command line options. disable_.set(LanguageFeature::OldDebugLines); disable_.set(LanguageFeature::OpenACC); @@ -94,57 +151,40 @@ LanguageFeatureControl::LanguageFeatureControl() { warnLanguage_.set(LanguageFeature::NullActualForAllocatable); } -// Ignore case and any inserted punctuation (like '-'/'_') -static std::optional GetWarningChar(char ch) { - if (ch >= 'a' && ch <= 'z') { - return ch; - } else if (ch >= 'A' && ch <= 'Z') { - return ch - 'A' + 'a'; - } else if (ch >= '0' && ch <= '9') { - return ch; - } else { - return std::nullopt; +// Take a string from the Cli and apply it to the LanguageFeatureControl. +bool LanguageFeatureControl::ApplyCliOption(std::string input) { + bool negated{false}; + if (input.size() > 3 && input.substr(0, 3) == "no-") { + negated = true; + input = input.substr(3); } -} - -static bool WarningNameMatch(const char *a, const char *b) { - while (true) { - auto ach{GetWarningChar(*a)}; - while (!ach && *a) { - ach = GetWarningChar(*++a); - } - auto bch{GetWarningChar(*b)}; - while (!bch && *b) { - bch = GetWarningChar(*++b); - } - if (!ach && !bch) { + if (auto it{cliOptions_.find(input)}; it != cliOptions_.end()) { + if (std::holds_alternative(it->second)) { + EnableWarning(std::get(it->second), !negated); return true; - } else if (!ach || !bch || *ach != *bch) { - return false; } - ++a, ++b; - } -} - -template -std::optional ScanEnum(const char *name) { - if (name) { - for (std::size_t j{0}; j < N; ++j) { - auto feature{static_cast(j)}; - if (WarningNameMatch(name, EnumToString(feature).data())) { - return feature; - } + if (std::holds_alternative(it->second)) { + EnableWarning(std::get(it->second), !negated); + return true; } } - return std::nullopt; + return false; } -std::optional FindLanguageFeature(const char *name) { - return ScanEnum(name); +void LanguageFeatureControl::ReplaceCliCanonicalSpelling( + LanguageFeature f, std::string input) { + std::string_view &old{languageFeatureCliCanonicalSpelling_[EnumToInt(f)]}; + cliOptions_.erase(std::string{old}); + languageFeatureCliCanonicalSpelling_[EnumToInt(f)] = input; + cliOptions_.insert({input, {f}}); } -std::optional FindUsageWarning(const char *name) { - return ScanEnum(name); +void LanguageFeatureControl::ReplaceCliCanonicalSpelling( + UsageWarning w, std::string input) { + std::string_view &old{usageWarningCliCanonicalSpelling_[EnumToInt(w)]}; + cliOptions_.erase(std::string{old}); + usageWarningCliCanonicalSpelling_[EnumToInt(w)] = input; + cliOptions_.insert({input, {w}}); } std::vector LanguageFeatureControl::GetNames( @@ -201,4 +241,26 @@ std::vector LanguageFeatureControl::GetNames( } } +void LanguageFeatureControl::WarnOnAllNonstandard(bool yes) { + warnAllLanguage_ = yes; + warnLanguage_.reset(); + if (yes) { + disableAllWarnings_ = false; + warnLanguage_.flip(); + // These three features do not need to be warned about, + // but we do want their feature flags. + warnLanguage_.set(LanguageFeature::OpenMP, false); + warnLanguage_.set(LanguageFeature::OpenACC, false); + warnLanguage_.set(LanguageFeature::CUDA, false); + } +} + +void LanguageFeatureControl::WarnOnAllUsage(bool yes) { + warnAllUsage_ = yes; + warnUsage_.reset(); + if (yes) { + disableAllWarnings_ = false; + warnUsage_.flip(); + } +} } // namespace Fortran::common diff --git a/flang/test/Driver/disable-diagnostic.f90 b/flang/test/Driver/disable-diagnostic.f90 new file mode 100644 index 0000000000000..849489377da12 --- /dev/null +++ b/flang/test/Driver/disable-diagnostic.f90 @@ -0,0 +1,20 @@ +! RUN: %flang -Wknown-bad-implicit-interface %s -c 2>&1 | FileCheck %s --check-prefix=WARN +! RUN: %flang -pedantic -Wno-known-bad-implicit-interface %s -c 2>&1 | FileCheck %s --allow-empty +! RUN: not %flang -WKnownBadImplicitInterface %s -c 2>&1 | FileCheck %s --check-prefix=ERROR1 +! RUN: not %flang -WKnown-Bad-Implicit-Interface %s -c 2>&1 | FileCheck %s --check-prefix=ERROR2 + +! ERROR1: error: Unknown diagnostic option: -WKnownBadImplicitInterface +! ERROR2: error: Unknown diagnostic option: -WKnown-Bad-Implicit-Interface + +program disable_diagnostic + REAL :: x + INTEGER :: y + ! CHECK-NOT: warning + ! WARN: warning: If the procedure's interface were explicit, this reference would be in error + call sub(x) + ! WARN: warning: If the procedure's interface were explicit, this reference would be in error + call sub(y) +end program disable_diagnostic + +subroutine sub() +end subroutine sub diff --git a/flang/test/Driver/werror-wrong.f90 b/flang/test/Driver/werror-wrong.f90 index 58adf6f745d5e..6e3c7cca15bc7 100644 --- a/flang/test/Driver/werror-wrong.f90 +++ b/flang/test/Driver/werror-wrong.f90 @@ -1,6 +1,7 @@ ! Ensure that only argument -Werror is supported. -! RUN: not %flang_fc1 -fsyntax-only -Wall %s 2>&1 | FileCheck %s --check-prefix=WRONG -! RUN: not %flang_fc1 -fsyntax-only -WX %s 2>&1 | FileCheck %s --check-prefix=WRONG +! RUN: not %flang_fc1 -fsyntax-only -Wall %s 2>&1 | FileCheck %s --check-prefix=WRONG1 +! RUN: not %flang_fc1 -fsyntax-only -WX %s 2>&1 | FileCheck %s --check-prefix=WRONG2 -! WRONG: Only `-Werror` is supported currently. +! WRONG1: error: Unknown diagnostic option: -Wall +! WRONG2: error: Unknown diagnostic option: -WX diff --git a/flang/test/Driver/wextra-ok.f90 b/flang/test/Driver/wextra-ok.f90 index 441029aa0af27..db15c7f14aa35 100644 --- a/flang/test/Driver/wextra-ok.f90 +++ b/flang/test/Driver/wextra-ok.f90 @@ -5,7 +5,7 @@ ! RUN: not %flang -std=f2018 -Wblah -Wextra %s -c 2>&1 | FileCheck %s --check-prefix=WRONG ! CHECK-OK: the warning option '-Wextra' is not supported -! WRONG: Only `-Werror` is supported currently. +! WRONG: Unknown diagnostic option: -Wblah program wextra_ok end program wextra_ok diff --git a/flang/unittests/Common/CMakeLists.txt b/flang/unittests/Common/CMakeLists.txt index bda02ed29a5ef..3149cb9f7bc47 100644 --- a/flang/unittests/Common/CMakeLists.txt +++ b/flang/unittests/Common/CMakeLists.txt @@ -1,3 +1,6 @@ add_flang_unittest(FlangCommonTests + EnumClassTests.cpp FastIntSetTest.cpp + FortranFeaturesTest.cpp ) +target_link_libraries(FlangCommonTests PRIVATE FortranSupport) diff --git a/flang/unittests/Common/EnumClassTests.cpp b/flang/unittests/Common/EnumClassTests.cpp new file mode 100644 index 0000000000000..eafba542a3b84 --- /dev/null +++ b/flang/unittests/Common/EnumClassTests.cpp @@ -0,0 +1,34 @@ +//===-- flang/unittests/Common/FastIntSetTest.cpp ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "flang/Common/enum-class.h" + +namespace Fortran::common { + +ENUM_CLASS(TestEnum, One, Two, Three) + +TEST(EnumClassTest, EnumToString) { + ASSERT_EQ(EnumToString(TestEnum::One), "One"); + ASSERT_EQ(EnumToString(TestEnum::Two), "Two"); + ASSERT_EQ(EnumToString(TestEnum::Three), "Three"); +} + +TEST(EnumClassTest, EnumClassForEach) { + std::string result; + bool first{true}; + ForEachTestEnum([&](auto e) { + if (!first) { + result += ", "; + } + result += EnumToString(e); + first = false; + }); + ASSERT_EQ(result, "One, Two, Three"); +} +} // namespace Fortran::common diff --git a/flang/unittests/Common/FortranFeaturesTest.cpp b/flang/unittests/Common/FortranFeaturesTest.cpp new file mode 100644 index 0000000000000..afd677f69a165 --- /dev/null +++ b/flang/unittests/Common/FortranFeaturesTest.cpp @@ -0,0 +1,561 @@ +//===-- flang/unittests/Common/FastIntSetTest.cpp ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "flang/Support/Fortran-features.h" + +namespace Fortran::common::details { + +std::string CamelCaseToLowerCaseHyphenated(std::string_view x); + +TEST(FortranFeaturesTest, CamelCaseToLowerCaseHyphenated) { + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BackslashEscapes)), + "backslash-escapes"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OldDebugLines)), + "old-debug-lines"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::FixedFormContinuationWithColumn1Ampersand)), + "fixed-form-continuation-with-column1-ampersand"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::LogicalAbbreviations)), + "logical-abbreviations"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::XOROperator)), + "xor-operator"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::PunctuationInNames)), + "punctuation-in-names"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OptionalFreeFormSpace)), + "optional-free-form-space"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BOZExtensions)), + "boz-extensions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EmptyStatement)), + "empty-statement"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AlternativeNE)), + "alternative-ne"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ExecutionPartNamelist)), + "execution-part-namelist"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DECStructures)), + "dec-structures"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DoubleComplex)), + "double-complex"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Byte)), + "byte"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::StarKind)), + "star-kind"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ExponentMatchingKindParam)), + "exponent-matching-kind-param"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::QuadPrecision)), + "quad-precision"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SlashInitialization)), + "slash-initialization"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::TripletInArrayConstructor)), + "triplet-in-array-constructor"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::MissingColons)), + "missing-colons"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SignedComplexLiteral)), + "signed-complex-literal"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OldStyleParameter)), + "old-style-parameter"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ComplexConstructor)), + "complex-constructor"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::PercentLOC)), + "percent-loc"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SignedMultOperand)), + "signed-mult-operand"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::FileName)), + "file-name"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::Carriagecontrol)), + "carriagecontrol"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Convert)), + "convert"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Dispose)), + "dispose"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::IOListLeadingComma)), + "io-list-leading-comma"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AbbreviatedEditDescriptor)), + "abbreviated-edit-descriptor"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ProgramParentheses)), + "program-parentheses"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::PercentRefAndVal)), + "percent-ref-and-val"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OmitFunctionDummies)), + "omit-function-dummies"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::CrayPointer)), + "cray-pointer"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Hollerith)), + "hollerith"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ArithmeticIF)), + "arithmetic-if"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Assign)), + "assign"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AssignedGOTO)), + "assigned-goto"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Pause)), + "pause"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::OpenACC)), + "open-acc"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::OpenMP)), + "open-mp"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::CUDA)), + "cuda"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::CruftAfterAmpersand)), + "cruft-after-ampersand"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ClassicCComments)), + "classic-c-comments"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AdditionalFormats)), + "additional-formats"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BigIntLiterals)), + "big-int-literals"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::RealDoControls)), + "real-do-controls"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EquivalenceNumericWithCharacter)), + "equivalence-numeric-with-character"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EquivalenceNonDefaultNumeric)), + "equivalence-non-default-numeric"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EquivalenceSameNonSequence)), + "equivalence-same-non-sequence"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AdditionalIntrinsics)), + "additional-intrinsics"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AnonymousParents)), + "anonymous-parents"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OldLabelDoEndStatements)), + "old-label-do-end-statements"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::LogicalIntegerAssignment)), + "logical-integer-assignment"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EmptySourceFile)), + "empty-source-file"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ProgramReturn)), + "program-return"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ImplicitNoneTypeNever)), + "implicit-none-type-never"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ImplicitNoneTypeAlways)), + "implicit-none-type-always"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ImplicitNoneExternal)), + "implicit-none-external"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ForwardRefImplicitNone)), + "forward-ref-implicit-none"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OpenAccessAppend)), + "open-access-append"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BOZAsDefaultInteger)), + "boz-as-default-integer"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DistinguishableSpecifics)), + "distinguishable-specifics"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DefaultSave)), + "default-save"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::PointerInSeqType)), + "pointer-in-seq-type"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::NonCharacterFormat)), + "non-character-format"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SaveMainProgram)), + "save-main-program"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SaveBigMainProgramVariables)), + "save-big-main-program-variables"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DistinctArrayConstructorLengths)), + "distinct-array-constructor-lengths"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::PPCVector)), + "ppc-vector"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::RelaxedIntentInChecking)), + "relaxed-intent-in-checking"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ForwardRefImplicitNoneData)), + "forward-ref-implicit-none-data"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::NullActualForAllocatable)), + "null-actual-for-allocatable"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::ActualIntegerConvertedToSmallerKind)), + "actual-integer-converted-to-smaller-kind"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::HollerithOrCharacterAsBOZ)), + "hollerith-or-character-as-boz"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BindingAsProcedure)), + "binding-as-procedure"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::StatementFunctionExtensions)), + "statement-function-extensions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::UseGenericIntrinsicWhenSpecificDoesntMatch)), + "use-generic-intrinsic-when-specific-doesnt-match"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DataStmtExtensions)), + "data-stmt-extensions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::RedundantContiguous)), + "redundant-contiguous"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::RedundantAttribute)), + "redundant-attribute"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::InitBlankCommon)), + "init-blank-common"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EmptyBindCDerivedType)), + "empty-bind-c-derived-type"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::MiscSourceExtensions)), + "misc-source-extensions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AllocateToOtherLength)), + "allocate-to-other-length"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::LongNames)), + "long-names"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::IntrinsicAsSpecific)), + "intrinsic-as-specific"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BenignNameClash)), + "benign-name-clash"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BenignRedundancy)), + "benign-redundancy"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::NullMoldAllocatableComponentValue)), + "null-mold-allocatable-component-value"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::NopassScalarBase)), + "nopass-scalar-base"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::MiscUseExtensions)), + "misc-use-extensions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ImpliedDoIndexScope)), + "implied-do-index-scope"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::DistinctCommonSizes)), + "distinct-common-sizes"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::OddIndexVariableRestrictions)), + "odd-index-variable-restrictions"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::IndistinguishableSpecifics)), + "indistinguishable-specifics"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SubroutineAndFunctionSpecifics)), + "subroutine-and-function-specifics"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::EmptySequenceType)), + "empty-sequence-type"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::NonSequenceCrayPointee)), + "non-sequence-cray-pointee"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BranchIntoConstruct)), + "branch-into-construct"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::BadBranchTarget)), + "bad-branch-target"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::HollerithPolymorphic)), + "hollerith-polymorphic"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ListDirectedSize)), + "list-directed-size"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::NonBindCInteroperability)), + "non-bind-c-interoperability"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::CudaManaged)), + "cuda-managed"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::CudaUnified)), + "cuda-unified"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature:: + PolymorphicActualAllocatableOrPointerToMonomorphicDummy)), + "polymorphic-actual-allocatable-or-pointer-to-monomorphic-dummy"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::RelaxedPureDummy)), + "relaxed-pure-dummy"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::UndefinableAsynchronousOrVolatileActual)), + "undefinable-asynchronous-or-volatile-actual"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AutomaticInMainProgram)), + "automatic-in-main-program"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::PrintCptr)), + "print-cptr"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::SavedLocalInSpecExpr)), + "saved-local-in-spec-expr"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::PrintNamelist)), + "print-namelist"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + LanguageFeature::AssumedRankPassedToNonAssumedRank)), + "assumed-rank-passed-to-non-assumed-rank"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::IgnoreIrrelevantAttributes)), + "ignore-irrelevant-attributes"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(LanguageFeature::Unsigned)), + "unsigned"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::AmbiguousStructureConstructor)), + "ambiguous-structure-constructor"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ContiguousOkForSeqAssociation)), + "contiguous-ok-for-seq-association"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(LanguageFeature::ForwardRefExplicitTypeDummy)), + "forward-ref-explicit-type-dummy"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::Portability)), + "portability"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::PointerToUndefinable)), + "pointer-to-undefinable"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::NonTargetPassedToTarget)), + "non-target-passed-to-target"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::PointerToPossibleNoncontiguous)), + "pointer-to-possible-noncontiguous"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ShortCharacterActual)), + "short-character-actual"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ShortArrayActual)), + "short-array-actual"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ImplicitInterfaceActual)), + "implicit-interface-actual"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::PolymorphicTransferArg)), + "polymorphic-transfer-arg"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::PointerComponentTransferArg)), + "pointer-component-transfer-arg"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::TransferSizePresence)), + "transfer-size-presence"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::F202XAllocatableBreakingChange)), + "f202-x-allocatable-breaking-change"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::OptionalMustBePresent)), + "optional-must-be-present"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::CommonBlockPadding)), + "common-block-padding"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::LogicalVsCBool)), + "logical-vs-c-bool"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::BindCCharLength)), + "bind-c-char-length"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ProcDummyArgShapes)), + "proc-dummy-arg-shapes"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ExternalNameConflict)), + "external-name-conflict"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::FoldingException)), + "folding-exception"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::FoldingAvoidsRuntimeCrash)), + "folding-avoids-runtime-crash"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::FoldingValueChecks)), + "folding-value-checks"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::FoldingFailure)), + "folding-failure"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::FoldingLimit)), + "folding-limit"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::Interoperability)), + "interoperability"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::CharacterInteroperability)), + "character-interoperability"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::Bounds)), + "bounds"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::Preprocessing)), + "preprocessing"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::Scanning)), + "scanning"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::OpenAccUsage)), + "open-acc-usage"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ProcPointerCompatibility)), + "proc-pointer-compatibility"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::VoidMold)), + "void-mold"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::KnownBadImplicitInterface)), + "known-bad-implicit-interface"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::EmptyCase)), + "empty-case"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::CaseOverflow)), + "case-overflow"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::CUDAUsage)), + "cuda-usage"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::IgnoreTKRUsage)), + "ignore-tkr-usage"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ExternalInterfaceMismatch)), + "external-interface-mismatch"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::DefinedOperatorArgs)), + "defined-operator-args"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::Final)), + "final"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::ZeroDoStep)), + "zero-do-step"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::UnusedForallIndex)), + "unused-forall-index"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::OpenMPUsage)), + "open-mp-usage"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::DataLength)), + "data-length"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::IgnoredDirective)), + "ignored-directive"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::HomonymousSpecific)), + "homonymous-specific"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::HomonymousResult)), + "homonymous-result"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::IgnoredIntrinsicFunctionType)), + "ignored-intrinsic-function-type"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::PreviousScalarUse)), + "previous-scalar-use"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::RedeclaredInaccessibleComponent)), + "redeclared-inaccessible-component"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::ImplicitShared)), + "implicit-shared"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::IndexVarRedefinition)), + "index-var-redefinition"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::IncompatibleImplicitInterfaces)), + "incompatible-implicit-interfaces"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::VectorSubscriptFinalization)), + "vector-subscript-finalization"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::UndefinedFunctionResult)), + "undefined-function-result"); + EXPECT_EQ( + CamelCaseToLowerCaseHyphenated(EnumToString(UsageWarning::UselessIomsg)), + "useless-iomsg"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::MismatchingDummyProcedure)), + "mismatching-dummy-procedure"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::SubscriptedEmptyArray)), + "subscripted-empty-array"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::UnsignedLiteralTruncation)), + "unsigned-literal-truncation"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + UsageWarning::CompatibleDeclarationsFromDistinctModules)), + "compatible-declarations-from-distinct-modules"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + UsageWarning::NullActualForDefaultIntentAllocatable)), + "null-actual-for-default-intent-allocatable"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated(EnumToString( + UsageWarning::UseAssociationIntoSameNameSubprogram)), + "use-association-into-same-name-subprogram"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::HostAssociatedIntentOutInSpecExpr)), + "host-associated-intent-out-in-spec-expr"); + EXPECT_EQ(CamelCaseToLowerCaseHyphenated( + EnumToString(UsageWarning::NonVolatilePointerToVolatile)), + "non-volatile-pointer-to-volatile"); +} + +} // namespace Fortran::common::details