Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -230,6 +230,8 @@ "The last /TC or /TP option takes precedence over earlier instances">; def note_drv_address_sanitizer_debug_runtime : Note< "AddressSanitizer doesn't support linking with debug runtime libraries yet">; +def note_drv_supported_values : Note<"supported values are:">; +def note_drv_supported_value_with_description : Note<"'%0' for standard '%1'">; def err_analyzer_config_no_value : Error< "analyzer-config option '%0' has a key but no value">; Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1694,10 +1694,21 @@ .Case(alias, LangStandard::lang_##id) #include "clang/Frontend/LangStandards.def" .Default(LangStandard::lang_unspecified); - if (LangStd == LangStandard::lang_unspecified) + if (LangStd == LangStandard::lang_unspecified) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); - else { + // Report all supported standards with description. + Diags.Report(diag::note_drv_supported_values); + for (unsigned KindValue = 0; + KindValue != LangStandard::lang_unspecified; + ++KindValue) + { + const LangStandard &Std = LangStandard::getLangStandardForKind( + static_cast(KindValue)); + Diags.Report(diag::note_drv_supported_value_with_description) + << Std.getName() << Std.getDescription(); + } + } else { // Valid standard, check to make sure language and standard are // compatible. const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); Index: test/Driver/unknown-std.c =================================================================== --- /dev/null +++ test/Driver/unknown-std.c @@ -0,0 +1,42 @@ +// RUN: not %clang %s -std=foobar -c 2>&1 | \ +// RUN: FileCheck %s + +// CHECK: error: invalid value 'foobar' in '-std=foobar' +// CHECK: note: supported values are: +// CHECK: note: 'c89' for standard 'ISO C 1990' +// CHECK: note: 'c90' for standard 'ISO C 1990' +// CHECK: note: 'iso9899:1990' for standard 'ISO C 1990' +// CHECK: note: 'iso9899:199409' for standard 'ISO C 1990 with amendment 1' +// CHECK: note: 'gnu89' for standard 'ISO C 1990 with GNU extensions' +// CHECK: note: 'gnu90' for standard 'ISO C 1990 with GNU extensions' +// CHECK: note: 'c99' for standard 'ISO C 1999' +// CHECK: note: 'c9x' for standard 'ISO C 1999' +// CHECK: note: 'iso9899:1999' for standard 'ISO C 1999' +// CHECK: note: 'iso9899:199x' for standard 'ISO C 1999' +// CHECK: note: 'gnu99' for standard 'ISO C 1999 with GNU extensions' +// CHECK: note: 'gnu9x' for standard 'ISO C 1999 with GNU extensions' +// CHECK: note: 'c11' for standard 'ISO C 2011' +// CHECK: note: 'c1x' for standard 'ISO C 2011' +// CHECK: note: 'iso9899:2011' for standard 'ISO C 2011' +// CHECK: note: 'iso9899:201x' for standard 'ISO C 2011' +// CHECK: note: 'gnu11' for standard 'ISO C 2011 with GNU extensions' +// CHECK: note: 'gnu1x' for standard 'ISO C 2011 with GNU extensions' +// CHECK: note: 'c++98' for standard 'ISO C++ 1998 with amendments' +// CHECK: note: 'c++03' for standard 'ISO C++ 1998 with amendments' +// CHECK: note: 'gnu++98' for standard 'ISO C++ 1998 with amendments and GNU extensions' +// CHECK: note: 'c++0x' for standard 'ISO C++ 2011 with amendments' +// CHECK: note: 'c++11' for standard 'ISO C++ 2011 with amendments' +// CHECK: note: 'gnu++0x' for standard 'ISO C++ 2011 with amendments and GNU extensions' +// CHECK: note: 'gnu++11' for standard 'ISO C++ 2011 with amendments and GNU extensions' +// CHECK: note: 'c++1y' for standard 'ISO C++ 2014 with amendments' +// CHECK: note: 'c++14' for standard 'ISO C++ 2014 with amendments' +// CHECK: note: 'gnu++1y' for standard 'ISO C++ 2014 with amendments and GNU extensions' +// CHECK: note: 'gnu++14' for standard 'ISO C++ 2014 with amendments and GNU extensions' +// CHECK: note: 'c++1z' for standard 'Working draft for ISO C++ 2017' +// CHECK: note: 'gnu++1z' for standard 'Working draft for ISO C++ 2017 with GNU extensions' +// CHECK: note: 'cl' for standard 'OpenCL 1.0' +// CHECK: note: 'cl1.1' for standard 'OpenCL 1.1' +// CHECK: note: 'cl1.2' for standard 'OpenCL 1.2' +// CHECK: note: 'cl2.0' for standard 'OpenCL 2.0' +// CHECK: note: 'cuda' for standard 'NVIDIA CUDA(tm)' +