diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -206,6 +206,7 @@ def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; +def err_drv_invalid_enum_value : Error<"invalid value '%1' in '%0', expected one of %2">; def err_drv_invalid_remap_file : Error< "invalid option '%0' not of the form ;">; def err_drv_invalid_gcc_output_type : Error< 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 @@ -243,9 +243,10 @@ if (auto MaybeEnumVal = findValueTableByName(Table, ArgValue)) return MaybeEnumVal->Value; - if (Diags) - Diags->Report(diag::err_drv_invalid_value) - << Arg->getAsString(Args) << ArgValue; + if (Diags) { + Diags->Report(diag::err_drv_invalid_enum_value) + << Arg->getAsString(Args) << ArgValue << Table.EnumValuesString; + } return None; } diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -342,7 +342,7 @@ // GEXTREFS: "-debug-info-kind={{standalone|constructor}}" // RUN: not %clang -cc1 -debug-info-kind=watkind 2>&1 | FileCheck -check-prefix=BADSTRING1 %s -// BADSTRING1: error: invalid value 'watkind' in '-debug-info-kind=watkind' +// BADSTRING1: error: invalid value 'watkind' in '-debug-info-kind=watkind', expected one of line-tables-only,line-directives-only,constructor,limited,standalone // RUN: not %clang -cc1 -debugger-tuning=gmodal 2>&1 | FileCheck -check-prefix=BADSTRING2 %s // BADSTRING2: error: invalid value 'gmodal' in '-debugger-tuning=gmodal' diff --git a/clang/test/Driver/eabi.c b/clang/test/Driver/eabi.c --- a/clang/test/Driver/eabi.c +++ b/clang/test/Driver/eabi.c @@ -10,4 +10,4 @@ // CHECK-EABI4: "-meabi" "4" // CHECK-EABI5: "-meabi" "5" // CHECK-GNUEABI: "-meabi" "gnu" -// CHECK-UNKNOWN: error: invalid value 'unknown' in '-meabi unknown' +// CHECK-UNKNOWN: error: invalid value 'unknown' in '-meabi unknown', expected one of default,4,5,gnu diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c --- a/clang/test/Driver/fveclib.c +++ b/clang/test/Driver/fveclib.c @@ -7,7 +7,7 @@ // CHECK-ACCELERATE: "-fveclib=Accelerate" // CHECK-MASSV: "-fveclib=MASSV" -// CHECK-INVALID: error: invalid value 'something' in '-fveclib=something' +// CHECK-INVALID: error: invalid value 'something' in '-fveclib=something', expected one of Accelerate,MASSV,SVML,none // RUN: %clang -fveclib=Accelerate %s -target arm64-apple-ios8.0.0 -### 2>&1 | FileCheck --check-prefix=CHECK-LINK %s // CHECK-LINK: "-framework" "Accelerate" diff --git a/clang/test/Driver/reloc-model.c b/clang/test/Driver/reloc-model.c --- a/clang/test/Driver/reloc-model.c +++ b/clang/test/Driver/reloc-model.c @@ -1,4 +1,4 @@ // RUN: not %clang -cc1 -mrelocation-model tinkywinky \ // RUN: -emit-llvm %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s -// CHECK-INVALID: error: invalid value 'tinkywinky' in '-mrelocation-model tinkywinky' +// CHECK-INVALID: error: invalid value 'tinkywinky' in '-mrelocation-model tinkywinky', expected one of static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic diff --git a/clang/test/Profile/c-generate.c b/clang/test/Profile/c-generate.c --- a/clang/test/Profile/c-generate.c +++ b/clang/test/Profile/c-generate.c @@ -7,7 +7,7 @@ // // PROF-INSTR-NONE-NOT: __llvm_prf // -// PROF-INSTR-GARBAGE: invalid value 'garbage' in '-fprofile-instrument=garbage' +// PROF-INSTR-GARBAGE: invalid value 'garbage' in '-fprofile-instrument=garbage', expected one of none,clang,llvm,csllvm int main(void) { return 0; diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -90,6 +90,7 @@ struct SimpleEnumValueTable { const SimpleEnumValue *Table; unsigned Size; + const char *EnumValuesString; }; )"; @@ -452,16 +453,21 @@ OS << "#ifdef SIMPLE_ENUM_VALUE_TABLE"; OS << "\n"; OS << MarshallingInfo::ValueTablePreamble; - std::vector ValueTableNames; + std::vector> ValueTableDescs; for (const auto &KindInfo : OptsWithMarshalling) if (auto MaybeValueTableName = KindInfo->emitValueTable(OS)) - ValueTableNames.push_back(*MaybeValueTableName); + ValueTableDescs.push_back( + {*MaybeValueTableName, KindInfo->R.getValueAsString("Values")}); OS << MarshallingInfo::ValueTablesDecl << "{"; - for (auto ValueTableName : ValueTableNames) - OS << "{" << ValueTableName << ", sizeof(" << ValueTableName - << ") / sizeof(SimpleEnumValue)" - << "},\n"; + for (auto ValueTable : ValueTableDescs) { + auto Name = ValueTable.first; + auto ValuesString = ValueTable.second; + OS << "{" << Name << ", sizeof(" << Name << ") / sizeof(SimpleEnumValue)" + << ", "; + write_cstring(OS, ValuesString); + OS << "},\n"; + } OS << "};\n"; OS << "static const unsigned SimpleEnumValueTablesSize = " "sizeof(SimpleEnumValueTables) / sizeof(SimpleEnumValueTable);\n";