diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp | 349 |
1 files changed, 274 insertions, 75 deletions
diff --git a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp index 81128fd..7b94132 100644 --- a/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp +++ b/contrib/llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp @@ -8,19 +8,19 @@ //===----------------------------------------------------------------------===// #include "clang/Frontend/CompilerInvocation.h" -#include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/Version.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Driver/Util.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/LangStandard.h" #include "clang/Frontend/Utils.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Serialization/ASTReader.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" @@ -28,13 +28,16 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" -#include "llvm/Support/system_error.h" +#include <atomic> +#include <memory> #include <sys/stat.h> +#include <system_error> using namespace clang; //===----------------------------------------------------------------------===// @@ -55,6 +58,8 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X) HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())), PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {} +CompilerInvocationBase::~CompilerInvocationBase() {} + //===----------------------------------------------------------------------===// // Deserialization (from args) //===----------------------------------------------------------------------===// @@ -106,25 +111,21 @@ static unsigned getOptimizationLevelSize(ArgList &Args) { return 0; } -static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) { - for (arg_iterator I = Args.filtered_begin(OPT_W_Group), - E = Args.filtered_end(); I != E; ++I) { - Arg *A = *I; - // If the argument is a pure flag, add its name (minus the "W" at the beginning) - // to the warning list. Else, add its value (for the OPT_W case). +static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, + OptSpecifier GroupWithValue, + std::vector<std::string> &Diagnostics) { + for (Arg *A : Args.filtered(Group)) { if (A->getOption().getKind() == Option::FlagClass) { - Warnings.push_back(A->getOption().getName().substr(1)); + // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add + // its name (minus the "W" or "R" at the beginning) to the warning list. + Diagnostics.push_back(A->getOption().getName().drop_front(1)); + } else if (A->getOption().matches(GroupWithValue)) { + // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group. + Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-")); } else { - for (unsigned Idx = 0, End = A->getNumValues(); - Idx < End; ++Idx) { - StringRef V = A->getValue(Idx); - // "-Wl," and such are not warning options. - // FIXME: Should be handled by putting these in separate flags. - if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,")) - continue; - - Warnings.push_back(V); - } + // Otherwise, add its value (for OPT_W_Joined and similar). + for (const char *Arg : A->getValues()) + Diagnostics.push_back(Arg); } } } @@ -262,7 +263,7 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, configList.split(configVals, ","); for (unsigned i = 0, e = configVals.size(); i != e; ++i) { StringRef key, val; - llvm::tie(key, val) = configVals[i].split("="); + std::tie(key, val) = configVals[i].split("="); if (val.empty()) { Diags.Report(SourceLocation(), diag::err_analyzer_config_no_value) << configVals[i]; @@ -294,6 +295,33 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } +static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) { + if (Arg *A = Args.getLastArg(OPT_mcode_model)) { + StringRef Value = A->getValue(); + if (Value == "small" || Value == "kernel" || Value == "medium" || + Value == "large") + return Value; + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value; + } + return "default"; +} + +/// \brief 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, + Arg *RpassArg) { + StringRef Val = RpassArg->getValue(); + std::string RegexError; + std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val); + if (!Pattern->isValid(RegexError)) { + Diags.Report(diag::err_drv_optimization_remark_pattern) + << RegexError << RpassArg->getAsString(Args); + Pattern.reset(); + } + return Pattern; +} + static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags, const TargetOptions &TargetOpts) { @@ -324,9 +352,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) || Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) { bool Default = false; - // Until dtrace (via CTF) can deal with distributed debug info, - // Darwin defaults to standalone/full debug info. - if (llvm::Triple(TargetOpts.Triple).isOSDarwin()) + // Until dtrace (via CTF) and LLDB can deal with distributed debug info, + // Darwin and FreeBSD default to standalone/full debug info. + if (llvm::Triple(TargetOpts.Triple).isOSDarwin() || + llvm::Triple(TargetOpts.Triple).isOSFreeBSD()) Default = true; if (Args.hasFlag(OPT_fstandalone_debug, OPT_fno_standalone_debug, Default)) @@ -365,20 +394,22 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize)); Opts.RerollLoops = Args.hasArg(OPT_freroll_loops); + Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as); Opts.Autolink = !Args.hasArg(OPT_fno_autolink); Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ); + Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate); + Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ); Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); - Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model); + Opts.CodeModel = getCodeModel(Args, Diags); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim); Opts.DisableFree = Args.hasArg(OPT_disable_free); Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls); Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi); - Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables); Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable); Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision); Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) || @@ -396,7 +427,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RelaxAll = Args.hasArg(OPT_mrelax_all); Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer); Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels); - Opts.NoDwarf2CFIAsm = Args.hasArg(OPT_fno_dwarf2_cfi_asm); Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm); Opts.SoftFloat = Args.hasArg(OPT_msoft_float); Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums); @@ -444,15 +474,14 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions); Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); + Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file); Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist); Opts.SanitizeMemoryTrackOrigins = - Args.hasArg(OPT_fsanitize_memory_track_origins); - Opts.SanitizeAddressZeroBaseShadow = - Args.hasArg(OPT_fsanitize_address_zero_base_shadow); + getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags); Opts.SanitizeUndefinedTrapOnError = - Args.hasArg(OPT_fsanitize_undefined_trap_on_error); + Args.hasArg(OPT_fsanitize_undefined_trap_on_error); Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); @@ -517,6 +546,30 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib); + bool NeedLocTracking = false; + + if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) { + Opts.OptimizationRemarkPattern = + GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } + + if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) { + Opts.OptimizationRemarkMissedPattern = + GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } + + if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) { + Opts.OptimizationRemarkAnalysisPattern = + GenerateOptimizationRemarkRegex(Diags, Args, A); + NeedLocTracking = true; + } + + // If the user requested one of the flags in the -Rpass family, make sure + // that the backend tracks source location information. + if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo) + Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly); return Success; } @@ -527,12 +580,15 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file); Opts.Targets = Args.getAllArgValues(OPT_MT); Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps); + Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps); Opts.UsePhonyTargets = Args.hasArg(OPT_MP); Opts.ShowHeaderIncludes = Args.hasArg(OPT_H); Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file); Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG); Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes); Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot); + Opts.ModuleDependencyOutputDir = + Args.getLastArgValue(OPT_module_dependency_dir); } bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, @@ -639,7 +695,8 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, << Opts.TabStop << DiagnosticOptions::DefaultTabStop; } Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); - addWarningArgs(Args, Opts.Warnings); + addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); + addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); return Success; } @@ -699,6 +756,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ProgramAction = frontend::ParseSyntaxOnly; break; case OPT_module_file_info: 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: @@ -827,10 +886,12 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty; if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty; + if (Args.hasArg(OPT_objcmt_migrate_designated_init)) + Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer; if (Args.hasArg(OPT_objcmt_migrate_all)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls; - Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_white_list_dir_path); + Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path); if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { @@ -913,6 +974,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0); Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir); Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path); + Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); // -fmodules implies -fmodule-maps Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules); @@ -920,6 +982,13 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60); Opts.ModuleCachePruneAfter = getLastArgIntValue(Args, OPT_fmodules_prune_after, 31 * 24 * 60 * 60); + Opts.ModulesValidateOncePerBuildSession = + Args.hasArg(OPT_fmodules_validate_once_per_build_session); + Opts.BuildSessionTimestamp = + getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0); + Opts.ModulesValidateSystemHeaders = + Args.hasArg(OPT_fmodules_validate_system_headers); + for (arg_iterator it = Args.filtered_begin(OPT_fmodules_ignore_macro), ie = Args.filtered_end(); it != ie; ++it) { @@ -1005,12 +1074,16 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { } // Add the path prefixes which are implicitly treated as being system headers. - for (arg_iterator I = Args.filtered_begin(OPT_isystem_prefix, - OPT_ino_system_prefix), + for (arg_iterator I = Args.filtered_begin(OPT_system_header_prefix, + OPT_no_system_header_prefix), E = Args.filtered_end(); I != E; ++I) - Opts.AddSystemHeaderPrefix((*I)->getValue(), - (*I)->getOption().matches(OPT_isystem_prefix)); + Opts.AddSystemHeaderPrefix( + (*I)->getValue(), (*I)->getOption().matches(OPT_system_header_prefix)); + + for (arg_iterator I = Args.filtered_begin(OPT_ivfsoverlay), + E = Args.filtered_end(); I != E; ++I) + Opts.AddVFSOverlayFile((*I)->getValue()); } void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, @@ -1063,6 +1136,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CPlusPlus = Std.isCPlusPlus(); Opts.CPlusPlus11 = Std.isCPlusPlus11(); Opts.CPlusPlus1y = Std.isCPlusPlus1y(); + Opts.CPlusPlus1z = Std.isCPlusPlus1z(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Std.isC99(); @@ -1070,18 +1144,13 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.ImplicitInt = Std.hasImplicitInt(); // Set OpenCL Version. - if (LangStd == LangStandard::lang_opencl) { - Opts.OpenCL = 1; + Opts.OpenCL = LangStd == LangStandard::lang_opencl || IK == IK_OpenCL; + if (LangStd == LangStandard::lang_opencl) Opts.OpenCLVersion = 100; - } - else if (LangStd == LangStandard::lang_opencl11) { - Opts.OpenCL = 1; + else if (LangStd == LangStandard::lang_opencl11) Opts.OpenCLVersion = 110; - } - else if (LangStd == LangStandard::lang_opencl12) { - Opts.OpenCL = 1; + else if (LangStd == LangStandard::lang_opencl12) Opts.OpenCLVersion = 120; - } // OpenCL has some additional defaults. if (Opts.OpenCL) { @@ -1092,12 +1161,14 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.NativeHalfType = 1; } - if (LangStd == LangStandard::lang_cuda) - Opts.CUDA = 1; + Opts.CUDA = LangStd == LangStandard::lang_cuda || IK == IK_CUDA; // OpenCL and C++ both have bool, true, false keywords. Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; + // OpenCL has half keyword + Opts.Half = Opts.OpenCL; + // C++ has wchar_t keyword. Opts.WChar = Opts.CPlusPlus; @@ -1106,7 +1177,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs // is specified, or -std is set to a conforming mode. - Opts.Trigraphs = !Opts.GNUMode; + // Trigraphs are disabled by default in c++1z onwards. + Opts.Trigraphs = !Opts.GNUMode && !Opts.CPlusPlus1z; Opts.DollarIdents = !Opts.AsmPreprocessor; @@ -1132,6 +1204,43 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, return DefaultVisibility; } +static unsigned parseMSCVersion(ArgList &Args, DiagnosticsEngine &Diags) { + auto Arg = Args.getLastArg(OPT_fms_compatibility_version); + if (!Arg) + return 0; + + // The MSC versioning scheme involves four versioning components: + // - Major + // - Minor + // - Build + // - Patch + // + // We accept either the old style (_MSC_VER) value, or a _MSC_FULL_VER value. + // Additionally, the value may be provided in the form of a more readable + // MM.mm.bbbbb.pp version. + // + // Unfortunately, due to the bit-width limitations, we cannot currently encode + // the value for the patch level. + + unsigned VC[4] = {0}; + StringRef Value = Arg->getValue(); + SmallVector<StringRef, 4> Components; + + Value.split(Components, ".", llvm::array_lengthof(VC)); + for (unsigned CI = 0, + CE = std::min(Components.size(), llvm::array_lengthof(VC)); + CI < CE; ++CI) { + if (Components[CI].getAsInteger(10, VC[CI])) { + Diags.Report(diag::err_drv_invalid_value) + << Arg->getAsString(Args) << Value; + return 0; + } + } + + // FIXME we cannot encode the patch level + return VC[0] * 10000000 + VC[1] * 100000 + VC[2]; +} + static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. @@ -1146,7 +1255,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(); else { - // Valid standard, check to make sure language and standard are compatable. + // Valid standard, check to make sure language and standard are + // compatible. const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); switch (IK) { case IK_C: @@ -1297,11 +1407,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, OPT_fno_dollars_in_identifiers, Opts.DollarIdents); Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings); - Opts.MicrosoftExt - = Args.hasArg(OPT_fms_extensions) || Args.hasArg(OPT_fms_compatibility); - Opts.MicrosoftMode = Args.hasArg(OPT_fms_compatibility); + Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility); + Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions); Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt; - Opts.MSCVersion = getLastArgIntValue(Args, OPT_fmsc_version, 0, Diags); + Opts.MSCompatibilityVersion = parseMSCVersion(Args, Diags); + Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags); Opts.Borland = Args.hasArg(OPT_fborland_extensions); Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings); Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings, @@ -1317,13 +1427,20 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp); Opts.RTTI = !Args.hasArg(OPT_fno_rtti); + Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data); Opts.Blocks = Args.hasArg(OPT_fblocks); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.Modules = Args.hasArg(OPT_fmodules); - Opts.ModulesDeclUse = Args.hasArg(OPT_fmodules_decluse); + Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse); + Opts.ModulesDeclUse = + Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse; + Opts.ModulesSearchAll = Opts.Modules && + !Args.hasArg(OPT_fno_modules_search_all) && + Args.hasArg(OPT_fmodules_search_all); + Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); - Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); + Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false); Opts.ShortEnums = Args.hasArg(OPT_fshort_enums); Opts.Freestanding = Args.hasArg(OPT_ffreestanding); Opts.FormatExtensions = Args.hasArg(OPT_fformat_extensions); @@ -1399,8 +1516,30 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } - // Check if -fopenmp is specified. - Opts.OpenMP = Args.hasArg(OPT_fopenmp); + if (Arg *A = Args.getLastArg(OPT_fms_memptr_rep_EQ)) { + LangOptions::PragmaMSPointersToMembersKind InheritanceModel = + llvm::StringSwitch<LangOptions::PragmaMSPointersToMembersKind>( + A->getValue()) + .Case("single", + LangOptions::PPTMK_FullGeneralitySingleInheritance) + .Case("multiple", + LangOptions::PPTMK_FullGeneralityMultipleInheritance) + .Case("virtual", + LangOptions::PPTMK_FullGeneralityVirtualInheritance) + .Default(LangOptions::PPTMK_BestCase); + if (InheritanceModel == LangOptions::PPTMK_BestCase) + Diags.Report(diag::err_drv_invalid_value) + << "-fms-memptr-rep=" << A->getValue(); + + Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel); + } + + // Check if -fopenmp= is specified. + if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) { + Opts.OpenMP = llvm::StringSwitch<bool>(A->getValue()) + .Case("libiomp5", true) + .Default(false); + } // Record whether the __DEPRECATED define was requested. Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro, @@ -1432,7 +1571,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, break; case 0: Opts.setStackProtector(LangOptions::SSPOff); break; case 1: Opts.setStackProtector(LangOptions::SSPOn); break; - case 2: Opts.setStackProtector(LangOptions::SSPReq); break; + case 2: Opts.setStackProtector(LangOptions::SSPStrong); break; + case 3: Opts.setStackProtector(LangOptions::SSPReq); break; } // Parse -fsanitize= arguments. @@ -1583,6 +1723,7 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, case frontend::GeneratePTH: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: + case frontend::VerifyPCH: case frontend::PluginAction: case frontend::PrintDeclContext: case frontend::RewriteObjC: @@ -1613,7 +1754,6 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { using namespace options; Opts.ABI = Args.getLastArgValue(OPT_target_abi); - Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi); Opts.CPU = Args.getLastArgValue(OPT_target_cpu); Opts.FPMath = Args.getLastArgValue(OPT_mfpmath); Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature); @@ -1625,8 +1765,6 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) { Opts.Triple = llvm::sys::getDefaultTargetTriple(); } -// - bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, const char *const *ArgBegin, const char *const *ArgEnd, @@ -1634,12 +1772,12 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, bool Success = true; // Parse the arguments. - OwningPtr<OptTable> Opts(createDriverOptTable()); + std::unique_ptr<OptTable> Opts(createDriverOptTable()); const unsigned IncludedFlagsBitmask = options::CC1Option; unsigned MissingArgIndex, MissingArgCount; - OwningPtr<InputArgList> Args( - Opts->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount, - IncludedFlagsBitmask)); + std::unique_ptr<InputArgList> Args( + Opts->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount, + IncludedFlagsBitmask)); // Check for missing argument error. if (MissingArgCount) { @@ -1760,8 +1898,7 @@ std::string CompilerInvocation::getModuleHash() const { // Extend the signature with the target options. code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU, - TargetOpts->ABI, TargetOpts->CXXABI, - TargetOpts->LinkerVersion); + TargetOpts->ABI); for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i) code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]); @@ -1770,7 +1907,6 @@ std::string CompilerInvocation::getModuleHash() const { const HeaderSearchOptions &hsOpts = getHeaderSearchOpts(); code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord); - std::vector<StringRef> MacroDefs; for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator I = getPreprocessorOpts().Macros.begin(), IEnd = getPreprocessorOpts().Macros.end(); @@ -1792,20 +1928,26 @@ std::string CompilerInvocation::getModuleHash() const { hsOpts.UseStandardSystemIncludes, hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx); + code = hash_combine(code, hsOpts.ResourceDir); + + // Extend the signature with the user build path. + code = hash_combine(code, hsOpts.ModuleUserBuildPath); // Darwin-specific hack: if we have a sysroot, use the contents and // modification time of // $sysroot/System/Library/CoreServices/SystemVersion.plist // as part of the module hash. if (!hsOpts.Sysroot.empty()) { - llvm::OwningPtr<llvm::MemoryBuffer> buffer; SmallString<128> systemVersionFile; systemVersionFile += hsOpts.Sysroot; llvm::sys::path::append(systemVersionFile, "System"); llvm::sys::path::append(systemVersionFile, "Library"); llvm::sys::path::append(systemVersionFile, "CoreServices"); llvm::sys::path::append(systemVersionFile, "SystemVersion.plist"); - if (!llvm::MemoryBuffer::getFile(systemVersionFile.str(), buffer)) { + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer = + llvm::MemoryBuffer::getFile(systemVersionFile.str()); + if (buffer) { code = hash_combine(code, buffer.get()->getBuffer()); struct stat statBuf; @@ -1819,10 +1961,11 @@ std::string CompilerInvocation::getModuleHash() const { namespace clang { -// Declared in clang/Frontend/Utils.h. -int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default, - DiagnosticsEngine *Diags) { - int Res = Default; +template<typename IntTy> +static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id, + IntTy Default, + DiagnosticsEngine *Diags) { + IntTy Res = Default; if (Arg *A = Args.getLastArg(Id)) { if (StringRef(A->getValue()).getAsInteger(10, Res)) { if (Diags) @@ -1832,4 +1975,60 @@ int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default, } return Res; } + + +// Declared in clang/Frontend/Utils.h. +int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default, + DiagnosticsEngine *Diags) { + return getLastArgIntValueImpl<int>(Args, Id, Default, Diags); +} + +uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id, + uint64_t Default, + DiagnosticsEngine *Diags) { + 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> +createVFSFromCompilerInvocation(const CompilerInvocation &CI, + DiagnosticsEngine &Diags) { + if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) + return vfs::getRealFileSystem(); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> + Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem())); + // earlier vfs files are on the bottom + for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) { + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = + llvm::MemoryBuffer::getFile(File); + if (!Buffer) { + Diags.Report(diag::err_missing_vfs_overlay_file) << File; + return IntrusiveRefCntPtr<vfs::FileSystem>(); + } + + IntrusiveRefCntPtr<vfs::FileSystem> FS = + vfs::getVFSFromYAML(Buffer->release(), /*DiagHandler*/ nullptr); + if (!FS.get()) { + Diags.Report(diag::err_invalid_vfs_overlay) << File; + return IntrusiveRefCntPtr<vfs::FileSystem>(); + } + Overlay->pushOverlay(FS); + } + return Overlay; } +} // end namespace clang |