diff options
Diffstat (limited to 'lib/Frontend/CompilerInvocation.cpp')
| -rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 365 | 
1 files changed, 285 insertions, 80 deletions
| diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 8db5cf1bc21a..ce61a4653d2e 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/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,8 +295,36 @@ 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) { +                             DiagnosticsEngine &Diags, +                             const TargetOptions &TargetOpts) {    using namespace options;    bool Success = true; @@ -322,10 +351,17 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,      Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly);    } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) ||               Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) { -    if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true)) -      Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); -    else +    bool Default = false; +    // 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))        Opts.setDebugInfo(CodeGenOptions::FullDebugInfo); +    else +      Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo);    }    Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);    Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); @@ -358,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) || @@ -389,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); @@ -437,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); @@ -510,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;  } @@ -520,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, @@ -632,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;  } @@ -692,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: @@ -820,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) { @@ -906,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); @@ -913,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) { @@ -998,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, @@ -1056,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(); @@ -1063,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) { @@ -1085,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; @@ -1099,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; @@ -1125,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. @@ -1139,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: @@ -1290,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, @@ -1310,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.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; @@ -1391,8 +1515,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, @@ -1424,7 +1570,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. @@ -1575,6 +1722,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: @@ -1605,7 +1753,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); @@ -1617,8 +1764,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, @@ -1626,12 +1771,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) { @@ -1656,8 +1801,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,    ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);    // FIXME: We shouldn't have to pass the DashX option around here    InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags); -  Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags) -            && Success; +  ParseTargetArgs(Res.getTargetOpts(), *Args); +  Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags, +                             Res.getTargetOpts()) && Success;    ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);    if (DashX != IK_AST && DashX != IK_LLVM_IR) {      ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags); @@ -1672,8 +1818,6 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,    ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags);    ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args,                                Res.getFrontendOpts().ProgramAction); -  ParseTargetArgs(Res.getTargetOpts(), *Args); -    return Success;  } @@ -1753,8 +1897,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]); @@ -1763,7 +1906,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(); @@ -1785,20 +1927,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; @@ -1812,10 +1960,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) @@ -1825,4 +1974,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 | 
