jansvoboda11 created this revision.
jansvoboda11 added reviewers: Bigcheese, dexonsmith.
jansvoboda11 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This patch correctly reports success/failure of `ParseLangArgs`. Besides being
consistent with other `Parse` functions, this is requires to make
round-tripping of `LangOptions` work.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95792
Files:
clang/include/clang/Frontend/CompilerInvocation.h
clang/lib/Frontend/CompilerInvocation.cpp
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -2632,10 +2632,11 @@
GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA);
}
-void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
+bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
InputKind IK, const llvm::Triple &T,
std::vector<std::string> &Includes,
DiagnosticsEngine &Diags) {
+ bool Success = true;
// FIXME: Cleanup per-file based stuff.
LangStandard::Kind LangStd = LangStandard::lang_unspecified;
if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
@@ -2643,6 +2644,7 @@
if (LangStd == LangStandard::lang_unspecified) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
+ Success = false;
// Report supported standards with short description.
for (unsigned KindValue = 0;
KindValue != LangStandard::lang_unspecified;
@@ -2673,6 +2675,7 @@
if (!IsInputCompatibleWithStandard(IK, Std)) {
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getAsString(Args) << GetInputKindName(IK);
+ Success = false;
}
}
}
@@ -2694,6 +2697,7 @@
if (OpenCLLangStd == LangStandard::lang_unspecified) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
+ Success = false;
}
else
LangStd = OpenCLLangStd;
@@ -2708,7 +2712,6 @@
// The key paths of codegen options defined in Options.td start with
// "LangOpts->". Let's provide the expected variable name and type.
LangOptions *LangOpts = &Opts;
- bool Success = true;
#define LANG_OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
@@ -2732,8 +2735,10 @@
if (Opts.ObjC) {
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
StringRef value = arg->getValue();
- if (Opts.ObjCRuntime.tryParse(value))
+ if (Opts.ObjCRuntime.tryParse(value)) {
Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
+ Success = false;
+ }
}
if (Args.hasArg(OPT_fobjc_gc_only))
@@ -2742,8 +2747,10 @@
Opts.setGC(LangOptions::HybridGC);
else if (Args.hasArg(OPT_fobjc_arc)) {
Opts.ObjCAutoRefCount = 1;
- if (!Opts.ObjCRuntime.allowsARC())
+ if (!Opts.ObjCRuntime.allowsARC()) {
Diags.Report(diag::err_arc_unsupported_on_runtime);
+ Success = false;
+ }
}
// ObjCWeakRuntime tracks whether the runtime supports __weak, not
@@ -2762,8 +2769,10 @@
assert(!Opts.ObjCWeak);
} else if (Opts.getGC() != LangOptions::NonGC) {
Diags.Report(diag::err_objc_weak_with_gc);
+ Success = false;
} else if (!Opts.ObjCWeakRuntime) {
Diags.Report(diag::err_objc_weak_unsupported);
+ Success = false;
} else {
Opts.ObjCWeak = 1;
}
@@ -2787,6 +2796,7 @@
if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
+ Success = false;
}
Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
}
@@ -2803,9 +2813,11 @@
Opts.MSCompatibilityVersion = 0;
if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
VersionTuple VT;
- if (VT.tryParse(A->getValue()))
+ if (VT.tryParse(A->getValue())) {
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
<< A->getValue();
+ Success = false;
+ }
Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
VT.getMinor().getValueOr(0) * 100000 +
VT.getSubminor().getValueOr(0);
@@ -2839,13 +2851,17 @@
// -mrtd option
if (Arg *A = Args.getLastArg(OPT_mrtd)) {
- if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
+ if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) {
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << "-fdefault-calling-conv";
+ Success = false;
+ }
else {
- if (T.getArch() != llvm::Triple::x86)
+ if (T.getArch() != llvm::Triple::x86) {
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< A->getSpelling() << T.getTriple();
+ Success = false;
+ }
else
Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
}
@@ -2880,6 +2896,7 @@
case llvm::Triple::nvptx:
case llvm::Triple::nvptx64:
Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
+ Success = false;
break;
}
}
@@ -2925,11 +2942,15 @@
TT.getArch() == llvm::Triple::nvptx64 ||
TT.getArch() == llvm::Triple::amdgcn ||
TT.getArch() == llvm::Triple::x86 ||
- TT.getArch() == llvm::Triple::x86_64))
+ TT.getArch() == llvm::Triple::x86_64)) {
Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
- else if (getArchPtrSize(T) != getArchPtrSize(TT))
+ Success = false;
+ }
+ else if (getArchPtrSize(T) != getArchPtrSize(TT)) {
Diags.Report(diag::err_drv_incompatible_omp_arch)
<< A->getValue(i) << T.str();
+ Success = false;
+ }
else
Opts.OMPTargetTriples.push_back(TT);
}
@@ -2985,8 +3006,10 @@
Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
else if (Val == "fast-honor-pragmas")
Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
- else
+ else {
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
+ Success = false;
+ }
}
// Parse -fsanitize= arguments.
@@ -3030,6 +3053,7 @@
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
+ Success = false;
}
}
@@ -3045,9 +3069,11 @@
else if (SignScope.equals_lower("non-leaf"))
Opts.setSignReturnAddressScope(
LangOptions::SignReturnAddressScopeKind::NonLeaf);
- else
+ else {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << SignScope;
+ Success = false;
+ }
if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
StringRef SignKey = A->getValue();
@@ -3058,12 +3084,16 @@
else if (SignKey.equals_lower("b_key"))
Opts.setSignReturnAddressKey(
LangOptions::SignReturnAddressKeyKind::BKey);
- else
+ else {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << SignKey;
+ Success = false;
+ }
}
}
}
+
+ return Success;
}
static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
@@ -3404,8 +3434,8 @@
} else {
// Other LangOpts are only initialized when the input is not AST or LLVM IR.
// FIXME: Should we really be calling this for an Language::Asm input?
- ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
- Diags);
+ Success &= ParseLangArgs(LangOpts, Args, DashX, T,
+ Res.getPreprocessorOpts().Includes, Diags);
if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
LangOpts.ObjCExceptions = 1;
if (T.isOSDarwin() && DashX.isPreprocessed()) {
Index: clang/include/clang/Frontend/CompilerInvocation.h
===================================================================
--- clang/include/clang/Frontend/CompilerInvocation.h
+++ clang/include/clang/Frontend/CompilerInvocation.h
@@ -249,7 +249,7 @@
DiagnosticsEngine &Diags);
/// Parse command line options that map to LangOptions.
- static void ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
+ static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
InputKind IK, const llvm::Triple &T,
std::vector<std::string> &Includes,
DiagnosticsEngine &Diags);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits