diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:04:05 +0000 |
commit | 676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch) | |
tree | 02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib/Frontend/CompilerInvocation.cpp | |
parent | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff) |
Notes
Diffstat (limited to 'lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 409 |
1 files changed, 331 insertions, 78 deletions
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 78e6babd0251..3e6528c25982 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -11,6 +11,7 @@ #include "TestModuleFileExtension.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/CommentOptions.h" #include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/Diagnostic.h" @@ -23,17 +24,16 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" -#include "clang/Basic/VirtualFileSystem.h" #include "clang/Basic/Visibility.h" #include "clang/Basic/XRayInstr.h" #include "clang/Config/config.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" -#include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/CommandLineSourceLoc.h" #include "clang/Frontend/DependencyOutputOptions.h" #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" @@ -55,6 +55,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/Linker/Linker.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Option/Arg.h" @@ -76,6 +77,7 @@ #include "llvm/Support/Process.h" #include "llvm/Support/Regex.h" #include "llvm/Support/VersionTuple.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" #include <algorithm> @@ -119,25 +121,25 @@ CompilerInvocationBase::~CompilerInvocationBase() = default; static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { - unsigned DefaultOpt = 0; + unsigned DefaultOpt = llvm::CodeGenOpt::None; if (IK.getLanguage() == InputKind::OpenCL && !Args.hasArg(OPT_cl_opt_disable)) - DefaultOpt = 2; + DefaultOpt = llvm::CodeGenOpt::Default; if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { if (A->getOption().matches(options::OPT_O0)) - return 0; + return llvm::CodeGenOpt::None; if (A->getOption().matches(options::OPT_Ofast)) - return 3; + return llvm::CodeGenOpt::Aggressive; assert(A->getOption().matches(options::OPT_O)); StringRef S(A->getValue()); if (S == "s" || S == "z" || S.empty()) - return 2; + return llvm::CodeGenOpt::Default; if (S == "g") - return 1; + return llvm::CodeGenOpt::Less; return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags); } @@ -180,6 +182,11 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, } } +// Parse the Static Analyzer configuration. If \p Diags is set to nullptr, +// it won't verify the input. +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine *Diags); + static void getAllNoBuiltinFuncValues(ArgList &Args, std::vector<std::string> &Funcs) { SmallVector<const char *, 8> Values; @@ -278,19 +285,24 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help); + Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help); Opts.ShowEnabledCheckerList = Args.hasArg(OPT_analyzer_list_enabled_checkers); + Opts.ShouldEmitErrorsOnInvalidConfigValue = + /* negated */!llvm::StringSwitch<bool>( + Args.getLastArgValue(OPT_analyzer_config_compatibility_mode)) + .Case("true", true) + .Case("false", false) + .Default(false); Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks); Opts.visualizeExplodedGraphWithGraphViz = Args.hasArg(OPT_analyzer_viz_egraph_graphviz); - Opts.visualizeExplodedGraphWithUbiGraph = - Args.hasArg(OPT_analyzer_viz_egraph_ubigraph); + Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph); Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted); 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.eagerlyAssumeBinOpBifurcation = Args.hasArg(OPT_analyzer_eagerly_assume); Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function); Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG); Opts.TrimGraph = Args.hasArg(OPT_trim_egraph); @@ -317,7 +329,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, // Go through the analyzer configuration options. for (const auto *A : Args.filtered(OPT_analyzer_config)) { - A->claim(); + // We can have a list of comma separated config names, e.g: // '-analyzer-config key1=val1,key2=val2' StringRef configList = A->getValue(); @@ -339,10 +351,25 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Success = false; break; } + + // TODO: Check checker options too, possibly in CheckerRegistry. + // Leave unknown non-checker configs unclaimed. + if (!key.contains(":") && Opts.isUnknownAnalyzerConfig(key)) { + if (Opts.ShouldEmitErrorsOnInvalidConfigValue) + Diags.Report(diag::err_analyzer_config_unknown) << key; + continue; + } + + A->claim(); Opts.Config[key] = val; } } + if (Opts.ShouldEmitErrorsOnInvalidConfigValue) + parseAnalyzerConfigs(Opts, &Diags); + else + parseAnalyzerConfigs(Opts, nullptr); + llvm::raw_string_ostream os(Opts.FullCompilerInvocation); for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) { if (i != 0) @@ -354,6 +381,91 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, return Success; } +static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, + StringRef OptionName, StringRef DefaultVal) { + return Config.insert({OptionName, DefaultVal}).first->second; +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + DiagnosticsEngine *Diags, + StringRef &OptionField, StringRef Name, + StringRef DefaultVal) { + // String options may be known to invalid (e.g. if the expected string is a + // file name, but the file does not exist), those will have to be checked in + // parseConfigs. + OptionField = getStringOption(Config, Name, DefaultVal); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + DiagnosticsEngine *Diags, + bool &OptionField, StringRef Name, bool DefaultVal) { + auto PossiblyInvalidVal = llvm::StringSwitch<Optional<bool>>( + getStringOption(Config, Name, (DefaultVal ? "true" : "false"))) + .Case("true", true) + .Case("false", false) + .Default(None); + + if (!PossiblyInvalidVal) { + if (Diags) + Diags->Report(diag::err_analyzer_config_invalid_input) + << Name << "a boolean"; + else + OptionField = DefaultVal; + } else + OptionField = PossiblyInvalidVal.getValue(); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + DiagnosticsEngine *Diags, + unsigned &OptionField, StringRef Name, + unsigned DefaultVal) { + + OptionField = DefaultVal; + bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal)) + .getAsInteger(10, OptionField); + if (Diags && HasFailed) + Diags->Report(diag::err_analyzer_config_invalid_input) + << Name << "an unsigned"; +} + +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine *Diags) { + // TODO: There's no need to store the entire configtable, it'd be plenty + // enough tostore checker options. + +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL); + +#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ + SHALLOW_VAL, DEEP_VAL) \ + switch (AnOpts.getUserMode()) { \ + case UMK_Shallow: \ + initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, SHALLOW_VAL); \ + break; \ + case UMK_Deep: \ + initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEEP_VAL); \ + break; \ + } \ + +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef ANALYZER_OPTION +#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE + + // At this point, AnalyzerOptions is configured. Let's validate some options. + + if (!Diags) + return; + + if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir)) + Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir" + << "a filename"; + + if (!AnOpts.ModelPath.empty() && + !llvm::sys::fs::is_directory(AnOpts.ModelPath)) + Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path" + << "a filename"; +} + static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) { Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error); Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal); @@ -369,7 +481,7 @@ 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 == "large" || Value == "tiny") return Value; Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; } @@ -568,6 +680,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, unsigned Val = llvm::StringSwitch<unsigned>(A->getValue()) .Case("line-tables-only", codegenoptions::DebugLineTablesOnly) + .Case("line-directives-only", codegenoptions::DebugDirectivesOnly) .Case("limited", codegenoptions::LimitedDebugInfo) .Case("standalone", codegenoptions::FullDebugInfo) .Default(~0U); @@ -592,12 +705,29 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags); Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); Opts.EmitCodeView = Args.hasArg(OPT_gcodeview); + Opts.CodeViewGHash = Args.hasArg(OPT_gcodeview_ghash); Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro); Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables); Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std); - Opts.EnableSplitDwarf = Args.hasArg(OPT_enable_split_dwarf); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining); + + if (Arg *A = + Args.getLastArg(OPT_enable_split_dwarf, OPT_enable_split_dwarf_EQ)) { + if (A->getOption().matches(options::OPT_enable_split_dwarf)) { + Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission); + } else { + StringRef Name = A->getValue(); + if (Name == "single") + Opts.setSplitDwarfMode(CodeGenOptions::SingleFileFission); + else if (Name == "split") + Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << Name; + } + } + 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); @@ -614,6 +744,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers); Opts.DisableO0ImplyOptNone = Args.hasArg(OPT_disable_O0_optnone); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); + Opts.IndirectTlsSegRefs = Args.hasArg(OPT_mno_tls_direct_seg_refs); Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables); Opts.UseRegisterSizedBitfieldAccess = Args.hasArg( OPT_fuse_register_sized_bitfield_access); @@ -625,6 +756,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants); Opts.NoCommon = Args.hasArg(OPT_fno_common); Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float); @@ -643,7 +775,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); Opts.DebugInfoForProfiling = Args.hasFlag( OPT_fdebug_info_for_profiling, OPT_fno_debug_info_for_profiling, false); - Opts.GnuPubnames = Args.hasArg(OPT_ggnu_pubnames); + Opts.DebugNameTable = static_cast<unsigned>( + Args.hasArg(OPT_ggnu_pubnames) + ? llvm::DICompileUnit::DebugNameTableKind::GNU + : Args.hasArg(OPT_gpubnames) + ? llvm::DICompileUnit::DebugNameTableKind::Default + : llvm::DICompileUnit::DebugNameTableKind::None); + Opts.DebugRangesBaseAddress = Args.hasArg(OPT_fdebug_ranges_base_address); setPGOInstrumentor(Opts, Args, Diags); Opts.InstrProfileOutput = @@ -652,6 +790,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); + if (!Opts.ProfileRemappingFile.empty() && !Opts.ExperimentalNewPassManager) { + Diags.Report(diag::err_drv_argument_only_allowed_with) + << Args.getLastArg(OPT_fprofile_remapping_file_EQ)->getAsString(Args) + << "-fexperimental-new-pass-manager"; + } Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); @@ -664,7 +809,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RegisterGlobalDtorsWithAtExit = Args.hasArg(OPT_fregister_global_dtors_with_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); - Opts.CodeModel = getCodeModel(Args, Diags); + Opts.CodeModel = TargetOpts.CodeModel; Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg)); @@ -762,6 +907,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S; } 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) Diags.Report(diag::err_drv_argument_only_allowed_with) @@ -797,6 +943,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum); Opts.CoverageNoFunctionNamesInData = Args.hasArg(OPT_coverage_no_function_names_in_data); + Opts.ProfileFilterFiles = + 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); if (Args.hasArg(OPT_coverage_version_EQ)) { @@ -844,7 +994,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, for (const auto &arg : ASL) { StringRef ArgStr(arg); Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end()); - // using \00 to seperate each commandline options. + // using \00 to separate each commandline options. Opts.CmdArgs.push_back('\0'); } } @@ -912,10 +1062,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); for (auto *A : - Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) { + Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) { CodeGenOptions::BitcodeFileToLink F; F.Filename = A->getValue(); - if (A->getOption().matches(OPT_mlink_cuda_bitcode)) { + if (A->getOption().matches(OPT_mlink_builtin_bitcode)) { F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded; // When linking CUDA bitcode, propagate function attributes so that // e.g. libdevice gets fast-math attrs if we're building with fast-math. @@ -955,11 +1105,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_fsanitize_cfi_icall_generalize_pointers); Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats); if (Arg *A = Args.getLastArg( - OPT_fsanitize_address_poison_class_member_array_new_cookie, - OPT_fno_sanitize_address_poison_class_member_array_new_cookie)) { - Opts.SanitizeAddressPoisonClassMemberArrayNewCookie = + OPT_fsanitize_address_poison_custom_array_cookie, + OPT_fno_sanitize_address_poison_custom_array_cookie)) { + Opts.SanitizeAddressPoisonCustomArrayCookie = A->getOption().getID() == - OPT_fsanitize_address_poison_class_member_array_new_cookie; + OPT_fsanitize_address_poison_custom_array_cookie; } if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope, OPT_fno_sanitize_address_use_after_scope)) { @@ -968,6 +1118,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.SanitizeAddressGlobalsDeadStripping = Args.hasArg(OPT_fsanitize_address_globals_dead_stripping); + if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_odr_indicator, + OPT_fno_sanitize_address_use_odr_indicator)) { + Opts.SanitizeAddressUseOdrIndicator = + A->getOption().getID() == OPT_fsanitize_address_use_odr_indicator; + } Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); @@ -1003,6 +1158,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } + + if (Args.hasArg(OPT_fno_objc_convert_messages_to_runtime_calls)) + Opts.ObjCConvertMessagesToRuntimeCalls = 0; + if (Args.getLastArg(OPT_femulated_tls) || Args.getLastArg(OPT_fno_emulated_tls)) { Opts.ExplicitEmulatedTLS = true; @@ -1125,6 +1284,44 @@ 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); + + Opts.DefaultFunctionAttrs = Args.getAllArgValues(OPT_default_function_attr); + return Success; } @@ -1316,7 +1513,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Success = false; } else - llvm::sort(Opts.VerifyPrefixes.begin(), Opts.VerifyPrefixes.end()); + llvm::sort(Opts.VerifyPrefixes); DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None; Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=", Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), @@ -1425,17 +1622,17 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::EmitObj; break; case OPT_fixit_EQ: Opts.FixItSuffix = A->getValue(); - // fall-through! + LLVM_FALLTHROUGH; case OPT_fixit: Opts.ProgramAction = frontend::FixIt; break; case OPT_emit_module: Opts.ProgramAction = frontend::GenerateModule; break; case OPT_emit_module_interface: Opts.ProgramAction = frontend::GenerateModuleInterface; break; + case OPT_emit_header_module: + Opts.ProgramAction = frontend::GenerateHeaderModule; break; case OPT_emit_pch: Opts.ProgramAction = frontend::GeneratePCH; break; - case OPT_emit_pth: - Opts.ProgramAction = frontend::GeneratePTH; break; case OPT_init_only: Opts.ProgramAction = frontend::InitOnly; break; case OPT_fsyntax_only: @@ -1444,8 +1641,6 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::ModuleFileInfo; break; case OPT_verify_pch: Opts.ProgramAction = frontend::VerifyPCH; break; - case OPT_print_decl_contexts: - Opts.ProgramAction = frontend::PrintDeclContext; break; case OPT_print_preamble: Opts.ProgramAction = frontend::PrintPreamble; break; case OPT_E: @@ -1550,8 +1745,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.OverrideRecordLayoutsFile = Args.getLastArgValue(OPT_foverride_record_layout_EQ); - Opts.AuxTriple = - llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple)); + Opts.AuxTriple = Args.getLastArgValue(OPT_aux_triple); Opts.StatsFile = Args.getLastArgValue(OPT_stats_file); if (const Arg *A = Args.getLastArg(OPT_arcmt_check, @@ -1867,7 +2061,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, if (IK.getLanguage() == InputKind::Asm) { Opts.AsmPreprocessor = 1; } else if (IK.isObjectiveC()) { - Opts.ObjC1 = Opts.ObjC2 = 1; + Opts.ObjC = 1; } if (LangStd == LangStandard::lang_unspecified) { @@ -2130,6 +2324,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } + if (Args.hasArg(OPT_fno_dllexport_inlines)) + Opts.DllExportInlines = false; + if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { StringRef Name = A->getValue(); if (Name == "full" || Name == "branch") { @@ -2196,9 +2393,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals)) Opts.CUDADeviceApproxTranscendentals = 1; - Opts.CUDARelocatableDeviceCode = Args.hasArg(OPT_fcuda_rdc); + Opts.GPURelocatableDeviceCode = Args.hasArg(OPT_fgpu_rdc); - if (Opts.ObjC1) { + if (Opts.ObjC) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { StringRef value = arg->getValue(); if (Opts.ObjCRuntime.tryParse(value)) @@ -2265,8 +2462,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_print_ivar_layout)) Opts.ObjCGCBitmapPrint = 1; + if (Args.hasArg(OPT_fno_constant_cfstrings)) Opts.NoConstantCFStrings = 1; + if (const auto *A = Args.getLastArg(OPT_fcf_runtime_abi_EQ)) + Opts.CFRuntime = + llvm::StringSwitch<LangOptions::CoreFoundationABI>(A->getValue()) + .Cases("unspecified", "standalone", "objc", + LangOptions::CoreFoundationABI::ObjectiveC) + .Cases("swift", "swift-5.0", + LangOptions::CoreFoundationABI::Swift5_0) + .Case("swift-4.2", LangOptions::CoreFoundationABI::Swift4_2) + .Case("swift-4.1", LangOptions::CoreFoundationABI::Swift4_1) + .Default(LangOptions::CoreFoundationABI::ObjectiveC); if (Args.hasArg(OPT_fzvector)) Opts.ZVector = 1; @@ -2291,6 +2499,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fvisibility_inlines_hidden)) Opts.InlineVisibilityHidden = 1; + if (Args.hasArg(OPT_fvisibility_global_new_delete_hidden)) + Opts.GlobalAllocationFunctionVisibilityHidden = 1; + if (Args.hasArg(OPT_ftrapv)) { Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping); // Set the handler, if one is specified. @@ -2314,7 +2525,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, VT.getSubminor().getValueOr(0); } - // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs + // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs // is specified, or -std is set to a conforming mode. // Trigraphs are disabled by default in c++1z onwards. Opts.Trigraphs = !Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17; @@ -2395,7 +2606,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.hasArg(OPT_fchar8__t); + Opts.Char8 = Args.hasFlag(OPT_fchar8__t, OPT_fno_char8__t, Opts.CPlusPlus2a); if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) { Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue()) .Case("char", 1) @@ -2478,7 +2689,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.CurrentModule = Opts.ModuleName; Opts.AppExt = Args.hasArg(OPT_fapplication_extension); Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature); - llvm::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end()); + llvm::sort(Opts.ModuleFeatures); Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type); Opts.NativeHalfArgsAndReturns |= Args.hasArg(OPT_fnative_half_arguments_and_returns); // Enable HalfArgsAndReturns if present in Args or if NativeHalfArgsAndReturns @@ -2627,6 +2838,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.Exceptions = 0; Opts.CXXExceptions = 0; } + if (Opts.OpenMPIsDevice && T.isNVPTX()) { + Opts.OpenMPCUDANumSMs = + getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ, + Opts.OpenMPCUDANumSMs, Diags); + Opts.OpenMPCUDABlocksPerSM = + getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ, + Opts.OpenMPCUDABlocksPerSM, Diags); + } + + // Prevent auto-widening the representation of loop counters during an + // OpenMP collapse clause. + Opts.OpenMPOptimisticCollapse = + Args.hasArg(options::OPT_fopenmp_optimistic_collapse) ? 1 : 0; // Get the OpenMP target triples if any. if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) { @@ -2657,10 +2881,15 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, << Opts.OMPHostIRFile; } - // set CUDA mode for OpenMP target NVPTX if specified in options + // Set CUDA mode for OpenMP target NVPTX if specified in options Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() && Args.hasArg(options::OPT_fopenmp_cuda_mode); + // Set CUDA mode for OpenMP target NVPTX if specified in options + Opts.OpenMPCUDAForceFullRuntime = + Opts.OpenMPIsDevice && T.isNVPTX() && + Args.hasArg(options::OPT_fopenmp_cuda_force_full_runtime); + // Record whether the __DEPRECATED define was requested. Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro, OPT_fno_deprecated_macro, @@ -2718,6 +2947,19 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, case 3: Opts.setStackProtector(LangOptions::SSPReq); break; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init)) { + StringRef Val = A->getValue(); + if (Val == "uninitialized") + Opts.setTrivialAutoVarInit( + LangOptions::TrivialAutoVarInitKind::Uninitialized); + else if (Val == "zero") + Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Zero); + else if (Val == "pattern") + Opts.setTrivialAutoVarInit(LangOptions::TrivialAutoVarInitKind::Pattern); + else + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); @@ -2753,6 +2995,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // -fallow-editor-placeholders Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders); + Opts.RegisterStaticDestructors = !Args.hasArg(OPT_fno_cxx_static_destructors); + if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) { Opts.setClangABICompat(LangOptions::ClangABI::Latest); @@ -2776,6 +3020,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setClangABICompat(LangOptions::ClangABI::Ver4); else if (Major <= 6) Opts.setClangABICompat(LangOptions::ClangABI::Ver6); + else if (Major <= 7) + Opts.setClangABICompat(LangOptions::ClangABI::Ver7); } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); @@ -2802,13 +3048,12 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::FixIt: case frontend::GenerateModule: case frontend::GenerateModuleInterface: + case frontend::GenerateHeaderModule: case frontend::GeneratePCH: - case frontend::GeneratePTH: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: case frontend::VerifyPCH: case frontend::PluginAction: - case frontend::PrintDeclContext: case frontend::RewriteObjC: case frontend::RewriteTest: case frontend::RunAnalysis: @@ -2833,12 +3078,10 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action) { Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch); - Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth); + 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); - if (const Arg *A = Args.getLastArg(OPT_token_cache)) - Opts.TokenCache = A->getValue(); - else - Opts.TokenCache = Opts.ImplicitPTHInclude; Opts.UsePredefines = !Args.hasArg(OPT_undef); Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record); Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch); @@ -2943,6 +3186,7 @@ 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); if (Arg *A = Args.getLastArg(OPT_meabi)) { StringRef Value = A->getValue(); @@ -2971,6 +3215,14 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false); + if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) { + llvm::VersionTuple Version; + if (Version.tryParse(A->getValue())) + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + else + Opts.SDKVersion = Version; + } } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, @@ -3023,6 +3275,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Res.getTargetOpts(), Res.getFrontendOpts()); ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Res.getFileSystemOpts().WorkingDir); + llvm::Triple T(Res.getTargetOpts().Triple); if (DashX.getFormat() == InputKind::Precompiled || DashX.getLanguage() == InputKind::LLVM_IR) { // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the @@ -3037,12 +3290,18 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, LangOpts.Sanitize); } else { - // Other LangOpts are only initialzed when the input is not AST or LLVM IR. + // 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? ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), Res.getPreprocessorOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) LangOpts.ObjCExceptions = 1; + if (T.isOSDarwin() && DashX.isPreprocessed()) { + // Supress the darwin-specific 'stdlibcxx-not-found' diagnostic for + // preprocessed input as we don't expect it to be used with -std=libc++ + // anyway. + Res.getDiagnosticOpts().Warnings.push_back("no-stdlibcxx-not-found"); + } } LangOpts.FunctionAlignment = @@ -3064,7 +3323,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, // names. Res.getCodeGenOpts().DiscardValueNames &= !LangOpts.Sanitize.has(SanitizerKind::Address) && - !LangOpts.Sanitize.has(SanitizerKind::Memory); + !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) && + !LangOpts.Sanitize.has(SanitizerKind::Memory) && + !LangOpts.Sanitize.has(SanitizerKind::KernelMemory); ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags, Res.getFrontendOpts().ProgramAction); @@ -3072,7 +3333,6 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Res.getFrontendOpts().ProgramAction); // Turn on -Wspir-compat for SPIR target. - llvm::Triple T(Res.getTargetOpts().Triple); auto Arch = T.getArch(); if (Arch == llvm::Triple::spir || Arch == llvm::Triple::spir64) { Res.getDiagnosticOpts().Warnings.push_back("spir-compat"); @@ -3156,6 +3416,12 @@ std::string CompilerInvocation::getModuleHash() const { code = ext->hashExtension(code); } + // When compiling with -gmodules, also hash -fdebug-prefix-map as it + // affects the debug info in the PCM. + if (getCodeGenOpts().DebugTypeExtRefs) + for (const auto &KeyValue : getCodeGenOpts().DebugPrefixMap) + code = hash_combine(code, KeyValue.first, KeyValue.second); + // Extend the signature with the enabled sanitizers, if at least one is // enabled. Sanitizers which cannot affect AST generation aren't hashed. SanitizerSet SanHash = LangOpts->Sanitize; @@ -3195,53 +3461,40 @@ uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id, return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags); } -void BuryPointer(const void *Ptr) { - // This function may be called only a small fixed amount of times per each - // invocation, otherwise we do actually have a leak which we want to report. - // If this function is called more than kGraveYardMaxSize times, the pointers - // will not be properly buried and a leak detector will report a leak, which - // is what we want in such case. - static const size_t kGraveYardMaxSize = 16; - LLVM_ATTRIBUTE_UNUSED static const void *GraveYard[kGraveYardMaxSize]; - static std::atomic<unsigned> GraveYardSize; - unsigned Idx = GraveYardSize++; - if (Idx >= kGraveYardMaxSize) - return; - GraveYard[Idx] = Ptr; -} - -IntrusiveRefCntPtr<vfs::FileSystem> +IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags) { - return createVFSFromCompilerInvocation(CI, Diags, vfs::getRealFileSystem()); + return createVFSFromCompilerInvocation(CI, Diags, + llvm::vfs::getRealFileSystem()); } -IntrusiveRefCntPtr<vfs::FileSystem> -createVFSFromCompilerInvocation(const CompilerInvocation &CI, - DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<vfs::FileSystem> BaseFS) { +IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation( + const CompilerInvocation &CI, DiagnosticsEngine &Diags, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) { if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) return BaseFS; - IntrusiveRefCntPtr<vfs::OverlayFileSystem> Overlay( - new vfs::OverlayFileSystem(BaseFS)); + IntrusiveRefCntPtr<llvm::vfs::FileSystem> Result = BaseFS; // earlier vfs files are on the bottom for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = - BaseFS->getBufferForFile(File); + Result->getBufferForFile(File); if (!Buffer) { Diags.Report(diag::err_missing_vfs_overlay_file) << File; continue; } - IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML( - std::move(Buffer.get()), /*DiagHandler*/ nullptr, File); - if (FS) - Overlay->pushOverlay(FS); - else + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML( + std::move(Buffer.get()), /*DiagHandler*/ nullptr, File, + /*DiagContext*/ nullptr, Result); + if (!FS) { Diags.Report(diag::err_invalid_vfs_overlay) << File; + continue; + } + + Result = FS; } - return Overlay; + return Result; } } // namespace clang |