diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Frontend/CompilerInvocation.cpp | |
parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) |
Notes
Diffstat (limited to 'lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 576 |
1 files changed, 411 insertions, 165 deletions
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2e8a737de4e4..78e6babd0251 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1,4 +1,4 @@ -//===--- CompilerInvocation.cpp -------------------------------------------===// +//===- CompilerInvocation.cpp ---------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -10,54 +10,99 @@ #include "clang/Frontend/CompilerInvocation.h" #include "TestModuleFileExtension.h" #include "clang/Basic/Builtins.h" -#include "clang/Basic/FileManager.h" +#include "clang/Basic/CharInfo.h" +#include "clang/Basic/CommentOptions.h" +#include "clang/Basic/DebugInfoOptions.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/Sanitizers.h" +#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/Driver/Util.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/LangStandard.h" +#include "clang/Frontend/MigratorOptions.h" +#include "clang/Frontend/PreprocessorOutputOptions.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/PreprocessorOptions.h" -#include "clang/Serialization/ASTReader.h" +#include "clang/Sema/CodeCompleteOptions.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/Hashing.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/Twine.h" #include "llvm/Linker/Linker.h" +#include "llvm/MC/MCTargetOptions.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" +#include "llvm/Option/OptSpecifier.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/VersionTuple.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/ScopedPrinter.h" +#include <algorithm> #include <atomic> +#include <cassert> +#include <cstddef> +#include <cstring> #include <memory> -#include <sys/stat.h> -#include <system_error> +#include <string> +#include <tuple> +#include <utility> +#include <vector> + using namespace clang; +using namespace driver; +using namespace options; +using namespace llvm::opt; //===----------------------------------------------------------------------===// // Initialization. //===----------------------------------------------------------------------===// CompilerInvocationBase::CompilerInvocationBase() - : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()), - DiagnosticOpts(new DiagnosticOptions()), - HeaderSearchOpts(new HeaderSearchOptions()), - PreprocessorOpts(new PreprocessorOptions()) {} + : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()), + DiagnosticOpts(new DiagnosticOptions()), + HeaderSearchOpts(new HeaderSearchOptions()), + PreprocessorOpts(new PreprocessorOptions()) {} CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) : LangOpts(new LangOptions(*X.getLangOpts())), @@ -66,18 +111,12 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())), PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {} -CompilerInvocationBase::~CompilerInvocationBase() {} +CompilerInvocationBase::~CompilerInvocationBase() = default; //===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// -using namespace clang::driver; -using namespace clang::driver::options; -using namespace llvm::opt; - -// - static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { unsigned DefaultOpt = 0; @@ -91,7 +130,7 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, if (A->getOption().matches(options::OPT_Ofast)) return 3; - assert (A->getOption().matches(options::OPT_O)); + assert(A->getOption().matches(options::OPT_O)); StringRef S(A->getValue()); if (S == "s" || S == "z" || S.empty()) @@ -125,7 +164,7 @@ static unsigned getOptimizationLevelSize(ArgList &Args) { static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, OptSpecifier GroupWithValue, std::vector<std::string> &Diagnostics) { - for (Arg *A : Args.filtered(Group)) { + for (auto *A : Args.filtered(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. @@ -135,7 +174,7 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-")); } else { // Otherwise, add its value (for OPT_W_Joined and similar). - for (const char *Arg : A->getValues()) + for (const auto *Arg : A->getValues()) Diagnostics.emplace_back(Arg); } } @@ -157,7 +196,6 @@ static void getAllNoBuiltinFuncValues(ArgList &Args, static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { - using namespace options; bool Success = true; if (Arg *A = Args.getLastArg(OPT_analyzer_store)) { StringRef Name = A->getValue(); @@ -273,31 +311,31 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, StringRef checkerList = A->getValue(); SmallVector<StringRef, 4> checkers; checkerList.split(checkers, ","); - for (StringRef checker : checkers) + for (auto checker : checkers) Opts.CheckersControlList.emplace_back(checker, enable); } // Go through the analyzer configuration options. - for (const Arg *A : Args.filtered(OPT_analyzer_config)) { + 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(); SmallVector<StringRef, 4> configVals; configList.split(configVals, ","); - for (unsigned i = 0, e = configVals.size(); i != e; ++i) { + for (const auto &configVal : configVals) { StringRef key, val; - std::tie(key, val) = configVals[i].split("="); + std::tie(key, val) = configVal.split("="); if (val.empty()) { Diags.Report(SourceLocation(), - diag::err_analyzer_config_no_value) << configVals[i]; + diag::err_analyzer_config_no_value) << configVal; Success = false; break; } if (val.find('=') != StringRef::npos) { Diags.Report(SourceLocation(), diag::err_analyzer_config_multiple_values) - << configVals[i]; + << configVal; Success = false; break; } @@ -305,6 +343,14 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } } + llvm::raw_string_ostream os(Opts.FullCompilerInvocation); + for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) { + if (i != 0) + os << " "; + os << Args.getArgString(i); + } + os.flush(); + return Success; } @@ -330,18 +376,26 @@ static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) { return "default"; } -static StringRef getRelocModel(ArgList &Args, DiagnosticsEngine &Diags) { +static llvm::Reloc::Model getRelocModel(ArgList &Args, + DiagnosticsEngine &Diags) { if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) { StringRef Value = A->getValue(); - if (Value == "static" || Value == "pic" || Value == "ropi" || - Value == "rwpi" || Value == "ropi-rwpi" || Value == "dynamic-no-pic") - return Value; + 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 "pic"; + return llvm::Reloc::PIC_; } -/// \brief Create a new Regex instance out of the string value in \p RpassArg. +/// 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> GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args, @@ -392,6 +446,25 @@ static void parseSanitizerKinds(StringRef FlagName, } } +static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle, + ArgList &Args, DiagnosticsEngine &D, + XRayInstrSet &S) { + llvm::SmallVector<StringRef, 2> BundleParts; + llvm::SplitString(Bundle, BundleParts, ","); + for (const auto B : BundleParts) { + auto Mask = parseXRayInstrValue(B); + if (Mask == XRayInstrKind::None) + if (B != "none") + D.Report(diag::err_drv_invalid_value) << FlagName << Bundle; + else + S.Mask = Mask; + else if (Mask == XRayInstrKind::All) + S.Mask = Mask; + else + S.set(Mask, true); + } +} + // Set the profile kind for fprofile-instrument. static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { @@ -409,8 +482,7 @@ static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args, << S; return; } - CodeGenOptions::ProfileInstrKind Instrumentor = - static_cast<CodeGenOptions::ProfileInstrKind>(I); + auto Instrumentor = static_cast<CodeGenOptions::ProfileInstrKind>(I); Opts.setProfileInstr(Instrumentor); } @@ -434,8 +506,8 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts, static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, - const TargetOptions &TargetOpts) { - using namespace options; + const TargetOptions &TargetOpts, + const FrontendOptions &FrontendOpts) { bool Success = true; llvm::Triple Triple = llvm::Triple(TargetOpts.Triple); @@ -474,7 +546,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.ExperimentalNewPassManager = Args.hasFlag( OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager, - /* Default */ false); + /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER); Opts.DebugPassManager = Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager, @@ -529,6 +601,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); @@ -552,7 +625,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.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); + Opts.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants); Opts.NoCommon = Args.hasArg(OPT_fno_common); Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float); Opts.OptimizeSize = getOptimizationLevelSize(Args); @@ -580,33 +653,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (!Opts.ProfileInstrumentUsePath.empty()) setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath); - if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) { - Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest); - - StringRef Ver = A->getValue(); - std::pair<StringRef, StringRef> VerParts = Ver.split('.'); - unsigned Major, Minor = 0; - - // Check the version number is valid: either 3.x (0 <= x <= 9) or - // y or y.0 (4 <= y <= current version). - if (!VerParts.first.startswith("0") && - !VerParts.first.getAsInteger(10, Major) && - 3 <= Major && Major <= CLANG_VERSION_MAJOR && - (Major == 3 ? VerParts.second.size() == 1 && - !VerParts.second.getAsInteger(10, Minor) - : VerParts.first.size() == Ver.size() || - VerParts.second == "0")) { - // Got a valid version number. - if (Major == 3 && Minor <= 8) - Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8); - else if (Major <= 4) - Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4); - } else if (Ver != "latest") { - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << A->getValue(); - } - } - Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); @@ -615,6 +661,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); + Opts.RegisterGlobalDtorsWithAtExit = + Args.hasArg(OPT_fregister_global_dtors_with_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); Opts.CodeModel = getCodeModel(Args, Diags); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); @@ -623,6 +671,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || @@ -640,14 +690,20 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); + Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero) || + (Args.hasArg(OPT_fcuda_is_device) && + Args.hasArg(OPT_fcuda_flush_denormals_to_zero)); 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.BackendOptions = Args.getAllArgValues(OPT_backend_option); Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags); Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack); Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings); @@ -665,6 +721,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums); 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); @@ -682,6 +739,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, 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); @@ -689,14 +748,16 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables); + Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks); + Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate); Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ); - Opts.EmitSummaryIndex = false; + Opts.PrepareForThinLTO = false; if (Arg *A = Args.getLastArg(OPT_flto_EQ)) { StringRef S = A->getValue(); if (S == "thin") - Opts.EmitSummaryIndex = true; + Opts.PrepareForThinLTO = true; else if (S != "full") Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S; } @@ -707,6 +768,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, << A->getAsString(Args) << "-x ir"; Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ); } + if (Arg *A = Args.getLastArg(OPT_save_temps_EQ)) + Opts.SaveTempsFilePrefix = + llvm::StringSwitch<std::string>(A->getValue()) + .Case("obj", FrontendOpts.OutputFile) + .Default(llvm::sys::path::filename(FrontendOpts.OutputFile).str()); + Opts.ThinLinkBitcodeFile = Args.getLastArgValue(OPT_fthin_link_bitcode_EQ); Opts.MSVolatile = Args.hasArg(OPT_fms_volatile); @@ -719,6 +786,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name); Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); + Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard); + Opts.DisableGCov = Args.hasArg(OPT_test_coverage); Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); @@ -741,7 +810,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } } - // Handle -fembed-bitcode option. + // Handle -fembed-bitcode option. if (Arg *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) { StringRef Name = A->getValue(); unsigned Model = llvm::StringSwitch<unsigned>(Name) @@ -787,15 +856,44 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_finstrument_functions_after_inlining); Opts.InstrumentFunctionEntryBare = Args.hasArg(OPT_finstrument_function_entry_bare); - Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument); + + Opts.XRayInstrumentFunctions = + Args.hasArg(OPT_fxray_instrument); Opts.XRayAlwaysEmitCustomEvents = Args.hasArg(OPT_fxray_always_emit_customevents); + Opts.XRayAlwaysEmitTypedEvents = + Args.hasArg(OPT_fxray_always_emit_typedevents); Opts.XRayInstructionThreshold = getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags); + + auto XRayInstrBundles = + Args.getAllArgValues(OPT_fxray_instrumentation_bundle); + if (XRayInstrBundles.empty()) + Opts.XRayInstrumentationBundle.Mask = XRayInstrKind::All; + else + for (const auto &A : XRayInstrBundles) + parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args, + Diags, Opts.XRayInstrumentationBundle); + Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.CallFEntry = Args.hasArg(OPT_mfentry); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); + if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { + StringRef Name = A->getValue(); + if (Name == "full") { + Opts.CFProtectionReturn = 1; + Opts.CFProtectionBranch = 1; + } else if (Name == "return") + Opts.CFProtectionReturn = 1; + else if (Name == "branch") + Opts.CFProtectionBranch = 1; + else if (Name != "none") { + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name; + Success = false; + } + } + if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections, OPT_compress_debug_sections_EQ)) { if (A->getOption().getID() == OPT_compress_debug_sections) { @@ -813,7 +911,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); - for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) { + for (auto *A : + Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) { CodeGenOptions::BitcodeFileToLink F; F.Filename = A->getValue(); if (A->getOption().matches(OPT_mlink_cuda_bitcode)) { @@ -855,6 +954,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.SanitizeCfiICallGeneralizePointers = 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 = + A->getOption().getID() == + OPT_fsanitize_address_poison_class_member_array_new_cookie; + } if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope, OPT_fno_sanitize_address_use_after_scope)) { Opts.SanitizeAddressUseAfterScope = @@ -879,6 +985,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.StackProbeSize = StackProbeSize; } + Opts.NoStackArgProbe = Args.hasArg(OPT_mno_stack_arg_probe); + if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(); unsigned Method = llvm::StringSwitch<unsigned>(Name) @@ -895,8 +1003,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } - Opts.EmulatedTLS = - Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false); + if (Args.getLastArg(OPT_femulated_tls) || + Args.getLastArg(OPT_fno_emulated_tls)) { + Opts.ExplicitEmulatedTLS = true; + Opts.EmulatedTLS = + Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false); + } if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) { StringRef Name = A->getValue(); @@ -967,7 +1079,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, bool UsingProfile = UsingSampleProfile || (Opts.getProfileUse() != CodeGenOptions::ProfileNone); - if (Opts.DiagnosticsWithHotness && !UsingProfile) + if (Opts.DiagnosticsWithHotness && !UsingProfile && + // An IR file will contain PGO as metadata + IK.getLanguage() != InputKind::LLVM_IR) Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo) << "-fdiagnostics-show-hotness"; @@ -999,20 +1113,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags, Opts.SanitizeTrap); - Opts.CudaGpuBinaryFileNames = - Args.getAllArgValues(OPT_fcuda_include_gpubinary); + Opts.CudaGpuBinaryFileName = + Args.getLastArgValue(OPT_fcuda_include_gpubinary); Opts.Backchain = Args.hasArg(OPT_mbackchain); Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue( Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags); + Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true); + + Opts.Addrsig = Args.hasArg(OPT_faddrsig); + return Success; } static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args) { - using namespace options; Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); @@ -1021,7 +1138,17 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG); - Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes); + if (Args.hasArg(OPT_show_includes)) { + // Writing both /showIncludes and preprocessor output to stdout + // would produce interleaved output, so use stderr for /showIncludes. + // This behaves the same as cl.exe, when /E, /EP or /P are passed. + if (Args.hasArg(options::OPT_E) || Args.hasArg(options::OPT_P)) + Opts.ShowIncludesDest = ShowIncludesDestination::Stderr; + else + Opts.ShowIncludesDest = ShowIncludesDestination::Stdout; + } else { + Opts.ShowIncludesDest = ShowIncludesDestination::None; + } Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot); Opts.ModuleDependencyOutputDir = Args.getLastArgValue(OPT_module_dependency_dir); @@ -1032,7 +1159,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, // we let make / ninja to know about this implicit dependency. Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry); // Only the -fmodule-file=<file> form. - for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) Opts.ExtraDeps.push_back(Val); @@ -1049,7 +1176,7 @@ static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) { Colors_Off, Colors_Auto } ShowColors = DefaultColor ? Colors_Auto : Colors_Off; - for (Arg *A : Args) { + for (auto *A : Args) { const Option &O = A->getOption(); if (O.matches(options::OPT_fcolor_diagnostics) || O.matches(options::OPT_fdiagnostics_color)) { @@ -1095,7 +1222,6 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes, bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, DiagnosticsEngine *Diags, bool DefaultDiagColor, bool DefaultShowOpt) { - using namespace options; bool Success = true; Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file); @@ -1190,7 +1316,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Success = false; } else - std::sort(Opts.VerifyPrefixes.begin(), Opts.VerifyPrefixes.end()); + llvm::sort(Opts.VerifyPrefixes.begin(), Opts.VerifyPrefixes.end()); DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None; Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=", Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), @@ -1262,7 +1388,6 @@ static bool parseTestModuleFileExtensionArg(StringRef Arg, static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, bool &IsHeaderFile) { - using namespace options; Opts.ProgramAction = frontend::ParseSyntaxOnly; if (const Arg *A = Args.getLastArg(OPT_Action_Group)) { switch (A->getOption().getID()) { @@ -1278,6 +1403,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::ASTPrint; break; case OPT_ast_view: Opts.ProgramAction = frontend::ASTView; break; + case OPT_compiler_options_dump: + Opts.ProgramAction = frontend::DumpCompilerOptions; break; case OPT_dump_raw_tokens: Opts.ProgramAction = frontend::DumpRawTokens; break; case OPT_dump_tokens: @@ -1323,6 +1450,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::PrintPreamble; break; case OPT_E: Opts.ProgramAction = frontend::PrintPreprocessedInput; break; + case OPT_templight_dump: + Opts.ProgramAction = frontend::TemplightDump; break; case OPT_rewrite_macros: Opts.ProgramAction = frontend::RewriteMacros; break; case OPT_rewrite_objc: @@ -1344,7 +1473,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ActionName = A->getValue(); } Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin); - for (const Arg *AA : Args.filtered(OPT_plugin_arg)) + for (const auto *AA : Args.filtered(OPT_plugin_arg)) Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1)); for (const std::string &Arg : @@ -1397,7 +1526,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); // Only the -fmodule-file=<file> form. - for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') == StringRef::npos) Opts.ModuleFiles.push_back(Val); @@ -1416,12 +1545,13 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, = !Args.hasArg(OPT_no_code_completion_ns_level_decls); Opts.CodeCompleteOpts.IncludeBriefComments = Args.hasArg(OPT_code_completion_brief_comments); + Opts.CodeCompleteOpts.IncludeFixIts + = Args.hasArg(OPT_code_completion_with_fixits); Opts.OverrideRecordLayoutsFile = Args.getLastArgValue(OPT_foverride_record_layout_EQ); Opts.AuxTriple = llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple)); - Opts.FindPchSource = Args.getLastArgValue(OPT_find_pch_source_EQ); Opts.StatsFile = Args.getLastArgValue(OPT_stats_file); if (const Arg *A = Args.getLastArg(OPT_arcmt_check, @@ -1502,6 +1632,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, .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) @@ -1585,7 +1716,6 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0, static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, const std::string &WorkingDir) { - using namespace options; Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/"); Opts.Verbose = Args.hasArg(OPT_v); Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc); @@ -1608,12 +1738,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); // Only the -fmodule-file=<name>=<file> form. - for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + for (const auto *A : Args.filtered(OPT_fmodule_file)) { StringRef Val = A->getValue(); if (Val.find('=') != StringRef::npos) Opts.PrebuiltModuleFiles.insert(Val.split('=')); } - for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path)) + 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); @@ -1634,7 +1764,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ)) Opts.ModuleFormat = A->getValue(); - for (const Arg *A : Args.filtered(OPT_fmodules_ignore_macro)) { + for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) { StringRef MacroDef = A->getValue(); Opts.ModulesIgnoreMacros.insert( llvm::CachedHashString(MacroDef.split('=').first)); @@ -1644,7 +1774,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, bool IsIndexHeaderMap = false; bool IsSysrootSpecified = Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot); - for (const Arg *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { + for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) { if (A->getOption().matches(OPT_index_header_map)) { // -index-header-map applies to the next -I or -F. IsIndexHeaderMap = true; @@ -1671,7 +1801,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, // Add -iprefix/-iwithprefix/-iwithprefixbefore options. StringRef Prefix = ""; // FIXME: This isn't the correct default prefix. - for (const Arg *A : + for (const auto *A : Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) { if (A->getOption().matches(OPT_iprefix)) Prefix = A->getValue(); @@ -1681,31 +1811,31 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true); } - for (const Arg *A : Args.filtered(OPT_idirafter)) + for (const auto *A : Args.filtered(OPT_idirafter)) Opts.AddPath(A->getValue(), frontend::After, false, true); - for (const Arg *A : Args.filtered(OPT_iquote)) + for (const auto *A : Args.filtered(OPT_iquote)) Opts.AddPath(A->getValue(), frontend::Quoted, false, true); - for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) + for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) Opts.AddPath(A->getValue(), frontend::System, false, !A->getOption().matches(OPT_iwithsysroot)); - for (const Arg *A : Args.filtered(OPT_iframework)) + for (const auto *A : Args.filtered(OPT_iframework)) Opts.AddPath(A->getValue(), frontend::System, true, true); - for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot)) + for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot)) Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true, /*IgnoreSysRoot=*/false); // Add the paths for the various language specific isystem flags. - for (const Arg *A : Args.filtered(OPT_c_isystem)) + for (const auto *A : Args.filtered(OPT_c_isystem)) Opts.AddPath(A->getValue(), frontend::CSystem, false, true); - for (const Arg *A : Args.filtered(OPT_cxx_isystem)) + for (const auto *A : Args.filtered(OPT_cxx_isystem)) Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true); - for (const Arg *A : Args.filtered(OPT_objc_isystem)) + for (const auto *A : Args.filtered(OPT_objc_isystem)) Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true); - for (const Arg *A : Args.filtered(OPT_objcxx_isystem)) + for (const auto *A : Args.filtered(OPT_objcxx_isystem)) Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true); // Add the internal paths from a driver that detects standard include paths. - for (const Arg *A : + for (const auto *A : Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) { frontend::IncludeDirGroup Group = frontend::System; if (A->getOption().matches(OPT_internal_externc_isystem)) @@ -1714,12 +1844,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, } // Add the path prefixes which are implicitly treated as being system headers. - for (const Arg *A : + for (const auto *A : Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix)) Opts.AddSystemHeaderPrefix( A->getValue(), A->getOption().matches(OPT_system_header_prefix)); - for (const Arg *A : Args.filtered(OPT_ivfsoverlay)) + for (const auto *A : Args.filtered(OPT_ivfsoverlay)) Opts.AddVFSOverlayFile(A->getValue()); } @@ -1754,22 +1884,37 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, break; case InputKind::Asm: case InputKind::C: +#if defined(CLANG_DEFAULT_STD_C) + LangStd = CLANG_DEFAULT_STD_C; +#else // The PS4 uses C99 as the default C standard. if (T.isPS4()) LangStd = LangStandard::lang_gnu99; else LangStd = LangStandard::lang_gnu11; +#endif break; case InputKind::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: +#if defined(CLANG_DEFAULT_STD_CXX) + LangStd = CLANG_DEFAULT_STD_CXX; +#else LangStd = LangStandard::lang_gnucxx14; +#endif break; case InputKind::RenderScript: LangStd = LangStandard::lang_c99; break; + case InputKind::HIP: + LangStd = LangStandard::lang_hip; + break; } } @@ -1799,6 +1944,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.OpenCLVersion = 120; else if (LangStd == LangStandard::lang_opencl20) Opts.OpenCLVersion = 200; + else if (LangStd == LangStandard::lang_openclcpp) + Opts.OpenCLCPlusPlusVersion = 100; // OpenCL has some additional defaults. if (Opts.OpenCL) { @@ -1808,13 +1955,15 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.setDefaultFPContractMode(LangOptions::FPC_On); Opts.NativeHalfType = 1; Opts.NativeHalfArgsAndReturns = 1; + Opts.OpenCLCPlusPlus = Opts.CPlusPlus; // Include default header file for OpenCL. if (Opts.IncludeDefaultHeader) { PPOpts.Includes.push_back("opencl-c.h"); } } - Opts.CUDA = IK.getLanguage() == InputKind::CUDA; + Opts.HIP = IK.getLanguage() == InputKind::HIP; + Opts.CUDA = IK.getLanguage() == InputKind::CUDA || Opts.HIP; if (Opts.CUDA) // Set default FP_CONTRACT to FAST. Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); @@ -1885,6 +2034,10 @@ static bool IsInputCompatibleWithStandard(InputKind IK, return S.getLanguage() == InputKind::CUDA || S.getLanguage() == InputKind::CXX; + case InputKind::HIP: + return S.getLanguage() == InputKind::CXX || + S.getLanguage() == InputKind::HIP; + case InputKind::Asm: // Accept (and ignore) all -std= values. // FIXME: The -std= value is not ignored; it affects the tokenization @@ -1912,6 +2065,8 @@ static const StringRef GetInputKindName(InputKind IK) { return "CUDA"; case InputKind::RenderScript: return "RenderScript"; + case InputKind::HIP: + return "HIP"; case InputKind::Asm: return "Asm"; @@ -1975,6 +2130,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } + if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { + StringRef Name = A->getValue(); + if (Name == "full" || Name == "branch") { + Opts.CFProtectionBranch = 1; + } + } // -cl-std only applies for OpenCL language standards. // Override the -std option in this case. if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) { @@ -1984,6 +2145,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) .Default(LangStandard::lang_unspecified); if (OpenCLLangStd == LangStandard::lang_unspecified) { @@ -2004,11 +2166,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // this option was added for compatibility with OpenCL 1.0. if (Args.getLastArg(OPT_cl_strict_aliasing) && Opts.OpenCLVersion > 100) { - std::string VerSpec = llvm::to_string(Opts.OpenCLVersion / 100) + - std::string(".") + - llvm::to_string((Opts.OpenCLVersion % 100) / 10); Diags.Report(diag::warn_option_invalid_ocl_version) - << VerSpec << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args); + << Opts.getOpenCLVersionTuple().getAsString() + << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args); } // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension @@ -2019,6 +2179,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords, Opts.GNUKeywords); + Opts.Digraphs = Args.hasFlag(OPT_fdigraphs, OPT_fno_digraphs, Opts.Digraphs); + if (Args.hasArg(OPT_fno_operator_names)) Opts.CXXOperatorNames = 0; @@ -2031,12 +2193,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_fno_cuda_host_device_constexpr)) Opts.CUDAHostDeviceConstexpr = 0; - if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_flush_denormals_to_zero)) - Opts.CUDADeviceFlushDenormalsToZero = 1; - if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals)) Opts.CUDADeviceApproxTranscendentals = 1; + Opts.CUDARelocatableDeviceCode = Args.hasArg(OPT_fcuda_rdc); + if (Opts.ObjC1) { if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) { StringRef value = arg->getValue(); @@ -2177,12 +2338,27 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions); Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions); + // -ffixed-point + Opts.FixedPoint = + Args.hasFlag(OPT_ffixed_point, OPT_fno_fixed_point, /*Default=*/false) && + !Opts.CPlusPlus; + Opts.PaddingOnUnsignedFixedPoint = + Args.hasFlag(OPT_fpadding_on_unsigned_fixed_point, + OPT_fno_padding_on_unsigned_fixed_point, + /*Default=*/false) && + Opts.FixedPoint; + // Handle exception personalities Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions, options::OPT_fseh_exceptions, options::OPT_fdwarf_exceptions); if (A) { const Option &Opt = A->getOption(); + llvm::Triple T(TargetOpts.Triple); + if (T.isWindowsMSVCEnvironment()) + Diags.Report(diag::err_fe_invalid_exception_model) + << Opt.getName() << T.str(); + Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions); Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions); Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions); @@ -2194,7 +2370,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti); Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data); Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL - && Opts.OpenCLVersion >= 200); + && Opts.OpenCLVersion == 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts); @@ -2219,6 +2395,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); if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) { Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue()) .Case("char", 1) @@ -2297,10 +2474,11 @@ 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.CurrentModule = Args.getLastArgValue(OPT_fmodule_name_EQ); + Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ); + Opts.CurrentModule = Opts.ModuleName; Opts.AppExt = Args.hasArg(OPT_fapplication_extension); Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature); - std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end()); + llvm::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end()); 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 @@ -2407,16 +2585,25 @@ 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-simd is specified. + bool IsSimdSpecified = + Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd, + /*Default=*/false); + Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified; Opts.OpenMPUseTLS = Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls); Opts.OpenMPIsDevice = Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device); + bool IsTargetSpecified = + Opts.OpenMPIsDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ); - if (Opts.OpenMP) { - int Version = - getLastArgIntValue(Args, OPT_fopenmp_version_EQ, Opts.OpenMP, Diags); - if (Version != 0) + if (Opts.OpenMP || Opts.OpenMPSimd) { + if (int Version = getLastArgIntValue( + Args, OPT_fopenmp_version_EQ, + (IsSimdSpecified || IsTargetSpecified) ? 45 : 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) { @@ -2426,7 +2613,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // Add unsupported host targets here: case llvm::Triple::nvptx: case llvm::Triple::nvptx64: - Diags.Report(clang::diag::err_drv_omp_host_target_not_supported) + Diags.Report(diag::err_drv_omp_host_target_not_supported) << TargetOpts.Triple; break; } @@ -2435,7 +2622,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.OpenMPHostCXXExceptions = Opts.Exceptions && Opts.CXXExceptions; + if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) { Opts.Exceptions = 0; Opts.CXXExceptions = 0; } @@ -2454,7 +2642,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, TT.getArch() == llvm::Triple::nvptx64 || TT.getArch() == llvm::Triple::x86 || TT.getArch() == llvm::Triple::x86_64)) - Diags.Report(clang::diag::err_drv_invalid_omp_target) << A->getValue(i); + Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i); else Opts.OMPTargetTriples.push_back(TT); } @@ -2465,10 +2653,14 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) { Opts.OMPHostIRFile = A->getValue(); if (!llvm::sys::fs::exists(Opts.OMPHostIRFile)) - Diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found) + Diags.Report(diag::err_drv_omp_host_ir_file_not_found) << Opts.OMPHostIRFile; } + // set CUDA mode for OpenMP target NVPTX if specified in options + Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() && + Args.hasArg(options::OPT_fopenmp_cuda_mode); + // Record whether the __DEPRECATED define was requested. Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro, OPT_fno_deprecated_macro, @@ -2543,14 +2735,55 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Args.hasFlag(OPT_fxray_always_emit_customevents, OPT_fnoxray_always_emit_customevents, false); + // -fxray-always-emit-typedevents + Opts.XRayAlwaysEmitTypedEvents = + Args.hasFlag(OPT_fxray_always_emit_typedevents, + OPT_fnoxray_always_emit_customevents, false); + // -fxray-{always,never}-instrument= filenames. Opts.XRayAlwaysInstrumentFiles = Args.getAllArgValues(OPT_fxray_always_instrument); Opts.XRayNeverInstrumentFiles = Args.getAllArgValues(OPT_fxray_never_instrument); + Opts.XRayAttrListFiles = Args.getAllArgValues(OPT_fxray_attr_list); + + // -fforce-emit-vtables + Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables); // -fallow-editor-placeholders Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders); + + if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) { + Opts.setClangABICompat(LangOptions::ClangABI::Latest); + + StringRef Ver = A->getValue(); + std::pair<StringRef, StringRef> VerParts = Ver.split('.'); + unsigned Major, Minor = 0; + + // Check the version number is valid: either 3.x (0 <= x <= 9) or + // y or y.0 (4 <= y <= current version). + if (!VerParts.first.startswith("0") && + !VerParts.first.getAsInteger(10, Major) && + 3 <= Major && Major <= CLANG_VERSION_MAJOR && + (Major == 3 ? VerParts.second.size() == 1 && + !VerParts.second.getAsInteger(10, Minor) + : VerParts.first.size() == Ver.size() || + VerParts.second == "0")) { + // Got a valid version number. + if (Major == 3 && Minor <= 8) + Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8); + else if (Major <= 4) + Opts.setClangABICompat(LangOptions::ClangABI::Ver4); + else if (Major <= 6) + Opts.setClangABICompat(LangOptions::ClangABI::Ver6); + } else if (Ver != "latest") { + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + } + + Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers); + Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj); } static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { @@ -2579,9 +2812,11 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::RewriteObjC: case frontend::RewriteTest: case frontend::RunAnalysis: + case frontend::TemplightDump: case frontend::MigrateSource: return false; + case frontend::DumpCompilerOptions: case frontend::DumpRawTokens: case frontend::DumpTokens: case frontend::InitOnly: @@ -2595,12 +2830,11 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { } static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, - FileManager &FileMgr, DiagnosticsEngine &Diags, frontend::ActionKind Action) { - using namespace options; Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch); Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth); + Opts.PCHThroughHeader = Args.getLastArgValue(OPT_pch_through_header_EQ); if (const Arg *A = Args.getLastArg(OPT_token_cache)) Opts.TokenCache = A->getValue(); else @@ -2611,7 +2845,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors); Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls); - for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) + for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl)) Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue()); if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) { @@ -2630,8 +2864,19 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, } } + // Add the __CET__ macro if a CFProtection option is set. + if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) { + StringRef Name = A->getValue(); + if (Name == "branch") + Opts.addMacroDef("__CET__=1"); + else if (Name == "return") + Opts.addMacroDef("__CET__=2"); + else if (Name == "full") + Opts.addMacroDef("__CET__=3"); + } + // Add macros from the command line. - for (const Arg *A : Args.filtered(OPT_D, OPT_U)) { + for (const auto *A : Args.filtered(OPT_D, OPT_U)) { if (A->getOption().matches(OPT_D)) Opts.addMacroDef(A->getValue()); else @@ -2641,13 +2886,13 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros); // Add the ordered list of -includes. - for (const Arg *A : Args.filtered(OPT_include)) + for (const auto *A : Args.filtered(OPT_include)) Opts.Includes.emplace_back(A->getValue()); - for (const Arg *A : Args.filtered(OPT_chain_include)) + for (const auto *A : Args.filtered(OPT_chain_include)) Opts.ChainedIncludes.emplace_back(A->getValue()); - for (const Arg *A : Args.filtered(OPT_remap_file)) { + for (const auto *A : Args.filtered(OPT_remap_file)) { std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';'); if (Split.second.empty()) { @@ -2681,8 +2926,6 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, ArgList &Args, frontend::ActionKind Action) { - using namespace options; - if (isStrictlyPreprocessorAction(Action)) Opts.ShowCPP = !Args.hasArg(OPT_dM); else @@ -2700,7 +2943,6 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags) { - using namespace options; Opts.ABI = Args.getLastArgValue(OPT_target_abi); if (Arg *A = Args.getLastArg(OPT_meabi)) { StringRef Value = A->getValue(); @@ -2720,11 +2962,15 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args, Opts.FPMath = Args.getLastArgValue(OPT_mfpmath); Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version); - Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple)); + 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.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ); + Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); + Opts.NVPTXUseShortPointers = Args.hasFlag( + options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false); } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, @@ -2750,8 +2996,14 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, } // Issue errors on unknown arguments. - for (const Arg *A : Args.filtered(OPT_UNKNOWN)) { - Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args); + for (const auto *A : Args.filtered(OPT_UNKNOWN)) { + auto ArgString = A->getAsString(Args); + std::string Nearest; + 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) + << ArgString << Nearest; Success = false; } @@ -2768,7 +3020,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, LangOpts.IsHeaderFile); ParseTargetArgs(Res.getTargetOpts(), Args, Diags); Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, - Res.getTargetOpts()); + Res.getTargetOpts(), Res.getFrontendOpts()); ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Res.getFileSystemOpts().WorkingDir); if (DashX.getFormat() == InputKind::Precompiled || @@ -2793,6 +3045,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, LangOpts.ObjCExceptions = 1; } + LangOpts.FunctionAlignment = + getLastArgIntValue(Args, OPT_function_alignment, 0, Diags); + if (LangOpts.CUDA) { // During CUDA device-side compilation, the aux triple is the // triple used for host compilation. @@ -2811,12 +3066,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, !LangOpts.Sanitize.has(SanitizerKind::Address) && !LangOpts.Sanitize.has(SanitizerKind::Memory); - // FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of - // PCH file and find the original header name. Remove the need to do that in - // ParsePreprocessorArgs and remove the FileManager - // parameters from the function and the "FileManager.h" #include. - FileManager FileMgr(Res.getFileSystemOpts()); - ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, FileMgr, Diags, + ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags, Res.getFrontendOpts().ProgramAction); ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), Args, Res.getFrontendOpts().ProgramAction); @@ -2864,29 +3114,26 @@ std::string CompilerInvocation::getModuleHash() const { // Extend the signature with the target options. code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU, TargetOpts->ABI); - for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i) - code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]); + for (const auto &FeatureAsWritten : TargetOpts->FeaturesAsWritten) + code = hash_combine(code, FeatureAsWritten); // Extend the signature with preprocessor options. const PreprocessorOptions &ppOpts = getPreprocessorOpts(); const HeaderSearchOptions &hsOpts = getHeaderSearchOpts(); code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord); - for (std::vector<std::pair<std::string, bool/*isUndef*/>>::const_iterator - I = getPreprocessorOpts().Macros.begin(), - IEnd = getPreprocessorOpts().Macros.end(); - I != IEnd; ++I) { + for (const auto &I : getPreprocessorOpts().Macros) { // If we're supposed to ignore this macro for the purposes of modules, // don't put it into the hash. if (!hsOpts.ModulesIgnoreMacros.empty()) { // Check whether we're ignoring this macro. - StringRef MacroDef = I->first; + StringRef MacroDef = I.first; if (hsOpts.ModulesIgnoreMacros.count( llvm::CachedHashString(MacroDef.split('=').first))) continue; } - code = hash_combine(code, I->first, I->second); + code = hash_combine(code, I.first, I.second); } // Extend the signature with the sysroot and other header search options. @@ -2919,8 +3166,6 @@ std::string CompilerInvocation::getModuleHash() const { return llvm::APInt(64, code).toString(36, /*Signed=*/false); } -namespace clang { - template<typename IntTy> static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id, IntTy Default, @@ -2936,6 +3181,7 @@ static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id, return Res; } +namespace clang { // Declared in clang/Frontend/Utils.h. int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default, @@ -2980,22 +3226,22 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI, IntrusiveRefCntPtr<vfs::OverlayFileSystem> Overlay( new vfs::OverlayFileSystem(BaseFS)); // earlier vfs files are on the bottom - for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) { + for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = BaseFS->getBufferForFile(File); if (!Buffer) { Diags.Report(diag::err_missing_vfs_overlay_file) << File; - return IntrusiveRefCntPtr<vfs::FileSystem>(); + continue; } IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML( std::move(Buffer.get()), /*DiagHandler*/ nullptr, File); - if (!FS.get()) { + if (FS) + Overlay->pushOverlay(FS); + else Diags.Report(diag::err_invalid_vfs_overlay) << File; - return IntrusiveRefCntPtr<vfs::FileSystem>(); - } - Overlay->pushOverlay(FS); } return Overlay; } -} // end namespace clang + +} // namespace clang |