[clang][cli] Generate and round-trip CodeGen options

This patch implements generation of remaining codegen options and tests it by performing parse-generate-parse round trip.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D96056
This commit is contained in:
Jan Svoboda 2021-02-09 11:42:01 +01:00
parent ec12f5febe
commit e721bc9eff
6 changed files with 375 additions and 39 deletions

View File

@ -65,8 +65,13 @@ struct XRayInstrSet {
XRayInstrMask Mask = 0;
};
/// Parses a command line argument into a mask.
XRayInstrMask parseXRayInstrValue(StringRef Value);
/// Serializes a set into a list of command line arguments.
void serializeXRayInstrValue(XRayInstrSet Set,
SmallVectorImpl<StringRef> &Values);
} // namespace clang
#endif // LLVM_CLANG_BASIC_XRAYINSTR_H

View File

@ -4453,12 +4453,7 @@ def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">,
//===----------------------------------------------------------------------===//
let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">,
Values<"line-tables-only,line-directives-only,constructor,limited,standalone,unused-types">,
NormalizedValuesScope<"codegenoptions">,
NormalizedValues<["DebugLineTablesOnly", "DebugDirectivesOnly", "DebugInfoConstructor",
"LimitedDebugInfo", "FullDebugInfo", "UnusedTypeInfo"]>,
MarshallingInfoString<CodeGenOpts<"DebugInfo">, "NoDebugInfo">, AutoNormalizeEnum;
def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
def debug_info_macro : Flag<["-"], "debug-info-macro">,
HelpText<"Emit macro debug information">,
MarshallingInfoFlag<CodeGenOpts<"MacroDebugInfo">>;

View File

