Commit 19321ea6 by Nicolas Capens

Add LLVM dependencies for Subzero on Android and Linux.

Change-Id: I3ad40f5c0f9faf8aa27356b72b4d98763b9711d7 Reviewed-on: https://swiftshader-review.googlesource.com/8372Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent b7d5924b
/*===------- llvm/Config/abi-breaking.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* This file controls the C++ ABI break introduced in LLVM public header. */
#ifndef LLVM_ABI_BREAKING_CHECKS_H
#define LLVM_ABI_BREAKING_CHECKS_H
/* Define to enable checks that alter the LLVM C++ ABI */
#define LLVM_ENABLE_ABI_BREAKING_CHECKS 1
/* Define to disable the link-time checking of mismatch for
LLVM_ENABLE_ABI_BREAKING_CHECKS */
#define LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING 0
#if !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
// ABI_BREAKING_CHECKS protection: provides link-time failure when clients build
// mismatch with LLVM
#if defined(_MSC_VER)
// Use pragma with MSVC
#define LLVM_XSTR(s) LLVM_STR(s)
#define LLVM_STR(s) #s
#pragma detect_mismatch("LLVM_ENABLE_ABI_BREAKING_CHECKS", LLVM_XSTR(LLVM_ENABLE_ABI_BREAKING_CHECKS))
#undef LLVM_XSTR
#undef LLVM_STR
#elif defined(_WIN32) || defined(__CYGWIN__) // Win32 w/o #pragma detect_mismatch
// FIXME: Implement checks without weak.
#elif defined(__cplusplus)
namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
extern int EnableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyEnableABIBreakingChecks = &EnableABIBreakingChecks;
#else
extern int DisableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyDisableABIBreakingChecks = &DisableABIBreakingChecks;
#endif
}
#endif // _MSC_VER
#endif // LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
#endif
#ifndef CONFIG_H
#define CONFIG_H
/* Exported configuration */
#include "llvm/Config/llvm-config.h"
/* Bug report URL. */
#define BUG_REPORT_URL "http://llvm.org/bugs/"
/* Define to 1 to enable backtraces, and to 0 otherwise. */
#define ENABLE_BACKTRACES 1
/* Define to 1 to enable crash overrides, and to 0 otherwise. */
#define ENABLE_CRASH_OVERRIDES 1
/* Define to 1 if you have the `backtrace' function. */
/* #undef HAVE_BACKTRACE */
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
/* #undef HAVE_CRASHREPORTERCLIENT_H */
/* can use __crashreporter_info__ */
#define HAVE_CRASHREPORTER_INFO 0
/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
don't. */
#define HAVE_DECL_ARC4RANDOM 0
/* Define to 1 if you have the declaration of `FE_ALL_EXCEPT', and to 0 if you
don't. */
#define HAVE_DECL_FE_ALL_EXCEPT 1
/* Define to 1 if you have the declaration of `FE_INEXACT', and to 0 if you
don't. */
#define HAVE_DECL_FE_INEXACT 1
/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
don't. */
#define HAVE_DECL_STRERROR_S 0
/* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */
#define HAVE_DIA_SDK 0
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if dlopen() is available on this platform. */
#define HAVE_DLOPEN 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <execinfo.h> header file. */
/* #undef HAVE_EXECINFO_H */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <fenv.h> header file. */
#define HAVE_FENV_H 1
/* Define if libffi is available on this platform. */
/* #undef HAVE_FFI_CALL */
/* Define to 1 if you have the <ffi/ffi.h> header file. */
/* #undef HAVE_FFI_FFI_H */
/* Define to 1 if you have the <ffi.h> header file. */
/* #undef HAVE_FFI_H */
/* Define to 1 if you have the `futimens' function. */
#define HAVE_FUTIMENS 1
/* Define to 1 if you have the `futimes' function. */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the `getcwd' function. */
#define HAVE_GETCWD 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the `getrlimit' function. */
#define HAVE_GETRLIMIT 1
/* Define to 1 if you have the `getrusage' function. */
#define HAVE_GETRUSAGE 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if the system has the type `int64_t'. */
#define HAVE_INT64_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `isatty' function. */
#define HAVE_ISATTY 1
/* Define to 1 if you have the `edit' library (-ledit). */
/* #undef HAVE_LIBEDIT */
/* Define to 1 if you have the `psapi' library (-lpsapi). */
/* #undef HAVE_LIBPSAPI */
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `shell32' library (-lshell32). */
/* #undef HAVE_LIBSHELL32 */
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <link.h> header file. */
#define HAVE_LINK_H 1
/* Define to 1 if you have the `lseek64' function. */
#define HAVE_LSEEK64 1
/* Define to 1 if you have the <mach/mach.h> header file. */
/* #undef HAVE_MACH_MACH_H */
/* Define to 1 if you have the `mallctl' function. */
/* #undef HAVE_MALLCTL */
/* Define to 1 if you have the `mallinfo' function. */
#define HAVE_MALLINFO 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <malloc/malloc.h> header file. */
/* #undef HAVE_MALLOC_MALLOC_H */
/* Define to 1 if you have the `malloc_zone_statistics' function. */
/* #undef HAVE_MALLOC_ZONE_STATISTICS */
/* Define to 1 if you have the `mkdtemp' function. */
#define HAVE_MKDTEMP 1
/* Define to 1 if you have the `mkstemp' function. */
#define HAVE_MKSTEMP 1
/* Define to 1 if you have the `mktemp' function. */
#define HAVE_MKTEMP 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `posix_fallocate' function. */
#define HAVE_POSIX_FALLOCATE 1
/* Define to 1 if you have the `posix_spawn' function. */
/* #undef HAVE_POSIX_SPAWN */
/* Define to 1 if you have the `pread' function. */
#define HAVE_PREAD 1
/* Have pthread_getspecific */
#define HAVE_PTHREAD_GETSPECIFIC 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Have pthread_mutex_lock */
#define HAVE_PTHREAD_MUTEX_LOCK 1
/* Have pthread_rwlock_init */
#define HAVE_PTHREAD_RWLOCK_INIT 1
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1
/* Define to 1 if you have the `sbrk' function. */
#define HAVE_SBRK 1
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if you have the `setrlimit' function. */
#define HAVE_SETRLIMIT 1
/* Define to 1 if you have the `sigaltstack' function. */
#define HAVE_SIGALTSTACK 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_r' function. */
#define HAVE_STRERROR_R 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `sysconf' function. */
#define HAVE_SYSCONF 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#define HAVE_SYS_DIR_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define if the setupterm() function is supported this platform. */
/* #undef HAVE_TERMINFO */
/* Define if the xar_open() function is supported this platform. */
/* #undef HAVE_LIBXAR */
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `u_int64_t'. */
#define HAVE_U_INT64_T 1
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
/* #undef HAVE_VALGRIND_VALGRIND_H */
/* Define to 1 if you have the `writev' function. */
#define HAVE_WRITEV 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Have host's _alloca */
/* #undef HAVE__ALLOCA */
/* Define to 1 if you have the `_chsize_s' function. */
/* #undef HAVE__CHSIZE_S */
/* Define to 1 if you have the `_Unwind_Backtrace' function. */
#define HAVE__UNWIND_BACKTRACE 1
/* Have host's __alloca */
/* #undef HAVE___ALLOCA */
/* Have host's __ashldi3 */
/* #undef HAVE___ASHLDI3 */
/* Have host's __ashrdi3 */
/* #undef HAVE___ASHRDI3 */
/* Have host's __chkstk */
/* #undef HAVE___CHKSTK */
/* Have host's __chkstk_ms */
/* #undef HAVE___CHKSTK_MS */
/* Have host's __cmpdi2 */
/* #undef HAVE___CMPDI2 */
/* Have host's __divdi3 */
/* #undef HAVE___DIVDI3 */
/* Have host's __fixdfdi */
/* #undef HAVE___FIXDFDI */
/* Have host's __fixsfdi */
/* #undef HAVE___FIXSFDI */
/* Have host's __floatdidf */
/* #undef HAVE___FLOATDIDF */
/* Have host's __lshrdi3 */
/* #undef HAVE___LSHRDI3 */
/* Have host's __main */
/* #undef HAVE___MAIN */
/* Have host's __moddi3 */
/* #undef HAVE___MODDI3 */
/* Have host's __udivdi3 */
/* #undef HAVE___UDIVDI3 */
/* Have host's __umoddi3 */
/* #undef HAVE___UMODDI3 */
/* Have host's ___chkstk */
/* #undef HAVE____CHKSTK */
/* Have host's ___chkstk_ms */
/* #undef HAVE____CHKSTK_MS */
/* Linker version detected at compile time. */
/* #undef HOST_LINK_VERSION */
/* Define if we link Polly to the tools */
/* #undef LINK_POLLY_INTO_TOOLS */
/* Target triple LLVM will generate code for by default */
/* Doesn't use `cmakedefine` because it is allowed to be empty. */
#define LLVM_DEFAULT_TARGET_TRIPLE "x86_64-unknown-linux-gnu"
/* Define if threads enabled */
#define LLVM_ENABLE_THREADS 1
/* Define if zlib compression is available */
#define LLVM_ENABLE_ZLIB 1
/* Has gcc/MSVC atomic intrinsics */
#define LLVM_HAS_ATOMICS 1
/* Host triple LLVM will be executed on */
#define LLVM_HOST_TRIPLE "x86_64-unknown-linux-gnu"
/* LLVM architecture name for the native architecture, if available */
#define LLVM_NATIVE_ARCH X86
/* LLVM name for the native AsmParser init function, if available */
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser
/* LLVM name for the native AsmPrinter init function, if available */
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
/* LLVM name for the native Disassembler init function, if available */
#define LLVM_NATIVE_DISASSEMBLER LLVMInitializeX86Disassembler
/* LLVM name for the native Target init function, if available */
#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
/* LLVM name for the native TargetInfo init function, if available */
#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
/* LLVM name for the native target MC init function, if available */
#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
/* Define if this is Unixish platform */
#define LLVM_ON_UNIX 1
/* Define if this is Win32ish platform */
/* #undef LLVM_ON_WIN32 */
/* Installation prefix directory */
#define LLVM_PREFIX "/usr/local"
/* Define if we have the Intel JIT API runtime support library */
#define LLVM_USE_INTEL_JITEVENTS 0
/* Define if we have the oprofile JIT-support library */
#define LLVM_USE_OPROFILE 0
/* LLVM version information */
/* #undef LLVM_VERSION_INFO */
/* Major version of the LLVM API */
#define LLVM_VERSION_MAJOR 4
/* Minor version of the LLVM API */
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
#define LLVM_VERSION_PATCH 0
/* LLVM version string */
#define LLVM_VERSION_STRING "4.0.0svn"
/* Define to the extension used for shared libraries, say, ".so". */
#define LTDL_SHLIB_EXT ".so"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://llvm.org/bugs/"
/* Define to the full name of this package. */
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "LLVM 4.0.0svn"
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.0.0svn"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to a function replacing strtoll */
/* #undef strtoll */
/* Define to a function implementing strtoull */
/* #undef strtoull */
/* Define to a function implementing stricmp */
/* #undef stricmp */
/* Define to a function implementing strdup */
/* #undef strdup */
#endif
/*===------- llvm/Config/llvm-config.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* This file enumerates variables from the LLVM configuration so that they
can be in exported headers and won't override package specific directives.
This is a C header that can be included in the llvm-c headers. */
#ifndef LLVM_CONFIG_H
#define LLVM_CONFIG_H
/* Define if we link Polly to the tools */
/* #undef LINK_POLLY_INTO_TOOLS */
/* Target triple LLVM will generate code for by default */
#define LLVM_DEFAULT_TARGET_TRIPLE "x86_64-unknown-linux-gnu"
/* Define if threads enabled */
#define LLVM_ENABLE_THREADS 1
/* Has gcc/MSVC atomic intrinsics */
#define LLVM_HAS_ATOMICS 1
/* Host triple LLVM will be executed on */
#define LLVM_HOST_TRIPLE "x86_64-unknown-linux-gnu"
/* LLVM architecture name for the native architecture, if available */
#define LLVM_NATIVE_ARCH X86
/* LLVM name for the native AsmParser init function, if available */
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser
/* LLVM name for the native AsmPrinter init function, if available */
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
/* LLVM name for the native Disassembler init function, if available */
#define LLVM_NATIVE_DISASSEMBLER LLVMInitializeX86Disassembler
/* LLVM name for the native Target init function, if available */
#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
/* LLVM name for the native TargetInfo init function, if available */
#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
/* LLVM name for the native target MC init function, if available */
#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
/* Define if this is Unixish platform */
#define LLVM_ON_UNIX 1
/* Define if this is Win32ish platform */
/* #undef LLVM_ON_WIN32 */
/* Installation prefix directory */
#define LLVM_PREFIX "/usr/local"
/* Define if we have the Intel JIT API runtime support library */
#define LLVM_USE_INTEL_JITEVENTS 0
/* Define if we have the oprofile JIT-support library */
#define LLVM_USE_OPROFILE 0
/* Major version of the LLVM API */
#define LLVM_VERSION_MAJOR 4
/* Minor version of the LLVM API */
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
#define LLVM_VERSION_PATCH 0
/* LLVM version string */
#define LLVM_VERSION_STRING "4.0.0svn"
#endif
#ifdef GET_ATTR_ENUM
#undef GET_ATTR_ENUM
Alignment,
AllocSize,
AlwaysInline,
ArgMemOnly,
Builtin,
ByVal,
Cold,
Convergent,
Dereferenceable,
DereferenceableOrNull,
InAlloca,
InReg,
InaccessibleMemOnly,
InaccessibleMemOrArgMemOnly,
InlineHint,
JumpTable,
MinSize,
Naked,
Nest,
NoAlias,
NoBuiltin,
NoCapture,
NoDuplicate,
NoImplicitFloat,
NoInline,
NoRecurse,
NoRedZone,
NoReturn,
NoUnwind,
NonLazyBind,
NonNull,
OptimizeForSize,
OptimizeNone,
ReadNone,
ReadOnly,
Returned,
ReturnsTwice,
SExt,
SafeStack,
SanitizeAddress,
SanitizeMemory,
SanitizeThread,
StackAlignment,
StackProtect,
StackProtectReq,
StackProtectStrong,
StructRet,
SwiftError,
SwiftSelf,
UWTable,
WriteOnly,
ZExt,
#endif
#ifdef GET_ATTR_KIND_FROM_NAME
#undef GET_ATTR_KIND_FROM_NAME
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
return StringSwitch<Attribute::AttrKind>(AttrName)
.Case("align", Attribute::Alignment)
.Case("allocsize", Attribute::AllocSize)
.Case("alwaysinline", Attribute::AlwaysInline)
.Case("argmemonly", Attribute::ArgMemOnly)
.Case("builtin", Attribute::Builtin)
.Case("byval", Attribute::ByVal)
.Case("cold", Attribute::Cold)
.Case("convergent", Attribute::Convergent)
.Case("dereferenceable", Attribute::Dereferenceable)
.Case("dereferenceable_or_null", Attribute::DereferenceableOrNull)
.Case("inalloca", Attribute::InAlloca)
.Case("inreg", Attribute::InReg)
.Case("inaccessiblememonly", Attribute::InaccessibleMemOnly)
.Case("inaccessiblemem_or_argmemonly", Attribute::InaccessibleMemOrArgMemOnly)
.Case("inlinehint", Attribute::InlineHint)
.Case("jumptable", Attribute::JumpTable)
.Case("minsize", Attribute::MinSize)
.Case("naked", Attribute::Naked)
.Case("nest", Attribute::Nest)
.Case("noalias", Attribute::NoAlias)
.Case("nobuiltin", Attribute::NoBuiltin)
.Case("nocapture", Attribute::NoCapture)
.Case("noduplicate", Attribute::NoDuplicate)
.Case("noimplicitfloat", Attribute::NoImplicitFloat)
.Case("noinline", Attribute::NoInline)
.Case("norecurse", Attribute::NoRecurse)
.Case("noredzone", Attribute::NoRedZone)
.Case("noreturn", Attribute::NoReturn)
.Case("nounwind", Attribute::NoUnwind)
.Case("nonlazybind", Attribute::NonLazyBind)
.Case("nonnull", Attribute::NonNull)
.Case("optsize", Attribute::OptimizeForSize)
.Case("optnone", Attribute::OptimizeNone)
.Case("readnone", Attribute::ReadNone)
.Case("readonly", Attribute::ReadOnly)
.Case("returned", Attribute::Returned)
.Case("returns_twice", Attribute::ReturnsTwice)
.Case("signext", Attribute::SExt)
.Case("safestack", Attribute::SafeStack)
.Case("sanitize_address", Attribute::SanitizeAddress)
.Case("sanitize_memory", Attribute::SanitizeMemory)
.Case("sanitize_thread", Attribute::SanitizeThread)
.Case("alignstack", Attribute::StackAlignment)
.Case("ssp", Attribute::StackProtect)
.Case("sspreq", Attribute::StackProtectReq)
.Case("sspstrong", Attribute::StackProtectStrong)
.Case("sret", Attribute::StructRet)
.Case("swifterror", Attribute::SwiftError)
.Case("swiftself", Attribute::SwiftSelf)
.Case("uwtable", Attribute::UWTable)
.Case("writeonly", Attribute::WriteOnly)
.Case("zeroext", Attribute::ZExt)
.Default(Attribute::None);
}
#endif
#ifdef GET_ATTR_COMPAT_FUNC
#undef GET_ATTR_COMPAT_FUNC
struct EnumAttr {
static bool isSet(const Function &Fn,
Attribute::AttrKind Kind) {
return Fn.hasFnAttribute(Kind);
}
static void set(Function &Fn,
Attribute::AttrKind Kind, bool Val) {
if (Val)
Fn.addFnAttr(Kind);
else
Fn.removeFnAttr(Kind);
}
};
struct StrBoolAttr {
static bool isSet(const Function &Fn,
StringRef Kind) {
auto A = Fn.getFnAttribute(Kind);
return A.getValueAsString().equals("true");
}
static void set(Function &Fn,
StringRef Kind, bool Val) {
Fn.addFnAttr(Kind, Val ? "true" : "false");
}
};
// EnumAttr classes
struct AlignmentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Alignment;
}
};
struct AllocSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::AllocSize;
}
};
struct AlwaysInlineAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::AlwaysInline;
}
};
struct ArgMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ArgMemOnly;
}
};
struct BuiltinAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Builtin;
}
};
struct ByValAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ByVal;
}
};
struct ColdAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Cold;
}
};
struct ConvergentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Convergent;
}
};
struct DereferenceableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Dereferenceable;
}
};
struct DereferenceableOrNullAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::DereferenceableOrNull;
}
};
struct InAllocaAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InAlloca;
}
};
struct InRegAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InReg;
}
};
struct InaccessibleMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InaccessibleMemOnly;
}
};
struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InaccessibleMemOrArgMemOnly;
}
};
struct InlineHintAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InlineHint;
}
};
struct JumpTableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::JumpTable;
}
};
struct MinSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::MinSize;
}
};
struct NakedAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Naked;
}
};
struct NestAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Nest;
}
};
struct NoAliasAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoAlias;
}
};
struct NoBuiltinAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoBuiltin;
}
};
struct NoCaptureAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoCapture;
}
};
struct NoDuplicateAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoDuplicate;
}
};
struct NoImplicitFloatAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoImplicitFloat;
}
};
struct NoInlineAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoInline;
}
};
struct NoRecurseAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoRecurse;
}
};
struct NoRedZoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoRedZone;
}
};
struct NoReturnAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoReturn;
}
};
struct NoUnwindAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoUnwind;
}
};
struct NonLazyBindAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NonLazyBind;
}
};
struct NonNullAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NonNull;
}
};
struct OptimizeForSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::OptimizeForSize;
}
};
struct OptimizeNoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::OptimizeNone;
}
};
struct ReadNoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReadNone;
}
};
struct ReadOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReadOnly;
}
};
struct ReturnedAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Returned;
}
};
struct ReturnsTwiceAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReturnsTwice;
}
};
struct SExtAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SExt;
}
};
struct SafeStackAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SafeStack;
}
};
struct SanitizeAddressAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeAddress;
}
};
struct SanitizeMemoryAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeMemory;
}
};
struct SanitizeThreadAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeThread;
}
};
struct StackAlignmentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackAlignment;
}
};
struct StackProtectAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtect;
}
};
struct StackProtectReqAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtectReq;
}
};
struct StackProtectStrongAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtectStrong;
}
};
struct StructRetAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StructRet;
}
};
struct SwiftErrorAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SwiftError;
}
};
struct SwiftSelfAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SwiftSelf;
}
};
struct UWTableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::UWTable;
}
};
struct WriteOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::WriteOnly;
}
};
struct ZExtAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ZExt;
}
};
// StrBoolAttr classes
struct LessPreciseFPMADAttr : StrBoolAttr {
static StringRef getKind() {
return "less-precise-fpmad";
}
};
struct NoInfsFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "no-infs-fp-math";
}
};
struct NoJumpTablesAttr : StrBoolAttr {
static StringRef getKind() {
return "no-jump-tables";
}
};
struct NoNansFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "no-nans-fp-math";
}
};
struct UnsafeFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "unsafe-fp-math";
}
};
static inline bool hasCompatibleFnAttrs(const Function &Caller,
const Function &Callee) {
bool Ret = true;
Ret &= isEqual<SanitizeAddressAttr>(Caller, Callee);
Ret &= isEqual<SanitizeThreadAttr>(Caller, Callee);
Ret &= isEqual<SanitizeMemoryAttr>(Caller, Callee);
Ret &= isEqual<SafeStackAttr>(Caller, Callee);
return Ret;
}
static inline void mergeFnAttrs(Function &Caller,
const Function &Callee) {
adjustCallerSSPLevel(Caller, Callee);
setAND<LessPreciseFPMADAttr>(Caller, Callee);
setAND<NoInfsFPMathAttr>(Caller, Callee);
setAND<NoNansFPMathAttr>(Caller, Callee);
setAND<UnsafeFPMathAttr>(Caller, Callee);
setOR<NoImplicitFloatAttr>(Caller, Callee);
setOR<NoJumpTablesAttr>(Caller, Callee);
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file contains definitions to figure out the size of _HOST_ data types.*|
|* This file is important because different host OS's define different macros,*|
|* which makes portability tough. This file exports the following *|
|* definitions: *|
|* *|
|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
|* *|
|* No library is required when using these functions. *|
|* *|
|*===----------------------------------------------------------------------===*/
/* Please leave this file C-compatible. */
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UINT64_T 1
#define HAVE_U_INT64_T 1
#ifdef __cplusplus
#include <cmath>
#else
#include <math.h>
#endif
#ifdef __cplusplus
#include <cinttypes>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#ifdef __cplusplus
#include <cstdint>
#else
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#error "Compiler must provide an implementation of stdint.h"
#endif
#endif
#ifndef _MSC_VER
#if !defined(UINT32_MAX)
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
"__STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
#if !defined(UINT32_C)
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
"__STDC_CONSTANT_MACROS before #including Support/DataTypes.h"
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
#ifdef _AIX
// GCC is strict about defining large constants: they must have LL modifier.
#undef INT64_MAX
#undef INT64_MIN
#endif
/* Handle incorrect definition of uint64_t as u_int64_t */
#ifndef HAVE_UINT64_T
#ifdef HAVE_U_INT64_T
typedef u_int64_t uint64_t;
#else
# error "Don't have a definition for uint64_t on this platform"
#endif
#endif
#else /* _MSC_VER */
#ifdef __cplusplus
#include <cstdlib>
#include <cstddef>
#else
#include <stdlib.h>
#include <stddef.h>
#endif
#include <sys/types.h>
#if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
typedef signed int ssize_t;
#endif /* _WIN64 */
#ifndef HAVE_INTTYPES_H
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#endif /* HAVE_INTTYPES_H */
#endif /* _MSC_VER */
/* Set defaults for constants which we cannot find. */
#if !defined(INT64_MAX)
# define INT64_MAX 9223372036854775807LL
#endif
#if !defined(INT64_MIN)
# define INT64_MIN ((-INT64_MAX)-1)
#endif
#if !defined(UINT64_MAX)
# define UINT64_MAX 0xffffffffffffffffULL
#endif
#ifndef HUGE_VALF
#define HUGE_VALF (float)HUGE_VAL
#endif
#endif /* SUPPORT_DATATYPES_H */
/*===------- llvm/Config/abi-breaking.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* This file controls the C++ ABI break introduced in LLVM public header. */
#ifndef LLVM_ABI_BREAKING_CHECKS_H
#define LLVM_ABI_BREAKING_CHECKS_H
/* Define to enable checks that alter the LLVM C++ ABI */
#define LLVM_ENABLE_ABI_BREAKING_CHECKS 1
/* Define to disable the link-time checking of mismatch for
LLVM_ENABLE_ABI_BREAKING_CHECKS */
#define LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING 0
#if !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
// ABI_BREAKING_CHECKS protection: provides link-time failure when clients build
// mismatch with LLVM
#if defined(_MSC_VER)
// Use pragma with MSVC
#define LLVM_XSTR(s) LLVM_STR(s)
#define LLVM_STR(s) #s
#pragma detect_mismatch("LLVM_ENABLE_ABI_BREAKING_CHECKS", LLVM_XSTR(LLVM_ENABLE_ABI_BREAKING_CHECKS))
#undef LLVM_XSTR
#undef LLVM_STR
#elif defined(_WIN32) || defined(__CYGWIN__) // Win32 w/o #pragma detect_mismatch
// FIXME: Implement checks without weak.
#elif defined(__cplusplus)
namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
extern int EnableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyEnableABIBreakingChecks = &EnableABIBreakingChecks;
#else
extern int DisableABIBreakingChecks;
__attribute__((weak, visibility ("hidden"))) int *VerifyDisableABIBreakingChecks = &DisableABIBreakingChecks;
#endif
}
#endif // _MSC_VER
#endif // LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
#endif
#ifndef CONFIG_H
#define CONFIG_H
/* Exported configuration */
#include "llvm/Config/llvm-config.h"
/* Bug report URL. */
#define BUG_REPORT_URL "http://llvm.org/bugs/"
/* Define to 1 to enable backtraces, and to 0 otherwise. */
#define ENABLE_BACKTRACES 1
/* Define to 1 to enable crash overrides, and to 0 otherwise. */
#define ENABLE_CRASH_OVERRIDES 1
/* Define to 1 if you have the `backtrace' function. */
#define HAVE_BACKTRACE 1
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
/* #undef HAVE_CRASHREPORTERCLIENT_H */
/* can use __crashreporter_info__ */
#define HAVE_CRASHREPORTER_INFO 0
/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
don't. */
#define HAVE_DECL_ARC4RANDOM 0
/* Define to 1 if you have the declaration of `FE_ALL_EXCEPT', and to 0 if you
don't. */
#define HAVE_DECL_FE_ALL_EXCEPT 1
/* Define to 1 if you have the declaration of `FE_INEXACT', and to 0 if you
don't. */
#define HAVE_DECL_FE_INEXACT 1
/* Define to 1 if you have the declaration of `strerror_s', and to 0 if you
don't. */
#define HAVE_DECL_STRERROR_S 0
/* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */
#define HAVE_DIA_SDK 0
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if dlopen() is available on this platform. */
#define HAVE_DLOPEN 1
/* Define to 1 if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 1
/* Define to 1 if you have the <execinfo.h> header file. */
#define HAVE_EXECINFO_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <fenv.h> header file. */
#define HAVE_FENV_H 1
/* Define if libffi is available on this platform. */
/* #undef HAVE_FFI_CALL */
/* Define to 1 if you have the <ffi/ffi.h> header file. */
/* #undef HAVE_FFI_FFI_H */
/* Define to 1 if you have the <ffi.h> header file. */
/* #undef HAVE_FFI_H */
/* Define to 1 if you have the `futimens' function. */
#define HAVE_FUTIMENS 1
/* Define to 1 if you have the `futimes' function. */
#define HAVE_FUTIMES 1
/* Define to 1 if you have the `getcwd' function. */
#define HAVE_GETCWD 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the `getrlimit' function. */
#define HAVE_GETRLIMIT 1
/* Define to 1 if you have the `getrusage' function. */
#define HAVE_GETRUSAGE 1
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if the system has the type `int64_t'. */
#define HAVE_INT64_T 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `isatty' function. */
#define HAVE_ISATTY 1
/* Define to 1 if you have the `edit' library (-ledit). */
/* #undef HAVE_LIBEDIT */
/* Define to 1 if you have the `psapi' library (-lpsapi). */
/* #undef HAVE_LIBPSAPI */
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `shell32' library (-lshell32). */
/* #undef HAVE_LIBSHELL32 */
/* Define to 1 if you have the `z' library (-lz). */
#define HAVE_LIBZ 1
/* Define to 1 if you have the <link.h> header file. */
#define HAVE_LINK_H 1
/* Define to 1 if you have the `lseek64' function. */
#define HAVE_LSEEK64 1
/* Define to 1 if you have the <mach/mach.h> header file. */
/* #undef HAVE_MACH_MACH_H */
/* Define to 1 if you have the `mallctl' function. */
/* #undef HAVE_MALLCTL */
/* Define to 1 if you have the `mallinfo' function. */
#define HAVE_MALLINFO 1
/* Define to 1 if you have the <malloc.h> header file. */
#define HAVE_MALLOC_H 1
/* Define to 1 if you have the <malloc/malloc.h> header file. */
/* #undef HAVE_MALLOC_MALLOC_H */
/* Define to 1 if you have the `malloc_zone_statistics' function. */
/* #undef HAVE_MALLOC_ZONE_STATISTICS */
/* Define to 1 if you have the `mkdtemp' function. */
#define HAVE_MKDTEMP 1
/* Define to 1 if you have the `mkstemp' function. */
#define HAVE_MKSTEMP 1
/* Define to 1 if you have the `mktemp' function. */
#define HAVE_MKTEMP 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `posix_fallocate' function. */
#define HAVE_POSIX_FALLOCATE 1
/* Define to 1 if you have the `posix_spawn' function. */
#define HAVE_POSIX_SPAWN 1
/* Define to 1 if you have the `pread' function. */
#define HAVE_PREAD 1
/* Have pthread_getspecific */
#define HAVE_PTHREAD_GETSPECIFIC 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Have pthread_mutex_lock */
#define HAVE_PTHREAD_MUTEX_LOCK 1
/* Have pthread_rwlock_init */
#define HAVE_PTHREAD_RWLOCK_INIT 1
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1
/* Define to 1 if you have the `sbrk' function. */
#define HAVE_SBRK 1
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if you have the `setrlimit' function. */
#define HAVE_SETRLIMIT 1
/* Define to 1 if you have the `sigaltstack' function. */
#define HAVE_SIGALTSTACK 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the `strerror_r' function. */
#define HAVE_STRERROR_R 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `sysconf' function. */
#define HAVE_SYSCONF 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#define HAVE_SYS_DIR_H 1
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/uio.h> header file. */
#define HAVE_SYS_UIO_H 1
/* Define if the setupterm() function is supported this platform. */
/* #undef HAVE_TERMINFO */
/* Define if the xar_open() function is supported this platform. */
/* #undef HAVE_LIBXAR */
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if the system has the type `uint64_t'. */
#define HAVE_UINT64_T 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `u_int64_t'. */
#define HAVE_U_INT64_T 1
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
/* #undef HAVE_VALGRIND_VALGRIND_H */
/* Define to 1 if you have the `writev' function. */
#define HAVE_WRITEV 1
/* Define to 1 if you have the <zlib.h> header file. */
#define HAVE_ZLIB_H 1
/* Have host's _alloca */
/* #undef HAVE__ALLOCA */
/* Define to 1 if you have the `_chsize_s' function. */
/* #undef HAVE__CHSIZE_S */
/* Define to 1 if you have the `_Unwind_Backtrace' function. */
#define HAVE__UNWIND_BACKTRACE 1
/* Have host's __alloca */
/* #undef HAVE___ALLOCA */
/* Have host's __ashldi3 */
/* #undef HAVE___ASHLDI3 */
/* Have host's __ashrdi3 */
/* #undef HAVE___ASHRDI3 */
/* Have host's __chkstk */
/* #undef HAVE___CHKSTK */
/* Have host's __chkstk_ms */
/* #undef HAVE___CHKSTK_MS */
/* Have host's __cmpdi2 */
/* #undef HAVE___CMPDI2 */
/* Have host's __divdi3 */
/* #undef HAVE___DIVDI3 */
/* Have host's __fixdfdi */
/* #undef HAVE___FIXDFDI */
/* Have host's __fixsfdi */
/* #undef HAVE___FIXSFDI */
/* Have host's __floatdidf */
/* #undef HAVE___FLOATDIDF */
/* Have host's __lshrdi3 */
/* #undef HAVE___LSHRDI3 */
/* Have host's __main */
/* #undef HAVE___MAIN */
/* Have host's __moddi3 */
/* #undef HAVE___MODDI3 */
/* Have host's __udivdi3 */
/* #undef HAVE___UDIVDI3 */
/* Have host's __umoddi3 */
/* #undef HAVE___UMODDI3 */
/* Have host's ___chkstk */
/* #undef HAVE____CHKSTK */
/* Have host's ___chkstk_ms */
/* #undef HAVE____CHKSTK_MS */
/* Linker version detected at compile time. */
/* #undef HOST_LINK_VERSION */
/* Define if we link Polly to the tools */
/* #undef LINK_POLLY_INTO_TOOLS */
/* Target triple LLVM will generate code for by default */
/* Doesn't use `cmakedefine` because it is allowed to be empty. */
#define LLVM_DEFAULT_TARGET_TRIPLE "x86_64-unknown-linux-gnu"
/* Define if threads enabled */
#define LLVM_ENABLE_THREADS 1
/* Define if zlib compression is available */
#define LLVM_ENABLE_ZLIB 1
/* Has gcc/MSVC atomic intrinsics */
#define LLVM_HAS_ATOMICS 1
/* Host triple LLVM will be executed on */
#define LLVM_HOST_TRIPLE "x86_64-unknown-linux-gnu"
/* LLVM architecture name for the native architecture, if available */
#define LLVM_NATIVE_ARCH X86
/* LLVM name for the native AsmParser init function, if available */
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser
/* LLVM name for the native AsmPrinter init function, if available */
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
/* LLVM name for the native Disassembler init function, if available */
#define LLVM_NATIVE_DISASSEMBLER LLVMInitializeX86Disassembler
/* LLVM name for the native Target init function, if available */
#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
/* LLVM name for the native TargetInfo init function, if available */
#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
/* LLVM name for the native target MC init function, if available */
#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
/* Define if this is Unixish platform */
#define LLVM_ON_UNIX 1
/* Define if this is Win32ish platform */
/* #undef LLVM_ON_WIN32 */
/* Installation prefix directory */
#define LLVM_PREFIX "/usr/local"
/* Define if we have the Intel JIT API runtime support library */
#define LLVM_USE_INTEL_JITEVENTS 0
/* Define if we have the oprofile JIT-support library */
#define LLVM_USE_OPROFILE 0
/* LLVM version information */
/* #undef LLVM_VERSION_INFO */
/* Major version of the LLVM API */
#define LLVM_VERSION_MAJOR 4
/* Minor version of the LLVM API */
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
#define LLVM_VERSION_PATCH 0
/* LLVM version string */
#define LLVM_VERSION_STRING "4.0.0svn"
/* Define to the extension used for shared libraries, say, ".so". */
#define LTDL_SHLIB_EXT ".so"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://llvm.org/bugs/"
/* Define to the full name of this package. */
#define PACKAGE_NAME "LLVM"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "LLVM 4.0.0svn"
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#define PACKAGE_VERSION "4.0.0svn"
/* Define to the vendor of this package. */
/* #undef PACKAGE_VENDOR */
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to a function replacing strtoll */
/* #undef strtoll */
/* Define to a function implementing strtoull */
/* #undef strtoull */
/* Define to a function implementing stricmp */
/* #undef stricmp */
/* Define to a function implementing strdup */
/* #undef strdup */
#endif
/*===------- llvm/Config/llvm-config.h - llvm configuration -------*- C -*-===*/
/* */
/* The LLVM Compiler Infrastructure */
/* */
/* This file is distributed under the University of Illinois Open Source */
/* License. See LICENSE.TXT for details. */
/* */
/*===----------------------------------------------------------------------===*/
/* This file enumerates variables from the LLVM configuration so that they
can be in exported headers and won't override package specific directives.
This is a C header that can be included in the llvm-c headers. */
#ifndef LLVM_CONFIG_H
#define LLVM_CONFIG_H
/* Define if we link Polly to the tools */
/* #undef LINK_POLLY_INTO_TOOLS */
/* Target triple LLVM will generate code for by default */
#define LLVM_DEFAULT_TARGET_TRIPLE "x86_64-unknown-linux-gnu"
/* Define if threads enabled */
#define LLVM_ENABLE_THREADS 1
/* Has gcc/MSVC atomic intrinsics */
#define LLVM_HAS_ATOMICS 1
/* Host triple LLVM will be executed on */
#define LLVM_HOST_TRIPLE "x86_64-unknown-linux-gnu"
/* LLVM architecture name for the native architecture, if available */
#define LLVM_NATIVE_ARCH X86
/* LLVM name for the native AsmParser init function, if available */
#define LLVM_NATIVE_ASMPARSER LLVMInitializeX86AsmParser
/* LLVM name for the native AsmPrinter init function, if available */
#define LLVM_NATIVE_ASMPRINTER LLVMInitializeX86AsmPrinter
/* LLVM name for the native Disassembler init function, if available */
#define LLVM_NATIVE_DISASSEMBLER LLVMInitializeX86Disassembler
/* LLVM name for the native Target init function, if available */
#define LLVM_NATIVE_TARGET LLVMInitializeX86Target
/* LLVM name for the native TargetInfo init function, if available */
#define LLVM_NATIVE_TARGETINFO LLVMInitializeX86TargetInfo
/* LLVM name for the native target MC init function, if available */
#define LLVM_NATIVE_TARGETMC LLVMInitializeX86TargetMC
/* Define if this is Unixish platform */
#define LLVM_ON_UNIX 1
/* Define if this is Win32ish platform */
/* #undef LLVM_ON_WIN32 */
/* Installation prefix directory */
#define LLVM_PREFIX "/usr/local"
/* Define if we have the Intel JIT API runtime support library */
#define LLVM_USE_INTEL_JITEVENTS 0
/* Define if we have the oprofile JIT-support library */
#define LLVM_USE_OPROFILE 0
/* Major version of the LLVM API */
#define LLVM_VERSION_MAJOR 4
/* Minor version of the LLVM API */
#define LLVM_VERSION_MINOR 0
/* Patch version of the LLVM API */
#define LLVM_VERSION_PATCH 0
/* LLVM version string */
#define LLVM_VERSION_STRING "4.0.0svn"
#endif
#ifdef GET_ATTR_ENUM
#undef GET_ATTR_ENUM
Alignment,
AllocSize,
AlwaysInline,
ArgMemOnly,
Builtin,
ByVal,
Cold,
Convergent,
Dereferenceable,
DereferenceableOrNull,
InAlloca,
InReg,
InaccessibleMemOnly,
InaccessibleMemOrArgMemOnly,
InlineHint,
JumpTable,
MinSize,
Naked,
Nest,
NoAlias,
NoBuiltin,
NoCapture,
NoDuplicate,
NoImplicitFloat,
NoInline,
NoRecurse,
NoRedZone,
NoReturn,
NoUnwind,
NonLazyBind,
NonNull,
OptimizeForSize,
OptimizeNone,
ReadNone,
ReadOnly,
Returned,
ReturnsTwice,
SExt,
SafeStack,
SanitizeAddress,
SanitizeMemory,
SanitizeThread,
StackAlignment,
StackProtect,
StackProtectReq,
StackProtectStrong,
StructRet,
SwiftError,
SwiftSelf,
UWTable,
WriteOnly,
ZExt,
#endif
#ifdef GET_ATTR_KIND_FROM_NAME
#undef GET_ATTR_KIND_FROM_NAME
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
return StringSwitch<Attribute::AttrKind>(AttrName)
.Case("align", Attribute::Alignment)
.Case("allocsize", Attribute::AllocSize)
.Case("alwaysinline", Attribute::AlwaysInline)
.Case("argmemonly", Attribute::ArgMemOnly)
.Case("builtin", Attribute::Builtin)
.Case("byval", Attribute::ByVal)
.Case("cold", Attribute::Cold)
.Case("convergent", Attribute::Convergent)
.Case("dereferenceable", Attribute::Dereferenceable)
.Case("dereferenceable_or_null", Attribute::DereferenceableOrNull)
.Case("inalloca", Attribute::InAlloca)
.Case("inreg", Attribute::InReg)
.Case("inaccessiblememonly", Attribute::InaccessibleMemOnly)
.Case("inaccessiblemem_or_argmemonly", Attribute::InaccessibleMemOrArgMemOnly)
.Case("inlinehint", Attribute::InlineHint)
.Case("jumptable", Attribute::JumpTable)
.Case("minsize", Attribute::MinSize)
.Case("naked", Attribute::Naked)
.Case("nest", Attribute::Nest)
.Case("noalias", Attribute::NoAlias)
.Case("nobuiltin", Attribute::NoBuiltin)
.Case("nocapture", Attribute::NoCapture)
.Case("noduplicate", Attribute::NoDuplicate)
.Case("noimplicitfloat", Attribute::NoImplicitFloat)
.Case("noinline", Attribute::NoInline)
.Case("norecurse", Attribute::NoRecurse)
.Case("noredzone", Attribute::NoRedZone)
.Case("noreturn", Attribute::NoReturn)
.Case("nounwind", Attribute::NoUnwind)
.Case("nonlazybind", Attribute::NonLazyBind)
.Case("nonnull", Attribute::NonNull)
.Case("optsize", Attribute::OptimizeForSize)
.Case("optnone", Attribute::OptimizeNone)
.Case("readnone", Attribute::ReadNone)
.Case("readonly", Attribute::ReadOnly)
.Case("returned", Attribute::Returned)
.Case("returns_twice", Attribute::ReturnsTwice)
.Case("signext", Attribute::SExt)
.Case("safestack", Attribute::SafeStack)
.Case("sanitize_address", Attribute::SanitizeAddress)
.Case("sanitize_memory", Attribute::SanitizeMemory)
.Case("sanitize_thread", Attribute::SanitizeThread)
.Case("alignstack", Attribute::StackAlignment)
.Case("ssp", Attribute::StackProtect)
.Case("sspreq", Attribute::StackProtectReq)
.Case("sspstrong", Attribute::StackProtectStrong)
.Case("sret", Attribute::StructRet)
.Case("swifterror", Attribute::SwiftError)
.Case("swiftself", Attribute::SwiftSelf)
.Case("uwtable", Attribute::UWTable)
.Case("writeonly", Attribute::WriteOnly)
.Case("zeroext", Attribute::ZExt)
.Default(Attribute::None);
}
#endif
#ifdef GET_ATTR_COMPAT_FUNC
#undef GET_ATTR_COMPAT_FUNC
struct EnumAttr {
static bool isSet(const Function &Fn,
Attribute::AttrKind Kind) {
return Fn.hasFnAttribute(Kind);
}
static void set(Function &Fn,
Attribute::AttrKind Kind, bool Val) {
if (Val)
Fn.addFnAttr(Kind);
else
Fn.removeFnAttr(Kind);
}
};
struct StrBoolAttr {
static bool isSet(const Function &Fn,
StringRef Kind) {
auto A = Fn.getFnAttribute(Kind);
return A.getValueAsString().equals("true");
}
static void set(Function &Fn,
StringRef Kind, bool Val) {
Fn.addFnAttr(Kind, Val ? "true" : "false");
}
};
// EnumAttr classes
struct AlignmentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Alignment;
}
};
struct AllocSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::AllocSize;
}
};
struct AlwaysInlineAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::AlwaysInline;
}
};
struct ArgMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ArgMemOnly;
}
};
struct BuiltinAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Builtin;
}
};
struct ByValAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ByVal;
}
};
struct ColdAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Cold;
}
};
struct ConvergentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Convergent;
}
};
struct DereferenceableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Dereferenceable;
}
};
struct DereferenceableOrNullAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::DereferenceableOrNull;
}
};
struct InAllocaAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InAlloca;
}
};
struct InRegAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InReg;
}
};
struct InaccessibleMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InaccessibleMemOnly;
}
};
struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InaccessibleMemOrArgMemOnly;
}
};
struct InlineHintAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::InlineHint;
}
};
struct JumpTableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::JumpTable;
}
};
struct MinSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::MinSize;
}
};
struct NakedAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Naked;
}
};
struct NestAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Nest;
}
};
struct NoAliasAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoAlias;
}
};
struct NoBuiltinAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoBuiltin;
}
};
struct NoCaptureAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoCapture;
}
};
struct NoDuplicateAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoDuplicate;
}
};
struct NoImplicitFloatAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoImplicitFloat;
}
};
struct NoInlineAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoInline;
}
};
struct NoRecurseAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoRecurse;
}
};
struct NoRedZoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoRedZone;
}
};
struct NoReturnAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoReturn;
}
};
struct NoUnwindAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NoUnwind;
}
};
struct NonLazyBindAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NonLazyBind;
}
};
struct NonNullAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::NonNull;
}
};
struct OptimizeForSizeAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::OptimizeForSize;
}
};
struct OptimizeNoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::OptimizeNone;
}
};
struct ReadNoneAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReadNone;
}
};
struct ReadOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReadOnly;
}
};
struct ReturnedAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::Returned;
}
};
struct ReturnsTwiceAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ReturnsTwice;
}
};
struct SExtAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SExt;
}
};
struct SafeStackAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SafeStack;
}
};
struct SanitizeAddressAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeAddress;
}
};
struct SanitizeMemoryAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeMemory;
}
};
struct SanitizeThreadAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SanitizeThread;
}
};
struct StackAlignmentAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackAlignment;
}
};
struct StackProtectAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtect;
}
};
struct StackProtectReqAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtectReq;
}
};
struct StackProtectStrongAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StackProtectStrong;
}
};
struct StructRetAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::StructRet;
}
};
struct SwiftErrorAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SwiftError;
}
};
struct SwiftSelfAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::SwiftSelf;
}
};
struct UWTableAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::UWTable;
}
};
struct WriteOnlyAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::WriteOnly;
}
};
struct ZExtAttr : EnumAttr {
static enum Attribute::AttrKind getKind() {
return llvm::Attribute::ZExt;
}
};
// StrBoolAttr classes
struct LessPreciseFPMADAttr : StrBoolAttr {
static StringRef getKind() {
return "less-precise-fpmad";
}
};
struct NoInfsFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "no-infs-fp-math";
}
};
struct NoJumpTablesAttr : StrBoolAttr {
static StringRef getKind() {
return "no-jump-tables";
}
};
struct NoNansFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "no-nans-fp-math";
}
};
struct UnsafeFPMathAttr : StrBoolAttr {
static StringRef getKind() {
return "unsafe-fp-math";
}
};
static inline bool hasCompatibleFnAttrs(const Function &Caller,
const Function &Callee) {
bool Ret = true;
Ret &= isEqual<SanitizeAddressAttr>(Caller, Callee);
Ret &= isEqual<SanitizeThreadAttr>(Caller, Callee);
Ret &= isEqual<SanitizeMemoryAttr>(Caller, Callee);
Ret &= isEqual<SafeStackAttr>(Caller, Callee);
return Ret;
}
static inline void mergeFnAttrs(Function &Caller,
const Function &Callee) {
adjustCallerSSPLevel(Caller, Callee);
setAND<LessPreciseFPMADAttr>(Caller, Callee);
setAND<NoInfsFPMathAttr>(Caller, Callee);
setAND<NoNansFPMathAttr>(Caller, Callee);
setAND<UnsafeFPMathAttr>(Caller, Callee);
setOR<NoImplicitFloatAttr>(Caller, Callee);
setOR<NoJumpTablesAttr>(Caller, Callee);
}
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\
|* *|
|* The LLVM Compiler Infrastructure *|
|* *|
|* This file is distributed under the University of Illinois Open Source *|
|* License. See LICENSE.TXT for details. *|
|* *|
|*===----------------------------------------------------------------------===*|
|* *|
|* This file contains definitions to figure out the size of _HOST_ data types.*|
|* This file is important because different host OS's define different macros,*|
|* which makes portability tough. This file exports the following *|
|* definitions: *|
|* *|
|* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*|
|* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *|
|* *|
|* No library is required when using these functions. *|
|* *|
|*===----------------------------------------------------------------------===*/
/* Please leave this file C-compatible. */
#ifndef SUPPORT_DATATYPES_H
#define SUPPORT_DATATYPES_H
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UINT64_T 1
#define HAVE_U_INT64_T 1
#ifdef __cplusplus
#include <cmath>
#else
#include <math.h>
#endif
#ifdef __cplusplus
#include <cinttypes>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#ifdef __cplusplus
#include <cstdint>
#else
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#error "Compiler must provide an implementation of stdint.h"
#endif
#endif
#ifndef _MSC_VER
#if !defined(UINT32_MAX)
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
"__STDC_LIMIT_MACROS before #including Support/DataTypes.h"
#endif
#if !defined(UINT32_C)
# error "The standard header <cstdint> is not C++11 compliant. Must #define "\
"__STDC_CONSTANT_MACROS before #including Support/DataTypes.h"
#endif
/* Note that <inttypes.h> includes <stdint.h>, if this is a C99 system. */
#include <sys/types.h>
#ifdef _AIX
// GCC is strict about defining large constants: they must have LL modifier.
#undef INT64_MAX
#undef INT64_MIN
#endif
/* Handle incorrect definition of uint64_t as u_int64_t */
#ifndef HAVE_UINT64_T
#ifdef HAVE_U_INT64_T
typedef u_int64_t uint64_t;
#else
# error "Don't have a definition for uint64_t on this platform"
#endif
#endif
#else /* _MSC_VER */
#ifdef __cplusplus
#include <cstdlib>
#include <cstddef>
#else
#include <stdlib.h>
#include <stddef.h>
#endif
#include <sys/types.h>
#if defined(_WIN64)
typedef signed __int64 ssize_t;
#else
typedef signed int ssize_t;
#endif /* _WIN64 */
#ifndef HAVE_INTTYPES_H
#define PRId64 "I64d"
#define PRIi64 "I64i"
#define PRIo64 "I64o"
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#define PRIX64 "I64X"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#endif /* HAVE_INTTYPES_H */
#endif /* _MSC_VER */
/* Set defaults for constants which we cannot find. */
#if !defined(INT64_MAX)
# define INT64_MAX 9223372036854775807LL
#endif
#if !defined(INT64_MIN)
# define INT64_MIN ((-INT64_MAX)-1)
#endif
#if !defined(UINT64_MAX)
# define UINT64_MAX 0xffffffffffffffffULL
#endif
#ifndef HUGE_VALF
#define HUGE_VALF (float)HUGE_VAL
#endif
#endif /* SUPPORT_DATATYPES_H */
//===--- Demangle.h ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstddef>
namespace llvm {
/// This is a llvm local version of __cxa_demangle. Other than the name and
/// being in the llvm namespace it is identical.
///
/// The mangled_name is demangled into buf and returned. If the buffer is not
/// large enough, realloc is used to expand it.
///
/// The *status will be set to
/// unknown_error: -4
/// invalid_args: -3
/// invalid_mangled_name: -2
/// memory_alloc_failure: -1
/// success: 0
char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
int *status);
}
//===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a guard for a block of code that ensures a Mutex is locked
// upon construction and released upon destruction.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_UNIQUE_LOCK_H
#define LLVM_SUPPORT_UNIQUE_LOCK_H
#include "llvm/Support/Mutex.h"
namespace llvm {
/// A pared-down imitation of std::unique_lock from C++11. Contrary to the
/// name, it's really more of a wrapper for a lock. It may or may not have
/// an associated mutex, which is guaranteed to be locked upon creation
/// and unlocked after destruction. unique_lock can also unlock the mutex
/// and re-lock it freely during its lifetime.
/// @brief Guard a section of code with a mutex.
template<typename MutexT>
class unique_lock {
MutexT *M;
bool locked;
unique_lock(const unique_lock &) = delete;
void operator=(const unique_lock &) = delete;
public:
unique_lock() : M(nullptr), locked(false) {}
explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); }
void operator=(unique_lock &&o) {
if (owns_lock())
M->unlock();
M = o.M;
locked = o.locked;
o.M = nullptr;
o.locked = false;
}
~unique_lock() { if (owns_lock()) M->unlock(); }
void lock() {
assert(!locked && "mutex already locked!");
assert(M && "no associated mutex!");
M->lock();
locked = true;
}
void unlock() {
assert(locked && "unlocking a mutex that isn't locked!");
assert(M && "no associated mutex!");
M->unlock();
locked = false;
}
bool owns_lock() { return locked; }
};
}
#endif // LLVM_SUPPORT_UNIQUE_LOCK_H
This source diff could not be displayed because it is too large. You can view the blob instead.
//===- Errno.cpp - errno support --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the errno wrappers.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Errno.h"
#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/raw_ostream.h"
#include <string.h>
#if HAVE_ERRNO_H
#include <errno.h>
#endif
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//=== independent code.
//===----------------------------------------------------------------------===//
namespace llvm {
namespace sys {
#if HAVE_ERRNO_H
std::string StrError() {
return StrError(errno);
}
#endif // HAVE_ERRNO_H
std::string StrError(int errnum) {
std::string str;
if (errnum == 0)
return str;
#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
const int MaxErrStrLen = 2000;
char buffer[MaxErrStrLen];
buffer[0] = '\0';
#endif
#ifdef HAVE_STRERROR_R
// strerror_r is thread-safe.
#if defined(__GLIBC__) && defined(_GNU_SOURCE)
// glibc defines its own incompatible version of strerror_r
// which may not use the buffer supplied.
str = strerror_r(errnum, buffer, MaxErrStrLen - 1);
#else
strerror_r(errnum, buffer, MaxErrStrLen - 1);
str = buffer;
#endif
#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
strerror_s(buffer, MaxErrStrLen - 1, errnum);
str = buffer;
#elif defined(HAVE_STRERROR)
// Copy the thread un-safe result of strerror into
// the buffer as fast as possible to minimize impact
// of collision of strerror in multiple threads.
str = strerror(errnum);
#else
// Strange that this system doesn't even have strerror
// but, oh well, just use a generic message
raw_string_ostream stream(str);
stream << "Error #" << errnum;
stream.flush();
#endif
return str;
}
} // namespace sys
} // namespace llvm
//===- llvm/Support/Unix/COM.inc - Unix COM Implementation -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix portion of COM support.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
namespace llvm {
namespace sys {
InitializeCOMRAII::InitializeCOMRAII(COMThreadingMode Threading,
bool SpeedOverMemory) {}
InitializeCOMRAII::~InitializeCOMRAII() {}
}
}
//===- llvm/Support/Unix/Host.inc -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the UNIX Host support.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include <cctype>
#include <string>
#include <sys/utsname.h>
using namespace llvm;
static std::string getOSVersion() {
struct utsname info;
if (uname(&info))
return "";
return info.release;
}
std::string sys::getDefaultTargetTriple() {
std::string TargetTripleString(LLVM_DEFAULT_TARGET_TRIPLE);
// On darwin, we want to update the version to match that of the
// target.
std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
if (DarwinDashIdx != std::string::npos) {
TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
TargetTripleString += getOSVersion();
}
return Triple::normalize(TargetTripleString);
}
//===- Unix/Memory.cpp - Generic UNIX System Configuration ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some functions for various memory management utilities.
//
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Process.h"
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#ifdef __APPLE__
#include <mach/mach.h>
#endif
#if defined(__mips__)
# if defined(__OpenBSD__)
# include <mips64/sysarch.h>
# else
# include <sys/cachectl.h>
# endif
#endif
#ifdef __APPLE__
extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
#else
extern "C" void __clear_cache(void *, void*);
#endif
namespace {
int getPosixProtectionFlags(unsigned Flags) {
switch (Flags) {
case llvm::sys::Memory::MF_READ:
return PROT_READ;
case llvm::sys::Memory::MF_WRITE:
return PROT_WRITE;
case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
return PROT_READ | PROT_WRITE;
case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_EXEC;
case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE |
llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_WRITE | PROT_EXEC;
case llvm::sys::Memory::MF_EXEC:
#if defined(__FreeBSD__)
// On PowerPC, having an executable page that has no read permission
// can have unintended consequences. The function InvalidateInstruction-
// Cache uses instructions dcbf and icbi, both of which are treated by
// the processor as loads. If the page has no read permissions,
// executing these instructions will result in a segmentation fault.
// Somehow, this problem is not present on Linux, but it does happen
// on FreeBSD.
return PROT_READ | PROT_EXEC;
#else
return PROT_EXEC;
#endif
default:
llvm_unreachable("Illegal memory protection flag specified!");
}
// Provide a default return value as required by some compilers.
return PROT_NONE;
}
} // anonymous namespace
namespace llvm {
namespace sys {
MemoryBlock
Memory::allocateMappedMemory(size_t NumBytes,
const MemoryBlock *const NearBlock,
unsigned PFlags,
std::error_code &EC) {
EC = std::error_code();
if (NumBytes == 0)
return MemoryBlock();
static const size_t PageSize = Process::getPageSize();
const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
int MMFlags = MAP_PRIVATE |
#ifdef MAP_ANONYMOUS
MAP_ANONYMOUS
#else
MAP_ANON
#endif
; // Ends statement above
int Protect = getPosixProtectionFlags(PFlags);
// Use any near hint and the page size to set a page-aligned starting address
uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
NearBlock->size() : 0;
if (Start && Start % PageSize)
Start += PageSize - Start % PageSize;
void *Addr = ::mmap(reinterpret_cast<void*>(Start), PageSize*NumPages,
Protect, MMFlags, fd, 0);
if (Addr == MAP_FAILED) {
if (NearBlock) //Try again without a near hint
return allocateMappedMemory(NumBytes, nullptr, PFlags, EC);
EC = std::error_code(errno, std::generic_category());
return MemoryBlock();
}
MemoryBlock Result;
Result.Address = Addr;
Result.Size = NumPages*PageSize;
if (PFlags & MF_EXEC)
Memory::InvalidateInstructionCache(Result.Address, Result.Size);
return Result;
}
std::error_code
Memory::releaseMappedMemory(MemoryBlock &M) {
if (M.Address == nullptr || M.Size == 0)
return std::error_code();
if (0 != ::munmap(M.Address, M.Size))
return std::error_code(errno, std::generic_category());
M.Address = nullptr;
M.Size = 0;
return std::error_code();
}
std::error_code
Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
static const size_t PageSize = Process::getPageSize();
if (M.Address == nullptr || M.Size == 0)
return std::error_code();
if (!Flags)
return std::error_code(EINVAL, std::generic_category());
int Protect = getPosixProtectionFlags(Flags);
uintptr_t Start = alignAddr((uint8_t *)M.Address - PageSize + 1, PageSize);
uintptr_t End = alignAddr((uint8_t *)M.Address + M.Size, PageSize);
int Result = ::mprotect((void *)Start, End - Start, Protect);
if (Result != 0)
return std::error_code(errno, std::generic_category());
if (Flags & MF_EXEC)
Memory::InvalidateInstructionCache(M.Address, M.Size);
return std::error_code();
}
/// AllocateRWX - Allocate a slab of memory with read/write/execute
/// permissions. This is typically used for JIT applications where we want
/// to emit code to the memory then jump to it. Getting this type of memory
/// is very OS specific.
///
MemoryBlock
Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
static const size_t PageSize = Process::getPageSize();
size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
int flags = MAP_PRIVATE |
#ifdef MAP_ANONYMOUS
MAP_ANONYMOUS
#else
MAP_ANON
#endif
;
void* start = NearBlock ? (unsigned char*)NearBlock->base() +
NearBlock->size() : nullptr;
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC,
flags, fd, 0);
#else
void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
flags, fd, 0);
#endif
if (pa == MAP_FAILED) {
if (NearBlock) //Try again without a near hint
return AllocateRWX(NumBytes, nullptr);
MakeErrMsg(ErrMsg, "Can't allocate RWX Memory");
return MemoryBlock();
}
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
(vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect max RX failed");
return MemoryBlock();
}
kr = vm_protect(mach_task_self(), (vm_address_t)pa,
(vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_WRITE);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect RW failed");
return MemoryBlock();
}
#endif
MemoryBlock result;
result.Address = pa;
result.Size = NumPages*PageSize;
return result;
}
bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
if (M.Address == nullptr || M.Size == 0) return false;
if (0 != ::munmap(M.Address, M.Size))
return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
return false;
}
bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
if (M.Address == 0 || M.Size == 0) return false;
Memory::InvalidateInstructionCache(M.Address, M.Size);
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
return KERN_SUCCESS == kr;
#else
return true;
#endif
}
bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
if (M.Address == nullptr || M.Size == 0) return false;
Memory::InvalidateInstructionCache(M.Address, M.Size);
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
return KERN_SUCCESS == kr;
#else
return true;
#endif
}
bool Memory::setRangeWritable(const void *Addr, size_t Size) {
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
(vm_size_t)Size, 0,
VM_PROT_READ | VM_PROT_WRITE);
return KERN_SUCCESS == kr;
#else
return true;
#endif
}
bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__))
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
(vm_size_t)Size, 0,
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
return KERN_SUCCESS == kr;
#else
return true;
#endif
}
/// InvalidateInstructionCache - Before the JIT can run a block of code
/// that has been emitted it must invalidate the instruction cache on some
/// platforms.
void Memory::InvalidateInstructionCache(const void *Addr,
size_t Len) {
// icache invalidation for PPC and ARM.
#if defined(__APPLE__)
# if (defined(__POWERPC__) || defined (__ppc__) || \
defined(_POWER) || defined(_ARCH_PPC) || defined(__arm__) || \
defined(__arm64__))
sys_icache_invalidate(const_cast<void *>(Addr), Len);
# endif
#else
# if (defined(__POWERPC__) || defined (__ppc__) || \
defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
const size_t LineSize = 32;
const intptr_t Mask = ~(LineSize - 1);
const intptr_t StartLine = ((intptr_t) Addr) & Mask;
const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("dcbf 0, %0" : : "r"(Line));
asm volatile("sync");
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("icbi 0, %0" : : "r"(Line));
asm volatile("isync");
# elif (defined(__arm__) || defined(__aarch64__) || defined(__mips__)) && \
defined(__GNUC__)
// FIXME: Can we safely always call this for __GNUC__ everywhere?
const char *Start = static_cast<const char *>(Addr);
const char *End = Start + Len;
__clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
# endif
#endif // end apple
ValgrindDiscardTranslations(Addr, Len);
}
} // namespace sys
} // namespace llvm
//===- llvm/Support/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific (non-pthread) Mutex class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
namespace llvm
{
using namespace sys;
MutexImpl::MutexImpl( bool recursive)
{
}
MutexImpl::~MutexImpl()
{
}
bool
MutexImpl::release()
{
return true;
}
bool
MutexImpl::tryacquire( void )
{
return true;
}
}
//===- llvm/Support/Unix/Path.inc - Unix Path Implementation ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific implementation of the Path API.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include <limits.h>
#include <stdio.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <sys/attr.h>
#endif
// Both stdio.h and cstdio are included via different paths and
// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros
// either.
#undef ferror
#undef feof
// For GNU Hurd
#if defined(__GNU__) && !defined(PATH_MAX)
# define PATH_MAX 4096
#endif
#include <sys/types.h>
#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__ANDROID__)
#include <sys/statvfs.h>
#define STATVFS statvfs
#define STATVFS_F_FRSIZE(vfs) vfs.f_frsize
#else
#ifdef __OpenBSD__
#include <sys/param.h>
#include <sys/mount.h>
#elif defined(__ANDROID__)
#include <sys/vfs.h>
#else
#include <sys/mount.h>
#endif
#define STATVFS statfs
#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize)
#endif
using namespace llvm;
namespace llvm {
namespace sys {
namespace fs {
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__) || \
defined(_AIX)
static int
test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
{
struct stat sb;
char fullpath[PATH_MAX];
snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin);
if (!realpath(fullpath, ret))
return 1;
if (stat(fullpath, &sb) != 0)
return 1;
return 0;
}
static char *
getprogpath(char ret[PATH_MAX], const char *bin)
{
char *pv, *s, *t;
/* First approach: absolute path. */
if (bin[0] == '/') {
if (test_dir(ret, "/", bin) == 0)
return ret;
return nullptr;
}
/* Second approach: relative path. */
if (strchr(bin, '/')) {
char cwd[PATH_MAX];
if (!getcwd(cwd, PATH_MAX))
return nullptr;
if (test_dir(ret, cwd, bin) == 0)
return ret;
return nullptr;
}
/* Third approach: $PATH */
if ((pv = getenv("PATH")) == nullptr)
return nullptr;
s = pv = strdup(pv);
if (!pv)
return nullptr;
while ((t = strsep(&s, ":")) != nullptr) {
if (test_dir(ret, t, bin) == 0) {
free(pv);
return ret;
}
}
free(pv);
return nullptr;
}
#endif // __FreeBSD__ || __NetBSD__ || __FreeBSD_kernel__
/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
std::string getMainExecutable(const char *argv0, void *MainAddr) {
#if defined(__APPLE__)
// On OS X the executable path is saved to the stack by dyld. Reading it
// from there is much faster than calling dladdr, especially for large
// binaries with symbols.
char exe_path[MAXPATHLEN];
uint32_t size = sizeof(exe_path);
if (_NSGetExecutablePath(exe_path, &size) == 0) {
char link_path[MAXPATHLEN];
if (realpath(exe_path, link_path))
return link_path;
}
#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
defined(__FreeBSD_kernel__) || defined(_AIX)
char exe_path[PATH_MAX];
if (getprogpath(exe_path, argv0) != NULL)
return exe_path;
#elif defined(__linux__) || defined(__CYGWIN__)
char exe_path[MAXPATHLEN];
StringRef aPath("/proc/self/exe");
if (sys::fs::exists(aPath)) {
// /proc is not always mounted under Linux (chroot for example).
ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
if (len >= 0)
return std::string(exe_path, len);
} else {
// Fall back to the classical detection.
if (getprogpath(exe_path, argv0))
return exe_path;
}
#elif defined(HAVE_DLFCN_H)
// Use dladdr to get executable path if available.
Dl_info DLInfo;
int err = dladdr(MainAddr, &DLInfo);
if (err == 0)
return "";
// If the filename is a symlink, we need to resolve and return the location of
// the actual executable.
char link_path[MAXPATHLEN];
if (realpath(DLInfo.dli_fname, link_path))
return link_path;
#else
#error GetMainExecutable is not implemented on this host yet.
#endif
return "";
}
TimePoint<> file_status::getLastAccessedTime() const {
return toTimePoint(fs_st_atime);
}
TimePoint<> file_status::getLastModificationTime() const {
return toTimePoint(fs_st_mtime);
}
UniqueID file_status::getUniqueID() const {
return UniqueID(fs_st_dev, fs_st_ino);
}
ErrorOr<space_info> disk_space(const Twine &Path) {
struct STATVFS Vfs;
if (::STATVFS(Path.str().c_str(), &Vfs))
return std::error_code(errno, std::generic_category());
auto FrSize = STATVFS_F_FRSIZE(Vfs);
space_info SpaceInfo;
SpaceInfo.capacity = static_cast<uint64_t>(Vfs.f_blocks) * FrSize;
SpaceInfo.free = static_cast<uint64_t>(Vfs.f_bfree) * FrSize;
SpaceInfo.available = static_cast<uint64_t>(Vfs.f_bavail) * FrSize;
return SpaceInfo;
}
std::error_code current_path(SmallVectorImpl<char> &result) {
result.clear();
const char *pwd = ::getenv("PWD");
llvm::sys::fs::file_status PWDStatus, DotStatus;
if (pwd && llvm::sys::path::is_absolute(pwd) &&
!llvm::sys::fs::status(pwd, PWDStatus) &&
!llvm::sys::fs::status(".", DotStatus) &&
PWDStatus.getUniqueID() == DotStatus.getUniqueID()) {
result.append(pwd, pwd + strlen(pwd));
return std::error_code();
}
#ifdef MAXPATHLEN
result.reserve(MAXPATHLEN);
#else
// For GNU Hurd
result.reserve(1024);
#endif
while (true) {
if (::getcwd(result.data(), result.capacity()) == nullptr) {
// See if there was a real error.
if (errno != ENOMEM)
return std::error_code(errno, std::generic_category());
// Otherwise there just wasn't enough space.
result.reserve(result.capacity() * 2);
} else
break;
}
result.set_size(strlen(result.data()));
return std::error_code();
}
std::error_code create_directory(const Twine &path, bool IgnoreExisting,
perms Perms) {
SmallString<128> path_storage;
StringRef p = path.toNullTerminatedStringRef(path_storage);
if (::mkdir(p.begin(), Perms) == -1) {
if (errno != EEXIST || !IgnoreExisting)
return std::error_code(errno, std::generic_category());
}
return std::error_code();
}
// Note that we are using symbolic link because hard links are not supported by
// all filesystems (SMB doesn't).
std::error_code create_link(const Twine &to, const Twine &from) {
// Get arguments.
SmallString<128> from_storage;
SmallString<128> to_storage;
StringRef f = from.toNullTerminatedStringRef(from_storage);
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::symlink(t.begin(), f.begin()) == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
std::error_code create_hard_link(const Twine &to, const Twine &from) {
// Get arguments.
SmallString<128> from_storage;
SmallString<128> to_storage;
StringRef f = from.toNullTerminatedStringRef(from_storage);
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::link(t.begin(), f.begin()) == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
SmallString<128> path_storage;
StringRef p = path.toNullTerminatedStringRef(path_storage);
struct stat buf;
if (lstat(p.begin(), &buf) != 0) {
if (errno != ENOENT || !IgnoreNonExisting)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
// Note: this check catches strange situations. In all cases, LLVM should
// only be involved in the creation and deletion of regular files. This
// check ensures that what we're trying to erase is a regular file. It
// effectively prevents LLVM from erasing things like /dev/null, any block
// special file, or other things that aren't "regular" files.
if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode))
return make_error_code(errc::operation_not_permitted);
if (::remove(p.begin()) == -1) {
if (errno != ENOENT || !IgnoreNonExisting)
return std::error_code(errno, std::generic_category());
}
return std::error_code();
}
std::error_code rename(const Twine &from, const Twine &to) {
// Get arguments.
SmallString<128> from_storage;
SmallString<128> to_storage;
StringRef f = from.toNullTerminatedStringRef(from_storage);
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::rename(f.begin(), t.begin()) == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
std::error_code resize_file(int FD, uint64_t Size) {
#if defined(HAVE_POSIX_FALLOCATE)
// If we have posix_fallocate use it. Unlike ftruncate it always allocates
// space, so we get an error if the disk is full.
if (int Err = ::posix_fallocate(FD, 0, Size))
return std::error_code(Err, std::generic_category());
#else
// Use ftruncate as a fallback. It may or may not allocate space. At least on
// OS X with HFS+ it does.
if (::ftruncate(FD, Size) == -1)
return std::error_code(errno, std::generic_category());
#endif
return std::error_code();
}
static int convertAccessMode(AccessMode Mode) {
switch (Mode) {
case AccessMode::Exist:
return F_OK;
case AccessMode::Write:
return W_OK;
case AccessMode::Execute:
return R_OK | X_OK; // scripts also need R_OK.
}
llvm_unreachable("invalid enum");
}
std::error_code access(const Twine &Path, AccessMode Mode) {
SmallString<128> PathStorage;
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
if (::access(P.begin(), convertAccessMode(Mode)) == -1)
return std::error_code(errno, std::generic_category());
if (Mode == AccessMode::Execute) {
// Don't say that directories are executable.
struct stat buf;
if (0 != stat(P.begin(), &buf))
return errc::permission_denied;
if (!S_ISREG(buf.st_mode))
return errc::permission_denied;
}
return std::error_code();
}
bool can_execute(const Twine &Path) {
return !access(Path, AccessMode::Execute);
}
bool equivalent(file_status A, file_status B) {
assert(status_known(A) && status_known(B));
return A.fs_st_dev == B.fs_st_dev &&
A.fs_st_ino == B.fs_st_ino;
}
std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
file_status fsA, fsB;
if (std::error_code ec = status(A, fsA))
return ec;
if (std::error_code ec = status(B, fsB))
return ec;
result = equivalent(fsA, fsB);
return std::error_code();
}
static std::error_code fillStatus(int StatRet, const struct stat &Status,
file_status &Result) {
if (StatRet != 0) {
std::error_code ec(errno, std::generic_category());
if (ec == errc::no_such_file_or_directory)
Result = file_status(file_type::file_not_found);
else
Result = file_status(file_type::status_error);
return ec;
}
file_type Type = file_type::type_unknown;
if (S_ISDIR(Status.st_mode))
Type = file_type::directory_file;
else if (S_ISREG(Status.st_mode))
Type = file_type::regular_file;
else if (S_ISBLK(Status.st_mode))
Type = file_type::block_file;
else if (S_ISCHR(Status.st_mode))
Type = file_type::character_file;
else if (S_ISFIFO(Status.st_mode))
Type = file_type::fifo_file;
else if (S_ISSOCK(Status.st_mode))
Type = file_type::socket_file;
perms Perms = static_cast<perms>(Status.st_mode);
Result =
file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_atime,
Status.st_mtime, Status.st_uid, Status.st_gid,
Status.st_size);
return std::error_code();
}
std::error_code status(const Twine &Path, file_status &Result) {
SmallString<128> PathStorage;
StringRef P = Path.toNullTerminatedStringRef(PathStorage);
struct stat Status;
int StatRet = ::stat(P.begin(), &Status);
return fillStatus(StatRet, Status, Result);
}
std::error_code status(int FD, file_status &Result) {
struct stat Status;
int StatRet = ::fstat(FD, &Status);
return fillStatus(StatRet, Status, Result);
}
std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
#if defined(HAVE_FUTIMENS)
timespec Times[2];
Times[0] = Times[1] = sys::toTimeSpec(Time);
if (::futimens(FD, Times))
return std::error_code(errno, std::generic_category());
return std::error_code();
#elif defined(HAVE_FUTIMES)
timeval Times[2];
Times[0] = Times[1] = sys::toTimeVal(
std::chrono::time_point_cast<std::chrono::microseconds>(Time));
if (::futimes(FD, Times))
return std::error_code(errno, std::generic_category());
return std::error_code();
#else
#warning Missing futimes() and futimens()
return make_error_code(errc::function_not_supported);
#endif
}
std::error_code mapped_file_region::init(int FD, uint64_t Offset,
mapmode Mode) {
assert(Size != 0);
int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset);
if (Mapping == MAP_FAILED)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
uint64_t offset, std::error_code &ec)
: Size(length), Mapping() {
// Make sure that the requested size fits within SIZE_T.
if (length > std::numeric_limits<size_t>::max()) {
ec = make_error_code(errc::invalid_argument);
return;
}
ec = init(fd, offset, mode);
if (ec)
Mapping = nullptr;
}
mapped_file_region::~mapped_file_region() {
if (Mapping)
::munmap(Mapping, Size);
}
uint64_t mapped_file_region::size() const {
assert(Mapping && "Mapping failed but used anyway!");
return Size;
}
char *mapped_file_region::data() const {
assert(Mapping && "Mapping failed but used anyway!");
return reinterpret_cast<char*>(Mapping);
}
const char *mapped_file_region::const_data() const {
assert(Mapping && "Mapping failed but used anyway!");
return reinterpret_cast<const char*>(Mapping);
}
int mapped_file_region::alignment() {
return Process::getPageSize();
}
std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
StringRef path){
SmallString<128> path_null(path);
DIR *directory = ::opendir(path_null.c_str());
if (!directory)
return std::error_code(errno, std::generic_category());
it.IterationHandle = reinterpret_cast<intptr_t>(directory);
// Add something for replace_filename to replace.
path::append(path_null, ".");
it.CurrentEntry = directory_entry(path_null.str());
return directory_iterator_increment(it);
}
std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
if (it.IterationHandle)
::closedir(reinterpret_cast<DIR *>(it.IterationHandle));
it.IterationHandle = 0;
it.CurrentEntry = directory_entry();
return std::error_code();
}
std::error_code detail::directory_iterator_increment(detail::DirIterState &it) {
errno = 0;
dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle));
if (cur_dir == nullptr && errno != 0) {
return std::error_code(errno, std::generic_category());
} else if (cur_dir != nullptr) {
StringRef name(cur_dir->d_name, NAMLEN(cur_dir));
if ((name.size() == 1 && name[0] == '.') ||
(name.size() == 2 && name[0] == '.' && name[1] == '.'))
return directory_iterator_increment(it);
it.CurrentEntry.replace_filename(name);
} else
return directory_iterator_destruct(it);
return std::error_code();
}
#if !defined(F_GETPATH)
static bool hasProcSelfFD() {
// If we have a /proc filesystem mounted, we can quickly establish the
// real name of the file with readlink
static const bool Result = (::access("/proc/self/fd", R_OK) == 0);
return Result;
}
#endif
std::error_code openFileForRead(const Twine &Name, int &ResultFD,
SmallVectorImpl<char> *RealPath) {
SmallString<128> Storage;
StringRef P = Name.toNullTerminatedStringRef(Storage);
while ((ResultFD = open(P.begin(), O_RDONLY)) < 0) {
if (errno != EINTR)
return std::error_code(errno, std::generic_category());
}
// Attempt to get the real name of the file, if the user asked
if(!RealPath)
return std::error_code();
RealPath->clear();
#if defined(F_GETPATH)
// When F_GETPATH is availble, it is the quickest way to get
// the real path name.
char Buffer[MAXPATHLEN];
if (::fcntl(ResultFD, F_GETPATH, Buffer) != -1)
RealPath->append(Buffer, Buffer + strlen(Buffer));
#else
char Buffer[PATH_MAX];
if (hasProcSelfFD()) {
char ProcPath[64];
snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", ResultFD);
ssize_t CharCount = ::readlink(ProcPath, Buffer, sizeof(Buffer));
if (CharCount > 0)
RealPath->append(Buffer, Buffer + CharCount);
} else {
// Use ::realpath to get the real path name
if (::realpath(P.begin(), Buffer) != nullptr)
RealPath->append(Buffer, Buffer + strlen(Buffer));
}
#endif
return std::error_code();
}
std::error_code openFileForWrite(const Twine &Name, int &ResultFD,
sys::fs::OpenFlags Flags, unsigned Mode) {
// Verify that we don't have both "append" and "excl".
assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) &&
"Cannot specify both 'excl' and 'append' file creation flags!");
int OpenFlags = O_CREAT;
if (Flags & F_RW)
OpenFlags |= O_RDWR;
else
OpenFlags |= O_WRONLY;
if (Flags & F_Append)
OpenFlags |= O_APPEND;
else
OpenFlags |= O_TRUNC;
if (Flags & F_Excl)
OpenFlags |= O_EXCL;
SmallString<128> Storage;
StringRef P = Name.toNullTerminatedStringRef(Storage);
while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) {
if (errno != EINTR)
return std::error_code(errno, std::generic_category());
}
return std::error_code();
}
std::error_code getPathFromOpenFD(int FD, SmallVectorImpl<char> &ResultPath) {
if (FD < 0)
return make_error_code(errc::bad_file_descriptor);
#if defined(F_GETPATH)
// When F_GETPATH is availble, it is the quickest way to get
// the path from a file descriptor.
ResultPath.reserve(MAXPATHLEN);
if (::fcntl(FD, F_GETPATH, ResultPath.begin()) == -1)
return std::error_code(errno, std::generic_category());
ResultPath.set_size(strlen(ResultPath.begin()));
#else
// If we have a /proc filesystem mounted, we can quickly establish the
// real name of the file with readlink. Otherwise, we don't know how to
// get the filename from a file descriptor. Give up.
if (!fs::hasProcSelfFD())
return make_error_code(errc::function_not_supported);
ResultPath.reserve(PATH_MAX);
char ProcPath[64];
snprintf(ProcPath, sizeof(ProcPath), "/proc/self/fd/%d", FD);
ssize_t CharCount = ::readlink(ProcPath, ResultPath.begin(), ResultPath.capacity());
if (CharCount < 0)
return std::error_code(errno, std::generic_category());
// Was the filename truncated?
if (static_cast<size_t>(CharCount) == ResultPath.capacity()) {
// Use lstat to get the size of the filename
struct stat sb;
if (::lstat(ProcPath, &sb) < 0)
return std::error_code(errno, std::generic_category());
ResultPath.reserve(sb.st_size + 1);
CharCount = ::readlink(ProcPath, ResultPath.begin(), ResultPath.capacity());
if (CharCount < 0)
return std::error_code(errno, std::generic_category());
// Test for race condition: did the link size change?
if (CharCount > sb.st_size)
return std::error_code(ENAMETOOLONG, std::generic_category());
}
ResultPath.set_size(static_cast<size_t>(CharCount));
#endif
return std::error_code();
}
} // end namespace fs
namespace path {
bool home_directory(SmallVectorImpl<char> &result) {
if (char *RequestedDir = getenv("HOME")) {
result.clear();
result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
return true;
}
return false;
}
static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
// On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
// macros defined in <unistd.h> on darwin >= 9
int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR
: _CS_DARWIN_USER_CACHE_DIR;
size_t ConfLen = confstr(ConfName, nullptr, 0);
if (ConfLen > 0) {
do {
Result.resize(ConfLen);
ConfLen = confstr(ConfName, Result.data(), Result.size());
} while (ConfLen > 0 && ConfLen != Result.size());
if (ConfLen > 0) {
assert(Result.back() == 0);
Result.pop_back();
return true;
}
Result.clear();
}
#endif
return false;
}
static bool getUserCacheDir(SmallVectorImpl<char> &Result) {
// First try using XDG_CACHE_HOME env variable,
// as specified in XDG Base Directory Specification at
// http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
if (const char *XdgCacheDir = std::getenv("XDG_CACHE_HOME")) {
Result.clear();
Result.append(XdgCacheDir, XdgCacheDir + strlen(XdgCacheDir));
return true;
}
// Try Darwin configuration query
if (getDarwinConfDir(false, Result))
return true;
// Use "$HOME/.cache" if $HOME is available
if (home_directory(Result)) {
append(Result, ".cache");
return true;
}
return false;
}
static const char *getEnvTempDir() {
// Check whether the temporary directory is specified by an environment
// variable.
const char *EnvironmentVariables[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
for (const char *Env : EnvironmentVariables) {
if (const char *Dir = std::getenv(Env))
return Dir;
}
return nullptr;
}
static const char *getDefaultTempDir(bool ErasedOnReboot) {
#ifdef P_tmpdir
if ((bool)P_tmpdir)
return P_tmpdir;
#endif
if (ErasedOnReboot)
return "/tmp";
return "/var/tmp";
}
void system_temp_directory(bool ErasedOnReboot, SmallVectorImpl<char> &Result) {
Result.clear();
if (ErasedOnReboot) {
// There is no env variable for the cache directory.
if (const char *RequestedDir = getEnvTempDir()) {
Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
return;
}
}
if (getDarwinConfDir(ErasedOnReboot, Result))
return;
const char *RequestedDir = getDefaultTempDir(ErasedOnReboot);
Result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
}
} // end namespace path
} // end namespace sys
} // end namespace llvm
//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides the generic Unix implementation of the Process class.
//
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
// DragonFlyBSD, OpenBSD, and Bitrig have deprecated <malloc.h> for
// <stdlib.h> instead. Unix.h includes this for us already.
#if defined(HAVE_MALLOC_H) && !defined(__DragonFly__) && \
!defined(__OpenBSD__) && !defined(__Bitrig__)
#include <malloc.h>
#endif
#if defined(HAVE_MALLCTL)
#include <malloc_np.h>
#endif
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_TERMIOS_H
# include <termios.h>
#endif
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
using namespace llvm;
using namespace sys;
static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsageTimes() {
#if defined(HAVE_GETRUSAGE)
struct rusage RU;
::getrusage(RUSAGE_SELF, &RU);
return { toDuration(RU.ru_utime), toDuration(RU.ru_stime) };
#else
#warning Cannot get usage times on this platform
return { std::chrono::microseconds::zero(), std::chrono::microseconds::zero() };
#endif
}
// On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
// offset in mmap(3) should be aligned to the AllocationGranularity.
unsigned Process::getPageSize() {
#if defined(HAVE_GETPAGESIZE)
static const int page_size = ::getpagesize();
#elif defined(HAVE_SYSCONF)
static long page_size = ::sysconf(_SC_PAGE_SIZE);
#else
#warning Cannot get the page size on this machine
#endif
return static_cast<unsigned>(page_size);
}
size_t Process::GetMallocUsage() {
#if defined(HAVE_MALLINFO)
struct mallinfo mi;
mi = ::mallinfo();
return mi.uordblks;
#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
malloc_statistics_t Stats;
malloc_zone_statistics(malloc_default_zone(), &Stats);
return Stats.size_in_use; // darwin
#elif defined(HAVE_MALLCTL)
size_t alloc, sz;
sz = sizeof(size_t);
if (mallctl("stats.allocated", &alloc, &sz, NULL, 0) == 0)
return alloc;
return 0;
#elif defined(HAVE_SBRK)
// Note this is only an approximation and more closely resembles
// the value returned by mallinfo in the arena field.
static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
char *EndOfMemory = (char*)sbrk(0);
if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
return EndOfMemory - StartOfMemory;
return 0;
#else
#warning Cannot get malloc info on this platform
return 0;
#endif
}
void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
std::chrono::nanoseconds &sys_time) {
elapsed = std::chrono::system_clock::now();
std::tie(user_time, sys_time) = getRUsageTimes();
}
#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
#include <mach/mach.h>
#endif
// Some LLVM programs such as bugpoint produce core files as a normal part of
// their operation. To prevent the disk from filling up, this function
// does what's necessary to prevent their generation.
void Process::PreventCoreFiles() {
#if HAVE_SETRLIMIT
struct rlimit rlim;
rlim.rlim_cur = rlim.rlim_max = 0;
setrlimit(RLIMIT_CORE, &rlim);
#endif
#if defined(HAVE_MACH_MACH_H) && !defined(__GNU__)
// Disable crash reporting on Mac OS X 10.0-10.4
// get information about the original set of exception ports for the task
mach_msg_type_number_t Count = 0;
exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
exception_port_t OriginalPorts[EXC_TYPES_COUNT];
exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
kern_return_t err =
task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
&Count, OriginalPorts, OriginalBehaviors,
OriginalFlavors);
if (err == KERN_SUCCESS) {
// replace each with MACH_PORT_NULL.
for (unsigned i = 0; i != Count; ++i)
task_set_exception_ports(mach_task_self(), OriginalMasks[i],
MACH_PORT_NULL, OriginalBehaviors[i],
OriginalFlavors[i]);
}
// Disable crash reporting on Mac OS X 10.5
signal(SIGABRT, _exit);
signal(SIGILL, _exit);
signal(SIGFPE, _exit);
signal(SIGSEGV, _exit);
signal(SIGBUS, _exit);
#endif
coreFilesPrevented = true;
}
Optional<std::string> Process::GetEnv(StringRef Name) {
std::string NameStr = Name.str();
const char *Val = ::getenv(NameStr.c_str());
if (!Val)
return None;
return std::string(Val);
}
std::error_code
Process::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut,
ArrayRef<const char *> ArgsIn,
SpecificBumpPtrAllocator<char> &) {
ArgsOut.append(ArgsIn.begin(), ArgsIn.end());
return std::error_code();
}
namespace {
class FDCloser {
public:
FDCloser(int &FD) : FD(FD), KeepOpen(false) {}
void keepOpen() { KeepOpen = true; }
~FDCloser() {
if (!KeepOpen && FD >= 0)
::close(FD);
}
private:
FDCloser(const FDCloser &) = delete;
void operator=(const FDCloser &) = delete;
int &FD;
bool KeepOpen;
};
}
std::error_code Process::FixupStandardFileDescriptors() {
int NullFD = -1;
FDCloser FDC(NullFD);
const int StandardFDs[] = {STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO};
for (int StandardFD : StandardFDs) {
struct stat st;
errno = 0;
while (fstat(StandardFD, &st) < 0) {
assert(errno && "expected errno to be set if fstat failed!");
// fstat should return EBADF if the file descriptor is closed.
if (errno == EBADF)
break;
// retry fstat if we got EINTR, otherwise bubble up the failure.
if (errno != EINTR)
return std::error_code(errno, std::generic_category());
}
// if fstat succeeds, move on to the next FD.
if (!errno)
continue;
assert(errno == EBADF && "expected errno to have EBADF at this point!");
if (NullFD < 0) {
while ((NullFD = open("/dev/null", O_RDWR)) < 0) {
if (errno == EINTR)
continue;
return std::error_code(errno, std::generic_category());
}
}
if (NullFD == StandardFD)
FDC.keepOpen();
else if (dup2(NullFD, StandardFD) < 0)
return std::error_code(errno, std::generic_category());
}
return std::error_code();
}
std::error_code Process::SafelyCloseFileDescriptor(int FD) {
// Create a signal set filled with *all* signals.
sigset_t FullSet;
if (sigfillset(&FullSet) < 0)
return std::error_code(errno, std::generic_category());
// Atomically swap our current signal mask with a full mask.
sigset_t SavedSet;
#if LLVM_ENABLE_THREADS
if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet))
return std::error_code(EC, std::generic_category());
#else
if (sigprocmask(SIG_SETMASK, &FullSet, &SavedSet) < 0)
return std::error_code(errno, std::generic_category());
#endif
// Attempt to close the file descriptor.
// We need to save the error, if one occurs, because our subsequent call to
// pthread_sigmask might tamper with errno.
int ErrnoFromClose = 0;
if (::close(FD) < 0)
ErrnoFromClose = errno;
// Restore the signal mask back to what we saved earlier.
int EC = 0;
#if LLVM_ENABLE_THREADS
EC = pthread_sigmask(SIG_SETMASK, &SavedSet, nullptr);
#else
if (sigprocmask(SIG_SETMASK, &SavedSet, nullptr) < 0)
EC = errno;
#endif
// The error code from close takes precedence over the one from
// pthread_sigmask.
if (ErrnoFromClose)
return std::error_code(ErrnoFromClose, std::generic_category());
return std::error_code(EC, std::generic_category());
}
bool Process::StandardInIsUserInput() {
return FileDescriptorIsDisplayed(STDIN_FILENO);
}
bool Process::StandardOutIsDisplayed() {
return FileDescriptorIsDisplayed(STDOUT_FILENO);
}
bool Process::StandardErrIsDisplayed() {
return FileDescriptorIsDisplayed(STDERR_FILENO);
}
bool Process::FileDescriptorIsDisplayed(int fd) {
#if HAVE_ISATTY
return isatty(fd);
#else
// If we don't have isatty, just return false.
return false;
#endif
}
static unsigned getColumns(int FileID) {
// If COLUMNS is defined in the environment, wrap to that many columns.
if (const char *ColumnsStr = std::getenv("COLUMNS")) {
int Columns = std::atoi(ColumnsStr);
if (Columns > 0)
return Columns;
}
unsigned Columns = 0;
#if defined(HAVE_SYS_IOCTL_H) && defined(HAVE_TERMIOS_H)
// Try to determine the width of the terminal.
struct winsize ws;
if (ioctl(FileID, TIOCGWINSZ, &ws) == 0)
Columns = ws.ws_col;
#endif
return Columns;
}
unsigned Process::StandardOutColumns() {
if (!StandardOutIsDisplayed())
return 0;
return getColumns(1);
}
unsigned Process::StandardErrColumns() {
if (!StandardErrIsDisplayed())
return 0;
return getColumns(2);
}
#ifdef HAVE_TERMINFO
// We manually declare these extern functions because finding the correct
// headers from various terminfo, curses, or other sources is harder than
// writing their specs down.
extern "C" int setupterm(char *term, int filedes, int *errret);
extern "C" struct term *set_curterm(struct term *termp);
extern "C" int del_curterm(struct term *termp);
extern "C" int tigetnum(char *capname);
#endif
#ifdef HAVE_TERMINFO
static ManagedStatic<sys::Mutex> TermColorMutex;
#endif
static bool terminalHasColors(int fd) {
#ifdef HAVE_TERMINFO
// First, acquire a global lock because these C routines are thread hostile.
MutexGuard G(*TermColorMutex);
int errret = 0;
if (setupterm((char *)nullptr, fd, &errret) != 0)
// Regardless of why, if we can't get terminfo, we shouldn't try to print
// colors.
return false;
// Test whether the terminal as set up supports color output. How to do this
// isn't entirely obvious. We can use the curses routine 'has_colors' but it
// would be nice to avoid a dependency on curses proper when we can make do
// with a minimal terminfo parsing library. Also, we don't really care whether
// the terminal supports the curses-specific color changing routines, merely
// if it will interpret ANSI color escape codes in a reasonable way. Thus, the
// strategy here is just to query the baseline colors capability and if it
// supports colors at all to assume it will translate the escape codes into
// whatever range of colors it does support. We can add more detailed tests
// here if users report them as necessary.
//
// The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
// the terminfo says that no colors are supported.
bool HasColors = tigetnum(const_cast<char *>("colors")) > 0;
// Now extract the structure allocated by setupterm and free its memory
// through a really silly dance.
struct term *termp = set_curterm((struct term *)nullptr);
(void)del_curterm(termp); // Drop any errors here.
// Return true if we found a color capabilities for the current terminal.
if (HasColors)
return true;
#endif
// Otherwise, be conservative.
return false;
}
bool Process::FileDescriptorHasColors(int fd) {
// A file descriptor has colors if it is displayed and the terminal has
// colors.
return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
}
bool Process::StandardOutHasColors() {
return FileDescriptorHasColors(STDOUT_FILENO);
}
bool Process::StandardErrHasColors() {
return FileDescriptorHasColors(STDERR_FILENO);
}
void Process::UseANSIEscapeCodes(bool /*enable*/) {
// No effect.
}
bool Process::ColorNeedsFlush() {
// No, we use ANSI escape sequences.
return false;
}
const char *Process::OutputColor(char code, bool bold, bool bg) {
return colorcodes[bg?1:0][bold?1:0][code&7];
}
const char *Process::OutputBold(bool bg) {
return "\033[1m";
}
const char *Process::OutputReverse() {
return "\033[7m";
}
const char *Process::ResetColor() {
return "\033[0m";
}
#if !HAVE_DECL_ARC4RANDOM
static unsigned GetRandomNumberSeed() {
// Attempt to get the initial seed from /dev/urandom, if possible.
int urandomFD = open("/dev/urandom", O_RDONLY);
if (urandomFD != -1) {
unsigned seed;
// Don't use a buffered read to avoid reading more data
// from /dev/urandom than we need.
int count = read(urandomFD, (void *)&seed, sizeof(seed));
close(urandomFD);
// Return the seed if the read was successful.
if (count == sizeof(seed))
return seed;
}
// Otherwise, swizzle the current time and the process ID to form a reasonable
// seed.
const auto Now = std::chrono::high_resolution_clock::now();
return hash_combine(Now.time_since_epoch().count(), ::getpid());
}
#endif
unsigned llvm::sys::Process::GetRandomNumber() {
#if HAVE_DECL_ARC4RANDOM
return arc4random();
#else
static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0);
(void)x;
return ::rand();
#endif
}
//===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific portion of the Program class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_POSIX_SPAWN
#ifdef __sun__
#define _RESTRICT_KYWD
#endif
#include <spawn.h>
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
#if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
#define USE_NSGETENVIRON 1
#else
#define USE_NSGETENVIRON 0
#endif
#if !USE_NSGETENVIRON
extern char **environ;
#else
#include <crt_externs.h> // _NSGetEnviron
#endif
#endif
namespace llvm {
using namespace sys;
ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {}
ErrorOr<std::string> sys::findProgramByName(StringRef Name,
ArrayRef<StringRef> Paths) {
assert(!Name.empty() && "Must have a name!");
// Use the given path verbatim if it contains any slashes; this matches
// the behavior of sh(1) and friends.
if (Name.find('/') != StringRef::npos)
return std::string(Name);
SmallVector<StringRef, 16> EnvironmentPaths;
if (Paths.empty())
if (const char *PathEnv = std::getenv("PATH")) {
SplitString(PathEnv, EnvironmentPaths, ":");
Paths = EnvironmentPaths;
}
for (auto Path : Paths) {
if (Path.empty())
continue;
// Check to see if this first directory contains the executable...
SmallString<128> FilePath(Path);
sys::path::append(FilePath, Name);
if (sys::fs::can_execute(FilePath.c_str()))
return std::string(FilePath.str()); // Found the executable!
}
return errc::no_such_file_or_directory;
}
static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) {
if (!Path) // Noop
return false;
std::string File;
if (Path->empty())
// Redirect empty paths to /dev/null
File = "/dev/null";
else
File = *Path;
// Open the file
int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
if (InFD == -1) {
MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
+ (FD == 0 ? "input" : "output"));
return true;
}
// Install it as the requested FD
if (dup2(InFD, FD) == -1) {
MakeErrMsg(ErrMsg, "Cannot dup2");
close(InFD);
return true;
}
close(InFD); // Close the original FD
return false;
}
#ifdef HAVE_POSIX_SPAWN
static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
posix_spawn_file_actions_t *FileActions) {
if (!Path) // Noop
return false;
const char *File;
if (Path->empty())
// Redirect empty paths to /dev/null
File = "/dev/null";
else
File = Path->c_str();
if (int Err = posix_spawn_file_actions_addopen(
FileActions, FD, File,
FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
return false;
}
#endif
static void TimeOutHandler(int Sig) {
}
static void SetMemoryLimits (unsigned size)
{
#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
struct rlimit r;
__typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
// Heap size
getrlimit (RLIMIT_DATA, &r);
r.rlim_cur = limit;
setrlimit (RLIMIT_DATA, &r);
#ifdef RLIMIT_RSS
// Resident set size.
getrlimit (RLIMIT_RSS, &r);
r.rlim_cur = limit;
setrlimit (RLIMIT_RSS, &r);
#endif
#ifdef RLIMIT_AS // e.g. NetBSD doesn't have it.
// Don't set virtual memory limit if built with any Sanitizer. They need 80Tb
// of virtual memory for shadow memory mapping.
#if !LLVM_MEMORY_SANITIZER_BUILD && !LLVM_ADDRESS_SANITIZER_BUILD
// Virtual memory.
getrlimit (RLIMIT_AS, &r);
r.rlim_cur = limit;
setrlimit (RLIMIT_AS, &r);
#endif
#endif
#endif
}
}
static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
const char **envp, const StringRef **redirects,
unsigned memoryLimit, std::string *ErrMsg) {
if (!llvm::sys::fs::exists(Program)) {
if (ErrMsg)
*ErrMsg = std::string("Executable \"") + Program.str() +
std::string("\" doesn't exist!");
return false;
}
// If this OS has posix_spawn and there is no memory limit being implied, use
// posix_spawn. It is more efficient than fork/exec.
#ifdef HAVE_POSIX_SPAWN
if (memoryLimit == 0) {
posix_spawn_file_actions_t FileActionsStore;
posix_spawn_file_actions_t *FileActions = nullptr;
// If we call posix_spawn_file_actions_addopen we have to make sure the
// c strings we pass to it stay alive until the call to posix_spawn,
// so we copy any StringRefs into this variable.
std::string RedirectsStorage[3];
if (redirects) {
std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr};
for (int I = 0; I < 3; ++I) {
if (redirects[I]) {
RedirectsStorage[I] = *redirects[I];
RedirectsStr[I] = &RedirectsStorage[I];
}
}
FileActions = &FileActionsStore;
posix_spawn_file_actions_init(FileActions);
// Redirect stdin/stdout.
if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) ||
RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions))
return false;
if (redirects[1] == nullptr || redirects[2] == nullptr ||
*redirects[1] != *redirects[2]) {
// Just redirect stderr
if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions))
return false;
} else {
// If stdout and stderr should go to the same place, redirect stderr
// to the FD already open for stdout.
if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
}
}
if (!envp)
#if !USE_NSGETENVIRON
envp = const_cast<const char **>(environ);
#else
// environ is missing in dylibs.
envp = const_cast<const char **>(*_NSGetEnviron());
#endif
// Explicitly initialized to prevent what appears to be a valgrind false
// positive.
pid_t PID = 0;
int Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
/*attrp*/nullptr, const_cast<char **>(args),
const_cast<char **>(envp));
if (FileActions)
posix_spawn_file_actions_destroy(FileActions);
if (Err)
return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
PI.Pid = PID;
return true;
}
#endif
// Create a child process.
int child = fork();
switch (child) {
// An error occurred: Return to the caller.
case -1:
MakeErrMsg(ErrMsg, "Couldn't fork");
return false;
// Child process: Execute the program.
case 0: {
// Redirect file descriptors...
if (redirects) {
// Redirect stdin
if (RedirectIO(redirects[0], 0, ErrMsg)) { return false; }
// Redirect stdout
if (RedirectIO(redirects[1], 1, ErrMsg)) { return false; }
if (redirects[1] && redirects[2] &&
*(redirects[1]) == *(redirects[2])) {
// If stdout and stderr should go to the same place, redirect stderr
// to the FD already open for stdout.
if (-1 == dup2(1,2)) {
MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
return false;
}
} else {
// Just redirect stderr
if (RedirectIO(redirects[2], 2, ErrMsg)) { return false; }
}
}
// Set memory limits
if (memoryLimit!=0) {
SetMemoryLimits(memoryLimit);
}
// Execute!
std::string PathStr = Program;
if (envp != nullptr)
execve(PathStr.c_str(),
const_cast<char **>(args),
const_cast<char **>(envp));
else
execv(PathStr.c_str(),
const_cast<char **>(args));
// If the execve() failed, we should exit. Follow Unix protocol and
// return 127 if the executable was not found, and 126 otherwise.
// Use _exit rather than exit so that atexit functions and static
// object destructors cloned from the parent process aren't
// redundantly run, and so that any data buffered in stdio buffers
// cloned from the parent aren't redundantly written out.
_exit(errno == ENOENT ? 127 : 126);
}
// Parent process: Break out of the switch to do our processing.
default:
break;
}
PI.Pid = child;
return true;
}
namespace llvm {
ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
bool WaitUntilTerminates, std::string *ErrMsg) {
struct sigaction Act, Old;
assert(PI.Pid && "invalid pid to wait on, process not started?");
int WaitPidOptions = 0;
pid_t ChildPid = PI.Pid;
if (WaitUntilTerminates) {
SecondsToWait = 0;
} else if (SecondsToWait) {
// Install a timeout handler. The handler itself does nothing, but the
// simple fact of having a handler at all causes the wait below to return
// with EINTR, unlike if we used SIG_IGN.
memset(&Act, 0, sizeof(Act));
Act.sa_handler = TimeOutHandler;
sigemptyset(&Act.sa_mask);
sigaction(SIGALRM, &Act, &Old);
alarm(SecondsToWait);
} else if (SecondsToWait == 0)
WaitPidOptions = WNOHANG;
// Parent process: Wait for the child process to terminate.
int status;
ProcessInfo WaitResult;
do {
WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions);
} while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR);
if (WaitResult.Pid != PI.Pid) {
if (WaitResult.Pid == 0) {
// Non-blocking wait.
return WaitResult;
} else {
if (SecondsToWait && errno == EINTR) {
// Kill the child.
kill(PI.Pid, SIGKILL);
// Turn off the alarm and restore the signal handler
alarm(0);
sigaction(SIGALRM, &Old, nullptr);
// Wait for child to die
if (wait(&status) != ChildPid)
MakeErrMsg(ErrMsg, "Child timed out but wouldn't die");
else
MakeErrMsg(ErrMsg, "Child timed out", 0);
WaitResult.ReturnCode = -2; // Timeout detected
return WaitResult;
} else if (errno != EINTR) {
MakeErrMsg(ErrMsg, "Error waiting for child process");
WaitResult.ReturnCode = -1;
return WaitResult;
}
}
}
// We exited normally without timeout, so turn off the timer.
if (SecondsToWait && !WaitUntilTerminates) {
alarm(0);
sigaction(SIGALRM, &Old, nullptr);
}
// Return the proper exit status. Detect error conditions
// so we can return -1 for them and set ErrMsg informatively.
int result = 0;
if (WIFEXITED(status)) {
result = WEXITSTATUS(status);
WaitResult.ReturnCode = result;
if (result == 127) {
if (ErrMsg)
*ErrMsg = llvm::sys::StrError(ENOENT);
WaitResult.ReturnCode = -1;
return WaitResult;
}
if (result == 126) {
if (ErrMsg)
*ErrMsg = "Program could not be executed";
WaitResult.ReturnCode = -1;
return WaitResult;
}
} else if (WIFSIGNALED(status)) {
if (ErrMsg) {
*ErrMsg = strsignal(WTERMSIG(status));
#ifdef WCOREDUMP
if (WCOREDUMP(status))
*ErrMsg += " (core dumped)";
#endif
}
// Return a special value to indicate that the process received an unhandled
// signal during execution as opposed to failing to execute.
WaitResult.ReturnCode = -2;
}
return WaitResult;
}
std::error_code sys::ChangeStdinToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
return std::error_code();
}
std::error_code sys::ChangeStdoutToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
return std::error_code();
}
std::error_code
llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
WindowsEncodingMethod Encoding /*unused*/) {
std::error_code EC;
llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text);
if (EC)
return EC;
OS << Contents;
if (OS.has_error())
return make_error_code(errc::io_error);
return EC;
}
bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef<const char*> Args) {
static long ArgMax = sysconf(_SC_ARG_MAX);
// System says no practical limit.
if (ArgMax == -1)
return true;
// Conservatively account for space required by environment variables.
long HalfArgMax = ArgMax / 2;
size_t ArgLength = Program.size() + 1;
for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
I != E; ++I) {
ArgLength += strlen(*I) + 1;
if (ArgLength > size_t(HalfArgMax)) {
return false;
}
}
return true;
}
}
llvm/lib/Support/Unix README
===========================
This directory provides implementations of the lib/System classes that
are common to two or more variants of UNIX. For example, the directory
structure underneath this directory could look like this:
Unix - only code that is truly generic to all UNIX platforms
Posix - code that is specific to Posix variants of UNIX
SUS - code that is specific to the Single Unix Specification
SysV - code that is specific to System V variants of UNIX
As a rule, only those directories actually needing to be created should be
created. Also, further subdirectories could be created to reflect versions of
the various standards. For example, under SUS there could be v1, v2, and v3
subdirectories to reflect the three major versions of SUS.
//= llvm/Support/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific (non-pthread) RWMutex class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#include "llvm/Support/Mutex.h"
namespace llvm {
using namespace sys;
// This naive implementation treats readers the same as writers. This
// will therefore deadlock if a thread tries to acquire a read lock
// multiple times.
RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { }
RWMutexImpl::~RWMutexImpl() {
delete static_cast<MutexImpl *>(data_);
}
bool RWMutexImpl::reader_acquire() {
return static_cast<MutexImpl *>(data_)->acquire();
}
bool RWMutexImpl::reader_release() {
return static_cast<MutexImpl *>(data_)->release();
}
bool RWMutexImpl::writer_acquire() {
return static_cast<MutexImpl *>(data_)->acquire();
}
bool RWMutexImpl::writer_release() {
return static_cast<MutexImpl *>(data_)->release();
}
}
//===- Signals.cpp - Generic Unix Signals Implementation -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
// Unix signals occurring while your program is running.
//
//===----------------------------------------------------------------------===//
#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/UniqueLock.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
#if HAVE_EXECINFO_H
# include <execinfo.h> // For backtrace().
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#if HAVE_MACH_MACH_H
#include <mach/mach.h>
#endif
#if HAVE_LINK_H
#include <link.h>
#endif
#ifdef HAVE__UNWIND_BACKTRACE
// FIXME: We should be able to use <unwind.h> for any target that has an
// _Unwind_Backtrace function, but on FreeBSD the configure test passes
// despite the function not existing, and on Android, <unwind.h> conflicts
// with <link.h>.
#if defined(__GLIBC__) || defined(__APPLE__)
#include <unwind.h>
#else
#undef HAVE__UNWIND_BACKTRACE
#endif
#endif
using namespace llvm;
static RETSIGTYPE SignalHandler(int Sig); // defined below.
static ManagedStatic<SmartMutex<true> > SignalsMutex;
/// InterruptFunction - The function to call if ctrl-c is pressed.
static void (*InterruptFunction)() = nullptr;
static ManagedStatic<std::vector<std::string>> FilesToRemove;
static StringRef Argv0;
// IntSigs - Signals that represent requested termination. There's no bug
// or failure, or if there is, it's not our direct responsibility. For whatever
// reason, our continued execution is no longer desirable.
static const int IntSigs[] = {
SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
};
// KillSigs - Signals that represent that we have a bug, and our prompt
// termination has been ordered.
static const int KillSigs[] = {
SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT
#ifdef SIGSYS
, SIGSYS
#endif
#ifdef SIGXCPU
, SIGXCPU
#endif
#ifdef SIGXFSZ
, SIGXFSZ
#endif
#ifdef SIGEMT
, SIGEMT
#endif
};
static unsigned NumRegisteredSignals = 0;
static struct {
struct sigaction SA;
int SigNo;
} RegisteredSignalInfo[array_lengthof(IntSigs) + array_lengthof(KillSigs)];
static void RegisterHandler(int Signal) {
assert(NumRegisteredSignals < array_lengthof(RegisteredSignalInfo) &&
"Out of space for signal handlers!");
struct sigaction NewHandler;
NewHandler.sa_handler = SignalHandler;
NewHandler.sa_flags = SA_NODEFER | SA_RESETHAND | SA_ONSTACK;
sigemptyset(&NewHandler.sa_mask);
// Install the new handler, save the old one in RegisteredSignalInfo.
sigaction(Signal, &NewHandler,
&RegisteredSignalInfo[NumRegisteredSignals].SA);
RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
++NumRegisteredSignals;
}
#if defined(HAVE_SIGALTSTACK)
// Hold onto both the old and new alternate signal stack so that it's not
// reported as a leak. We don't make any attempt to remove our alt signal
// stack if we remove our signal handlers; that can't be done reliably if
// someone else is also trying to do the same thing.
static stack_t OldAltStack;
static void* NewAltStackPointer;
static void CreateSigAltStack() {
const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
// If we're executing on the alternate stack, or we already have an alternate
// signal stack that we're happy with, there's nothing for us to do. Don't
// reduce the size, some other part of the process might need a larger stack
// than we do.
if (sigaltstack(nullptr, &OldAltStack) != 0 ||
OldAltStack.ss_flags & SS_ONSTACK ||
(OldAltStack.ss_sp && OldAltStack.ss_size >= AltStackSize))
return;
stack_t AltStack = {};
AltStack.ss_sp = reinterpret_cast<char *>(malloc(AltStackSize));
NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
AltStack.ss_size = AltStackSize;
if (sigaltstack(&AltStack, &OldAltStack) != 0)
free(AltStack.ss_sp);
}
#else
static void CreateSigAltStack() {}
#endif
static void RegisterHandlers() {
// We need to dereference the signals mutex during handler registration so
// that we force its construction. This is to prevent the first use being
// during handling an actual signal because you can't safely call new in a
// signal handler.
*SignalsMutex;
// If the handlers are already registered, we're done.
if (NumRegisteredSignals != 0) return;
// Create an alternate stack for signal handling. This is necessary for us to
// be able to reliably handle signals due to stack overflow.
CreateSigAltStack();
for (auto S : IntSigs) RegisterHandler(S);
for (auto S : KillSigs) RegisterHandler(S);
}
static void UnregisterHandlers() {
// Restore all of the signal handlers to how they were before we showed up.
for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
sigaction(RegisteredSignalInfo[i].SigNo,
&RegisteredSignalInfo[i].SA, nullptr);
NumRegisteredSignals = 0;
}
/// RemoveFilesToRemove - Process the FilesToRemove list. This function
/// should be called with the SignalsMutex lock held.
/// NB: This must be an async signal safe function. It cannot allocate or free
/// memory, even in debug builds.
static void RemoveFilesToRemove() {
// Avoid constructing ManagedStatic in the signal handler.
// If FilesToRemove is not constructed, there are no files to remove.
if (!FilesToRemove.isConstructed())
return;
// We avoid iterators in case of debug iterators that allocate or release
// memory.
std::vector<std::string>& FilesToRemoveRef = *FilesToRemove;
for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) {
const char *path = FilesToRemoveRef[i].c_str();
// Get the status so we can determine if it's a file or directory. If we
// can't stat the file, ignore it.
struct stat buf;
if (stat(path, &buf) != 0)
continue;
// If this is not a regular file, ignore it. We want to prevent removal of
// special files like /dev/null, even if the compiler is being run with the
// super-user permissions.
if (!S_ISREG(buf.st_mode))
continue;
// Otherwise, remove the file. We ignore any errors here as there is nothing
// else we can do.
unlink(path);
}
}
// SignalHandler - The signal handler that runs.
static RETSIGTYPE SignalHandler(int Sig) {
// Restore the signal behavior to default, so that the program actually
// crashes when we return and the signal reissues. This also ensures that if
// we crash in our signal handler that the program will terminate immediately
// instead of recursing in the signal handler.
UnregisterHandlers();
// Unmask all potentially blocked kill signals.
sigset_t SigMask;
sigfillset(&SigMask);
sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);
{
unique_lock<SmartMutex<true>> Guard(*SignalsMutex);
RemoveFilesToRemove();
if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig)
!= std::end(IntSigs)) {
if (InterruptFunction) {
void (*IF)() = InterruptFunction;
Guard.unlock();
InterruptFunction = nullptr;
IF(); // run the interrupt function.
return;
}
Guard.unlock();
raise(Sig); // Execute the default handler.
return;
}
}
// Otherwise if it is a fault (like SEGV) run any handler.
llvm::sys::RunSignalHandlers();
#ifdef __s390__
// On S/390, certain signals are delivered with PSW Address pointing to
// *after* the faulting instruction. Simply returning from the signal
// handler would continue execution after that point, instead of
// re-raising the signal. Raise the signal manually in those cases.
if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
raise(Sig);
#endif
}
void llvm::sys::RunInterruptHandlers() {
sys::SmartScopedLock<true> Guard(*SignalsMutex);
RemoveFilesToRemove();
}
void llvm::sys::SetInterruptFunction(void (*IF)()) {
{
sys::SmartScopedLock<true> Guard(*SignalsMutex);
InterruptFunction = IF;
}
RegisterHandlers();
}
// RemoveFileOnSignal - The public API
bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
std::string* ErrMsg) {
{
sys::SmartScopedLock<true> Guard(*SignalsMutex);
FilesToRemove->push_back(Filename);
}
RegisterHandlers();
return false;
}
// DontRemoveFileOnSignal - The public API
void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
sys::SmartScopedLock<true> Guard(*SignalsMutex);
std::vector<std::string>::reverse_iterator RI =
find(reverse(*FilesToRemove), Filename);
std::vector<std::string>::iterator I = FilesToRemove->end();
if (RI != FilesToRemove->rend())
I = FilesToRemove->erase(RI.base()-1);
}
/// AddSignalHandler - Add a function to be called when a signal is delivered
/// to the process. The handler can have a cookie passed to it to identify
/// what instance of the handler it is.
void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie));
RegisterHandlers();
}
#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
(defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData {
void **StackTrace;
int depth;
bool first;
const char **modules;
intptr_t *offsets;
const char *main_exec_name;
};
static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
const char *name = data->first ? data->main_exec_name : info->dlpi_name;
data->first = false;
for (int i = 0; i < info->dlpi_phnum; i++) {
const auto *phdr = &info->dlpi_phdr[i];
if (phdr->p_type != PT_LOAD)
continue;
intptr_t beg = info->dlpi_addr + phdr->p_vaddr;
intptr_t end = beg + phdr->p_memsz;
for (int j = 0; j < data->depth; j++) {
if (data->modules[j])
continue;
intptr_t addr = (intptr_t)data->StackTrace[j];
if (beg <= addr && addr < end) {
data->modules[j] = name;
data->offsets[j] = addr - info->dlpi_addr;
}
}
}
return 0;
}
/// If this is an ELF platform, we can find all loaded modules and their virtual
/// addresses with dl_iterate_phdr.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
const char *MainExecutableName,
StringSaver &StrPool) {
DlIteratePhdrData data = {StackTrace, Depth, true,
Modules, Offsets, MainExecutableName};
dl_iterate_phdr(dl_iterate_phdr_cb, &data);
return true;
}
#else
/// This platform does not have dl_iterate_phdr, so we do not yet know how to
/// find all loaded DSOs.
static bool findModulesAndOffsets(void **StackTrace, int Depth,
const char **Modules, intptr_t *Offsets,
const char *MainExecutableName,
StringSaver &StrPool) {
return false;
}
#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
static int unwindBacktrace(void **StackTrace, int MaxEntries) {
if (MaxEntries < 0)
return 0;
// Skip the first frame ('unwindBacktrace' itself).
int Entries = -1;
auto HandleFrame = [&](_Unwind_Context *Context) -> _Unwind_Reason_Code {
// Apparently we need to detect reaching the end of the stack ourselves.
void *IP = (void *)_Unwind_GetIP(Context);
if (!IP)
return _URC_END_OF_STACK;
assert(Entries < MaxEntries && "recursively called after END_OF_STACK?");
if (Entries >= 0)
StackTrace[Entries] = IP;
if (++Entries == MaxEntries)
return _URC_END_OF_STACK;
return _URC_NO_REASON;
};
_Unwind_Backtrace(
[](_Unwind_Context *Context, void *Handler) {
return (*static_cast<decltype(HandleFrame) *>(Handler))(Context);
},
static_cast<void *>(&HandleFrame));
return std::max(Entries, 0);
}
#endif
// PrintStackTrace - In the case of a program crash or fault, print out a stack
// trace so that the user has an indication of why and where we died.
//
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
void llvm::sys::PrintStackTrace(raw_ostream &OS) {
#if ENABLE_BACKTRACES
static void *StackTrace[256];
int depth = 0;
#if defined(HAVE_BACKTRACE)
// Use backtrace() to output a backtrace on Linux systems with glibc.
if (!depth)
depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
#endif
#if defined(HAVE__UNWIND_BACKTRACE)
// Try _Unwind_Backtrace() if backtrace() failed.
if (!depth)
depth = unwindBacktrace(StackTrace,
static_cast<int>(array_lengthof(StackTrace)));
#endif
if (!depth)
return;
if (printSymbolizedStackTrace(Argv0, StackTrace, depth, OS))
return;
#if HAVE_DLFCN_H && __GNUG__ && !defined(__CYGWIN__)
int width = 0;
for (int i = 0; i < depth; ++i) {
Dl_info dlinfo;
dladdr(StackTrace[i], &dlinfo);
const char* name = strrchr(dlinfo.dli_fname, '/');
int nwidth;
if (!name) nwidth = strlen(dlinfo.dli_fname);
else nwidth = strlen(name) - 1;
if (nwidth > width) width = nwidth;
}
for (int i = 0; i < depth; ++i) {
Dl_info dlinfo;
dladdr(StackTrace[i], &dlinfo);
OS << format("%-2d", i);
const char* name = strrchr(dlinfo.dli_fname, '/');
if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
else OS << format(" %-*s", width, name+1);
OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
(unsigned long)StackTrace[i]);
if (dlinfo.dli_sname != nullptr) {
OS << ' ';
int res;
char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
if (!d) OS << dlinfo.dli_sname;
else OS << d;
free(d);
// FIXME: When we move to C++11, use %t length modifier. It's not in
// C++03 and causes gcc to issue warnings. Losing the upper 32 bits of
// the stack offset for a stack dump isn't likely to cause any problems.
OS << format(" + %u",(unsigned)((char*)StackTrace[i]-
(char*)dlinfo.dli_saddr));
}
OS << '\n';
}
#elif defined(HAVE_BACKTRACE)
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
#endif
#endif
}
static void PrintStackTraceSignalHandler(void *) {
PrintStackTrace(llvm::errs());
}
void llvm::sys::DisableSystemDialogsOnCrash() {}
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
bool DisableCrashReporting) {
::Argv0 = Argv0;
AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
// Environment variable to disable any kind of crash dialog.
if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
mach_port_t self = mach_task_self();
exception_mask_t mask = EXC_MASK_CRASH;
kern_return_t ret = task_set_exception_ports(self,
mask,
MACH_PORT_NULL,
EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
THREAD_STATE_NONE);
(void)ret;
}
#endif
}
//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific (non-pthread) ThreadLocal class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
#include <cassert>
#include <pthread.h>
#include <stdlib.h>
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() : data() {
static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
int errorcode = pthread_key_create(key, nullptr);
assert(errorcode == 0);
(void) errorcode;
}
ThreadLocalImpl::~ThreadLocalImpl() {
pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
int errorcode = pthread_key_delete(*key);
assert(errorcode == 0);
(void) errorcode;
}
void ThreadLocalImpl::setInstance(const void* d) {
pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
int errorcode = pthread_setspecific(*key, d);
assert(errorcode == 0);
(void) errorcode;
}
void *ThreadLocalImpl::getInstance() {
pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
return pthread_getspecific(*key);
}
void ThreadLocalImpl::removeInstance() {
setInstance(nullptr);
}
}
#else
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() : data() { }
ThreadLocalImpl::~ThreadLocalImpl() { }
void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
void *ThreadLocalImpl::getInstance() { return data; }
void ThreadLocalImpl::removeInstance() { setInstance(0); }
}
#endif
//===- llvm/Support/Unix/Unix.h - Common Unix Include File -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines things specific to Unix implementations.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_SUPPORT_UNIX_UNIX_H
#define LLVM_LIB_SUPPORT_UNIX_UNIX_H
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on all UNIX variants.
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Errno.h"
#include <algorithm>
#include <assert.h>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <time.h>
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
/// This function builds an error message into \p ErrMsg using the \p prefix
/// string and the Unix error number given by \p errnum. If errnum is -1, the
/// default then the value of errno is used.
/// @brief Make an error message
///
/// If the error number can be converted to a string, it will be
/// separated from prefix by ": ".
static inline bool MakeErrMsg(
std::string* ErrMsg, const std::string& prefix, int errnum = -1) {
if (!ErrMsg)
return true;
if (errnum == -1)
errnum = errno;
*ErrMsg = prefix + ": " + llvm::sys::StrError(errnum);
return true;
}
namespace llvm {
namespace sys {
/// Convert a struct timeval to a duration. Note that timeval can be used both
/// as a time point and a duration. Be sure to check what the input represents.
inline std::chrono::microseconds toDuration(const struct timeval &TV) {
return std::chrono::seconds(TV.tv_sec) +
std::chrono::microseconds(TV.tv_usec);
}
/// Convert a time point to struct timespec.
inline struct timespec toTimeSpec(TimePoint<> TP) {
using namespace std::chrono;
struct timespec RetVal;
RetVal.tv_sec = toTimeT(TP);
RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count();
return RetVal;
}
/// Convert a time point to struct timeval.
inline struct timeval toTimeVal(TimePoint<std::chrono::microseconds> TP) {
using namespace std::chrono;
struct timeval RetVal;
RetVal.tv_sec = toTimeT(TP);
RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count();
return RetVal;
}
} // namespace sys
} // namespace llvm
#endif
//===--- Unix/Watchdog.inc - Unix Watchdog Implementation -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides the generic Unix implementation of the Watchdog class.
//
//===----------------------------------------------------------------------===//
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
namespace llvm {
namespace sys {
Watchdog::Watchdog(unsigned int seconds) {
#ifdef HAVE_UNISTD_H
alarm(seconds);
#endif
}
Watchdog::~Watchdog() {
#ifdef HAVE_UNISTD_H
alarm(0);
#endif
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment