diff options
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 757 |
1 files changed, 498 insertions, 259 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e1e59565083b7..75d7cf5d26d3f 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -41,11 +41,13 @@ #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/PreprocessorOptions.h" #include "clang/Sema/CodeCompleteOptions.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/CachedHashString.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" @@ -116,6 +118,62 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) CompilerInvocationBase::~CompilerInvocationBase() = default; //===----------------------------------------------------------------------===// +// Normalizers +//===----------------------------------------------------------------------===// + +#define SIMPLE_ENUM_VALUE_TABLE +#include "clang/Driver/Options.inc" +#undef SIMPLE_ENUM_VALUE_TABLE + +static llvm::Optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt, + unsigned TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + + StringRef ArgValue = Arg->getValue(); + for (int I = 0, E = Table.Size; I != E; ++I) + if (ArgValue == Table.Table[I].Name) + return Table.Table[I].Value; + + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << ArgValue; + return None; +} + +static const char *denormalizeSimpleEnum(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + assert(TableIndex < SimpleEnumValueTablesSize); + const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; + for (int I = 0, E = Table.Size; I != E; ++I) + if (Value == Table.Table[I].Value) + return Table.Table[I].Name; + + llvm_unreachable("The simple enum value was not correctly defined in " + "the tablegen option description"); +} + +static const char *denormalizeString(CompilerInvocation::StringAllocator SA, + unsigned TableIndex, + const std::string &Value) { + return SA(Value); +} + +static Optional<std::string> normalizeTriple(OptSpecifier Opt, int TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + auto *Arg = Args.getLastArg(Opt); + if (!Arg) + return None; + return llvm::Triple::normalize(Arg->getValue()); +} + +//===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// @@ -135,7 +193,7 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, assert(A->getOption().matches(options::OPT_O)); StringRef S(A->getValue()); - if (S == "s" || S == "z" || S.empty()) + if (S == "s" || S == "z") return llvm::CodeGenOpt::Default; if (S == "g") @@ -170,10 +228,12 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, if (A->getOption().getKind() == Option::FlagClass) { // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add // its name (minus the "W" or "R" at the beginning) to the warning list. - Diagnostics.push_back(A->getOption().getName().drop_front(1)); + Diagnostics.push_back( + std::string(A->getOption().getName().drop_front(1))); } else if (A->getOption().matches(GroupWithValue)) { // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group. - Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-")); + Diagnostics.push_back( + std::string(A->getOption().getName().drop_front(1).rtrim("=-"))); } else { // Otherwise, add its value (for OPT_W_Joined and similar). for (const auto *Arg : A->getValues()) @@ -307,14 +367,16 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); - Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph); + Opts.DumpExplodedGraphTo = + std::string(Args.getLastArgValue(OPT_analyzer_dump_egraph)); Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted); Opts.AnalyzerWerror = Args.hasArg(OPT_analyzer_werror); Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers); Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress); Opts.AnalyzeNestedBlocks = Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks); - Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function); + Opts.AnalyzeSpecificFunction = + std::string(Args.getLastArgValue(OPT_analyze_function)); Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG); Opts.TrimGraph = Args.hasArg(OPT_trim_egraph); Opts.maxBlockVisitOnPath = @@ -335,7 +397,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, SmallVector<StringRef, 16> CheckersAndPackages; CheckerAndPackageList.split(CheckersAndPackages, ","); for (const StringRef &CheckerOrPackage : CheckersAndPackages) - Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled); + Opts.CheckersAndPackages.emplace_back(std::string(CheckerOrPackage), + IsEnabled); } // Go through the analyzer configuration options. @@ -372,7 +435,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } A->claim(); - Opts.Config[key] = val; + Opts.Config[key] = std::string(val); } } @@ -394,7 +457,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, StringRef OptionName, StringRef DefaultVal) { - return Config.insert({OptionName, DefaultVal}).first->second; + return Config.insert({OptionName, std::string(DefaultVal)}).first->second; } static void initOption(AnalyzerOptions::ConfigTable &Config, @@ -521,36 +584,6 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } -static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mcode_model)) { - StringRef Value = A->getValue(); - if (Value == "small" || Value == "kernel" || Value == "medium" || - Value == "large" || Value == "tiny") - return Value; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return "default"; -} - -static llvm::Reloc::Model getRelocModel(ArgList &Args, - DiagnosticsEngine &Diags) { - if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) { - StringRef Value = A->getValue(); - auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(Value) - .Case("static", llvm::Reloc::Static) - .Case("pic", llvm::Reloc::PIC_) - .Case("ropi", llvm::Reloc::ROPI) - .Case("rwpi", llvm::Reloc::RWPI) - .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI) - .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC) - .Default(None); - if (RM.hasValue()) - return *RM; - Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; - } - return llvm::Reloc::PIC_; -} - /// Create a new Regex instance out of the string value in \p RpassArg. /// It returns a pointer to the newly generated Regex instance. static std::shared_ptr<llvm::Regex> @@ -754,7 +787,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setDebuggerTuning(static_cast<llvm::DebuggerKind>(Val)); } Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags); - Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); + Opts.DebugColumnInfo = !Args.hasArg(OPT_gno_column_info); Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); @@ -762,19 +795,21 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.VirtualFunctionElimination = Args.hasArg(OPT_fvirtual_function_elimination); Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std); - Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); - Opts.SplitDwarfOutput = Args.getLastArgValue(OPT_split_dwarf_output); + Opts.SplitDwarfFile = std::string(Args.getLastArgValue(OPT_split_dwarf_file)); + Opts.SplitDwarfOutput = + std::string(Args.getLastArgValue(OPT_split_dwarf_output)); Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining); Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import); Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params); Opts.EmbedSource = Args.hasArg(OPT_gembed_source); + Opts.ForceDwarfFrameSection = Args.hasArg(OPT_fforce_dwarf_frame); - Opts.ForceDwarfFrameSection = - Args.hasFlag(OPT_fforce_dwarf_frame, OPT_fno_force_dwarf_frame, false); - - for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) - Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); + for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) { + auto Split = StringRef(Arg).split('='); + Opts.DebugPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } if (const Arg *A = Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists)) @@ -785,12 +820,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, const llvm::Triple::ArchType DebugEntryValueArchs[] = { llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64, - llvm::Triple::arm, llvm::Triple::armeb}; + llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips, + llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el}; llvm::Triple T(TargetOpts.Triple); if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() && llvm::is_contained(DebugEntryValueArchs, T.getArch())) - Opts.EnableDebugEntryValues = Args.hasArg(OPT_femit_debug_entry_values); + Opts.EmitCallSiteInfo = true; Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); @@ -805,10 +841,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.FineGrainedBitfieldAccesses = Args.hasFlag(OPT_ffine_grained_bitfield_accesses, OPT_fno_fine_grained_bitfield_accesses, false); - Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); - Opts.RecordCommandLine = Args.getLastArgValue(OPT_record_command_line); + Opts.DwarfDebugFlags = + std::string(Args.getLastArgValue(OPT_dwarf_debug_flags)); + Opts.RecordCommandLine = + std::string(Args.getLastArgValue(OPT_record_command_line)); Opts.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants); - Opts.NoCommon = Args.hasArg(OPT_fno_common); + Opts.NoCommon = !Args.hasArg(OPT_fcommon); Opts.NoInlineLineTables = Args.hasArg(OPT_gno_inline_line_tables); Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float); Opts.OptimizeSize = getOptimizationLevelSize(Args); @@ -823,7 +861,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as); Opts.Autolink = !Args.hasArg(OPT_fno_autolink); - Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); + Opts.SampleProfileFile = + std::string(Args.getLastArgValue(OPT_fprofile_sample_use_EQ)); Opts.DebugInfoForProfiling = Args.hasFlag( OPT_fdebug_info_for_profiling, OPT_fno_debug_info_for_profiling, false); Opts.DebugNameTable = static_cast<unsigned>( @@ -836,13 +875,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, setPGOInstrumentor(Opts, Args, Diags); Opts.InstrProfileOutput = - Args.getLastArgValue(OPT_fprofile_instrument_path_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_instrument_path_EQ)); Opts.ProfileInstrumentUsePath = - Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_instrument_use_path_EQ)); if (!Opts.ProfileInstrumentUsePath.empty()) setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath); Opts.ProfileRemappingFile = - Args.getLastArgValue(OPT_fprofile_remapping_file_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_remapping_file_EQ)); if (!Opts.ProfileRemappingFile.empty() && !Opts.ExperimentalNewPassManager) { Diags.Report(diag::err_drv_argument_only_allowed_with) << Args.getLastArg(OPT_fprofile_remapping_file_EQ)->getAsString(Args) @@ -852,7 +891,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); - Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose); + Opts.AsmVerbose = !Args.hasArg(OPT_fno_verbose_asm); Opts.PreserveAsmComments = !Args.hasArg(OPT_fno_preserve_as_comments); Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); @@ -861,7 +900,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fregister_global_dtors_with_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.CodeModel = TargetOpts.CodeModel; - Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); + Opts.DebugPass = std::string(Args.getLastArgValue(OPT_mdebug_pass)); // Handle -mframe-pointer option. if (Arg *A = Args.getLastArg(OPT_mframe_pointer_EQ)) { @@ -883,49 +922,30 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setFramePointer(FP); } - // -pg may override -mframe-pointer - // TODO: This should be merged into getFramePointerKind in Clang.cpp. - if (Args.hasArg(OPT_pg)) - Opts.setFramePointer(CodeGenOptions::FramePointerKind::All); - Opts.DisableFree = Args.hasArg(OPT_disable_free); Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names); Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls); Opts.NoEscapingBlockTailCalls = Args.hasArg(OPT_fno_escaping_block_tail_calls); - Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); + Opts.FloatABI = std::string(Args.getLastArgValue(OPT_mfloat_abi)); Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || Args.hasArg(OPT_cl_fast_relaxed_math); - Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); - Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.NoNaNsFPMath = (Args.hasArg(OPT_menable_no_nans) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.NoSignedZeros = (Args.hasArg(OPT_fno_signed_zeros) || - Args.hasArg(OPT_cl_no_signed_zeros) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_fast_relaxed_math)); - Opts.Reassociate = Args.hasArg(OPT_mreassociate); - Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero) || - (Args.hasArg(OPT_fcuda_is_device) && - Args.hasArg(OPT_fcuda_flush_denormals_to_zero)); + Opts.LimitFloatPrecision = + std::string(Args.getLastArgValue(OPT_mlimit_float_precision)); Opts.CorrectlyRoundedDivSqrt = Args.hasArg(OPT_cl_fp32_correctly_rounded_divide_sqrt); Opts.UniformWGSize = Args.hasArg(OPT_cl_uniform_work_group_size); Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ); - Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math); - Opts.NoTrappingMath = Args.hasArg(OPT_fno_trapping_math); Opts.StrictFloatCastOverflow = !Args.hasArg(OPT_fno_strict_float_cast_overflow); - Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss); + Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_fno_zero_initialized_in_bss); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); + Opts.SmallDataLimit = + getLastArgIntValue(Args, OPT_msmall_data_limit, 0, Diags); Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn); Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks); @@ -942,27 +962,31 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return); Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers); Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables); - Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) || - Args.hasArg(OPT_cl_unsafe_math_optimizations) || - Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); - Opts.RelocationModel = getRelocModel(Args, Diags); - Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix"); + Opts.ThreadModel = + std::string(Args.getLastArgValue(OPT_mthread_model, "posix")); if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") Diags.Report(diag::err_drv_invalid_value) << Args.getLastArg(OPT_mthread_model)->getAsString(Args) << Opts.ThreadModel; - Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); + Opts.TrapFuncName = std::string(Args.getLastArgValue(OPT_ftrap_function_EQ)); Opts.UseInitArray = !Args.hasArg(OPT_fno_use_init_array); - Opts.FunctionSections = Args.hasFlag(OPT_ffunction_sections, - OPT_fno_function_sections, false); - Opts.DataSections = Args.hasFlag(OPT_fdata_sections, - OPT_fno_data_sections, false); - Opts.StackSizeSection = - Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false); - Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names, - OPT_fno_unique_section_names, true); + Opts.BBSections = + std::string(Args.getLastArgValue(OPT_fbasic_block_sections_EQ, "none")); + + // Basic Block Sections implies Function Sections. + Opts.FunctionSections = + Args.hasArg(OPT_ffunction_sections) || + (Opts.BBSections != "none" && Opts.BBSections != "labels"); + + Opts.DataSections = Args.hasArg(OPT_fdata_sections); + Opts.StackSizeSection = Args.hasArg(OPT_fstack_size_section); + Opts.UniqueSectionNames = !Args.hasArg(OPT_fno_unique_section_names); + Opts.UniqueBasicBlockSectionNames = + Args.hasArg(OPT_funique_basic_block_section_names); + Opts.UniqueInternalLinkageNames = + Args.hasArg(OPT_funique_internal_linkage_names); Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions); @@ -987,7 +1011,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (IK.getLanguage() != Language::LLVM_IR) Diags.Report(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) << "-x ir"; - Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ); + Opts.ThinLTOIndexFile = + std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ)); } if (Arg *A = Args.getLastArg(OPT_save_temps_EQ)) Opts.SaveTempsFilePrefix = @@ -995,16 +1020,18 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, .Case("obj", FrontendOpts.OutputFile) .Default(llvm::sys::path::filename(FrontendOpts.OutputFile).str()); - Opts.ThinLinkBitcodeFile = Args.getLastArgValue(OPT_fthin_link_bitcode_EQ); + Opts.ThinLinkBitcodeFile = + std::string(Args.getLastArgValue(OPT_fthin_link_bitcode_EQ)); Opts.MSVolatile = Args.hasArg(OPT_fms_volatile); Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops); Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp); - Opts.PreferVectorWidth = Args.getLastArgValue(OPT_mprefer_vector_width_EQ); + Opts.PreferVectorWidth = + std::string(Args.getLastArgValue(OPT_mprefer_vector_width_EQ)); - Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); + Opts.MainFileName = std::string(Args.getLastArgValue(OPT_main_file_name)); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); Opts.ControlFlowGuardNoChecks = Args.hasArg(OPT_cfguard_no_checks); @@ -1014,17 +1041,14 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) { - Opts.CoverageDataFile = Args.getLastArgValue(OPT_coverage_data_file); - Opts.CoverageNotesFile = Args.getLastArgValue(OPT_coverage_notes_file); - Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum); - Opts.CoverageNoFunctionNamesInData = - Args.hasArg(OPT_coverage_no_function_names_in_data); + Opts.CoverageDataFile = + std::string(Args.getLastArgValue(OPT_coverage_data_file)); + Opts.CoverageNotesFile = + std::string(Args.getLastArgValue(OPT_coverage_notes_file)); Opts.ProfileFilterFiles = - Args.getLastArgValue(OPT_fprofile_filter_files_EQ); + std::string(Args.getLastArgValue(OPT_fprofile_filter_files_EQ)); Opts.ProfileExcludeFiles = - Args.getLastArgValue(OPT_fprofile_exclude_files_EQ); - Opts.CoverageExitBlockBeforeBody = - Args.hasArg(OPT_coverage_exit_block_before_body); + std::string(Args.getLastArgValue(OPT_fprofile_exclude_files_EQ)); if (Args.hasArg(OPT_coverage_version_EQ)) { StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ); if (CoverageVersion.size() != 4) { @@ -1062,8 +1086,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, A->getOption().getID() == options::OPT_INPUT || A->getOption().getID() == options::OPT_x || A->getOption().getID() == options::OPT_fembed_bitcode || - (A->getOption().getGroup().isValid() && - A->getOption().getGroup().getID() == options::OPT_W_Group)) + A->getOption().matches(options::OPT_W_Group)) continue; ArgStringList ASL; A->render(Args, ASL); @@ -1091,6 +1114,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fxray_always_emit_typedevents); Opts.XRayInstructionThreshold = getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags); + Opts.XRayIgnoreLoops = Args.hasArg(OPT_fxray_ignore_loops); + Opts.XRayOmitFunctionIndex = Args.hasArg(OPT_fno_xray_function_index); auto XRayInstrBundles = Args.getAllArgValues(OPT_fxray_instrumentation_bundle); @@ -1103,6 +1128,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.PatchableFunctionEntryCount = getLastArgIntValue(Args, OPT_fpatchable_function_entry_EQ, 0, Diags); + Opts.PatchableFunctionEntryOffset = getLastArgIntValue( + Args, OPT_fpatchable_function_entry_offset_EQ, 0, Diags); Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.MNopMCount = Args.hasArg(OPT_mnop_mcount); @@ -1141,7 +1168,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); - Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); + Opts.DebugCompilationDir = + std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir)); for (auto *A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) { CodeGenOptions::BitcodeFileToLink F; @@ -1171,9 +1199,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeCoverageNoPrune = Args.hasArg(OPT_fsanitize_coverage_no_prune); Opts.SanitizeCoverageInline8bitCounters = Args.hasArg(OPT_fsanitize_coverage_inline_8bit_counters); + Opts.SanitizeCoverageInlineBoolFlag = + Args.hasArg(OPT_fsanitize_coverage_inline_bool_flag); Opts.SanitizeCoveragePCTable = Args.hasArg(OPT_fsanitize_coverage_pc_table); Opts.SanitizeCoverageStackDepth = Args.hasArg(OPT_fsanitize_coverage_stack_depth); + Opts.SanitizeCoverageAllowlistFiles = + Args.getAllArgValues(OPT_fsanitize_coverage_allowlist); + Opts.SanitizeCoverageBlocklistFiles = + Args.getAllArgValues(OPT_fsanitize_coverage_blocklist); Opts.SanitizeMemoryTrackOrigins = getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); Opts.SanitizeMemoryUseAfterDtor = @@ -1225,6 +1259,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.NoStackArgProbe = Args.hasArg(OPT_mno_stack_arg_probe); + Opts.StackClashProtector = Args.hasArg(OPT_fstack_clash_protection); + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(); unsigned Method = llvm::StringSwitch<unsigned>(Name) @@ -1273,15 +1309,35 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) { StringRef Val = A->getValue(); Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val); - if (Opts.FPDenormalMode == llvm::DenormalMode::Invalid) + if (!Opts.FPDenormalMode.isValid()) + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; + } + + if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) { + StringRef Val = A->getValue(); + Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val); + if (!Opts.FP32DenormalMode.isValid()) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } - if (Arg *A = Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return)) { - if (A->getOption().matches(OPT_fpcc_struct_return)) { + // X86_32 has -fppc-struct-return and -freg-struct-return. + // PPC32 has -maix-struct-return and -msvr4-struct-return. + if (Arg *A = + Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return, + OPT_maix_struct_return, OPT_msvr4_struct_return)) { + // TODO: We might want to consider enabling these options on AIX in the + // future. + if (T.isOSAIX()) + Diags.Report(diag::err_drv_unsupported_opt_for_target) + << A->getSpelling() << T.str(); + + const Option &O = A->getOption(); + if (O.matches(OPT_fpcc_struct_return) || + O.matches(OPT_maix_struct_return)) { Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack); } else { - assert(A->getOption().matches(OPT_freg_struct_return)); + assert(O.matches(OPT_freg_struct_return) || + O.matches(OPT_msvr4_struct_return)); Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs); } } @@ -1290,7 +1346,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LinkerOptions = Args.getAllArgValues(OPT_linker_option); bool NeedLocTracking = false; - Opts.OptRecordFile = Args.getLastArgValue(OPT_opt_record_file); + Opts.OptRecordFile = std::string(Args.getLastArgValue(OPT_opt_record_file)); if (!Opts.OptRecordFile.empty()) NeedLocTracking = true; @@ -1363,7 +1419,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeTrap); Opts.CudaGpuBinaryFileName = - Args.getLastArgValue(OPT_fcuda_include_gpubinary); + std::string(Args.getLastArgValue(OPT_fcuda_include_gpubinary)); Opts.Backchain = Args.hasArg(OPT_mbackchain); @@ -1374,38 +1430,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Addrsig = Args.hasArg(OPT_faddrsig); - if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { - StringRef SignScope = A->getValue(); - - if (SignScope.equals_lower("none")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None); - else if (SignScope.equals_lower("all")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All); - else if (SignScope.equals_lower("non-leaf")) - Opts.setSignReturnAddress( - CodeGenOptions::SignReturnAddressScope::NonLeaf); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignScope; - - if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { - StringRef SignKey = A->getValue(); - if (!SignScope.empty() && !SignKey.empty()) { - if (SignKey.equals_lower("a_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::AKey); - else if (SignKey.equals_lower("b_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::BKey); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignKey; - } - } - } - - Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); - Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts); Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); @@ -1414,20 +1438,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.PassPlugins = Args.getAllArgValues(OPT_fpass_plugin_EQ); - Opts.SymbolPartition = Args.getLastArgValue(OPT_fsymbol_partition_EQ); + Opts.SymbolPartition = + std::string(Args.getLastArgValue(OPT_fsymbol_partition_EQ)); + Opts.ForceAAPCSBitfieldLoad = Args.hasArg(OPT_ForceAAPCSBitfieldLoad); return Success; } static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args) { - Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); + Opts.OutputFile = std::string(Args.getLastArgValue(OPT_dependency_file)); Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps); Opts.UsePhonyTargets = Args.hasArg(OPT_MP); Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); - Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); + Opts.HeaderIncludeOutputFile = + std::string(Args.getLastArgValue(OPT_header_include_file)); Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG); if (Args.hasArg(OPT_show_includes)) { // Writing both /showIncludes and preprocessor output to stdout @@ -1440,9 +1467,9 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, } else { Opts.ShowIncludesDest = ShowIncludesDestination::None; } - Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot); + Opts.DOTOutputFile = std::string(Args.getLastArgValue(OPT_dependency_dot)); Opts.ModuleDependencyOutputDir = - Args.getLastArgValue(OPT_module_dependency_dir); + std::string(Args.getLastArgValue(OPT_module_dependency_dir)); if (Args.hasArg(OPT_MV)) Opts.OutputFormat = DependencyOutputFormat::NMake; // Add sanitizer blacklists as extra dependencies. @@ -1452,13 +1479,13 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, for (const auto *A : Args.filtered(OPT_fsanitize_blacklist)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } if (Opts.IncludeSystemHeaders) { for (const auto *A : Args.filtered(OPT_fsanitize_system_blacklist)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } } } @@ -1472,7 +1499,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ExtraDeps.push_back(Val); + Opts.ExtraDeps.push_back(std::string(Val)); } } @@ -1531,10 +1558,11 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes, bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, DiagnosticsEngine *Diags, - bool DefaultDiagColor, bool DefaultShowOpt) { + bool DefaultDiagColor) { bool Success = true; - Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file); + Opts.DiagnosticLogFile = + std::string(Args.getLastArgValue(OPT_diagnostic_log_file)); if (Arg *A = Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags)) Opts.DiagnosticSerializationFile = A->getValue(); @@ -1544,17 +1572,11 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.PedanticErrors = Args.hasArg(OPT_pedantic_errors); Opts.ShowCarets = !Args.hasArg(OPT_fno_caret_diagnostics); Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor); - Opts.ShowColumn = Args.hasFlag(OPT_fshow_column, - OPT_fno_show_column, - /*Default=*/true); + Opts.ShowColumn = !Args.hasArg(OPT_fno_show_column); Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info); Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location); Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); - Opts.ShowOptionNames = - Args.hasFlag(OPT_fdiagnostics_show_option, - OPT_fno_diagnostics_show_option, DefaultShowOpt); - - llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); + Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); // Default behavior is to not to show note include stacks. Opts.ShowNoteIncludeStack = false; @@ -1660,7 +1682,11 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Diags->Report(diag::warn_ignoring_ftabstop_value) << Opts.TabStop << DiagnosticOptions::DefaultTabStop; } - Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); + Opts.MessageLength = + getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); + + Opts.UndefPrefixes = Args.getAllArgValues(OPT_Wundef_prefix_EQ); + addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); @@ -1668,7 +1694,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, } static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) { - Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory); + Opts.WorkingDir = std::string(Args.getLastArgValue(OPT_working_directory)); } /// Parse the argument to the -ftest-module-file-extension @@ -1686,12 +1712,12 @@ static bool parseTestModuleFileExtensionArg(StringRef Arg, if (Args.size() < 5) return true; - BlockName = Args[0]; + BlockName = std::string(Args[0]); if (Args[1].getAsInteger(10, MajorVersion)) return true; if (Args[2].getAsInteger(10, MinorVersion)) return true; if (Args[3].getAsInteger(2, Hashed)) return true; if (Args.size() > 4) - UserInfo = Args[4]; + UserInfo = std::string(Args[4]); return false; } @@ -1724,6 +1750,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, case OPT_ast_dump: case OPT_ast_dump_all: case OPT_ast_dump_lookups: + case OPT_ast_dump_decl_types: Opts.ProgramAction = frontend::ASTDump; break; case OPT_ast_print: Opts.ProgramAction = frontend::ASTPrint; break; @@ -1766,25 +1793,26 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, StringRef ArgStr = Args.hasArg(OPT_interface_stub_version_EQ) ? Args.getLastArgValue(OPT_interface_stub_version_EQ) - : "experimental-ifs-v1"; + : "experimental-ifs-v2"; if (ArgStr == "experimental-yaml-elf-v1" || + ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-tapi-elf-v1") { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + " is deprecated."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; - } else if (ArgStr != "experimental-ifs-v1") { + } else if (!ArgStr.startswith("experimental-ifs-")) { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + "."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; } else { - Opts.ProgramAction = frontend::GenerateInterfaceIfsExpV1; + Opts.ProgramAction = frontend::GenerateInterfaceStubs; } break; } @@ -1859,7 +1887,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, } Opts.DisableFree = Args.hasArg(OPT_disable_free); - Opts.OutputFile = Args.getLastArgValue(OPT_o); + Opts.OutputFile = std::string(Args.getLastArgValue(OPT_o)); Opts.Plugins = Args.getAllArgValues(OPT_load); Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch); Opts.ShowHelp = Args.hasArg(OPT_help); @@ -1878,8 +1906,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp); Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ); Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ); - Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter); + Opts.ASTDumpFilter = std::string(Args.getLastArgValue(OPT_ast_dump_filter)); Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups); + Opts.ASTDumpDeclTypes = Args.hasArg(OPT_ast_dump_decl_types); Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index); Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); @@ -1887,12 +1916,17 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) - Opts.ModuleFiles.push_back(Val); + Opts.ModuleFiles.push_back(std::string(Val)); } Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ); Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files); Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp); Opts.UseTemporary = !Args.hasArg(OPT_fno_temp_file); + Opts.IsSystemModule = Args.hasArg(OPT_fsystem_module); + + if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule) + Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module" + << "-emit-module"; Opts.CodeCompleteOpts.IncludeMacros = Args.hasArg(OPT_code_completion_macros); @@ -1907,10 +1941,14 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.CodeCompleteOpts.IncludeFixIts = Args.hasArg(OPT_code_completion_with_fixits); - Opts.OverrideRecordLayoutsFile - = Args.getLastArgValue(OPT_foverride_record_layout_EQ); - Opts.AuxTriple = Args.getLastArgValue(OPT_aux_triple); - Opts.StatsFile = Args.getLastArgValue(OPT_stats_file); + Opts.OverrideRecordLayoutsFile = + std::string(Args.getLastArgValue(OPT_foverride_record_layout_EQ)); + Opts.AuxTriple = std::string(Args.getLastArgValue(OPT_aux_triple)); + if (Args.hasArg(OPT_aux_target_cpu)) + Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu)); + if (Args.hasArg(OPT_aux_target_feature)) + Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature); + Opts.StatsFile = std::string(Args.getLastArgValue(OPT_stats_file)); if (const Arg *A = Args.getLastArg(OPT_arcmt_check, OPT_arcmt_modify, @@ -1929,9 +1967,10 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, break; } } - Opts.MTMigrateDir = Args.getLastArgValue(OPT_mt_migrate_directory); - Opts.ARCMTMigrateReportOut - = Args.getLastArgValue(OPT_arcmt_migrate_report_output); + Opts.MTMigrateDir = + std::string(Args.getLastArgValue(OPT_mt_migrate_directory)); + Opts.ARCMTMigrateReportOut = + std::string(Args.getLastArgValue(OPT_arcmt_migrate_report_output)); Opts.ARCMTMigrateEmitARCErrors = Args.hasArg(OPT_arcmt_migrate_emit_arc_errors); @@ -1966,7 +2005,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_objcmt_migrate_all)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls; - Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path); + Opts.ObjCMTWhiteListPath = + std::string(Args.getLastArgValue(OPT_objcmt_whitelist_dir_path)); if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { @@ -2043,12 +2083,16 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DashX = IK; } + bool IsSystem = false; + // The -emit-module action implicitly takes a module map. if (Opts.ProgramAction == frontend::GenerateModule && - IK.getFormat() == InputKind::Source) + IK.getFormat() == InputKind::Source) { IK = IK.withFormat(InputKind::ModuleMap); + IsSystem = Opts.IsSystemModule; + } - Opts.Inputs.emplace_back(std::move(Inputs[i]), IK); + Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem); } return DashX; @@ -2063,14 +2107,14 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0, static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, const std::string &WorkingDir) { - Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/"); + Opts.Sysroot = std::string(Args.getLastArgValue(OPT_isysroot, "/")); Opts.Verbose = Args.hasArg(OPT_v); Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc); Opts.UseStandardSystemIncludes = !Args.hasArg(OPT_nostdsysteminc); Opts.UseStandardCXXIncludes = !Args.hasArg(OPT_nostdincxx); if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ)) Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0); - Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir); + Opts.ResourceDir = std::string(Args.getLastArgValue(OPT_resource_dir)); // Canonicalize -fmodules-cache-path before storing it. SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path)); @@ -2081,20 +2125,23 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, llvm::sys::fs::make_absolute(WorkingDir, P); } llvm::sys::path::remove_dots(P); - Opts.ModuleCachePath = P.str(); + Opts.ModuleCachePath = std::string(P.str()); - Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); + Opts.ModuleUserBuildPath = + std::string(Args.getLastArgValue(OPT_fmodules_user_build_path)); // Only the -fmodule-file=<name>=<file> form. for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); - if (Val.find('=') != StringRef::npos) - Opts.PrebuiltModuleFiles.insert(Val.split('=')); + if (Val.find('=') != StringRef::npos){ + auto Split = Val.split('='); + Opts.PrebuiltModuleFiles.insert( + {std::string(Split.first), std::string(Split.second)}); + } } for (const auto *A : Args.filtered(OPT_fprebuilt_module_path)) Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content); - Opts.ModulesStrictContextHash = Args.hasArg(OPT_fmodules_strict_context_hash); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps); @@ -2141,7 +2188,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, SmallString<32> Buffer; llvm::sys::path::append(Buffer, Opts.Sysroot, llvm::StringRef(A->getValue()).substr(1)); - Path = Buffer.str(); + Path = std::string(Buffer.str()); } Opts.AddPath(Path, Group, IsFramework, @@ -2241,7 +2288,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (T.isPS4()) LangStd = LangStandard::lang_gnu99; else - LangStd = LangStandard::lang_gnu11; + LangStd = LangStandard::lang_gnu17; #endif break; case Language::ObjC: @@ -2278,7 +2325,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CPlusPlus11 = Std.isCPlusPlus11(); Opts.CPlusPlus14 = Std.isCPlusPlus14(); Opts.CPlusPlus17 = Std.isCPlusPlus17(); - Opts.CPlusPlus2a = Std.isCPlusPlus2a(); + Opts.CPlusPlus20 = Std.isCPlusPlus20(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; @@ -2304,7 +2351,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.AltiVec = 0; Opts.ZVector = 0; Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::None); - Opts.setDefaultFPContractMode(LangOptions::FPC_On); + Opts.setDefaultFPContractMode(LangOptions::FPM_On); Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; Opts.OpenCLCPlusPlus = Opts.CPlusPlus; @@ -2324,7 +2371,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP; if (Opts.CUDA) // Set default FP_CONTRACT to FAST. - Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); Opts.RenderScript = IK.getLanguage() == Language::RenderScript; if (Opts.RenderScript) { @@ -2513,6 +2560,24 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, LangStd = OpenCLLangStd; } + Opts.SYCL = Args.hasArg(options::OPT_fsycl); + Opts.SYCLIsDevice = Opts.SYCL && Args.hasArg(options::OPT_fsycl_is_device); + if (Opts.SYCL) { + // -sycl-std applies to any SYCL source, not only those containing kernels, + // but also those using the SYCL API + if (const Arg *A = Args.getLastArg(OPT_sycl_std_EQ)) { + Opts.SYCLVersion = llvm::StringSwitch<unsigned>(A->getValue()) + .Cases("2017", "1.2.1", "121", "sycl-1.2.1", 2017) + .Default(0U); + + if (Opts.SYCLVersion == 0U) { + // User has passed an invalid value to the flag, this is an error + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + } + } + Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header); Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins); @@ -2699,7 +2764,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. Opts.OverflowHandler = - Args.getLastArgValue(OPT_ftrapv_handler); + std::string(Args.getLastArgValue(OPT_ftrapv_handler)); } else if (Args.hasArg(OPT_fwrapv)) Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); @@ -2750,6 +2815,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fno_threadsafe_statics)) Opts.ThreadsafeStatics = 0; Opts.Exceptions = Args.hasArg(OPT_fexceptions); + Opts.IgnoreExceptions = Args.hasArg(OPT_fignore_exceptions); Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions); Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions); @@ -2788,7 +2854,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL && Opts.OpenCLVersion == 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); - Opts.Coroutines = Opts.CPlusPlus2a || Args.hasArg(OPT_fcoroutines_ts); + Opts.Coroutines = Opts.CPlusPlus20 || Args.hasArg(OPT_fcoroutines_ts); Opts.ConvergentFunctions = Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Args.hasArg(OPT_fconvergent_functions); @@ -2798,7 +2864,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, OPT_fno_double_square_bracket_attributes, Opts.DoubleSquareBracketAttributes); - Opts.CPlusPlusModules = Opts.CPlusPlus2a; + Opts.CPlusPlusModules = Opts.CPlusPlus20; Opts.ModulesTS = Args.hasArg(OPT_fmodules_ts); Opts.Modules = Args.hasArg(OPT_fmodules) || Opts.ModulesTS || Opts.CPlusPlusModules; @@ -2819,7 +2885,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); - Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus2a); + Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus20); if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) { Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue()) .Case("char", 1) @@ -2852,7 +2918,15 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << A->getValue(); Opts.NewAlignOverride = 0; } - Opts.ConceptsTS = Args.hasArg(OPT_fconcepts_ts); + Opts.ConceptSatisfactionCaching = + !Args.hasArg(OPT_fno_concept_satisfaction_caching); + if (Args.hasArg(OPT_fconcepts_ts)) + Diags.Report(diag::warn_fe_concepts_ts_flag); + // Recovery AST still heavily relies on dependent-type machinery. + Opts.RecoveryAST = + Args.hasFlag(OPT_frecovery_ast, OPT_fno_recovery_ast, Opts.CPlusPlus); + Opts.RecoveryASTType = + Args.hasFlag(OPT_frecovery_ast_type, OPT_fno_recovery_ast_type, false); Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); Opts.AccessControl = !Args.hasArg(OPT_fno_access_control); Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); @@ -2873,7 +2947,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, getLastArgIntValue(Args, OPT_Wlarge_by_value_copy_EQ, 0, Diags); Opts.MSBitfields = Args.hasArg(OPT_mms_bitfields); Opts.ObjCConstantStringClass = - Args.getLastArgValue(OPT_fconstant_string_class); + std::string(Args.getLastArgValue(OPT_fconstant_string_class)); Opts.ObjCDefaultSynthProperties = !Args.hasArg(OPT_disable_objc_default_synthesize_properties); Opts.EncodeExtendedBlockSig = @@ -2882,6 +2956,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags); Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags); Opts.AlignDouble = Args.hasArg(OPT_malign_double); + Opts.DoubleSize = getLastArgIntValue(Args, OPT_mdouble_EQ, 0, Diags); Opts.LongDoubleSize = Args.hasArg(OPT_mlong_double_128) ? 128 : Args.hasArg(OPT_mlong_double_64) ? 64 : 0; @@ -2899,6 +2974,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align); Opts.SinglePrecisionConstants = Args.hasArg(OPT_cl_single_precision_constant); Opts.FastRelaxedMath = Args.hasArg(OPT_cl_fast_relaxed_math); + if (Opts.FastRelaxedMath) + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); Opts.HexagonQdsp6Compat = Args.hasArg(OPT_mqdsp6_compat); Opts.FakeAddressSpaceMap = Args.hasArg(OPT_ffake_address_space_map); Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype); @@ -2906,7 +2983,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id); Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal); Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack); - Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ); + Opts.ModuleName = std::string(Args.getLastArgValue(OPT_fmodule_name_EQ)); Opts.CurrentModule = Opts.ModuleName; Opts.AppExt = Args.hasArg(OPT_fapplication_extension); Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature); @@ -3001,6 +3078,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setDefaultCallingConv(DefaultCC); } + Opts.SemanticInterposition = Args.hasArg(OPT_fsemantic_interposition); + // An explicit -fno-semantic-interposition infers dso_local. + Opts.ExplicitNoSemanticInterposition = + Args.hasArg(OPT_fno_semantic_interposition); + // -mrtd option if (Arg *A = Args.getLastArg(OPT_mrtd)) { if (Opts.getDefaultCallingConv() != LangOptions::DCC_None) @@ -3016,8 +3098,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } - // Check if -fopenmp is specified and set default version to 4.5. - Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 45 : 0; + // Check if -fopenmp is specified and set default version to 5.0. + Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 50 : 0; // Check if -fopenmp-simd is specified. bool IsSimdSpecified = Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd, @@ -3035,10 +3117,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Opts.OpenMP || Opts.OpenMPSimd) { if (int Version = getLastArgIntValue( Args, OPT_fopenmp_version_EQ, - (IsSimdSpecified || IsTargetSpecified) ? 45 : Opts.OpenMP, Diags)) + (IsSimdSpecified || IsTargetSpecified) ? 50 : Opts.OpenMP, Diags)) Opts.OpenMP = Version; - else if (IsSimdSpecified || IsTargetSpecified) - Opts.OpenMP = 45; // Provide diagnostic when a given target is not expected to be an OpenMP // device or host. if (!Opts.OpenMPIsDevice) { @@ -3057,7 +3137,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // Set the flag to prevent the implementation from emitting device exception // handling code for those requiring so. - if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) { + if ((Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN())) || + Opts.OpenCLCPlusPlus) { Opts.Exceptions = 0; Opts.CXXExceptions = 0; } @@ -3091,6 +3172,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, TT.getArch() == llvm::Triple::ppc64le || TT.getArch() == llvm::Triple::nvptx || TT.getArch() == llvm::Triple::nvptx64 || + TT.getArch() == llvm::Triple::amdgcn || TT.getArch() == llvm::Triple::x86 || TT.getArch() == llvm::Triple::x86_64)) Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i); @@ -3108,15 +3190,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << Opts.OMPHostIRFile; } - Opts.SYCLIsDevice = Args.hasArg(options::OPT_fsycl_is_device); - - // Set CUDA mode for OpenMP target NVPTX if specified in options - Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() && + // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options + Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && Args.hasArg(options::OPT_fopenmp_cuda_mode); - // Set CUDA mode for OpenMP target NVPTX if specified in options + // Set CUDA support for parallel execution of target regions for OpenMP target + // NVPTX/AMDGCN if specified in options. + Opts.OpenMPCUDATargetParallel = + Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && + Args.hasArg(options::OPT_fopenmp_cuda_parallel_target_regions); + + // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options Opts.OpenMPCUDAForceFullRuntime = - Opts.OpenMPIsDevice && T.isNVPTX() && + Opts.OpenMPIsDevice && (T.isNVPTX() || T.isAMDGCN()) && Args.hasArg(options::OPT_fopenmp_cuda_force_full_runtime); // Record whether the __DEPRECATED define was requested. @@ -3140,30 +3226,65 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (InlineArg->getOption().matches(options::OPT_fno_inline)) Opts.NoInlineDefine = true; - Opts.FastMath = Args.hasArg(OPT_ffast_math) || - Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.FastMath = + Args.hasArg(OPT_ffast_math) || Args.hasArg(OPT_cl_fast_relaxed_math); Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) || - Args.hasArg(OPT_cl_finite_math_only) || - Args.hasArg(OPT_cl_fast_relaxed_math); + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.AllowFPReassoc = Args.hasArg(OPT_mreassociate) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoHonorNaNs = + Args.hasArg(OPT_menable_no_nans) || Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_ffast_math) || Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoHonorInfs = Args.hasArg(OPT_menable_no_infinities) || + Args.hasArg(OPT_ffinite_math_only) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_finite_math_only) || + Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.NoSignedZero = Args.hasArg(OPT_fno_signed_zeros) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_no_signed_zeros) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || Args.hasArg(OPT_cl_fast_relaxed_math); + Opts.AllowRecip = Args.hasArg(OPT_freciprocal_math) || + Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); + // Currently there's no clang option to enable this individually + Opts.ApproxFunc = Args.hasArg(OPT_menable_unsafe_fp_math) || + Args.hasArg(OPT_ffast_math) || + Args.hasArg(OPT_cl_unsafe_math_optimizations) || + Args.hasArg(OPT_cl_fast_relaxed_math); if (Arg *A = Args.getLastArg(OPT_ffp_contract)) { StringRef Val = A->getValue(); if (Val == "fast") - Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); + Opts.setDefaultFPContractMode(LangOptions::FPM_Fast); else if (Val == "on") - Opts.setDefaultFPContractMode(LangOptions::FPC_On); + Opts.setDefaultFPContractMode(LangOptions::FPM_On); else if (Val == "off") - Opts.setDefaultFPContractMode(LangOptions::FPC_Off); + Opts.setDefaultFPContractMode(LangOptions::FPM_Off); else Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } - LangOptions::FPRoundingModeKind FPRM = LangOptions::FPR_ToNearest; + if (Args.hasArg(OPT_fexperimental_strict_floating_point)) + Opts.ExpStrictFP = true; + + auto FPRM = llvm::RoundingMode::NearestTiesToEven; if (Args.hasArg(OPT_frounding_math)) { - FPRM = LangOptions::FPR_Dynamic; + FPRM = llvm::RoundingMode::Dynamic; } Opts.setFPRoundingMode(FPRM); @@ -3217,6 +3338,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init_stop_after)) { + int Val = std::stoi(A->getValue()); + Opts.TrivialAutoVarInitStopAfter = Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); @@ -3231,18 +3357,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, systemBlacklists.end()); // -fxray-instrument - Opts.XRayInstrument = - Args.hasFlag(OPT_fxray_instrument, OPT_fnoxray_instrument, false); - - // -fxray-always-emit-customevents + Opts.XRayInstrument = Args.hasArg(OPT_fxray_instrument); Opts.XRayAlwaysEmitCustomEvents = - Args.hasFlag(OPT_fxray_always_emit_customevents, - OPT_fnoxray_always_emit_customevents, false); - - // -fxray-always-emit-typedevents + Args.hasArg(OPT_fxray_always_emit_customevents); Opts.XRayAlwaysEmitTypedEvents = - Args.hasFlag(OPT_fxray_always_emit_typedevents, - OPT_fnoxray_always_emit_customevents, false); + Args.hasArg(OPT_fxray_always_emit_typedevents); // -fxray-{always,never}-instrument= filenames. Opts.XRayAlwaysInstrumentFiles = @@ -3294,6 +3413,54 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers); Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj); + Opts.PCHInstantiateTemplates = Args.hasArg(OPT_fpch_instantiate_templates); + + Opts.MatrixTypes = Args.hasArg(OPT_fenable_matrix); + + Opts.MaxTokens = getLastArgIntValue(Args, OPT_fmax_tokens_EQ, 0, Diags); + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { + StringRef SignScope = A->getValue(); + + if (SignScope.equals_lower("none")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::None); + else if (SignScope.equals_lower("all")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::All); + else if (SignScope.equals_lower("non-leaf")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::NonLeaf); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignScope; + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { + StringRef SignKey = A->getValue(); + if (!SignScope.empty() && !SignKey.empty()) { + if (SignKey.equals_lower("a_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::AKey); + else if (SignKey.equals_lower("b_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::BKey); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignKey; + } + } + } + + Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); + Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); + + Opts.CompatibilityQualifiedIdBlockParamTypeChecking = + Args.hasArg(OPT_fcompatibility_qualified_id_block_param_type_checking); + + Opts.RelativeCXXABIVTables = + Args.hasFlag(OPT_fexperimental_relative_cxx_abi_vtables, + OPT_fno_experimental_relative_cxx_abi_vtables, + /*default=*/false); } static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { @@ -3314,7 +3481,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::GenerateModuleInterface: case frontend::GenerateHeaderModule: case frontend::GeneratePCH: - case frontend::GenerateInterfaceIfsExpV1: + case frontend::GenerateInterfaceStubs: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: case frontend::VerifyPCH: @@ -3343,11 +3510,12 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action) { - Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch); + Opts.ImplicitPCHInclude = std::string(Args.getLastArgValue(OPT_include_pch)); Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) || Args.hasArg(OPT_pch_through_hdrstop_use); Opts.PCHWithHdrStopCreate = Args.hasArg(OPT_pch_through_hdrstop_create); - Opts.PCHThroughHeader = Args.getLastArgValue(OPT_pch_through_header_EQ); + Opts.PCHThroughHeader = + std::string(Args.getLastArgValue(OPT_pch_through_header_EQ)); Opts.UsePredefines = !Args.hasArg(OPT_undef); Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record); Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch); @@ -3357,8 +3525,11 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue()); - for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) - Opts.MacroPrefixMap.insert(StringRef(A).split('=')); + for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) { + auto Split = StringRef(A).split('='); + Opts.MacroPrefixMap.insert( + {std::string(Split.first), std::string(Split.second)}); + } if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) { StringRef Value(A->getValue()); @@ -3435,6 +3606,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Opts.LexEditorPlaceholders = false; Opts.SetUpStaticAnalyzer = Args.hasArg(OPT_setup_static_analyzer); + Opts.DisablePragmaDebugCrash = Args.hasArg(OPT_disable_pragma_debug_crash); } static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, @@ -3457,8 +3629,8 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { - Opts.CodeModel = getCodeModel(Args, Diags); - Opts.ABI = Args.getLastArgValue(OPT_target_abi); + Opts.CodeModel = std::string(Args.getLastArgValue(OPT_mcmodel_EQ, "default")); + Opts.ABI = std::string(Args.getLastArgValue(OPT_target_abi)); if (Arg *A = Args.getLastArg(OPT_meabi)) { StringRef Value = A->getValue(); llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value) @@ -3473,15 +3645,11 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, else Opts.EABIVersion = EABIVersion; } - Opts.CPU = Args.getLastArgValue(OPT_target_cpu); - Opts.FPMath = Args.getLastArgValue(OPT_mfpmath); + Opts.CPU = std::string(Args.getLastArgValue(OPT_target_cpu)); + Opts.FPMath = std::string(Args.getLastArgValue(OPT_mfpmath)); Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); - Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); - Opts.Triple = Args.getLastArgValue(OPT_triple); - // Use the default target triple if unspecified. - if (Opts.Triple.empty()) - Opts.Triple = llvm::sys::getDefaultTargetTriple(); - Opts.Triple = llvm::Triple::normalize(Opts.Triple); + Opts.LinkerVersion = + std::string(Args.getLastArgValue(OPT_target_linker_version)); Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ); Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( @@ -3496,9 +3664,35 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, } } +bool CompilerInvocation::parseSimpleArgs(const ArgList &Args, + DiagnosticsEngine &Diags) { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + this->KEYPATH = Args.hasArg(OPT_##ID) && IS_POSITIVE; + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + { \ + if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, Args, Diags)) \ + this->KEYPATH = static_cast<TYPE>(*MaybeValue); \ + else \ + this->KEYPATH = DEFAULT_VALUE; \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG + return true; +} + bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs, - DiagnosticsEngine &Diags) { + DiagnosticsEngine &Diags, + const char *Argv0) { bool Success = true; // Parse the arguments. @@ -3528,6 +3722,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success = false; } + Success &= Res.parseSimpleArgs(Args, Diags); + + llvm::sys::Process::UseANSIEscapeCodes( + Res.DiagnosticOpts->UseANSIEscapeCodes); + Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); @@ -3536,9 +3735,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Diags.Report(diag::err_fe_dependency_file_requires_MT); Success = false; } - Success &= - ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, - false /*DefaultDiagColor*/, false /*DefaultShowOpt*/); + Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, + /*DefaultDiagColor=*/false); ParseCommentArgs(LangOpts.CommentOpts, Args); ParseFileSystemArgs(Res.getFileSystemOpts(), Args); // FIXME: We shouldn't have to pass the DashX option around here @@ -3619,6 +3817,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false; Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored); } + + // Store the command-line for using in the CodeView backend. + Res.getCodeGenOpts().Argv0 = Argv0; + Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs; + return Success; } @@ -3635,6 +3838,11 @@ std::string CompilerInvocation::getModuleHash() const { // CityHash, but this will do for now. hash_code code = hash_value(getClangFullRepositoryVersion()); + // Also include the serialization version, in case LLVM_APPEND_VC_REV is off + // and getClangFullRepositoryVersion() doesn't include git revision. + code = hash_combine(code, serialization::VERSION_MAJOR, + serialization::VERSION_MINOR); + // Extend the signature with the language options #define LANGOPT(Name, Bits, Default, Description) \ code = hash_combine(code, LangOpts->Name); @@ -3647,6 +3855,10 @@ std::string CompilerInvocation::getModuleHash() const { for (StringRef Feature : LangOpts->ModuleFeatures) code = hash_combine(code, Feature); + code = hash_combine(code, LangOpts->ObjCRuntime); + const auto &BCN = LangOpts->CommentOpts.BlockCommandNames; + code = hash_combine(code, hash_combine_range(BCN.begin(), BCN.end())); + // Extend the signature with the target options. code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU, TargetOpts->ABI); @@ -3726,6 +3938,33 @@ std::string CompilerInvocation::getModuleHash() const { return llvm::APInt(64, code).toString(36, /*Signed=*/false); } +void CompilerInvocation::generateCC1CommandLine( + SmallVectorImpl<const char *> &Args, StringAllocator SA) const { +#define OPTION_WITH_MARSHALLING_FLAG(PREFIX_TYPE, NAME, ID, KIND, GROUP, \ + ALIAS, ALIASARGS, FLAGS, PARAM, HELPTEXT, \ + METAVAR, VALUES, SPELLING, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IS_POSITIVE) \ + if ((FLAGS) & options::CC1Option && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) \ + Args.push_back(SPELLING); + +#define OPTION_WITH_MARSHALLING_STRING( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + NORMALIZER_RET_TY, NORMALIZER, DENORMALIZER, TABLE_INDEX) \ + if (((FLAGS) & options::CC1Option) && \ + (ALWAYS_EMIT || this->KEYPATH != DEFAULT_VALUE)) { \ + if (Option::KIND##Class == Option::SeparateClass) { \ + Args.push_back(SPELLING); \ + Args.push_back(DENORMALIZER(SA, TABLE_INDEX, this->KEYPATH)); \ + } \ + } + +#include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_STRING +#undef OPTION_WITH_MARSHALLING_FLAG +} + namespace clang { IntrusiveRefCntPtr<llvm::vfs::FileSystem> |