@ -266,12 +266,26 @@ private:
StringAllocator SA, const llvm::Triple &T);
/// Parse command line options that map to CodeGenOptions.
static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
InputKind IK, DiagnosticsEngine &Diags,
const llvm::Triple &T,
static bool ParseCodeGenArgsImpl(CodeGenOptions &Opts,
llvm::opt::ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags,
const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions &LangOptsRef);
static bool ParseCodeGenArgs(CompilerInvocation &Res, CodeGenOptions &Opts,
llvm::opt::ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags, const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions &LangOptsRef);
// Generate command line options from CodeGenOptions.
static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
SmallVectorImpl<const char *> &Args,
StringAllocator SA, const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions *LangOpts);
/// Parse command line options that map to HeaderSearchOptions.
static void ParseHeaderSearchArgs(CompilerInvocation &Res,
HeaderSearchOptions &Opts,

View File

@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/XRayInstr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringSwitch.h"
namespace clang {
@ -30,4 +31,30 @@ XRayInstrMask parseXRayInstrValue(StringRef Value) {
return ParsedKind;
}
void serializeXRayInstrValue(XRayInstrSet Set,
SmallVectorImpl<StringRef> &Values) {
if (Set.Mask == XRayInstrKind::All) {
Values.push_back("all");
return;
}
if (Set.Mask == XRayInstrKind::None) {
Values.push_back("none");
return;
}
if (Set.has(XRayInstrKind::Custom))
Values.push_back("custom");
if (Set.has(XRayInstrKind::Typed))
Values.push_back("typed");
if (Set.has(XRayInstrKind::FunctionEntry) &&
Set.has(XRayInstrKind::FunctionExit))
Values.push_back("function");
else if (Set.has(XRayInstrKind::FunctionEntry))
Values.push_back("function-entry");
else if (Set.has(XRayInstrKind::FunctionExit))
Values.push_back("function-exit");
}
} // namespace clang

View File

@ -54,6 +54,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@ -625,14 +626,17 @@ static bool RoundTrip(ParseFn Parse, GenerateFn Generate, SwapOptsFn SwapOpts,
// Run the first parse on the original arguments with dummy options and
// diagnostics.
SwapOpts(Res);
if (!Parse(Res, OriginalArgs, DummyDiags)) {
if (!Parse(Res, OriginalArgs, DummyDiags) ||
DummyDiags.getNumWarnings() != 0) {
// If the first parse did not succeed, it must be user mistake (invalid
// command line arguments). We won't be able to generate arguments that
// would reproduce the same result. Let's fail again with the original
// options and diagnostics, so all side-effects of parsing are visible.
unsigned NumWarningsBefore = Diags.getNumWarnings();
SwapOpts(Res);
if (!Parse(Res, OriginalArgs, Diags))
return false;
auto Success = Parse(Res, OriginalArgs, Diags);
if (!Success || Diags.getNumWarnings() != NumWarningsBefore)
return Success;
// Parse with original options and diagnostics succeeded even though it
// shouldn't have. Something is off.
@ -749,16 +753,11 @@ static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
static void getAllNoBuiltinFuncValues(ArgList &Args,
std::vector<std::string> &Funcs) {
SmallVector<const char *, 8> Values;
for (const auto &Arg : Args) {
const Option &O = Arg->getOption();
if (O.matches(options::OPT_fno_builtin_)) {
const char *FuncName = Arg->getValue();
if (Builtin::Context::isBuiltinFunc(FuncName))
Values.push_back(FuncName);
}
}
Funcs.insert(Funcs.end(), Values.begin(), Values.end());
std::vector<std::string> Values = Args.getAllArgValues(OPT_fno_builtin_);
auto BuiltinEnd = llvm::partition(Values, [](const std::string FuncName) {
return Builtin::Context::isBuiltinFunc(FuncName);
});
Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
}
static void GenerateAnalyzerArgs(AnalyzerOptions &Opts,
@ -1238,6 +1237,15 @@ static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
}
}
static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S) {
llvm::SmallVector<StringRef, 2> BundleParts;
serializeXRayInstrValue(S, BundleParts);
std::string Buffer;
llvm::raw_string_ostream OS(Buffer);
llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; }, ",");
return OS.str();
}
// Set the profile kind using fprofile-instrument-use-path.
static void setPGOUseInstrumentor(CodeGenOptions &Opts,
const Twine &ProfileName) {
@ -1259,12 +1267,258 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts,
Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
}
bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
InputKind IK,
DiagnosticsEngine &Diags,
const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions &LangOptsRef) {
void CompilerInvocation::GenerateCodeGenArgs(
const CodeGenOptions &Opts, SmallVectorImpl<const char *> &Args,
StringAllocator SA, const llvm::Triple &T, const std::string &OutputFile,
const LangOptions *LangOpts) {
const CodeGenOptions &CodeGenOpts = Opts;
if (Opts.OptimizationLevel == 0)
GenerateArg(Args, OPT_O0, SA);
else
GenerateArg(Args, OPT_O, Twine(Opts.OptimizationLevel), SA);
#define CODEGEN_OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
MERGER, EXTRACTOR, TABLE_INDEX) \
GENERATE_OPTION_WITH_MARSHALLING( \
Args, SA, KIND, FLAGS, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
IMPLIED_CHECK, IMPLIED_VALUE, DENORMALIZER, EXTRACTOR, TABLE_INDEX)
#include "clang/Driver/Options.inc"
#undef CODEGEN_OPTION_WITH_MARSHALLING
if (Opts.OptimizationLevel > 0) {
if (Opts.Inlining == CodeGenOptions::NormalInlining)
GenerateArg(Args, OPT_finline_functions, SA);
else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining)
GenerateArg(Args, OPT_finline_hint_functions, SA);
else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining)
GenerateArg(Args, OPT_fno_inline, SA);
}
if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)
GenerateArg(Args, OPT_fdirect_access_external_data, SA);
else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
GenerateArg(Args, OPT_fno_direct_access_external_data, SA);
Optional<StringRef> DebugInfoVal;
switch (Opts.DebugInfo) {
case codegenoptions::DebugLineTablesOnly:
DebugInfoVal = "line-tables-only";
break;
case codegenoptions::DebugDirectivesOnly:
DebugInfoVal = "line-directives-only";
break;
case codegenoptions::DebugInfoConstructor:
DebugInfoVal = "constructor";
break;
case codegenoptions::LimitedDebugInfo:
DebugInfoVal = "limited";
break;
case codegenoptions::FullDebugInfo:
DebugInfoVal = "standalone";
break;
case codegenoptions::UnusedTypeInfo:
DebugInfoVal = "unused-types";
break;
case codegenoptions::NoDebugInfo: // default value
DebugInfoVal = None;
break;
case codegenoptions::LocTrackingOnly: // implied value
DebugInfoVal = None;
break;
}
if (DebugInfoVal)
GenerateArg(Args, OPT_debug_info_kind_EQ, *DebugInfoVal, SA);
if (Opts.DebugInfo == codegenoptions::DebugInfoConstructor)
GenerateArg(Args, OPT_fuse_ctor_homing, SA);
for (const auto &Prefix : Opts.DebugPrefixMap)
GenerateArg(Args, OPT_fdebug_prefix_map_EQ,
Prefix.first + "=" + Prefix.second, SA);
for (const auto &Prefix : Opts.ProfilePrefixMap)
GenerateArg(Args, OPT_fprofile_prefix_map_EQ,
Prefix.first + "=" + Prefix.second, SA);
if (Opts.NewStructPathTBAA)
GenerateArg(Args, OPT_new_struct_path_tbaa, SA);
if (Opts.OptimizeSize == 1)
GenerateArg(Args, OPT_O, "s", SA);
else if (Opts.OptimizeSize == 2)
GenerateArg(Args, OPT_O, "z", SA);
// SimplifyLibCalls is set only in the absence of -fno-builtin and
// -ffreestanding. We'll consider that when generating them.
// NoBuiltinFuncs are generated by LangOptions.
if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
GenerateArg(Args, OPT_funroll_loops, SA);
else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
GenerateArg(Args, OPT_fno_unroll_loops, SA);
if (!Opts.BinutilsVersion.empty())
GenerateArg(Args, OPT_fbinutils_version_EQ, Opts.BinutilsVersion, SA);
if (Opts.DebugNameTable ==
static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
GenerateArg(Args, OPT_ggnu_pubnames, SA);
else if (Opts.DebugNameTable ==
static_cast<unsigned>(
llvm::DICompileUnit::DebugNameTableKind::Default))
GenerateArg(Args, OPT_gpubnames, SA);
// ProfileInstrumentUsePath is marshalled automatically, no need to generate
// it or PGOUseInstrumentor.
if (Opts.TimePasses) {
if (Opts.TimePassesPerRun)
GenerateArg(Args, OPT_ftime_report_EQ, "per-pass-run", SA);
else
GenerateArg(Args, OPT_ftime_report, SA);
}
if (Opts.FunctionSections &&
(Opts.BBSections == "none" || Opts.BBSections == "labels"))
GenerateArg(Args, OPT_ffunction_sections, SA);
if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
GenerateArg(Args, OPT_flto, SA);
if (Opts.PrepareForThinLTO)
GenerateArg(Args, OPT_flto_EQ, "thin", SA);
if (!Opts.ThinLTOIndexFile.empty())
GenerateArg(Args, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile, SA);
if (Opts.SaveTempsFilePrefix == OutputFile)
GenerateArg(Args, OPT_save_temps_EQ, "obj", SA);
StringRef MemProfileBasename("memprof.profraw");
if (!Opts.MemoryProfileOutput.empty()) {
if (Opts.MemoryProfileOutput == MemProfileBasename) {
GenerateArg(Args, OPT_fmemory_profile, SA);
} else {
size_t ArgLength =
Opts.MemoryProfileOutput.size() - MemProfileBasename.size();
GenerateArg(Args, OPT_fmemory_profile_EQ,
Opts.MemoryProfileOutput.substr(0, ArgLength), SA);
}
}
if (memcmp(Opts.CoverageVersion, "408*", 4) != 0)
GenerateArg(Args, OPT_coverage_version_EQ, Opts.CoverageVersion, SA);
// TODO: Check if we need to generate arguments stored in CmdArgs. (Namely
// '-fembed_bitcode', which does not map to any CompilerInvocation field and
// won't be generated.)
if (Opts.XRayInstrumentationBundle.Mask != XRayInstrKind::All) {
std::string InstrBundle =
serializeXRayInstrumentationBundle(Opts.XRayInstrumentationBundle);
if (!InstrBundle.empty())
GenerateArg(Args, OPT_fxray_instrumentation_bundle, InstrBundle, SA);
}
if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
GenerateArg(Args, OPT_fcf_protection_EQ, "full", SA);
else if (Opts.CFProtectionReturn)
GenerateArg(Args, OPT_fcf_protection_EQ, "return", SA);
else if (Opts.CFProtectionBranch)
GenerateArg(Args, OPT_fcf_protection_EQ, "branch", SA);
for (const auto &F : Opts.LinkBitcodeFiles) {
bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
F.PropagateAttrs && F.Internalize;
GenerateArg(Args,
Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
F.Filename, SA);
}
// TODO: Consider removing marshalling annotations from f[no_]emulated_tls.
// That would make it easy to generate the option only **once** if it was
// explicitly set to non-default value.
if (Opts.ExplicitEmulatedTLS) {
GenerateArg(
Args, Opts.EmulatedTLS ? OPT_femulated_tls : OPT_fno_emulated_tls, SA);
}
if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE()) {
std::string Buffer;
llvm::raw_string_ostream OS(Buffer);
Opts.FPDenormalMode.print(OS);
GenerateArg(Args, OPT_fdenormal_fp_math_EQ, OS.str(), SA);
}
if (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()) {
std::string Buffer;
llvm::raw_string_ostream OS(Buffer);
Opts.FP32DenormalMode.print(OS);
GenerateArg(Args, OPT_fdenormal_fp_math_f32_EQ, OS.str(), SA);
}
if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) {
OptSpecifier Opt =
T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
GenerateArg(Args, Opt, SA);
} else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) {
OptSpecifier Opt =
T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
GenerateArg(Args, Opt, SA);
}
if (Opts.IgnoreXCOFFVisibility)
GenerateArg(Args, OPT_mignore_xcoff_visibility, SA);
if (Opts.EnableAIXExtendedAltivecABI)
GenerateArg(Args, OPT_mabi_EQ_vec_extabi, SA);
if (!Opts.OptRecordPasses.empty())
GenerateArg(Args, OPT_opt_record_passes, Opts.OptRecordPasses, SA);
if (!Opts.OptRecordFormat.empty())
GenerateArg(Args, OPT_opt_record_format, Opts.OptRecordFormat, SA);
if (Opts.OptimizationRemarkPattern)
GenerateArg(Args, OPT_Rpass_EQ, Opts.OptimizationRemarkPattern.Pattern, SA);
if (Opts.OptimizationRemarkMissedPattern)
GenerateArg(Args, OPT_Rpass_missed_EQ,
Opts.OptimizationRemarkMissedPattern.Pattern, SA);
if (Opts.OptimizationRemarkAnalysisPattern)
GenerateArg(Args, OPT_Rpass_analysis_EQ,
Opts.OptimizationRemarkAnalysisPattern.Pattern, SA);
GenerateArg(Args, OPT_fdiagnostics_hotness_threshold_EQ,
Opts.DiagnosticsHotnessThreshold
? Twine(*Opts.DiagnosticsHotnessThreshold)
: "auto",
SA);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover))
GenerateArg(Args, OPT_fsanitize_recover_EQ, Sanitizer, SA);
for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
GenerateArg(Args, OPT_fsanitize_trap_EQ, Sanitizer, SA);
if (!Opts.EmitVersionIdentMetadata)
GenerateArg(Args, OPT_Qn, SA);
}
bool CompilerInvocation::ParseCodeGenArgsImpl(CodeGenOptions &Opts,
ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags,
const llvm::Triple &T,
const std::string &OutputFile,
const LangOptions &LangOptsRef) {
unsigned NumErrorsBefore = Diags.getNumErrors();
bool Success = true;
unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
@ -1324,7 +1578,24 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.DirectAccessExternalData =
Args.hasArg(OPT_fdirect_access_external_data) ||
(!Args.hasArg(OPT_fno_direct_access_external_data) &&
getLastArgIntValue(Args, OPT_pic_level, 0, Diags) == 0);
LangOpts->PICLevel == 0);
if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
unsigned Val =
llvm::StringSwitch<unsigned>(A->getValue())
.Case("line-tables-only", codegenoptions::DebugLineTablesOnly)
.Case("line-directives-only", codegenoptions::DebugDirectivesOnly)
.Case("constructor", codegenoptions::DebugInfoConstructor)
.Case("limited", codegenoptions::LimitedDebugInfo)
.Case("standalone", codegenoptions::FullDebugInfo)
.Case("unused-types", codegenoptions::UnusedTypeInfo)
.Default(~0U);
if (Val == ~0U)
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
<< A->getValue();
else
Opts.setDebugInfo(static_cast<codegenoptions::DebugInfoKind>(Val));
}
// If -fuse-ctor-homing is set and limited debug info is already on, then use
// constructor homing.
@ -1356,10 +1627,9 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
Args.hasArg(OPT_new_struct_path_tbaa);
Opts.OptimizeSize = getOptimizationLevelSize(Args);
Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
Args.hasArg(OPT_ffreestanding));
Opts.SimplifyLibCalls = !LangOpts->NoBuiltin;
if (Opts.SimplifyLibCalls)
getAllNoBuiltinFuncValues(Args, Opts.NoBuiltinFuncs);
Opts.NoBuiltinFuncs = LangOpts->NoBuiltinFuncs;
Opts.UnrollLoops =
Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
(Opts.OptimizationLevel > 1));
@ -1434,6 +1704,7 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
} else if (Args.hasArg(OPT_fmemory_profile))
Opts.MemoryProfileOutput = MemProfileBasename;
memcpy(Opts.CoverageVersion, "408*", 4);
if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) {
if (Args.hasArg(OPT_coverage_version_EQ)) {
StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
@ -1650,7 +1921,30 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
return Success;
return Success && Diags.getNumErrors() == NumErrorsBefore;
}
bool CompilerInvocation::ParseCodeGenArgs(
CompilerInvocation &Res, CodeGenOptions &Opts, ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags, const llvm::Triple &T,
const std::string &OutputFile, const LangOptions &LangOptsRef) {
CodeGenOptions DummyOpts;
return RoundTrip(
[&](CompilerInvocation &Res, ArgList &Args, DiagnosticsEngine &Diags) {
Args.getLastArg(OPT_O0, OPT_O4, OPT_O, OPT_Ofast);
return ParseCodeGenArgsImpl(Res.getCodeGenOpts(), Args, IK, Diags, T,
OutputFile, LangOptsRef);
},
[&](CompilerInvocation &Res, SmallVectorImpl<const char *> &GeneratedArgs,
StringAllocator SA) {
GenerateCodeGenArgs(Res.getCodeGenOpts(), GeneratedArgs, SA, T,
OutputFile, &LangOptsRef);
},
[&DummyOpts](CompilerInvocation &Res) {
std::swap(Res.CodeGenOpts, DummyOpts);
},
Res, Args, Diags, "CodeGenOptions");
}
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
@ -2746,8 +3040,9 @@ void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts,
if (Opts.NoBuiltin && !Opts.Freestanding)
GenerateArg(Args, OPT_fno_builtin, SA);
// Not generating '-fno-builtin-xxx'. It's handled for CodeGenOptions, that
// also read OPT_fno_builtin_.
if (!Opts.NoBuiltin)
for (const auto &Func : Opts.NoBuiltinFuncs)
GenerateArg(Args, OPT_fno_builtin_, Func, SA);
if (Opts.LongDoubleSize == 128)
GenerateArg(Args, OPT_mlong_double_128, SA);
@ -3719,7 +4014,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
if (LangOpts.OpenMPIsDevice)
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
Success &= ParseCodeGenArgs(Res, Res.getCodeGenOpts(), Args, DashX, Diags, T,
Res.getFrontendOpts().OutputFile, LangOpts);
// FIXME: Override value name discarding when asan or msan is used because the
@ -3883,11 +4178,9 @@ void CompilerInvocation::generateCC1CommandLine(
EXTRACTOR, TABLE_INDEX)
#define DIAG_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
#define CODEGEN_OPTION_WITH_MARSHALLING OPTION_WITH_MARSHALLING
#include "clang/Driver/Options.inc"
#undef CODEGEN_OPTION_WITH_MARSHALLING
#undef DIAG_OPTION_WITH_MARSHALLING
#undef OPTION_WITH_MARSHALLING
@ -3896,6 +4189,8 @@ void CompilerInvocation::generateCC1CommandLine(
GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA);
GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA);
GenerateLangArgs(*LangOpts, Args, SA, T);
GenerateCodeGenArgs(CodeGenOpts, Args, SA, T, FrontendOpts.OutputFile,
&*LangOpts);
GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts,
FrontendOpts, CodeGenOpts);
}

View File

@ -175,7 +175,7 @@ class MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string(
class MarshallingInfoStringInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
: MarshallingInfo<kpm, defaultvalue> {
code Normalizer = "normalizeStringIntegral<"#type#">";
code Denormalizer = "denormalizeString";
code Denormalizer = "denormalizeString<"#type#">";
}
class MarshallingInfoStringVector<KeyPathAndMacro kpm>