summaryrefslogtreecommitdiff
path: root/external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2014-05-30 18:13:37 +0000
committerjoerg <joerg@NetBSD.org>2014-05-30 18:13:37 +0000
commitafb6842aba94daaa92cf6da14f14e79943a4b315 (patch)
tree73c8d7687de2d406457602d3a873497cdd38f5fe /external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp
parent9e68444d2911346f3a60c226b76244119cd3a530 (diff)
Import Clang 3.5svn r209886.
Diffstat (limited to 'external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r--external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp171
1 files changed, 134 insertions, 37 deletions
diff --git a/external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp b/external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp
index ad2d37cc297..70c2fec6ce9 100644
--- a/external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/external/bsd/llvm/dist/clang/lib/Frontend/CompilerInvocation.cpp
@@ -8,18 +8,17 @@
//===----------------------------------------------------------------------===//
#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/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -28,13 +27,15 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
-#include "llvm/Support/Atomic.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>
using namespace clang;
@@ -56,6 +57,8 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
+CompilerInvocationBase::~CompilerInvocationBase() {}
+
//===----------------------------------------------------------------------===//
// Deserialization (from args)
//===----------------------------------------------------------------------===//
@@ -263,7 +266,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];
@@ -295,6 +298,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) {
@@ -325,9 +355,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))
@@ -376,7 +407,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
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);
@@ -399,7 +430,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);
@@ -447,13 +477,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);
+ 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);
@@ -519,6 +550,29 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
+ if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
+ StringRef Val = A->getValue();
+ std::string RegexError;
+ Opts.OptimizationRemarkPattern = std::make_shared<llvm::Regex>(Val);
+ if (!Opts.OptimizationRemarkPattern->isValid(RegexError)) {
+ Diags.Report(diag::err_drv_optimization_remark_pattern)
+ << RegexError << A->getAsString(Args);
+ Opts.OptimizationRemarkPattern.reset();
+ }
+ }
+
+ if (Arg *A = Args.getLastArg(OPT_Rpass_EQ))
+ Opts.OptimizationRemarkPattern =
+ GenerateOptimizationRemarkRegex(Diags, Args, A);
+
+ if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ))
+ Opts.OptimizationRemarkMissedPattern =
+ GenerateOptimizationRemarkRegex(Diags, Args, A);
+
+ if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ))
+ Opts.OptimizationRemarkAnalysisPattern =
+ GenerateOptimizationRemarkRegex(Diags, Args, A);
+
return Success;
}
@@ -528,6 +582,7 @@ 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);
@@ -918,6 +973,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);
@@ -929,6 +985,9 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
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) {
@@ -1014,12 +1073,12 @@ 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)
@@ -1083,18 +1142,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) {
@@ -1105,12 +1159,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;
@@ -1334,7 +1390,13 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
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.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);
@@ -1430,8 +1492,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel);
}
- // Check if -fopenmp is specified.
- Opts.OpenMP = Args.hasArg(OPT_fopenmp);
+ // 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,
@@ -1664,12 +1730,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) {
@@ -1790,7 +1856,7 @@ std::string CompilerInvocation::getModuleHash() const {
// Extend the signature with the target options.
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
- TargetOpts->ABI, TargetOpts->LinkerVersion);
+ TargetOpts->ABI);
for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i)
code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]);
@@ -1820,13 +1886,17 @@ 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;
+ std::unique_ptr<llvm::MemoryBuffer> buffer;
SmallString<128> systemVersionFile;
systemVersionFile += hsOpts.Sysroot;
llvm::sys::path::append(systemVersionFile, "System");
@@ -1883,10 +1953,37 @@ void BuryPointer(const void *Ptr) {
// is what we want in such case.
static const size_t kGraveYardMaxSize = 16;
LLVM_ATTRIBUTE_UNUSED static const void *GraveYard[kGraveYardMaxSize];
- static llvm::sys::cas_flag GraveYardSize;
- llvm::sys::cas_flag Idx = llvm::sys::AtomicIncrement(&GraveYardSize) - 1;
+ 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) {
+ std::unique_ptr<llvm::MemoryBuffer> Buffer;
+ if (llvm::errc::success != llvm::MemoryBuffer::getFile(File, 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.getPtr()) {
+ Diags.Report(diag::err_invalid_vfs_overlay) << File;
+ return IntrusiveRefCntPtr<vfs::FileSystem>();
+ }
+ Overlay->pushOverlay(FS);
+ }
+ return Overlay;
}
+} // end namespace clang