diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -554,7 +554,7 @@ NormalizedValuesScope<"FrontendOptions">, NormalizedValues<["ARCMT_Check", "ARCMT_Modify", "ARCMT_Migrate"]>, MarshallingInfoString<"FrontendOpts.ARCMTAction", "ARCMT_None">, - AutoNormalizeEnumJoined; + AutoNormalizeEnum; def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">, MarshallingInfoFlag<"FrontendOpts.ShowStats", "false">; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -143,7 +143,8 @@ void denormalizeSimpleFlag(SmallVectorImpl &Args, const char *Spelling, CompilerInvocation::StringAllocator SA, - unsigned TableIndex, T Value) { + Option::OptionClass OptClass, unsigned TableIndex, + T Value) { Args.push_back(Spelling); } @@ -177,6 +178,38 @@ Args.push_back(NegSpelling); } +static Optional normalizeString(OptSpecifier Opt, int TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + return std::string(Arg->getValue()); +} + +template +static void denormalizeString(SmallVectorImpl &Args, + const char *Spelling, + CompilerInvocation::StringAllocator SA, + Option::OptionClass OptClass, unsigned TableIndex, + T &&Value) { + static_assert(std::is_constructible::value, + "Cannot convert this value to Twine"); + switch (OptClass) { + case Option::SeparateClass: + case Option::JoinedOrSeparateClass: + Args.push_back(Spelling); + Args.push_back(SA(Twine(std::forward(Value)))); + break; + case Option::JoinedClass: + Args.push_back(SA(Twine(Spelling) + Twine(std::forward(Value)))); + break; + default: + llvm_unreachable("Cannot denormalize an option with option class " + "incompatible with string denormalization."); + } +} + static Optional findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name) { for (int I = 0, E = Table.Size; I != E; ++I) @@ -218,51 +251,19 @@ static void denormalizeSimpleEnum(SmallVectorImpl &Args, const char *Spelling, CompilerInvocation::StringAllocator SA, + Option::OptionClass OptClass, unsigned TableIndex, unsigned Value) { assert(TableIndex < SimpleEnumValueTablesSize); const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) { - Args.push_back(Spelling); - Args.push_back(MaybeEnumVal->Name); + denormalizeString(Args, Spelling, SA, OptClass, TableIndex, + MaybeEnumVal->Name); } else { llvm_unreachable("The simple enum value was not correctly defined in " "the tablegen option description"); } } -static void denormalizeSimpleEnumJoined(SmallVectorImpl &Args, - const char *Spelling, - CompilerInvocation::StringAllocator SA, - unsigned TableIndex, unsigned Value) { - assert(TableIndex < SimpleEnumValueTablesSize); - const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; - if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) - Args.push_back(SA(Twine(Spelling) + MaybeEnumVal->Name)); - else - llvm_unreachable("The simple enum value was not correctly defined in " - "the tablegen option description"); -} - -static Optional normalizeString(OptSpecifier Opt, int TableIndex, - const ArgList &Args, - DiagnosticsEngine &Diags) { - auto *Arg = Args.getLastArg(Opt); - if (!Arg) - return None; - return std::string(Arg->getValue()); -} - -template -static void denormalizeString(SmallVectorImpl &Args, - const char *Spelling, - CompilerInvocation::StringAllocator SA, - unsigned TableIndex, T &&Value) { - static_assert(std::is_constructible::value, - "Cannot convert this value to Twine"); - Args.push_back(Spelling); - Args.push_back(SA(Twine(std::forward(Value)))); -} - template static Optional normalizeStringIntegral(OptSpecifier Opt, int TableIndex, const ArgList &Args, @@ -3474,7 +3475,8 @@ const auto &Extracted = EXTRACTOR(this->KEYPATH); \ if (ALWAYS_EMIT || \ static_cast(Extracted) != DEFAULT_VALUE) \ - DENORMALIZER(Args, SPELLING, SA, TABLE_INDEX, Extracted); \ + DENORMALIZER(Args, SPELLING, SA, Option::KIND##Class, TABLE_INDEX, \ + Extracted); \ } #define OPTION_WITH_MARSHALLING_BOOLEAN( \ diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td --- a/llvm/include/llvm/Option/OptParser.td +++ b/llvm/include/llvm/Option/OptParser.td @@ -198,9 +198,6 @@ code Normalizer = "normalizeSimpleEnum"; code Denormalizer = "denormalizeSimpleEnum"; } -class AutoNormalizeEnumJoined : AutoNormalizeEnum { - code Denormalizer = "denormalizeSimpleEnumJoined"; -} class ValueMerger { code ValueMerger = merger; } class ValueExtractor { code ValueExtractor = extractor; }