зеркало из https://github.com/microsoft/clang-1.git
clang -cc1: Use proper diagnostics for all parsing errors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90100 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2da84ff228
Коммит
9e612408c2
|
@ -57,6 +57,9 @@ def err_drv_invalid_mfloat_abi : Error<
|
|||
"invalid float ABI '%0'">;
|
||||
def err_drv_I_dash_not_supported : Error<
|
||||
"'%0' not supported, please use -iquote instead">;
|
||||
def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
|
||||
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 warn_drv_input_file_unused : Warning<
|
||||
"%0: '%1' input unused when '%2' is present">;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "clang/Basic/Version.h"
|
||||
#include "clang/Driver/ArgList.h"
|
||||
#include "clang/Driver/Arg.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
#include "clang/Frontend/CompilerInvocation.h"
|
||||
|
@ -19,10 +20,10 @@
|
|||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/System/Host.h"
|
||||
#include "llvm/System/Path.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::options;
|
||||
using namespace clang::driver::cc1options;
|
||||
|
@ -61,16 +62,15 @@ static llvm::StringRef getLastArgValue(ArgList &Args, cc1options::ID ID,
|
|||
}
|
||||
|
||||
static int getLastArgIntValue(ArgList &Args, cc1options::ID ID,
|
||||
int Default = 0) {
|
||||
int Default, Diagnostic &Diags) {
|
||||
Arg *A = Args.getLastArg(ID);
|
||||
if (!A)
|
||||
return Default;
|
||||
|
||||
int Res = Default;
|
||||
// FIXME: What to do about argument parsing errors?
|
||||
if (llvm::StringRef(A->getValue(Args)).getAsInteger(10, Res))
|
||||
llvm::errs() << "error: invalid integral argument in '"
|
||||
<< A->getAsString(Args) << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_int_value)
|
||||
<< A->getAsString(Args) << A->getValue(Args);
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
@ -84,7 +84,8 @@ getAllArgValues(ArgList &Args, cc1options::ID ID) {
|
|||
|
||||
//
|
||||
|
||||
static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) {
|
||||
static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
|
||||
Diagnostic &Diags) {
|
||||
using namespace cc1options;
|
||||
|
||||
Opts.AnalysisList.clear();
|
||||
|
@ -101,7 +102,8 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) {
|
|||
.Default(NumStores);
|
||||
// FIXME: Error handling.
|
||||
if (Value == NumStores)
|
||||
llvm::errs() << "error: invalid analysis store '" << Name << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_O)->getAsString(Args) << Name;
|
||||
else
|
||||
Opts.AnalysisStoreOpt = Value;
|
||||
}
|
||||
|
@ -115,7 +117,8 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) {
|
|||
.Default(NumConstraints);
|
||||
// FIXME: Error handling.
|
||||
if (Value == NumConstraints)
|
||||
llvm::errs() << "error: invalid analysis constraints '" << Name << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_O)->getAsString(Args) << Name;
|
||||
else
|
||||
Opts.AnalysisConstraintsOpt = Value;
|
||||
}
|
||||
|
@ -129,7 +132,8 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) {
|
|||
.Default(NUM_ANALYSIS_DIAG_CLIENTS);
|
||||
// FIXME: Error handling.
|
||||
if (Value == NUM_ANALYSIS_DIAG_CLIENTS)
|
||||
llvm::errs() << "error: invalid analysis output '" << Name << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_O)->getAsString(Args) << Name;
|
||||
else
|
||||
Opts.AnalysisDiagOpt = Value;
|
||||
}
|
||||
|
@ -147,19 +151,19 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) {
|
|||
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
|
||||
}
|
||||
|
||||
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args) {
|
||||
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
|
||||
Diagnostic &Diags) {
|
||||
using namespace cc1options;
|
||||
// -Os implies -O2
|
||||
if (Args.hasArg(OPT_Os))
|
||||
Opts.OptimizationLevel = 2;
|
||||
else
|
||||
Opts.OptimizationLevel = getLastArgIntValue(Args, OPT_O);
|
||||
|
||||
// FIXME: What to do about argument parsing errors?
|
||||
if (Opts.OptimizationLevel > 3) {
|
||||
llvm::errs() << "error: invalid optimization level '"
|
||||
<< Opts.OptimizationLevel << "' (out of range)\n";
|
||||
Opts.OptimizationLevel = 3;
|
||||
else {
|
||||
Opts.OptimizationLevel = getLastArgIntValue(Args, OPT_O, 0, Diags);
|
||||
if (Opts.OptimizationLevel > 3) {
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_O)->getAsString(Args) << Opts.OptimizationLevel;
|
||||
Opts.OptimizationLevel = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// We must always run at least the always inlining pass.
|
||||
|
@ -212,7 +216,8 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
|
|||
Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
|
||||
}
|
||||
|
||||
static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args) {
|
||||
static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
|
||||
Diagnostic &Diags) {
|
||||
using namespace cc1options;
|
||||
Opts.IgnoreWarnings = Args.hasArg(OPT_w);
|
||||
Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
|
||||
|
@ -226,13 +231,13 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args) {
|
|||
Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
|
||||
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
|
||||
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
|
||||
Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length);
|
||||
Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
|
||||
Opts.DumpBuildInformation = getLastArgValue(Args, OPT_dump_build_information);
|
||||
Opts.Warnings = getAllArgValues(Args, OPT_W);
|
||||
}
|
||||
|
||||
static FrontendOptions::InputKind
|
||||
ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args) {
|
||||
ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
|
||||
using namespace cc1options;
|
||||
Opts.ProgramAction = frontend::ParseSyntaxOnly;
|
||||
if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
|
||||
|
@ -302,21 +307,22 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args) {
|
|||
Opts.CodeCompletionAt =
|
||||
ParsedSourceLocation::FromString(A->getValue(Args));
|
||||
if (Opts.CodeCompletionAt.FileName.empty())
|
||||
llvm::errs() << "error: invalid source location '"
|
||||
<< A->getAsString(Args) << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getAsString(Args) << A->getValue(Args);
|
||||
}
|
||||
Opts.DebugCodeCompletionPrinter =
|
||||
!Args.hasArg(OPT_no_code_completion_debug_printer);
|
||||
Opts.DisableFree = Args.hasArg(OPT_disable_free);
|
||||
Opts.EmptyInputOnly = Args.hasArg(OPT_empty_input_only);
|
||||
|
||||
std::vector<std::string> Fixits = getAllArgValues(Args, OPT_fixit_at);
|
||||
Opts.FixItLocations.clear();
|
||||
for (unsigned i = 0, e = Fixits.size(); i != e; ++i) {
|
||||
ParsedSourceLocation PSL = ParsedSourceLocation::FromString(Fixits[i]);
|
||||
for (arg_iterator it = Args.filtered_begin(OPT_fixit_at),
|
||||
ie = Args.filtered_end(); it != ie; ++it) {
|
||||
const char *Loc = it->getValue(Args);
|
||||
ParsedSourceLocation PSL = ParsedSourceLocation::FromString(Loc);
|
||||
|
||||
if (PSL.FileName.empty()) {
|
||||
llvm::errs() << "error: invalid source location '" << Fixits[i] << "'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value) << it->getAsString(Args) << Loc;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -352,8 +358,8 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args) {
|
|||
.Case("ast", FrontendOptions::IK_AST)
|
||||
.Default(FrontendOptions::IK_None);
|
||||
if (DashX == FrontendOptions::IK_None)
|
||||
llvm::errs() << "error: invalid argument '" << A->getValue(Args)
|
||||
<< "' to '-x'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getAsString(Args) << A->getValue(Args);
|
||||
}
|
||||
|
||||
// '-' is the default input if none is given.
|
||||
|
@ -440,7 +446,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
|
|||
}
|
||||
|
||||
static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
FrontendOptions::InputKind IK) {
|
||||
FrontendOptions::InputKind IK,
|
||||
Diagnostic &Diags) {
|
||||
// FIXME: Cleanup per-file based stuff.
|
||||
|
||||
// Set some properties which depend soley on the input kind; it would be nice
|
||||
|
@ -463,8 +470,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||
#include "clang/Frontend/LangStandards.def"
|
||||
.Default(LangStandard::lang_unspecified);
|
||||
if (LangStd == LangStandard::lang_unspecified)
|
||||
llvm::errs() << "error: invalid argument '" << A->getValue(Args)
|
||||
<< "' to '-std'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< A->getAsString(Args) << A->getValue(Args);
|
||||
}
|
||||
|
||||
if (LangStd == LangStandard::lang_unspecified) {
|
||||
|
@ -540,8 +547,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||
else if (Vis == "protected")
|
||||
Opts.setVisibilityMode(LangOptions::Protected);
|
||||
else
|
||||
llvm::errs() << "error: invalid argument '" << Vis
|
||||
<< "' to '-fvisibility'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis;
|
||||
|
||||
Opts.OverflowChecking = Args.hasArg(OPT_ftrapv);
|
||||
|
||||
|
@ -571,23 +578,24 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
|||
Opts.AccessControl = Args.hasArg(OPT_faccess_control);
|
||||
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
|
||||
Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno);
|
||||
Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99);
|
||||
Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
|
||||
Diags);
|
||||
Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
|
||||
Opts.ObjCConstantStringClass = getLastArgValue(Args,
|
||||
OPT_fconstant_string_class);
|
||||
Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
|
||||
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
|
||||
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0);
|
||||
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
|
||||
Opts.Static = Args.hasArg(OPT_static_define);
|
||||
Opts.OptimizeSize = 0;
|
||||
Opts.Optimize = 0; // FIXME!
|
||||
Opts.NoInline = 0; // FIXME!
|
||||
|
||||
unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0);
|
||||
unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags);
|
||||
switch (SSP) {
|
||||
default:
|
||||
llvm::errs() << "error: invalid value '" << SSP
|
||||
<< "' for '-stack-protector'\n";
|
||||
Diags.Report(diag::err_drv_invalid_value)
|
||||
<< Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP;
|
||||
break;
|
||||
case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break;
|
||||
case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break;
|
||||
|
@ -668,37 +676,30 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
|||
// Parse the arguments.
|
||||
llvm::OwningPtr<OptTable> Opts(createCC1OptTable());
|
||||
unsigned MissingArgIndex, MissingArgCount;
|
||||
llvm::OwningPtr<InputArgList> InputArgs(
|
||||
llvm::OwningPtr<InputArgList> Args(
|
||||
Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
|
||||
|
||||
// Check for missing argument error.
|
||||
if (MissingArgCount) {
|
||||
// FIXME: Use proper diagnostics!
|
||||
llvm::errs() << "error: argument to '"
|
||||
<< InputArgs->getArgString(MissingArgIndex)
|
||||
<< "' is missing (expected " << MissingArgCount
|
||||
<< " value )\n";
|
||||
}
|
||||
if (MissingArgCount)
|
||||
Diags.Report(diag::err_drv_missing_argument)
|
||||
<< Args->getArgString(MissingArgIndex) << MissingArgCount;
|
||||
|
||||
// Issue errors on unknown arguments.
|
||||
for (arg_iterator it = InputArgs->filtered_begin(OPT_UNKNOWN),
|
||||
ie = InputArgs->filtered_end(); it != ie; ++it) {
|
||||
unsigned ID = Diags.getCustomDiagID(Diagnostic::Error,
|
||||
"unknown argument: '%0'");
|
||||
Diags.Report(ID) << it->getAsString(*InputArgs);
|
||||
}
|
||||
for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
|
||||
ie = Args->filtered_end(); it != ie; ++it)
|
||||
Diags.Report(diag::err_drv_unknown_argument) << it->getAsString(*Args);
|
||||
|
||||
ParseAnalyzerArgs(Res.getAnalyzerOpts(), *InputArgs);
|
||||
ParseCodeGenArgs(Res.getCodeGenOpts(), *InputArgs);
|
||||
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *InputArgs);
|
||||
ParseDiagnosticArgs(Res.getDiagnosticOpts(), *InputArgs);
|
||||
ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags);
|
||||
ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, Diags);
|
||||
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
|
||||
ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags);
|
||||
FrontendOptions::InputKind DashX =
|
||||
ParseFrontendArgs(Res.getFrontendOpts(), *InputArgs);
|
||||
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *InputArgs,
|
||||
ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
|
||||
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args,
|
||||
Argv0, MainAddr);
|
||||
if (DashX != FrontendOptions::IK_AST)
|
||||
ParseLangArgs(Res.getLangOpts(), *InputArgs, DashX);
|
||||
ParsePreprocessorArgs(Res.getPreprocessorOpts(), *InputArgs);
|
||||
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *InputArgs);
|
||||
ParseTargetArgs(Res.getTargetOpts(), *InputArgs);
|
||||
ParseLangArgs(Res.getLangOpts(), *Args, DashX, Diags);
|
||||
ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args);
|
||||
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args);
|
||||
ParseTargetArgs(Res.getTargetOpts(), *Args);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче