diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -223,7 +223,6 @@ InputArgList Args = getOpts().ParseArgs(ArgStrings, MissingArgIndex, MissingArgCount, IncludedFlagsBitmask, ExcludedFlagsBitmask); - // Check for missing argument error. if (MissingArgCount) { Diag(diag::err_drv_missing_argument) @@ -263,20 +262,43 @@ } for (const Arg *A : Args.filtered(options::OPT_UNKNOWN)) { - unsigned DiagID; + // The default diagnostic when the option is unknow + unsigned DiagID = diag::err_drv_unknown_argument; + + // Try to find a good hint for the user auto ArgString = A->getAsString(Args); std::string Nearest; - if (getOpts().findNearest( - ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask) > 1) { - DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl - : diag::err_drv_unknown_argument; - Diags.Report(DiagID) << ArgString; - } else { + unsigned Distance = getOpts().findNearest( + ArgString, Nearest, IncludedFlagsBitmask, ExcludedFlagsBitmask); + assert(Distance != 0 && "This option should not be 'unknown'"); + + if (Distance == 1) { + // Found a good suggestion - propose that in the diagnostic DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion : diag::err_drv_unknown_argument_with_suggestion; Diags.Report(DiagID) << ArgString << Nearest; + } else { + // No good suggestion was found - the diagnostic depends on the mode in + // which the driver operates + if (IsCLMode()) + // In CL mode just warn the user (MSVC consumes everything anyway) + DiagID = diag::warn_drv_unknown_argument_clang_cl; + else if (!IsFlangMode()) { + // In non-Flang mode, check whether this is a Flang flag and + // communicate accordingly. + ExcludedFlagsBitmask &= ~options::FlangOnlyOption; + if (getOpts().findNearest(ArgString, Nearest, IncludedFlagsBitmask, + ExcludedFlagsBitmask) == 0) + DiagID = + Diags.getCustomDiagID(clang::DiagnosticsEngine::Warning, + "command line option ‘%0’ is only valid " + "in Flang mode (i.e. for Fortran input)"); + } // TODO: Check whether this is a C-mode flag and report accordingly. + + Diags.Report(DiagID) << ArgString; } + ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > DiagnosticsEngine::Warning; }