diff options
Diffstat (limited to 'lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 376 |
1 files changed, 251 insertions, 125 deletions
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8a9844096f08..665695ec3b18 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -18,6 +18,7 @@ #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/LangStandard.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" @@ -34,7 +35,6 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/FrontendPluginRegistry.h" -#include "clang/Frontend/LangStandard.h" #include "clang/Frontend/MigratorOptions.h" #include "clang/Frontend/PreprocessorOutputOptions.h" #include "clang/Frontend/Utils.h" @@ -122,7 +122,7 @@ CompilerInvocationBase::~CompilerInvocationBase() = default; static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { unsigned DefaultOpt = llvm::CodeGenOpt::None; - if (IK.getLanguage() == InputKind::OpenCL && !Args.hasArg(OPT_cl_opt_disable)) + if (IK.getLanguage() == Language::OpenCL && !Args.hasArg(OPT_cl_opt_disable)) DefaultOpt = llvm::CodeGenOpt::Default; if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { @@ -303,7 +303,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, .Case("true", true) .Case("false", false) .Default(false); - Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks); + Opts.DisableAllCheckers = Args.hasArg(OPT_analyzer_disable_all_checks); Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); @@ -324,18 +324,18 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, getLastArgIntValue(Args, OPT_analyzer_inline_max_stack_depth, Opts.InlineMaxStackDepth, Diags); - Opts.CheckersControlList.clear(); + Opts.CheckersAndPackages.clear(); for (const Arg *A : Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) { A->claim(); - bool enable = (A->getOption().getID() == OPT_analyzer_checker); + bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker; // We can have a list of comma separated checker names, e.g: // '-analyzer-checker=cocoa,unix' - StringRef checkerList = A->getValue(); - SmallVector<StringRef, 4> checkers; - checkerList.split(checkers, ","); - for (auto checker : checkers) - Opts.CheckersControlList.emplace_back(checker, enable); + StringRef CheckerAndPackageList = A->getValue(); + SmallVector<StringRef, 16> CheckersAndPackages; + CheckerAndPackageList.split(CheckersAndPackages, ","); + for (const StringRef CheckerOrPackage : CheckersAndPackages) + Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled); } // Go through the analyzer configuration options. @@ -464,6 +464,35 @@ static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, // At this point, AnalyzerOptions is configured. Let's validate some options. + // FIXME: Here we try to validate the silenced checkers or packages are valid. + // The current approach only validates the registered checkers which does not + // contain the runtime enabled checkers and optimally we would validate both. + if (!AnOpts.RawSilencedCheckersAndPackages.empty()) { + std::vector<StringRef> Checkers = + AnOpts.getRegisteredCheckers(/*IncludeExperimental=*/true); + std::vector<StringRef> Packages = + AnOpts.getRegisteredPackages(/*IncludeExperimental=*/true); + + SmallVector<StringRef, 16> CheckersAndPackages; + AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";"); + + for (const StringRef CheckerOrPackage : CheckersAndPackages) { + if (Diags) { + bool IsChecker = CheckerOrPackage.contains('.'); + bool IsValidName = + IsChecker + ? llvm::find(Checkers, CheckerOrPackage) != Checkers.end() + : llvm::find(Packages, CheckerOrPackage) != Packages.end(); + + if (!IsValidName) + Diags->Report(diag::err_unknown_analyzer_checker_or_package) + << CheckerOrPackage; + } + + AnOpts.SilencedCheckersAndPackages.emplace_back(CheckerOrPackage); + } + } + if (!Diags) return; @@ -729,6 +758,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables); + 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); @@ -748,10 +779,14 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes); Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers); + const llvm::Triple::ArchType DebugEntryValueArchs[] = { + llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64, + llvm::Triple::arm, llvm::Triple::armeb}; + llvm::Triple T(TargetOpts.Triple); - llvm::Triple::ArchType Arch = T.getArch(); if (Opts.OptimizationLevel > 0 && - (Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64)) + Opts.getDebugInfo() >= codegenoptions::LimitedDebugInfo && + llvm::is_contained(DebugEntryValueArchs, T.getArch())) Opts.EnableDebugEntryValues = Args.hasArg(OPT_femit_debug_entry_values); Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone); @@ -823,8 +858,32 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.CodeModel = TargetOpts.CodeModel; Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); - Opts.DisableFPElim = - (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg)); + + // Handle -mframe-pointer option. + if (Arg *A = Args.getLastArg(OPT_mframe_pointer_EQ)) { + CodeGenOptions::FramePointerKind FP; + StringRef Name = A->getValue(); + bool ValidFP = true; + if (Name == "none") + FP = CodeGenOptions::FramePointerKind::None; + else if (Name == "non-leaf") + FP = CodeGenOptions::FramePointerKind::NonLeaf; + else if (Name == "all") + FP = CodeGenOptions::FramePointerKind::All; + else { + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; + Success = false; + ValidFP = false; + } + if (ValidFP) + 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); @@ -864,6 +923,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); + Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn); Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks); Opts.RelaxAll = Args.hasArg(OPT_mrelax_all); Opts.IncrementalLinkerCompatible = @@ -871,7 +931,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.PIECopyRelocations = Args.hasArg(OPT_mpie_copy_relocations); Opts.NoPLT = Args.hasArg(OPT_fno_plt); - Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer); Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels); Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm); Opts.SoftFloat = Args.hasArg(OPT_msoft_float); @@ -921,7 +980,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false); Opts.EnableSplitLTOUnit = Args.hasArg(OPT_fsplit_lto_unit); if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) { - if (IK.getLanguage() != InputKind::LLVM_IR) + 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); @@ -1115,6 +1174,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso); Opts.SanitizeCfiICallGeneralizePointers = Args.hasArg(OPT_fsanitize_cfi_icall_generalize_pointers); + Opts.SanitizeCfiCanonicalJumpTables = + Args.hasArg(OPT_fsanitize_cfi_canonical_jump_tables); Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats); if (Arg *A = Args.getLastArg( OPT_fsanitize_address_poison_custom_array_cookie, @@ -1262,7 +1323,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (Opts.DiagnosticsWithHotness && !UsingProfile && // An IR file will contain PGO as metadata - IK.getLanguage() != InputKind::LLVM_IR) + IK.getLanguage() != Language::LLVM_IR) Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo) << "-fdiagnostics-show-hotness"; @@ -1675,23 +1736,30 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::GenerateHeaderModule; break; case OPT_emit_pch: Opts.ProgramAction = frontend::GeneratePCH; break; - case OPT_emit_iterface_stubs: { - llvm::Optional<frontend::ActionKind> ProgramAction = - llvm::StringSwitch<llvm::Optional<frontend::ActionKind>>( - Args.hasArg(OPT_iterface_stub_version_EQ) - ? Args.getLastArgValue(OPT_iterface_stub_version_EQ) - : "") - .Case("experimental-yaml-elf-v1", - frontend::GenerateInterfaceYAMLExpV1) - .Case("experimental-tapi-elf-v1", - frontend::GenerateInterfaceTBEExpV1) - .Default(llvm::None); - if (!ProgramAction) + case OPT_emit_interface_stubs: { + StringRef ArgStr = + Args.hasArg(OPT_interface_stub_version_EQ) + ? Args.getLastArgValue(OPT_interface_stub_version_EQ) + : "experimental-ifs-v1"; + if (ArgStr == "experimental-yaml-elf-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" + << ErrorMessage; + } else if (ArgStr != "experimental-ifs-v1") { + std::string ErrorMessage = + "Invalid interface stub format: " + ArgStr.str() + "."; Diags.Report(diag::err_drv_invalid_value) - << "Must specify a valid interface stub format type using " - << "-interface-stub-version=<experimental-tapi-elf-v1 | " - "experimental-yaml-elf-v1>"; - Opts.ProgramAction = *ProgramAction; + << "Must specify a valid interface stub format type, ie: " + "-interface-stub-version=experimental-ifs-v1" + << ErrorMessage; + } else { + Opts.ProgramAction = frontend::GenerateInterfaceIfsExpV1; + } break; } case OPT_init_only: @@ -1773,6 +1841,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ShowTimers = Args.hasArg(OPT_ftime_report); Opts.PrintSupportedCPUs = Args.hasArg(OPT_print_supported_cpus); Opts.TimeTrace = Args.hasArg(OPT_ftime_trace); + Opts.TimeTraceGranularity = getLastArgIntValue( + Args, OPT_ftime_trace_granularity_EQ, Opts.TimeTraceGranularity, Diags); Opts.ShowVersion = Args.hasArg(OPT_version); Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge); Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm); @@ -1877,7 +1947,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, << "ARC migration" << "ObjC migration"; } - InputKind DashX(InputKind::Unknown); + InputKind DashX(Language::Unknown); if (const Arg *A = Args.getLastArg(OPT_x)) { StringRef XValue = A->getValue(); @@ -1890,33 +1960,33 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, // Principal languages. DashX = llvm::StringSwitch<InputKind>(XValue) - .Case("c", InputKind::C) - .Case("cl", InputKind::OpenCL) - .Case("cuda", InputKind::CUDA) - .Case("hip", InputKind::HIP) - .Case("c++", InputKind::CXX) - .Case("objective-c", InputKind::ObjC) - .Case("objective-c++", InputKind::ObjCXX) - .Case("renderscript", InputKind::RenderScript) - .Default(InputKind::Unknown); + .Case("c", Language::C) + .Case("cl", Language::OpenCL) + .Case("cuda", Language::CUDA) + .Case("hip", Language::HIP) + .Case("c++", Language::CXX) + .Case("objective-c", Language::ObjC) + .Case("objective-c++", Language::ObjCXX) + .Case("renderscript", Language::RenderScript) + .Default(Language::Unknown); // "objc[++]-cpp-output" is an acceptable synonym for // "objective-c[++]-cpp-output". if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap) DashX = llvm::StringSwitch<InputKind>(XValue) - .Case("objc", InputKind::ObjC) - .Case("objc++", InputKind::ObjCXX) - .Default(InputKind::Unknown); + .Case("objc", Language::ObjC) + .Case("objc++", Language::ObjCXX) + .Default(Language::Unknown); // Some special cases cannot be combined with suffixes. if (DashX.isUnknown() && !Preprocessed && !ModuleMap && !IsHeaderFile) DashX = llvm::StringSwitch<InputKind>(XValue) - .Case("cpp-output", InputKind(InputKind::C).getPreprocessed()) - .Case("assembler-with-cpp", InputKind::Asm) + .Case("cpp-output", InputKind(Language::C).getPreprocessed()) + .Case("assembler-with-cpp", Language::Asm) .Cases("ast", "pcm", - InputKind(InputKind::Unknown, InputKind::Precompiled)) - .Case("ir", InputKind::LLVM_IR) - .Default(InputKind::Unknown); + InputKind(Language::Unknown, InputKind::Precompiled)) + .Case("ir", Language::LLVM_IR) + .Default(Language::Unknown); if (DashX.isUnknown()) Diags.Report(diag::err_drv_invalid_value) @@ -1940,7 +2010,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, StringRef(Inputs[i]).rsplit('.').second); // FIXME: Warn on this? if (IK.isUnknown()) - IK = InputKind::C; + IK = Language::C; // FIXME: Remove this hack. if (i == 0) DashX = IK; @@ -1997,6 +2067,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, 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); @@ -2011,6 +2082,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0); Opts.ModulesValidateSystemHeaders = Args.hasArg(OPT_fmodules_validate_system_headers); + Opts.ValidateASTInputFilesContent = + Args.hasArg(OPT_fvalidate_ast_input_files_content); if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ)) Opts.ModuleFormat = A->getValue(); @@ -2114,7 +2187,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, // FIXME: Perhaps a better model would be for a single source file to have // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std) // simultaneously active? - if (IK.getLanguage() == InputKind::Asm) { + if (IK.getLanguage() == Language::Asm) { Opts.AsmPreprocessor = 1; } else if (IK.isObjectiveC()) { Opts.ObjC = 1; @@ -2123,17 +2196,17 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (LangStd == LangStandard::lang_unspecified) { // Based on the base language, pick one. switch (IK.getLanguage()) { - case InputKind::Unknown: - case InputKind::LLVM_IR: + case Language::Unknown: + case Language::LLVM_IR: llvm_unreachable("Invalid input kind!"); - case InputKind::OpenCL: + case Language::OpenCL: LangStd = LangStandard::lang_opencl10; break; - case InputKind::CUDA: + case Language::CUDA: LangStd = LangStandard::lang_cuda; break; - case InputKind::Asm: - case InputKind::C: + case Language::Asm: + case Language::C: #if defined(CLANG_DEFAULT_STD_C) LangStd = CLANG_DEFAULT_STD_C; #else @@ -2144,25 +2217,25 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, LangStd = LangStandard::lang_gnu11; #endif break; - case InputKind::ObjC: + case Language::ObjC: #if defined(CLANG_DEFAULT_STD_C) LangStd = CLANG_DEFAULT_STD_C; #else LangStd = LangStandard::lang_gnu11; #endif break; - case InputKind::CXX: - case InputKind::ObjCXX: + case Language::CXX: + case Language::ObjCXX: #if defined(CLANG_DEFAULT_STD_CXX) LangStd = CLANG_DEFAULT_STD_CXX; #else LangStd = LangStandard::lang_gnucxx14; #endif break; - case InputKind::RenderScript: + case Language::RenderScript: LangStd = LangStandard::lang_c99; break; - case InputKind::HIP: + case Language::HIP: LangStd = LangStandard::lang_hip; break; } @@ -2182,6 +2255,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; + Opts.GNUCVersion = 0; Opts.HexFloats = Std.hasHexFloats(); Opts.ImplicitInt = Std.hasImplicitInt(); @@ -2202,7 +2276,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (Opts.OpenCL) { Opts.AltiVec = 0; Opts.ZVector = 0; - Opts.LaxVectorConversions = 0; + Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::None); Opts.setDefaultFPContractMode(LangOptions::FPC_On); Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; @@ -2219,13 +2293,13 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, } } - Opts.HIP = IK.getLanguage() == InputKind::HIP; - Opts.CUDA = IK.getLanguage() == InputKind::CUDA || Opts.HIP; + Opts.HIP = IK.getLanguage() == Language::HIP; + Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP; if (Opts.CUDA) // Set default FP_CONTRACT to FAST. Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); - Opts.RenderScript = IK.getLanguage() == InputKind::RenderScript; + Opts.RenderScript = IK.getLanguage() == Language::RenderScript; if (Opts.RenderScript) { Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; @@ -2273,32 +2347,31 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S) { switch (IK.getLanguage()) { - case InputKind::Unknown: - case InputKind::LLVM_IR: + case Language::Unknown: + case Language::LLVM_IR: llvm_unreachable("should not parse language flags for this input"); - case InputKind::C: - case InputKind::ObjC: - case InputKind::RenderScript: - return S.getLanguage() == InputKind::C; + case Language::C: + case Language::ObjC: + case Language::RenderScript: + return S.getLanguage() == Language::C; - case InputKind::OpenCL: - return S.getLanguage() == InputKind::OpenCL; + case Language::OpenCL: + return S.getLanguage() == Language::OpenCL; - case InputKind::CXX: - case InputKind::ObjCXX: - return S.getLanguage() == InputKind::CXX; + case Language::CXX: + case Language::ObjCXX: + return S.getLanguage() == Language::CXX; - case InputKind::CUDA: + case Language::CUDA: // FIXME: What -std= values should be permitted for CUDA compilations? - return S.getLanguage() == InputKind::CUDA || - S.getLanguage() == InputKind::CXX; + return S.getLanguage() == Language::CUDA || + S.getLanguage() == Language::CXX; - case InputKind::HIP: - return S.getLanguage() == InputKind::CXX || - S.getLanguage() == InputKind::HIP; + case Language::HIP: + return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP; - case InputKind::Asm: + case Language::Asm: // Accept (and ignore) all -std= values. // FIXME: The -std= value is not ignored; it affects the tokenization // and preprocessing rules if we're preprocessing this asm input. @@ -2311,29 +2384,29 @@ static bool IsInputCompatibleWithStandard(InputKind IK, /// Get language name for given input kind. static const StringRef GetInputKindName(InputKind IK) { switch (IK.getLanguage()) { - case InputKind::C: + case Language::C: return "C"; - case InputKind::ObjC: + case Language::ObjC: return "Objective-C"; - case InputKind::CXX: + case Language::CXX: return "C++"; - case InputKind::ObjCXX: + case Language::ObjCXX: return "Objective-C++"; - case InputKind::OpenCL: + case Language::OpenCL: return "OpenCL"; - case InputKind::CUDA: + case Language::CUDA: return "CUDA"; - case InputKind::RenderScript: + case Language::RenderScript: return "RenderScript"; - case InputKind::HIP: + case Language::HIP: return "HIP"; - case InputKind::Asm: + case Language::Asm: return "Asm"; - case InputKind::LLVM_IR: + case Language::LLVM_IR: return "LLVM IR"; - case InputKind::Unknown: + case Language::Unknown: break; } llvm_unreachable("unknown input language"); @@ -2346,13 +2419,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; if (const Arg *A = Args.getLastArg(OPT_std_EQ)) { - LangStd = llvm::StringSwitch<LangStandard::Kind>(A->getValue()) -#define LANGSTANDARD(id, name, lang, desc, features) \ - .Case(name, LangStandard::lang_##id) -#define LANGSTANDARD_ALIAS(id, alias) \ - .Case(alias, LangStandard::lang_##id) -#include "clang/Frontend/LangStandards.def" - .Default(LangStandard::lang_unspecified); + LangStd = LangStandard::getLangKind(A->getValue()); if (LangStd == LangStandard::lang_unspecified) { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); @@ -2370,13 +2437,13 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, #define LANGSTANDARD_ALIAS(id, alias) \ if (KindValue == LangStandard::lang_##id) ++NumAliases; #define LANGSTANDARD_ALIAS_DEPR(id, alias) -#include "clang/Frontend/LangStandards.def" +#include "clang/Basic/LangStandards.def" Diag << NumAliases; #define LANGSTANDARD(id, name, lang, desc, features) #define LANGSTANDARD_ALIAS(id, alias) \ if (KindValue == LangStandard::lang_##id) Diag << alias; #define LANGSTANDARD_ALIAS_DEPR(id, alias) -#include "clang/Frontend/LangStandards.def" +#include "clang/Basic/LangStandards.def" } } } else { @@ -2408,7 +2475,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11) .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12) .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20) - .Case("c++", LangStandard::lang_openclcpp) + .Cases("clc++", "CLC++", LangStandard::lang_openclcpp) .Default(LangStandard::lang_unspecified); if (OpenCLLangStd == LangStandard::lang_unspecified) { @@ -2461,6 +2528,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.CUDADeviceApproxTranscendentals = 1; Opts.GPURelocatableDeviceCode = Args.hasArg(OPT_fgpu_rdc); + Opts.HIPUseNewLaunchAPI = Args.hasArg(OPT_fhip_new_launch_api); if (Opts.ObjC) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { @@ -2512,6 +2580,21 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, (Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX); } + if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) { + // Check that the version has 1 to 3 components and the minor and patch + // versions fit in two decimal digits. + VersionTuple GNUCVer; + bool Invalid = GNUCVer.tryParse(A->getValue()); + unsigned Major = GNUCVer.getMajor(); + unsigned Minor = GNUCVer.getMinor().getValueOr(0); + unsigned Patch = GNUCVer.getSubminor().getValueOr(0); + if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) { + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch; + } + if (Args.hasArg(OPT_fgnu89_inline)) { if (Opts.CPlusPlus) Diags.Report(diag::err_drv_argument_not_allowed_with) @@ -2611,8 +2694,18 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings); Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings, Opts.ConstStrings); - if (Args.hasArg(OPT_fno_lax_vector_conversions)) - Opts.LaxVectorConversions = 0; + if (Arg *A = Args.getLastArg(OPT_flax_vector_conversions_EQ)) { + using LaxKind = LangOptions::LaxVectorConversionKind; + if (auto Kind = llvm::StringSwitch<Optional<LaxKind>>(A->getValue()) + .Case("none", LaxKind::None) + .Case("integer", LaxKind::Integer) + .Case("all", LaxKind::All) + .Default(llvm::None)) + Opts.setLaxVectorConversions(*Kind); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } if (Args.hasArg(OPT_fno_threadsafe_statics)) Opts.ThreadsafeStatics = 0; Opts.Exceptions = Args.hasArg(OPT_fexceptions); @@ -2630,9 +2723,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.FixedPoint; // Handle exception personalities - Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions, - options::OPT_fseh_exceptions, - options::OPT_fdwarf_exceptions); + Arg *A = Args.getLastArg( + options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions, + options::OPT_fdwarf_exceptions, options::OPT_fwasm_exceptions); if (A) { const Option &Opt = A->getOption(); llvm::Triple T(TargetOpts.Triple); @@ -2643,6 +2736,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions); Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions); Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions); + Opts.WasmExceptions = Opt.matches(options::OPT_fwasm_exceptions); } Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind); @@ -2727,6 +2821,10 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, getLastArgIntValue(Args, OPT_fconstexpr_depth, 512, Diags); Opts.ConstexprStepLimit = getLastArgIntValue(Args, OPT_fconstexpr_steps, 1048576, Diags); + Opts.EnableNewConstInterp = + Args.hasArg(OPT_fexperimental_new_constant_interpreter); + Opts.ForceNewConstInterp = + Args.hasArg(OPT_fforce_experimental_new_constant_interpreter); Opts.BracketDepth = getLastArgIntValue(Args, OPT_fbracket_depth, 256, Diags); Opts.DelayedTemplateParsing = Args.hasArg(OPT_fdelayed_template_parsing); Opts.NumLargeByValueCopy = @@ -2876,8 +2974,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } - // Check if -fopenmp is specified. - Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0; + // Check if -fopenmp is specified and set default version to 4.5. + Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 45 : 0; // Check if -fopenmp-simd is specified. bool IsSimdSpecified = Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd, @@ -3108,6 +3206,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setClangABICompat(LangOptions::ClangABI::Ver6); else if (Major <= 7) Opts.setClangABICompat(LangOptions::ClangABI::Ver7); + else if (Major <= 9) + Opts.setClangABICompat(LangOptions::ClangABI::Ver9); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); @@ -3136,8 +3236,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::GenerateModuleInterface: case frontend::GenerateHeaderModule: case frontend::GeneratePCH: - case frontend::GenerateInterfaceYAMLExpV1: - case frontend::GenerateInterfaceTBEExpV1: + case frontend::GenerateInterfaceIfsExpV1: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: case frontend::VerifyPCH: @@ -3253,6 +3352,8 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, // "editor placeholder in source file" error in PP only mode. if (isStrictlyPreprocessorAction(Action)) Opts.LexEditorPlaceholders = false; + + Opts.SetUpStaticAnalyzer = Args.hasArg(OPT_setup_static_analyzer); } static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, @@ -3315,18 +3416,16 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, - const char *const *ArgBegin, - const char *const *ArgEnd, + ArrayRef<const char *> CommandLineArgs, DiagnosticsEngine &Diags) { bool Success = true; // Parse the arguments. - std::unique_ptr<OptTable> Opts = createDriverOptTable(); + const OptTable &Opts = getDriverOptTable(); const unsigned IncludedFlagsBitmask = options::CC1Option; unsigned MissingArgIndex, MissingArgCount; - InputArgList Args = - Opts->ParseArgs(llvm::makeArrayRef(ArgBegin, ArgEnd), MissingArgIndex, - MissingArgCount, IncludedFlagsBitmask); + InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex, + MissingArgCount, IncludedFlagsBitmask); LangOptions &LangOpts = *Res.getLangOpts(); // Check for missing argument error. @@ -3340,7 +3439,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, for (const auto *A : Args.filtered(OPT_UNKNOWN)) { auto ArgString = A->getAsString(Args); std::string Nearest; - if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) + if (Opts.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) Diags.Report(diag::err_drv_unknown_argument) << ArgString; else Diags.Report(diag::err_drv_unknown_argument_with_suggestion) @@ -3351,6 +3450,11 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Success &= ParseAnalyzerArgs(*Res.getAnalyzerOpts(), Args, Diags); Success &= ParseMigratorArgs(Res.getMigratorOpts(), Args); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), Args); + if (!Res.getDependencyOutputOpts().OutputFile.empty() && + Res.getDependencyOutputOpts().Targets.empty()) { + Diags.Report(diag::err_fe_dependency_file_requires_MT); + Success = false; + } Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, false /*DefaultDiagColor*/, false /*DefaultShowOpt*/); @@ -3366,7 +3470,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Res.getFileSystemOpts().WorkingDir); llvm::Triple T(Res.getTargetOpts().Triple); if (DashX.getFormat() == InputKind::Precompiled || - DashX.getLanguage() == InputKind::LLVM_IR) { + DashX.getLanguage() == Language::LLVM_IR) { // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the // PassManager in BackendUtil.cpp. They need to be initializd no matter // what the input type is. @@ -3380,7 +3484,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Diags, LangOpts.Sanitize); } else { // Other LangOpts are only initialized when the input is not AST or LLVM IR. - // FIXME: Should we really be calling this for an InputKind::Asm input? + // FIXME: Should we really be calling this for an Language::Asm input? ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), Res.getPreprocessorOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) @@ -3393,6 +3497,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, } } + if (Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) + Res.FrontendOpts.LLVMArgs.push_back("-pgo-warn-misexpect"); + LangOpts.FunctionAlignment = getLastArgIntValue(Args, OPT_function_alignment, 0, Diags); @@ -3440,6 +3547,7 @@ std::string CompilerInvocation::getModuleHash() const { using llvm::hash_code; using llvm::hash_value; using llvm::hash_combine; + using llvm::hash_combine_range; // Start the signature with the compiler version. // FIXME: We'd rather use something more cryptographically sound than @@ -3494,6 +3602,24 @@ std::string CompilerInvocation::getModuleHash() const { hsOpts.ModulesValidateDiagnosticOptions); code = hash_combine(code, hsOpts.ResourceDir); + if (hsOpts.ModulesStrictContextHash) { + hash_code SHPC = hash_combine_range(hsOpts.SystemHeaderPrefixes.begin(), + hsOpts.SystemHeaderPrefixes.end()); + hash_code UEC = hash_combine_range(hsOpts.UserEntries.begin(), + hsOpts.UserEntries.end()); + code = hash_combine(code, hsOpts.SystemHeaderPrefixes.size(), SHPC, + hsOpts.UserEntries.size(), UEC); + + const DiagnosticOptions &diagOpts = getDiagnosticOpts(); + #define DIAGOPT(Name, Bits, Default) \ + code = hash_combine(code, diagOpts.Name); + #define ENUM_DIAGOPT(Name, Type, Bits, Default) \ + code = hash_combine(code, diagOpts.get##Name()); + #include "clang/Basic/DiagnosticOptions.def" + #undef DIAGOPT + #undef ENUM_DIAGOPT + } + // Extend the signature with the user build path. code = hash_combine(code, hsOpts.ModuleUserBuildPath); |