Merge llvm, clang, lld, lldb, compiler-rt and libc++ r302418, and update

build glue.
This commit is contained in:
Dimitry Andric 2017-05-08 19:20:55 +00:00
396 changed files with 26143 additions and 21009 deletions

View File

@ -15,10 +15,11 @@
#define XRAY_XRAY_INTERFACE_H
#include <cstdint>
#include <stddef.h>
extern "C" {
// Synchronize this with AsmPrinter::SledKind in LLVM.
/// Synchronize this with AsmPrinter::SledKind in LLVM.
enum XRayEntryType {
ENTRY = 0,
EXIT = 1,
@ -26,32 +27,43 @@ enum XRayEntryType {
LOG_ARGS_ENTRY = 3,
};
// Provide a function to invoke for when instrumentation points are hit. This is
// a user-visible control surface that overrides the default implementation. The
// function provided should take the following arguments:
//
// - function id: an identifier that indicates the id of a function; this id
// is generated by xray; the mapping between the function id
// and the actual function pointer is available through
// __xray_table.
// - entry type: identifies what kind of instrumentation point was encountered
// (function entry, function exit, etc.). See the enum
// XRayEntryType for more details.
//
// The user handler must handle correctly spurious calls after this handler is
// removed or replaced with another handler, because it would be too costly for
// XRay runtime to avoid spurious calls.
// To prevent circular calling, the handler function itself and all its
// direct&indirect callees must not be instrumented with XRay, which can be
// achieved by marking them all with: __attribute__((xray_never_instrument))
//
// Returns 1 on success, 0 on error.
/// Provide a function to invoke for when instrumentation points are hit. This
/// is a user-visible control surface that overrides the default implementation.
/// The function provided should take the following arguments:
///
/// - function id: an identifier that indicates the id of a function; this id
/// is generated by xray; the mapping between the function id
/// and the actual function pointer is available through
/// __xray_table.
/// - entry type: identifies what kind of instrumentation point was
/// encountered (function entry, function exit, etc.). See the
/// enum XRayEntryType for more details.
///
/// The user handler must handle correctly spurious calls after this handler is
/// removed or replaced with another handler, because it would be too costly for
/// XRay runtime to avoid spurious calls.
/// To prevent circular calling, the handler function itself and all its
/// direct&indirect callees must not be instrumented with XRay, which can be
/// achieved by marking them all with: __attribute__((xray_never_instrument))
///
/// Returns 1 on success, 0 on error.
extern int __xray_set_handler(void (*entry)(int32_t, XRayEntryType));
// This removes whatever the currently provided handler is. Returns 1 on
// success, 0 on error.
/// This removes whatever the currently provided handler is. Returns 1 on
/// success, 0 on error.
extern int __xray_remove_handler();
/// Use XRay to log the first argument of each (instrumented) function call.
/// When this function exits, all threads will have observed the effect and
/// start logging their subsequent affected function calls (if patched).
///
/// Returns 1 on success, 0 on error.
extern int __xray_set_handler_arg1(void (*)(int32_t, XRayEntryType, uint64_t));
/// Disables the XRay handler used to log first arguments of function calls.
/// Returns 1 on success, 0 on error.
extern int __xray_remove_handler_arg1();
enum XRayPatchingStatus {
NOT_INITIALIZED = 0,
SUCCESS = 1,
@ -59,24 +71,31 @@ enum XRayPatchingStatus {
FAILED = 3,
};
// This tells XRay to patch the instrumentation points. See XRayPatchingStatus
// for possible result values.
/// This tells XRay to patch the instrumentation points. See XRayPatchingStatus
/// for possible result values.
extern XRayPatchingStatus __xray_patch();
// Reverses the effect of __xray_patch(). See XRayPatchingStatus for possible
// result values.
/// Reverses the effect of __xray_patch(). See XRayPatchingStatus for possible
/// result values.
extern XRayPatchingStatus __xray_unpatch();
// Use XRay to log the first argument of each (instrumented) function call.
// When this function exits, all threads will have observed the effect and
// start logging their subsequent affected function calls (if patched).
//
// Returns 1 on success, 0 on error.
extern int __xray_set_handler_arg1(void (*)(int32_t, XRayEntryType, uint64_t));
/// This patches a specific function id. See XRayPatchingStatus for possible
/// result values.
extern XRayPatchingStatus __xray_patch_function(int32_t FuncId);
/// This unpatches a specific function id. See XRayPatchingStatus for possible
/// result values.
extern XRayPatchingStatus __xray_unpatch_function(int32_t FuncId);
/// This function returns the address of the function provided a valid function
/// id. We return 0 if we encounter any error, even if 0 may be a valid function
/// address.
extern uintptr_t __xray_function_address(int32_t FuncId);
/// This function returns the maximum valid function id. Returns 0 if we
/// encounter errors (when there are no instrumented functions, etc.).
extern size_t __xray_max_function_id();
// Disables the XRay handler used to log first arguments of function calls.
// Returns 1 on success, 0 on error.
extern int __xray_remove_handler_arg1();
}
#endif

View File

@ -443,6 +443,13 @@ INTERCEPTOR(void, _longjmp, void *env, int val) {
}
#endif
#if ASAN_INTERCEPT___LONGJMP_CHK
INTERCEPTOR(void, __longjmp_chk, void *env, int val) {
__asan_handle_no_return();
REAL(__longjmp_chk)(env, val);
}
#endif
#if ASAN_INTERCEPT_SIGLONGJMP
INTERCEPTOR(void, siglongjmp, void *env, int val) {
__asan_handle_no_return();
@ -758,6 +765,9 @@ void InitializeAsanInterceptors() {
#if ASAN_INTERCEPT__LONGJMP
ASAN_INTERCEPT_FUNC(_longjmp);
#endif
#if ASAN_INTERCEPT___LONGJMP_CHK
ASAN_INTERCEPT_FUNC(__longjmp_chk);
#endif
#if ASAN_INTERCEPT_SIGLONGJMP
ASAN_INTERCEPT_FUNC(siglongjmp);
#endif

View File

@ -58,6 +58,12 @@
# define ASAN_INTERCEPT_SIGLONGJMP 0
#endif
#if SANITIZER_LINUX && !SANITIZER_ANDROID
# define ASAN_INTERCEPT___LONGJMP_CHK 1
#else
# define ASAN_INTERCEPT___LONGJMP_CHK 0
#endif
// Android bug: https://code.google.com/p/android/issues/detail?id=61799
#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && \
!(SANITIZER_ANDROID && defined(__i386))

View File

@ -98,7 +98,7 @@ static __inline emutls_address_array* emutls_getspecific() {
#else
#include <Windows.h>
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include <assert.h>

View File

@ -60,9 +60,7 @@ typedef union
}s;
} udwords;
/* MIPS64 issue: PR 20098 */
#if (defined(__LP64__) || defined(__wasm__)) && \
!(defined(__mips__) && defined(__clang__))
#if (defined(__LP64__) || defined(__wasm__) || defined(__mips64))
#define CRT_HAS_128BIT
#endif

View File

@ -24,3 +24,8 @@ fun:_ZNSt3__19addressof*
# Windows C++ stdlib headers that contain bad unrelated casts.
src:*xmemory0
src:*xstddef
# std::_Sp_counted_ptr_inplace::_Sp_counted_ptr_inplace() (libstdc++).
# This ctor is used by std::make_shared and needs to cast to uninitialized T*
# in order to call std::allocator_traits<T>::construct.
fun:_ZNSt23_Sp_counted_ptr_inplace*

View File

@ -368,11 +368,12 @@ struct ScudoAllocator {
void *Ptr;
uptr Salt;
uptr AllocationAlignment = FromPrimary ? MinAlignment : Alignment;
ScudoThreadContext *ThreadContext = getThreadContext();
ScudoThreadContext *ThreadContext = getThreadContextAndLock();
if (LIKELY(ThreadContext)) {
Salt = getPrng(ThreadContext)->getNext();
Ptr = BackendAllocator.Allocate(getAllocatorCache(ThreadContext),
NeededSize, AllocationAlignment);
ThreadContext->unlock();
} else {
SpinMutexLock l(&FallbackMutex);
Salt = FallbackPrng.getNext();
@ -434,9 +435,10 @@ struct ScudoAllocator {
if (BypassQuarantine) {
Chunk->eraseHeader();
void *Ptr = Chunk->getAllocBeg(Header);
ScudoThreadContext *ThreadContext = getThreadContext();
ScudoThreadContext *ThreadContext = getThreadContextAndLock();
if (LIKELY(ThreadContext)) {
getBackendAllocator().Deallocate(getAllocatorCache(ThreadContext), Ptr);
ThreadContext->unlock();
} else {
SpinMutexLock Lock(&FallbackMutex);
getBackendAllocator().Deallocate(&FallbackAllocatorCache, Ptr);
@ -445,12 +447,13 @@ struct ScudoAllocator {
UnpackedHeader NewHeader = *Header;
NewHeader.State = ChunkQuarantine;
Chunk->compareExchangeHeader(&NewHeader, Header);
ScudoThreadContext *ThreadContext = getThreadContext();
ScudoThreadContext *ThreadContext = getThreadContextAndLock();
if (LIKELY(ThreadContext)) {
AllocatorQuarantine.Put(getQuarantineCache(ThreadContext),
QuarantineCallback(
getAllocatorCache(ThreadContext)),
Chunk, Size);
ThreadContext->unlock();
} else {
SpinMutexLock l(&FallbackMutex);
AllocatorQuarantine.Put(&FallbackQuarantineCache,

View File

@ -72,7 +72,13 @@ const uptr AlignedChunkHeaderSize =
#if SANITIZER_CAN_USE_ALLOCATOR64
const uptr AllocatorSpace = ~0ULL;
const uptr AllocatorSize = 0x40000000000ULL; // 4TB.
# if defined(__aarch64__) && SANITIZER_ANDROID
const uptr AllocatorSize = 0x4000000000ULL; // 256G.
# elif defined(__aarch64__)
const uptr AllocatorSize = 0x10000000000ULL; // 1T.
# else
const uptr AllocatorSize = 0x40000000000ULL; // 4T.
# endif
typedef DefaultSizeClassMap SizeClassMap;
struct AP {
static const uptr kSpaceBeg = AllocatorSpace;

View File

@ -19,10 +19,16 @@
#include "scudo_allocator.h"
#include "scudo_utils.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_platform.h"
namespace __scudo {
struct ALIGNED(64) ScudoThreadContext {
public:
// Platform specific base thread context definitions.
#include "scudo_tls_context_android.inc"
#include "scudo_tls_context_linux.inc"
struct ALIGNED(64) ScudoThreadContext : public ScudoThreadContextPlatform {
AllocatorCache Cache;
Xorshift128Plus Prng;
uptr QuarantineCachePlaceHolder[4];
@ -32,8 +38,9 @@ struct ALIGNED(64) ScudoThreadContext {
void initThread();
// Fastpath functions are defined in the following platform specific headers.
#include "scudo_tls_linux.h"
// Platform specific dastpath functions definitions.
#include "scudo_tls_android.inc"
#include "scudo_tls_linux.inc"
} // namespace __scudo

View File

@ -0,0 +1,95 @@
//===-- scudo_tls_android.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Scudo thread local structure implementation for Android.
///
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_LINUX && SANITIZER_ANDROID
#include "scudo_tls.h"
#include <pthread.h>
namespace __scudo {
static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
static pthread_key_t PThreadKey;
static atomic_uint32_t ThreadContextCurrentIndex;
static ScudoThreadContext *ThreadContexts;
static uptr NumberOfContexts;
// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory.
static uptr getNumberOfCPUs() {
cpu_set_t CPUs;
CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0);
return CPU_COUNT(&CPUs);
}
static void initOnce() {
// Hack: TLS_SLOT_TSAN was introduced in N. To be able to use it on M for
// testing, we create an unused key. Since the key_data array follows the tls
// array, it basically gives us the extra entry we need.
// TODO(kostyak): remove and restrict to N and above.
CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0);
initScudo();
NumberOfContexts = getNumberOfCPUs();
ThreadContexts = reinterpret_cast<ScudoThreadContext *>(
MmapOrDie(sizeof(ScudoThreadContext) * NumberOfContexts, __func__));
for (int i = 0; i < NumberOfContexts; i++)
ThreadContexts[i].init();
}
void initThread() {
pthread_once(&GlobalInitialized, initOnce);
// Initial context assignment is done in a plain round-robin fashion.
u32 Index = atomic_fetch_add(&ThreadContextCurrentIndex, 1,
memory_order_relaxed);
ScudoThreadContext *ThreadContext =
&ThreadContexts[Index % NumberOfContexts];
*get_android_tls_ptr() = reinterpret_cast<uptr>(ThreadContext);
}
ScudoThreadContext *getThreadContextAndLockSlow() {
ScudoThreadContext *ThreadContext;
// Go through all the contexts and find the first unlocked one.
for (u32 i = 0; i < NumberOfContexts; i++) {
ThreadContext = &ThreadContexts[i];
if (ThreadContext->tryLock()) {
*get_android_tls_ptr() = reinterpret_cast<uptr>(ThreadContext);
return ThreadContext;
}
}
// No luck, find the one with the lowest precedence, and slow lock it.
u64 Precedence = UINT64_MAX;
for (u32 i = 0; i < NumberOfContexts; i++) {
u64 SlowLockPrecedence = ThreadContexts[i].getSlowLockPrecedence();
if (SlowLockPrecedence && SlowLockPrecedence < Precedence) {
ThreadContext = &ThreadContexts[i];
Precedence = SlowLockPrecedence;
}
}
if (LIKELY(Precedence != UINT64_MAX)) {
ThreadContext->lock();
*get_android_tls_ptr() = reinterpret_cast<uptr>(ThreadContext);
return ThreadContext;
}
// Last resort (can this happen?), stick with the current one.
ThreadContext =
reinterpret_cast<ScudoThreadContext *>(*get_android_tls_ptr());
ThreadContext->lock();
return ThreadContext;
}
} // namespace __scudo
#endif // SANITIZER_LINUX && SANITIZER_ANDROID

View File

@ -0,0 +1,44 @@
//===-- scudo_tls_android.inc -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Scudo thread local structure fastpath functions implementation for Android.
///
//===----------------------------------------------------------------------===//
#ifndef SCUDO_TLS_ANDROID_H_
#define SCUDO_TLS_ANDROID_H_
#ifndef SCUDO_TLS_H_
# error "This file must be included inside scudo_tls.h."
#endif // SCUDO_TLS_H_
#if SANITIZER_LINUX && SANITIZER_ANDROID
ALWAYS_INLINE void initThreadMaybe() {
if (LIKELY(*get_android_tls_ptr()))
return;
initThread();
}
ScudoThreadContext *getThreadContextAndLockSlow();
ALWAYS_INLINE ScudoThreadContext *getThreadContextAndLock() {
ScudoThreadContext *ThreadContext =
reinterpret_cast<ScudoThreadContext *>(*get_android_tls_ptr());
CHECK(ThreadContext);
// Try to lock the currently associated context.
if (ThreadContext->tryLock())
return ThreadContext;
// If it failed, go the slow path.
return getThreadContextAndLockSlow();
}
#endif // SANITIZER_LINUX && SANITIZER_ANDROID
#endif // SCUDO_TLS_ANDROID_H_

View File

@ -0,0 +1,54 @@
//===-- scudo_tls_context_android.inc ---------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Android specific base thread context definition.
///
//===----------------------------------------------------------------------===//
#ifndef SCUDO_TLS_CONTEXT_ANDROID_INC_
#define SCUDO_TLS_CONTEXT_ANDROID_INC_
#ifndef SCUDO_TLS_H_
# error "This file must be included inside scudo_tls.h."
#endif // SCUDO_TLS_H_
#if SANITIZER_LINUX && SANITIZER_ANDROID
struct ScudoThreadContextPlatform {
INLINE bool tryLock() {
if (Mutex.TryLock()) {
atomic_store_relaxed(&SlowLockPrecedence, 0);
return true;
}
if (atomic_load_relaxed(&SlowLockPrecedence) == 0)
atomic_store_relaxed(&SlowLockPrecedence, NanoTime());
return false;
}
INLINE void lock() {
Mutex.Lock();
atomic_store_relaxed(&SlowLockPrecedence, 0);
}
INLINE void unlock() {
Mutex.Unlock();
}
INLINE u64 getSlowLockPrecedence() {
return atomic_load_relaxed(&SlowLockPrecedence);
}
private:
StaticSpinMutex Mutex;
atomic_uint64_t SlowLockPrecedence;
};
#endif // SANITIZER_LINUX && SANITIZER_ANDROID
#endif // SCUDO_TLS_CONTEXT_ANDROID_INC_

View File

@ -0,0 +1,29 @@
//===-- scudo_tls_context_linux.inc -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// Linux specific base thread context definition.
///
//===----------------------------------------------------------------------===//
#ifndef SCUDO_TLS_CONTEXT_LINUX_INC_
#define SCUDO_TLS_CONTEXT_LINUX_INC_
#ifndef SCUDO_TLS_H_
# error "This file must be included inside scudo_tls.h."
#endif // SCUDO_TLS_H_
#if SANITIZER_LINUX && !SANITIZER_ANDROID
struct ScudoThreadContextPlatform {
ALWAYS_INLINE void unlock() {}
};
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
#endif // SCUDO_TLS_CONTEXT_LINUX_INC_

View File

@ -14,7 +14,7 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
#include "scudo_tls.h"
@ -26,8 +26,10 @@ namespace __scudo {
static pthread_once_t GlobalInitialized = PTHREAD_ONCE_INIT;
static pthread_key_t PThreadKey;
thread_local ThreadState ScudoThreadState = ThreadNotInitialized;
thread_local ScudoThreadContext ThreadLocalContext;
__attribute__((tls_model("initial-exec")))
THREADLOCAL ThreadState ScudoThreadState = ThreadNotInitialized;
__attribute__((tls_model("initial-exec")))
THREADLOCAL ScudoThreadContext ThreadLocalContext;
static void teardownThread(void *Ptr) {
uptr Iteration = reinterpret_cast<uptr>(Ptr);
@ -59,4 +61,4 @@ void initThread() {
} // namespace __scudo
#endif // SANITIZER_LINUX
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID

View File

@ -1,4 +1,4 @@
//===-- scudo_tls_linux.h ---------------------------------------*- C++ -*-===//
//===-- scudo_tls_linux.inc -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -19,17 +19,17 @@
# error "This file must be included inside scudo_tls.h."
#endif // SCUDO_TLS_H_
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
enum ThreadState : u8 {
ThreadNotInitialized = 0,
ThreadInitialized,
ThreadTornDown,
};
extern thread_local ThreadState ScudoThreadState;
extern thread_local ScudoThreadContext ThreadLocalContext;
__attribute__((tls_model("initial-exec")))
extern THREADLOCAL ThreadState ScudoThreadState;
__attribute__((tls_model("initial-exec")))
extern THREADLOCAL ScudoThreadContext ThreadLocalContext;
ALWAYS_INLINE void initThreadMaybe() {
if (LIKELY(ScudoThreadState != ThreadNotInitialized))
@ -37,12 +37,12 @@ ALWAYS_INLINE void initThreadMaybe() {
initThread();
}
ALWAYS_INLINE ScudoThreadContext *getThreadContext() {
ALWAYS_INLINE ScudoThreadContext *getThreadContextAndLock() {
if (UNLIKELY(ScudoThreadState == ThreadTornDown))
return nullptr;
return &ThreadLocalContext;
}
#endif // SANITIZER_LINUX
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
#endif // SCUDO_TLS_LINUX_H_

View File

@ -0,0 +1,37 @@
//===-- ubsan_diag_standalone.cc ------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Diagnostic reporting for the standalone UBSan runtime.
//
//===----------------------------------------------------------------------===//
#include "ubsan_platform.h"
#if CAN_SANITIZE_UB
#include "ubsan_diag.h"
using namespace __ubsan;
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_print_stack_trace() {
uptr top = 0;
uptr bottom = 0;
bool request_fast_unwind = common_flags()->fast_unwind_on_fatal;
if (request_fast_unwind)
__sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
GET_REPORT_OPTIONS(false);
BufferedStackTrace stack;
stack.Unwind(kStackTraceMax, Opts.pc, Opts.bp, nullptr, top, bottom,
request_fast_unwind);
stack.Print();
}
} // extern "C"
#endif // CAN_SANITIZE_UB

View File

@ -410,7 +410,8 @@ static void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val,
SourceLocation Loc = Data->Loc.acquire();
// This check could be more precise if we used different handlers for
// -fsanitize=bool and -fsanitize=enum.
bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), "'bool'"));
bool IsBool = (0 == internal_strcmp(Data->Type.getTypeName(), "'bool'")) ||
(0 == internal_strncmp(Data->Type.getTypeName(), "'BOOL'", 6));
ErrorType ET =
IsBool ? ErrorType::InvalidBoolLoad : ErrorType::InvalidEnumLoad;

View File

@ -25,6 +25,8 @@ extern "C" {
void __xray_init();
extern const XRaySledEntry __start_xray_instr_map[] __attribute__((weak));
extern const XRaySledEntry __stop_xray_instr_map[] __attribute__((weak));
extern const XRayFunctionSledIndex __start_xray_fn_idx[] __attribute__((weak));
extern const XRayFunctionSledIndex __stop_xray_fn_idx[] __attribute__((weak));
}
using namespace __xray;
@ -55,6 +57,8 @@ void __xray_init() XRAY_NEVER_INSTRUMENT {
__sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
XRayInstrMap.Sleds = __start_xray_instr_map;
XRayInstrMap.Entries = __stop_xray_instr_map - __start_xray_instr_map;
XRayInstrMap.SledsIndex = __start_xray_fn_idx;
XRayInstrMap.Functions = __stop_xray_fn_idx - __start_xray_fn_idx;
}
__sanitizer::atomic_store(&XRayInitialized, true,
__sanitizer::memory_order_release);

View File

@ -132,12 +132,48 @@ CleanupInvoker<Function> scopeCleanup(Function Fn) XRAY_NEVER_INSTRUMENT {
return CleanupInvoker<Function>{Fn};
}
inline bool patchSled(const XRaySledEntry &Sled, bool Enable,
int32_t FuncId) XRAY_NEVER_INSTRUMENT {
// While we're here, we should patch the nop sled. To do that we mprotect
// the page containing the function to be writeable.
const uint64_t PageSize = GetPageSizeCached();
void *PageAlignedAddr =
reinterpret_cast<void *>(Sled.Address & ~(PageSize - 1));
std::size_t MProtectLen = (Sled.Address + cSledLength) -
reinterpret_cast<uint64_t>(PageAlignedAddr);
MProtectHelper Protector(PageAlignedAddr, MProtectLen);
if (Protector.MakeWriteable() == -1) {
printf("Failed mprotect: %d\n", errno);
return XRayPatchingStatus::FAILED;
}
bool Success = false;
switch (Sled.Kind) {
case XRayEntryType::ENTRY:
Success = patchFunctionEntry(Enable, FuncId, Sled, __xray_FunctionEntry);
break;
case XRayEntryType::EXIT:
Success = patchFunctionExit(Enable, FuncId, Sled);
break;
case XRayEntryType::TAIL:
Success = patchFunctionTailExit(Enable, FuncId, Sled);
break;
case XRayEntryType::LOG_ARGS_ENTRY:
Success = patchFunctionEntry(Enable, FuncId, Sled, __xray_ArgLoggerEntry);
break;
default:
Report("Unsupported sled kind '%d' @%04x\n", Sled.Address, int(Sled.Kind));
return false;
}
return Success;
}
// controlPatching implements the common internals of the patching/unpatching
// implementation. |Enable| defines whether we're enabling or disabling the
// runtime XRay instrumentation.
XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT {
if (!__sanitizer::atomic_load(&XRayInitialized,
__sanitizer::memory_order_acquire))
__sanitizer::memory_order_acquire))
return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.
uint8_t NotPatching = false;
@ -179,38 +215,7 @@ XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT {
++FuncId;
CurFun = F;
}
// While we're here, we should patch the nop sled. To do that we mprotect
// the page containing the function to be writeable.
void *PageAlignedAddr =
reinterpret_cast<void *>(Sled.Address & ~(PageSize - 1));
std::size_t MProtectLen = (Sled.Address + cSledLength) -
reinterpret_cast<uint64_t>(PageAlignedAddr);
MProtectHelper Protector(PageAlignedAddr, MProtectLen);
if (Protector.MakeWriteable() == -1) {
printf("Failed mprotect: %d\n", errno);
return XRayPatchingStatus::FAILED;
}
bool Success = false;
switch (Sled.Kind) {
case XRayEntryType::ENTRY:
Success = patchFunctionEntry(Enable, FuncId, Sled, __xray_FunctionEntry);
break;
case XRayEntryType::EXIT:
Success = patchFunctionExit(Enable, FuncId, Sled);
break;
case XRayEntryType::TAIL:
Success = patchFunctionTailExit(Enable, FuncId, Sled);
break;
case XRayEntryType::LOG_ARGS_ENTRY:
Success = patchFunctionEntry(Enable, FuncId, Sled, __xray_ArgLoggerEntry);
break;
default:
Report("Unsupported sled kind: %d\n", int(Sled.Kind));
continue;
}
(void)Success;
patchSled(Sled, Enable, FuncId);
}
__sanitizer::atomic_store(&XRayPatching, false,
__sanitizer::memory_order_release);
@ -226,6 +231,64 @@ XRayPatchingStatus __xray_unpatch() XRAY_NEVER_INSTRUMENT {
return controlPatching(false);
}
XRayPatchingStatus patchFunction(int32_t FuncId,
bool Enable) XRAY_NEVER_INSTRUMENT {
if (!__sanitizer::atomic_load(&XRayInitialized,
__sanitizer::memory_order_acquire))
return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.
uint8_t NotPatching = false;
if (!__sanitizer::atomic_compare_exchange_strong(
&XRayPatching, &NotPatching, true, __sanitizer::memory_order_acq_rel))
return XRayPatchingStatus::ONGOING; // Already patching.
// Next, we look for the function index.
XRaySledMap InstrMap;
{
__sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
InstrMap = XRayInstrMap;
}
// If we don't have an index, we can't patch individual functions.
if (InstrMap.Functions == 0)
return XRayPatchingStatus::NOT_INITIALIZED;
// FuncId must be a positive number, less than the number of functions
// instrumented.
if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions) {
Report("Invalid function id provided: %d\n", FuncId);
return XRayPatchingStatus::FAILED;
}
// Now we patch ths sleds for this specific function.
auto SledRange = InstrMap.SledsIndex[FuncId - 1];
auto *f = SledRange.Begin;
auto *e = SledRange.End;
bool SucceedOnce = false;
while (f != e)
SucceedOnce |= patchSled(*f++, Enable, FuncId);
__sanitizer::atomic_store(&XRayPatching, false,
__sanitizer::memory_order_release);
if (!SucceedOnce) {
Report("Failed patching any sled for function '%d'.", FuncId);
return XRayPatchingStatus::FAILED;
}
return XRayPatchingStatus::SUCCESS;
}
XRayPatchingStatus __xray_patch_function(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
return patchFunction(FuncId, true);
}
XRayPatchingStatus
__xray_unpatch_function(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
return patchFunction(FuncId, false);
}
int __xray_set_handler_arg1(void (*Handler)(int32_t, XRayEntryType, uint64_t)) {
if (!__sanitizer::atomic_load(&XRayInitialized,
__sanitizer::memory_order_acquire))
@ -239,3 +302,15 @@ int __xray_set_handler_arg1(void (*Handler)(int32_t, XRayEntryType, uint64_t)) {
return 1;
}
int __xray_remove_handler_arg1() { return __xray_set_handler_arg1(nullptr); }
uintptr_t __xray_function_address(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
__sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
if (FuncId <= 0 || static_cast<size_t>(FuncId) > XRayInstrMap.Functions)
return 0;
return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Address;
}
size_t __xray_max_function_id() XRAY_NEVER_INSTRUMENT {
__sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
return XRayInstrMap.Functions;
}

View File

@ -39,6 +39,11 @@ struct XRaySledEntry {
#error "Unsupported word size."
#endif
};
struct XRayFunctionSledIndex {
const XRaySledEntry* Begin;
const XRaySledEntry* End;
};
}
namespace __xray {
@ -46,6 +51,8 @@ namespace __xray {
struct XRaySledMap {
const XRaySledEntry *Sleds;
size_t Entries;
const XRayFunctionSledIndex *SledsIndex;
size_t Functions;
};
bool patchFunctionEntry(bool Enable, uint32_t FuncId,

View File

@ -314,7 +314,7 @@ typedef __char32_t char32_t;
#define _LIBCPP_NO_EXCEPTIONS
#endif
#if !(__has_feature(cxx_rtti))
#if !(__has_feature(cxx_rtti)) && !defined(_LIBCPP_NO_RTTI)
#define _LIBCPP_NO_RTTI
#endif
@ -1089,6 +1089,13 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_DIAGNOSE_ERROR(...)
#endif
#if __has_attribute(fallthough) || _GNUC_VER >= 700
// Use a function like macro to imply that it must be followed by a semicolon
#define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__))
#else
#define _LIBCPP_FALLTHROUGH() ((void)0)
#endif
#if defined(_LIBCPP_ABI_MICROSOFT) && \
(defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
@ -1113,4 +1120,77 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
#endif // __cplusplus
// Decide whether to use availability macros.
#if !defined(_LIBCPP_BUILDING_LIBRARY) && \
!defined(_LIBCPP_DISABLE_AVAILABILITY) && \
__has_feature(attribute_availability_with_strict) && \
__has_feature(attribute_availability_in_templates)
#ifdef __APPLE__
#define _LIBCPP_USE_AVAILABILITY_APPLE
#endif
#endif
// Define availability macros.
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE)
#define _LIBCPP_AVAILABILITY_SHARED_MUTEX \
__attribute__((availability(macosx,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable))
#define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable))
#define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \
__attribute__((availability(macosx,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
#define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \
__attribute__((availability(macosx,strict,introduced=10.12))) \
__attribute__((availability(ios,strict,introduced=10.0))) \
__attribute__((availability(tvos,strict,introduced=10.0))) \
__attribute__((availability(watchos,strict,introduced=3.0)))
#define _LIBCPP_AVAILABILITY_FUTURE_ERROR \
__attribute__((availability(ios,strict,introduced=6.0)))
#define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \
__attribute__((availability(macosx,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
#define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \
__attribute__((availability(macosx,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
#define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \
__attribute__((availability(macosx,strict,introduced=10.9))) \
__attribute__((availability(ios,strict,introduced=7.0)))
#else
#define _LIBCPP_AVAILABILITY_SHARED_MUTEX
#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
#define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS
#define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE
#define _LIBCPP_AVAILABILITY_FUTURE_ERROR
#define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
#define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY
#define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
#endif
// Define availability that depends on _LIBCPP_NO_EXCEPTIONS.
#ifdef _LIBCPP_NO_EXCEPTIONS
#define _LIBCPP_AVAILABILITY_DYNARRAY
#define _LIBCPP_AVAILABILITY_FUTURE
#else
#define _LIBCPP_AVAILABILITY_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR
#endif
// Availability of stream API in the dylib got dropped and re-added. The
// extern template should effectively be available at:
// availability(macosx,introduced=10.9)
// availability(ios,introduced=7.0)
#if defined(_LIBCPP_USE_AVAILABILITY_APPLE) && \
((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1090) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ <= 70000))
#define _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
#endif
#endif // _LIBCPP_CONFIG

View File

@ -69,6 +69,7 @@ public:
class _LIBCPP_TYPE_VIS id;
typedef int category;
_LIBCPP_AVAILABILITY_LOCALE_CATEGORY
static const category // values assigned here are for exposition only
none = 0,
collate = LC_COLLATE_MASK,

View File

@ -474,7 +474,10 @@ int __libcpp_condvar_timedwait(__libcpp_condvar_t *__cv, __libcpp_mutex_t *__m,
timeout_ms.count() > 0 ? timeout_ms.count()
: 0,
0))
return GetLastError();
{
auto __ec = GetLastError();
return __ec == ERROR_TIMEOUT ? ETIMEDOUT : __ec;
}
return 0;
}

View File

@ -127,30 +127,33 @@ _LIBCPP_FUNC_VIS terminate_handler get_terminate() _NOEXCEPT;
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void terminate() _NOEXCEPT;
_LIBCPP_FUNC_VIS bool uncaught_exception() _NOEXCEPT;
_LIBCPP_FUNC_VIS int uncaught_exceptions() _NOEXCEPT;
_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS int uncaught_exceptions() _NOEXCEPT;
class _LIBCPP_TYPE_VIS exception_ptr;
_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);
#ifndef _LIBCPP_ABI_MICROSOFT
class _LIBCPP_TYPE_VIS exception_ptr
{
void* __ptr_;
public:
_LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
exception_ptr(const exception_ptr&) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr&) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_EXPLICIT
operator bool() const _NOEXCEPT {return __ptr_ != nullptr;}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_EXPLICIT operator bool() const _NOEXCEPT
{return __ptr_ != nullptr;}
friend _LIBCPP_INLINE_VISIBILITY
bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
{return __x.__ptr_ == __y.__ptr_;}
friend _LIBCPP_INLINE_VISIBILITY
bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
{return !(__x == __y);}
@ -178,6 +181,54 @@ make_exception_ptr(_Ep __e) _NOEXCEPT
#endif
}
#else // _LIBCPP_ABI_MICROSOFT
class _LIBCPP_TYPE_VIS exception_ptr
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
#endif
void* __ptr1_;
void* __ptr2_;
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
public:
exception_ptr() _NOEXCEPT;
exception_ptr(nullptr_t) _NOEXCEPT;
exception_ptr(const exception_ptr& __other) _NOEXCEPT;
exception_ptr& operator=(const exception_ptr& __other) _NOEXCEPT;
exception_ptr& operator=(nullptr_t) _NOEXCEPT;
~exception_ptr() _NOEXCEPT;
_LIBCPP_EXPLICIT operator bool() const _NOEXCEPT;
};
_LIBCPP_FUNC_VIS
bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT;
inline _LIBCPP_INLINE_VISIBILITY
bool operator!=(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
{return !(__x == __y);}
_LIBCPP_FUNC_VIS void swap(exception_ptr&, exception_ptr&) _NOEXCEPT;
_LIBCPP_FUNC_VIS exception_ptr __copy_exception_ptr(void *__except, const void* __ptr);
_LIBCPP_FUNC_VIS exception_ptr current_exception() _NOEXCEPT;
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr p);
// This is a built-in template function which automagically extracts the required
// information.
template <class _E> void *__GetExceptionInfo(_E);
template<class _Ep>
exception_ptr
make_exception_ptr(_Ep __e) _NOEXCEPT
{
return __copy_exception_ptr(_VSTD::addressof(__e), __GetExceptionInfo(__e));
}
#endif // _LIBCPP_ABI_MICROSOFT
// nested_exception
class _LIBCPP_EXCEPTION_ABI nested_exception

View File

@ -110,7 +110,7 @@ public:
namespace std { namespace experimental { inline namespace __array_extensions_v1 {
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS dynarray
struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_DYNARRAY dynarray
{
public:
// types:

View File

@ -145,7 +145,7 @@ namespace std { namespace experimental { inline namespace fundamentals_v1 {
#include <stdexcept>
_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
class _LIBCPP_EXCEPTION_ABI bad_optional_access
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
: public std::logic_error
{
public:
@ -523,6 +523,9 @@ public:
constexpr explicit operator bool() const noexcept {return this->__engaged_;}
_LIBCPP_NORETURN _LIBCPP_INLINE_VISIBILITY
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
#endif
constexpr void __throw_bad_optional_access() const
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@ -532,7 +535,7 @@ public:
#endif
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
constexpr value_type const& value() const
{
if (!this->__engaged_)
@ -540,7 +543,7 @@ public:
return this->__val_;
}
_LIBCPP_INLINE_VISIBILITY
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)

View File

@ -2224,7 +2224,7 @@ typename __bind_return<_Fp, _BoundArgs, _Args>::type
__apply_functor(_Fp& __f, _BoundArgs& __bound_args, __tuple_indices<_Indx...>,
_Args&& __args)
{
return __invoke(__f, __mu(_VSTD::get<_Indx>(__bound_args), __args)...);
return _VSTD::__invoke(__f, _VSTD::__mu(_VSTD::get<_Indx>(__bound_args), __args)...);
}
template<class _Fp, class ..._BoundArgs>
@ -2257,7 +2257,7 @@ public:
typename __bind_return<_Fd, _Td, tuple<_Args&&...> >::type
operator()(_Args&& ...__args)
{
return __apply_functor(__f_, __bound_args_, __indices(),
return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
}
@ -2266,7 +2266,7 @@ public:
typename __bind_return<const _Fd, const _Td, tuple<_Args&&...> >::type
operator()(_Args&& ...__args) const
{
return __apply_functor(__f_, __bound_args_, __indices(),
return _VSTD::__apply_functor(__f_, __bound_args_, __indices(),
tuple<_Args&&...>(_VSTD::forward<_Args>(__args)...));
}
};

View File

@ -499,7 +499,7 @@ make_error_condition(future_errc __e) _NOEXCEPT
return error_condition(static_cast<int>(__e), future_category());
}
class _LIBCPP_EXCEPTION_ABI future_error
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_FUTURE_ERROR future_error
: public logic_error
{
error_code __ec_;
@ -515,6 +515,9 @@ public:
};
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_FUTURE_ERROR
#endif
void __throw_future_error(future_errc _Ev)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
@ -525,7 +528,7 @@ void __throw_future_error(future_errc _Ev)
#endif
}
class _LIBCPP_TYPE_VIS __assoc_sub_state
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state
: public __shared_count
{
protected:
@ -612,7 +615,7 @@ __assoc_sub_state::wait_for(const chrono::duration<_Rep, _Period>& __rel_time) c
}
template <class _Rp>
class __assoc_state
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
@ -652,6 +655,7 @@ __assoc_state<_Rp>::__on_zero_shared() _NOEXCEPT
template <class _Rp>
template <class _Arg>
_LIBCPP_AVAILABILITY_FUTURE
void
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
__assoc_state<_Rp>::set_value(_Arg&& __arg)
@ -707,7 +711,7 @@ __assoc_state<_Rp>::copy()
}
template <class _Rp>
class __assoc_state<_Rp&>
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state<_Rp&>
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
@ -767,7 +771,7 @@ __assoc_state<_Rp&>::copy()
}
template <class _Rp, class _Alloc>
class __assoc_state_alloc
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc
: public __assoc_state<_Rp>
{
typedef __assoc_state<_Rp> base;
@ -795,7 +799,7 @@ __assoc_state_alloc<_Rp, _Alloc>::__on_zero_shared() _NOEXCEPT
}
template <class _Rp, class _Alloc>
class __assoc_state_alloc<_Rp&, _Alloc>
class _LIBCPP_AVAILABILITY_FUTURE __assoc_state_alloc<_Rp&, _Alloc>
: public __assoc_state<_Rp&>
{
typedef __assoc_state<_Rp&> base;
@ -821,7 +825,7 @@ __assoc_state_alloc<_Rp&, _Alloc>::__on_zero_shared() _NOEXCEPT
}
template <class _Alloc>
class __assoc_sub_state_alloc
class _LIBCPP_AVAILABILITY_FUTURE __assoc_sub_state_alloc
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
@ -847,7 +851,7 @@ __assoc_sub_state_alloc<_Alloc>::__on_zero_shared() _NOEXCEPT
}
template <class _Rp, class _Fp>
class __deferred_assoc_state
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state
: public __assoc_state<_Rp>
{
typedef __assoc_state<_Rp> base;
@ -894,7 +898,7 @@ __deferred_assoc_state<_Rp, _Fp>::__execute()
}
template <class _Fp>
class __deferred_assoc_state<void, _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __deferred_assoc_state<void, _Fp>
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
@ -942,7 +946,7 @@ __deferred_assoc_state<void, _Fp>::__execute()
}
template <class _Rp, class _Fp>
class __async_assoc_state
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state
: public __assoc_state<_Rp>
{
typedef __assoc_state<_Rp> base;
@ -997,7 +1001,7 @@ __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT
}
template <class _Fp>
class __async_assoc_state<void, _Fp>
class _LIBCPP_AVAILABILITY_FUTURE __async_assoc_state<void, _Fp>
: public __assoc_sub_state
{
typedef __assoc_sub_state base;
@ -1076,7 +1080,7 @@ __make_async_assoc_state(_Fp __f);
#endif
template <class _Rp>
class _LIBCPP_TEMPLATE_VIS future
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future
{
__assoc_state<_Rp>* __state_;
@ -1179,7 +1183,7 @@ future<_Rp>::get()
}
template <class _Rp>
class _LIBCPP_TEMPLATE_VIS future<_Rp&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE future<_Rp&>
{
__assoc_state<_Rp&>* __state_;
@ -1277,7 +1281,7 @@ future<_Rp&>::get()
}
template <>
class _LIBCPP_TYPE_VIS future<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE future<void>
{
__assoc_sub_state* __state_;
@ -1360,7 +1364,7 @@ swap(future<_Rp>& __x, future<_Rp>& __y) _NOEXCEPT
template <class _Callable> class packaged_task;
template <class _Rp>
class _LIBCPP_TEMPLATE_VIS promise
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise
{
__assoc_state<_Rp>* __state_;
@ -1527,7 +1531,7 @@ promise<_Rp>::set_exception_at_thread_exit(exception_ptr __p)
// promise<R&>
template <class _Rp>
class _LIBCPP_TEMPLATE_VIS promise<_Rp&>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<_Rp&>
{
__assoc_state<_Rp&>* __state_;
@ -1663,7 +1667,7 @@ promise<_Rp&>::set_exception_at_thread_exit(exception_ptr __p)
// promise<void>
template <>
class _LIBCPP_TYPE_VIS promise<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE promise<void>
{
__assoc_sub_state* __state_;
@ -1749,7 +1753,7 @@ template <class _Rp, class _Alloc>
template<class _Fp> class __packaged_task_base;
template<class _Rp, class ..._ArgTypes>
class __packaged_task_base<_Rp(_ArgTypes...)>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_base<_Rp(_ArgTypes...)>
{
__packaged_task_base(const __packaged_task_base&);
__packaged_task_base& operator=(const __packaged_task_base&);
@ -1767,7 +1771,7 @@ public:
template<class _FD, class _Alloc, class _FB> class __packaged_task_func;
template<class _Fp, class _Alloc, class _Rp, class ..._ArgTypes>
class __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>
: public __packaged_task_base<_Rp(_ArgTypes...)>
{
__compressed_pair<_Fp, _Alloc> __f_;
@ -1825,7 +1829,7 @@ __packaged_task_func<_Fp, _Alloc, _Rp(_ArgTypes...)>::operator()(_ArgTypes&& ...
template <class _Callable> class __packaged_task_function;
template<class _Rp, class ..._ArgTypes>
class __packaged_task_function<_Rp(_ArgTypes...)>
class _LIBCPP_AVAILABILITY_FUTURE __packaged_task_function<_Rp(_ArgTypes...)>
{
typedef __packaged_task_base<_Rp(_ArgTypes...)> __base;
typename aligned_storage<3*sizeof(void*)>::type __buf_;
@ -2000,7 +2004,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::operator()(_ArgTypes... __arg) cons
}
template<class _Rp, class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS packaged_task<_Rp(_ArgTypes...)>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<_Rp(_ArgTypes...)>
{
public:
typedef _Rp result_type; // extension
@ -2129,7 +2133,7 @@ packaged_task<_Rp(_ArgTypes...)>::reset()
}
template<class ..._ArgTypes>
class _LIBCPP_TEMPLATE_VIS packaged_task<void(_ArgTypes...)>
class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FUTURE packaged_task<void(_ArgTypes...)>
{
public:
typedef void result_type; // extension
@ -2517,7 +2521,7 @@ shared_future<_Rp&>::operator=(const shared_future& __rhs)
}
template <>
class _LIBCPP_TYPE_VIS shared_future<void>
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_FUTURE shared_future<void>
{
__assoc_sub_state* __state_;

View File

@ -1675,9 +1675,11 @@ operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
return __is;
}
#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_istream<wchar_t>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_iostream<char>)
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -1402,6 +1402,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, true, __iob.flags());
const unsigned __nbuf = (numeric_limits<long>::digits / 3)
+ ((numeric_limits<long>::digits % 3) != 0)
+ ((__iob.flags() & ios_base::showbase) != 0)
+ 2;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@ -1428,6 +1429,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, true, __iob.flags());
const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
+ ((numeric_limits<long long>::digits % 3) != 0)
+ ((__iob.flags() & ios_base::showbase) != 0)
+ 2;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@ -1454,6 +1456,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, false, __iob.flags());
const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
+ ((numeric_limits<unsigned long>::digits % 3) != 0)
+ ((__iob.flags() & ios_base::showbase) != 0)
+ 1;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@ -1480,6 +1483,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, false, __iob.flags());
const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
+ ((numeric_limits<unsigned long long>::digits % 3) != 0)
+ ((__iob.flags() & ios_base::showbase) != 0)
+ 1;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@ -1685,6 +1689,22 @@ protected:
~__time_get_c_storage() {}
};
template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__weeks() const;
template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__months() const;
template <> _LIBCPP_FUNC_VIS const string* __time_get_c_storage<char>::__am_pm() const;
template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__c() const;
template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__r() const;
template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__x() const;
template <> _LIBCPP_FUNC_VIS const string& __time_get_c_storage<char>::__X() const;
template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__weeks() const;
template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__months() const;
template <> _LIBCPP_FUNC_VIS const wstring* __time_get_c_storage<wchar_t>::__am_pm() const;
template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__c() const;
template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__r() const;
template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__x() const;
template <> _LIBCPP_FUNC_VIS const wstring& __time_get_c_storage<wchar_t>::__X() const;
template <class _CharT, class _InputIterator = istreambuf_iterator<_CharT> >
class _LIBCPP_TEMPLATE_VIS time_get
: public locale::facet,
@ -2825,7 +2845,7 @@ money_get<_CharT, _InputIterator>::__do_get(iter_type& __b, iter_type __e,
return false;
}
}
// drop through
_LIBCPP_FALLTHROUGH();
case money_base::none:
if (__p != 3)
{

View File

@ -3559,7 +3559,7 @@ template <class _Tp, class _Dp, class _Alloc>
const void*
__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPT
{
return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : 0;
return __t == typeid(_Dp) ? _VSTD::addressof(__data_.first().second()) : nullptr;
}
#endif // _LIBCPP_NO_RTTI
@ -5293,7 +5293,8 @@ private:
friend _LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
};
_LIBCPP_FUNC_VIS __sp_mut& __get_sp_mut(const void*);
_LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
__sp_mut& __get_sp_mut(const void*);
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
@ -5304,6 +5305,7 @@ atomic_is_lock_free(const shared_ptr<_Tp>*)
}
template <class _Tp>
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_load(const shared_ptr<_Tp>* __p)
{
@ -5316,6 +5318,7 @@ atomic_load(const shared_ptr<_Tp>* __p)
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
{
@ -5323,6 +5326,7 @@ atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
}
template <class _Tp>
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
void
atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
{
@ -5334,6 +5338,7 @@ atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
void
atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
{
@ -5341,6 +5346,7 @@ atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
}
template <class _Tp>
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
{
@ -5353,6 +5359,7 @@ atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
shared_ptr<_Tp>
atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
{
@ -5360,6 +5367,7 @@ atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order
}
template <class _Tp>
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
bool
atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
{
@ -5381,6 +5389,7 @@ atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, share
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
bool
atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
{
@ -5389,6 +5398,7 @@ atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
bool
atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
shared_ptr<_Tp> __w, memory_order, memory_order)
@ -5398,6 +5408,7 @@ atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* _
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
bool
atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
shared_ptr<_Tp> __w, memory_order, memory_order)

View File

@ -146,9 +146,8 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_bad_alloc(); // not in C++ spec
#if defined(_LIBCPP_BUILDING_LIBRARY) || (_LIBCPP_STD_VER > 11)
class _LIBCPP_EXCEPTION_ABI bad_array_length
: public bad_alloc
{
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
bad_array_length : public bad_alloc {
public:
bad_array_length() _NOEXCEPT;
virtual ~bad_array_length() _NOEXCEPT;
@ -182,7 +181,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, const std::not
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz) _NOEXCEPT;
#endif
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz) _THROW_BAD_ALLOC;
@ -190,7 +189,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, const std::n
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz) _NOEXCEPT;
#endif
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
@ -199,7 +198,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new(std::size_t __sz, std::align_val
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete(void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
_LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_val_t) _THROW_BAD_ALLOC;
@ -207,7 +206,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS void* operator new[](std::size_t __sz, std::align_v
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::align_val_t, const std::nothrow_t&) _NOEXCEPT;
#ifndef _LIBCPP_HAS_NO_SIZED_DEALLOCATION
_LIBCPP_OVERRIDABLE_FUNC_VIS void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE void operator delete[](void* __p, std::size_t __sz, std::align_val_t) _NOEXCEPT;
#endif
#endif
@ -238,6 +237,9 @@ inline _LIBCPP_INLINE_VISIBILITY void __libcpp_deallocate(void *__ptr) {
#ifdef _LIBCPP_BAD_ARRAY_LENGTH_DEFINED
_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
#ifndef _LIBCPP_NO_EXCEPTIONS
_LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH
#endif
void __throw_bad_array_length()
{
#ifndef _LIBCPP_NO_EXCEPTIONS

View File

@ -1080,8 +1080,10 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const bitset<_Size>& __x)
use_facet<ctype<_CharT> >(__os.getloc()).widen('1'));
}
#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostream<wchar_t>)
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -3997,16 +3997,30 @@ public:
{return !(__x == __y);}
};
#ifndef _LIBCPP_MSVCRT
extern "C" double lgamma_r(double, int *);
#endif
inline _LIBCPP_INLINE_VISIBILITY double __libcpp_lgamma(double __d) {
#if defined(_LIBCPP_MSVCRT)
return lgamma(__d);
#else
int __sign;
return lgamma_r(__d, &__sign);
#endif
}
template<class _IntType>
binomial_distribution<_IntType>::param_type::param_type(result_type __t, double __p)
binomial_distribution<_IntType>::param_type::param_type(const result_type __t, const double __p)
: __t_(__t), __p_(__p)
{
if (0 < __p_ && __p_ < 1)
{
__r0_ = static_cast<result_type>((__t_ + 1) * __p_);
__pr_ = _VSTD::exp(_VSTD::lgamma(__t_ + 1.) - _VSTD::lgamma(__r0_ + 1.) -
_VSTD::lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
(__t_ - __r0_) * _VSTD::log(1 - __p_));
__pr_ = _VSTD::exp(__libcpp_lgamma(__t_ + 1.) -
__libcpp_lgamma(__r0_ + 1.) -
__libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
(__t_ - __r0_) * _VSTD::log(1 - __p_));
__odds_ratio_ = __p_ / (1 - __p_);
}
}

View File

@ -141,7 +141,7 @@ template <class Mutex>
_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_TYPE_VIS __shared_mutex_base
struct _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX __shared_mutex_base
{
mutex __mut_;
condition_variable __gate1_;
@ -173,11 +173,11 @@ struct _LIBCPP_TYPE_VIS __shared_mutex_base
#if _LIBCPP_STD_VER > 14
class _LIBCPP_TYPE_VIS shared_mutex
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_mutex
{
__shared_mutex_base __base;
public:
shared_mutex() : __base() {}
_LIBCPP_INLINE_VISIBILITY shared_mutex() : __base() {}
_LIBCPP_INLINE_VISIBILITY ~shared_mutex() = default;
shared_mutex(const shared_mutex&) = delete;
@ -199,7 +199,7 @@ public:
#endif
class _LIBCPP_TYPE_VIS shared_timed_mutex
class _LIBCPP_TYPE_VIS _LIBCPP_AVAILABILITY_SHARED_MUTEX shared_timed_mutex
{
__shared_mutex_base __base;
public:

View File

@ -476,11 +476,13 @@ basic_streambuf<_CharT, _Traits>::overflow(int_type)
return traits_type::eof();
}
#ifndef _LIBCPP_AVAILABILITY_NO_STREAMS_EXTERN_TEMPLATE
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_streambuf<wchar_t>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<char>)
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ios<wchar_t>)
#endif
_LIBCPP_END_NAMESPACE_STD

View File

@ -108,6 +108,7 @@ protected:
#endif
public:
_LIBCPP_AVAILABILITY_TYPEINFO_VTABLE
virtual ~type_info();
#if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)

View File

@ -20,7 +20,7 @@
#if defined(_LIBCPP_ABI_MICROSOFT)
#include "support/runtime/exception_msvc.ipp"
#include "support/runtime/exception_pointer_unimplemented.ipp"
#include "support/runtime/exception_pointer_msvc.ipp"
#elif defined(_LIBCPPABI_VERSION)
#include "support/runtime/exception_libcxxabi.ipp"
#include "support/runtime/exception_pointer_cxxabi.ipp"

View File

@ -513,8 +513,8 @@ bool checked_set(CType* out, ChronoType time) {
return true;
}
using TimeSpec = struct ::timespec;
using StatT = struct ::stat;
using TimeSpec = struct timespec;
using StatT = struct stat;
#if defined(__APPLE__)
TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }

View File

@ -68,8 +68,8 @@ T&
make(A0 a0)
{
static typename aligned_storage<sizeof(T)>::type buf;
::new (&buf) T(a0);
return *reinterpret_cast<T*>(&buf);
auto *obj = ::new (&buf) T(a0);
return *obj;
}
template <class T, class A0, class A1>
@ -88,8 +88,8 @@ T&
make(A0 a0, A1 a1, A2 a2)
{
static typename aligned_storage<sizeof(T)>::type buf;
::new (&buf) T(a0, a1, a2);
return *reinterpret_cast<T*>(&buf);
auto *obj = ::new (&buf) T(a0, a1, a2);
return *obj;
}
template <typename T, size_t N>
@ -480,8 +480,8 @@ locale::__imp::make_global()
{
// only one thread can get in here and it only gets in once
static aligned_storage<sizeof(locale)>::type buf;
::new (&buf) locale(locale::classic());
return *reinterpret_cast<locale*>(&buf);
auto *obj = ::new (&buf) locale(locale::classic());
return *obj;
}
locale&

View File

@ -120,7 +120,7 @@ __shared_weak_count::lock() _NOEXCEPT
object_owners+1))
return this;
}
return 0;
return nullptr;
}
#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
@ -128,7 +128,7 @@ __shared_weak_count::lock() _NOEXCEPT
const void*
__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
{
return 0;
return nullptr;
}
#endif // _LIBCPP_NO_RTTI
@ -154,7 +154,7 @@ __sp_mut::lock() _NOEXCEPT
{
auto m = static_cast<__libcpp_mutex_t*>(__lx);
unsigned count = 0;
while (__libcpp_mutex_trylock(m) != 0)
while (!__libcpp_mutex_trylock(m))
{
if (++count > 16)
{

View File

@ -0,0 +1,94 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
#include <stdlib.h>
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void*,
_In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
__ExceptionPtrAssign(_Inout_ void*, _In_ const void*);
_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL
__ExceptionPtrCompare(_In_ const void*, _In_ const void*);
_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL
__ExceptionPtrToBool(_In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*,
_Inout_ void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
__ExceptionPtrCurrentException(_Out_ void*);
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
__ExceptionPtrRethrow(_In_ const void*);
_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL
__ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*);
namespace std {
exception_ptr::exception_ptr() _NOEXCEPT { __ExceptionPtrCreate(this); }
exception_ptr::exception_ptr(nullptr_t) _NOEXCEPT { __ExceptionPtrCreate(this); }
exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT {
__ExceptionPtrCopy(this, &__other);
}
exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT {
__ExceptionPtrAssign(this, &__other);
return *this;
}
exception_ptr& exception_ptr::operator=(nullptr_t) _NOEXCEPT {
exception_ptr dummy;
__ExceptionPtrAssign(this, &dummy);
return *this;
}
exception_ptr::~exception_ptr() _NOEXCEPT { __ExceptionPtrDestroy(this); }
exception_ptr::operator bool() const _NOEXCEPT {
return __ExceptionPtrToBool(this);
}
bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT {
return __ExceptionPtrCompare(&__x, &__y);
}
void swap(exception_ptr& lhs, exception_ptr& rhs) _NOEXCEPT {
__ExceptionPtrSwap(&rhs, &lhs);
}
exception_ptr __copy_exception_ptr(void* __except, const void* __ptr) {
exception_ptr __ret = nullptr;
if (__ptr)
__ExceptionPtrCopyException(&__ret, __except, __ptr);
return __ret;
}
exception_ptr current_exception() _NOEXCEPT {
exception_ptr __ret;
__ExceptionPtrCurrentException(&__ret);
return __ret;
}
_LIBCPP_NORETURN
void rethrow_exception(exception_ptr p) { __ExceptionPtrRethrow(&p); }
nested_exception::nested_exception() _NOEXCEPT : __ptr_(current_exception()) {}
nested_exception::~nested_exception() _NOEXCEPT {}
_LIBCPP_NORETURN
void nested_exception::rethrow_nested() const {
if (__ptr_ == nullptr)
terminate();
rethrow_exception(__ptr_);
}
} // namespace std

View File

@ -842,6 +842,7 @@ class LLVM_NODISCARD APInt {
///
/// \returns *this
APInt &operator*=(const APInt &RHS);
APInt &operator*=(uint64_t RHS);
/// \brief Addition assignment operator.
///
@ -2043,6 +2044,16 @@ inline APInt operator-(uint64_t LHS, APInt b) {
return b;
}
inline APInt operator*(APInt a, uint64_t RHS) {
a *= RHS;
return a;
}
inline APInt operator*(uint64_t LHS, APInt b) {
b *= LHS;
return b;
}
namespace APIntOps {

View File

@ -217,7 +217,7 @@ class BitVector {
unsigned BitPos = Prev % BITWORD_SIZE;
BitWord Copy = Bits[WordPos];
// Mask off previous bits.
Copy &= ~0UL << BitPos;
Copy &= maskTrailingZeros<BitWord>(BitPos);
if (Copy != 0)
return WordPos * BITWORD_SIZE + countTrailingZeros(Copy);
@ -229,7 +229,7 @@ class BitVector {
return -1;
}
/// find_next_unset - Returns the index of the next usnet bit following the
/// find_next_unset - Returns the index of the next unset bit following the
/// "Prev" bit. Returns -1 if all remaining bits are set.
int find_next_unset(unsigned Prev) const {
++Prev;
@ -253,7 +253,34 @@ class BitVector {
return -1;
}
/// clear - Clear all bits.
/// find_prev - Returns the index of the first set bit that precedes the
/// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
int find_prev(unsigned PriorTo) {
if (PriorTo == 0)
return -1;
--PriorTo;
unsigned WordPos = PriorTo / BITWORD_SIZE;
unsigned BitPos = PriorTo % BITWORD_SIZE;
BitWord Copy = Bits[WordPos];
// Mask off next bits.
Copy &= maskTrailingOnes<BitWord>(BitPos + 1);
if (Copy != 0)
return (WordPos + 1) * BITWORD_SIZE - countLeadingZeros(Copy) - 1;
// Check previous words.
for (unsigned i = 1; i <= WordPos; ++i) {
unsigned Index = WordPos - i;
if (Bits[Index] == 0)
continue;
return (Index + 1) * BITWORD_SIZE - countLeadingZeros(Bits[Index]) - 1;
}
return -1;
}
/// clear - Removes all bits from the bitvector. Does not change capacity.
void clear() {
Size = 0;
}

View File

@ -278,6 +278,24 @@ class SmallBitVector {
return getPointer()->find_next_unset(Prev);
}
/// find_prev - Returns the index of the first set bit that precedes the
/// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
int find_prev(unsigned PriorTo) const {
if (isSmall()) {
if (PriorTo == 0)
return -1;
--PriorTo;
uintptr_t Bits = getSmallBits();
Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1);
if (Bits == 0)
return -1;
return NumBaseBits - countLeadingZeros(Bits) - 1;
}
return getPointer()->find_prev(PriorTo);
}
/// Clear all bits.
void clear() {
if (!isSmall())

View File

@ -220,8 +220,8 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const {
BI = df_ext_begin(getHeader(), VisitSet),
BE = df_ext_end(getHeader(), VisitSet);
// Keep track of the number of BBs visited.
unsigned NumVisited = 0;
// Keep track of the BBs visited.
SmallPtrSet<BlockT*, 8> VisitedBBs;
// Check the individual blocks.
for ( ; BI != BE; ++BI) {
@ -259,10 +259,18 @@ void LoopBase<BlockT, LoopT>::verifyLoop() const {
assert(BB != &getHeader()->getParent()->front() &&
"Loop contains function entry block!");
NumVisited++;
VisitedBBs.insert(BB);
}
assert(NumVisited == getNumBlocks() && "Unreachable block in loop");
if (VisitedBBs.size() != getNumBlocks()) {
dbgs() << "The following blocks are unreachable in the loop: ";
for (auto BB : Blocks) {
if (!VisitedBBs.count(BB)) {
dbgs() << *BB << "\n";
}
}
assert(false && "Unreachable block in loop");
}
// Check the subloops.
for (iterator I = begin(), E = end(); I != E; ++I)

View File

@ -54,6 +54,18 @@ class ProfileSummaryInfo {
ProfileSummaryInfo(Module &M) : M(M) {}
ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
: M(Arg.M), Summary(std::move(Arg.Summary)) {}
/// Handle the invalidation of this information.
///
/// When used as a result of \c ProfileSummaryAnalysis this method will be
/// called when the module this was computed for changes. Since profile
/// summary is immutable after it is annotated on the module, we return false
/// here.
bool invalidate(Module &, const PreservedAnalyses &,
ModuleAnalysisManager::Invalidator &) {
return false;
}
/// Returns the profile count for \p CallInst.
static Optional<uint64_t> getProfileCount(const Instruction *CallInst,
BlockFrequencyInfo *BFI);

View File

@ -782,13 +782,13 @@ class ScalarEvolution {
/// Set the memoized range for the given SCEV.
const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint,
const ConstantRange &CR) {
ConstantRange &&CR) {
DenseMap<const SCEV *, ConstantRange> &Cache =
Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges;
auto Pair = Cache.insert({S, CR});
auto Pair = Cache.try_emplace(S, std::move(CR));
if (!Pair.second)
Pair.first->second = CR;
Pair.first->second = std::move(CR);
return Pair.first->second;
}
@ -816,6 +816,10 @@ class ScalarEvolution {
/// Helper function called from createNodeForPHI.
const SCEV *createAddRecFromPHI(PHINode *PN);
/// A helper function for createAddRecFromPHI to handle simple cases.
const SCEV *createSimpleAffineAddRec(PHINode *PN, Value *BEValueV,
Value *StartValueV);
/// Helper function called from createNodeForPHI.
const SCEV *createNodeFromSelectLikePHI(PHINode *PN);
@ -1565,7 +1569,7 @@ class ScalarEvolution {
/// delinearization).
void findArrayDimensions(SmallVectorImpl<const SCEV *> &Terms,
SmallVectorImpl<const SCEV *> &Sizes,
const SCEV *ElementSize) const;
const SCEV *ElementSize);
void print(raw_ostream &OS) const;
void verify() const;

View File

@ -1115,6 +1115,9 @@ TLI_DEFINE_STRING_INTERNAL("vsprintf")
/// int vsscanf(const char *s, const char *format, va_list arg);
TLI_DEFINE_ENUM_INTERNAL(vsscanf)
TLI_DEFINE_STRING_INTERNAL("vsscanf")
/// size_t wcslen (const wchar_t* wcs);
TLI_DEFINE_ENUM_INTERNAL(wcslen)
TLI_DEFINE_STRING_INTERNAL("wcslen")
/// ssize_t write(int fildes, const void *buf, size_t nbyte);
TLI_DEFINE_ENUM_INTERNAL(write)
TLI_DEFINE_STRING_INTERNAL("write")

View File

@ -226,6 +226,7 @@ class AsmPrinter : public MachineFunctionPass {
FUNCTION_EXIT = 1,
TAIL_CALL = 2,
LOG_ARGS_ENTER = 3,
CUSTOM_EVENT = 4,
};
// The table will contain these structs that point to the sled, the function
@ -242,7 +243,7 @@ class AsmPrinter : public MachineFunctionPass {
};
// All the sleds to be emitted.
std::vector<XRayFunctionEntry> Sleds;
SmallVector<XRayFunctionEntry, 4> Sleds;
// Helper function to record a given XRay sled.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind);

View File

@ -506,6 +506,7 @@ class FastISel {
bool selectCast(const User *I, unsigned Opcode);
bool selectExtractValue(const User *I);
bool selectInsertValue(const User *I);
bool selectXRayCustomEvent(const CallInst *II);
private:
/// \brief Handle PHI nodes in successor blocks.

View File

@ -249,7 +249,7 @@ class FunctionLoweringInfo {
void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
const KnownBits &Known) {
// Only install this information if it tells us something.
if (NumSignBits == 1 && Known.Zero == 0 && Known.One == 0)
if (NumSignBits == 1 && Known.isUnknown())
return;
LiveOutRegInfo.grow(Reg);

View File

@ -78,7 +78,7 @@ class IRTranslator : public MachineFunctionPass {
/// this function.
DenseMap<const AllocaInst *, int> FrameIndices;
/// Methods for translating form LLVM IR to MachineInstr.
/// \name Methods for translating form LLVM IR to MachineInstr.
/// \see ::translate for general information on the translate methods.
/// @{

View File

@ -45,7 +45,7 @@ class MachineIRBuilder {
/// Debug location to be set to any instruction we create.
DebugLoc DL;
/// Fields describing the insertion point.
/// \name Fields describing the insertion point.
/// @{
MachineBasicBlock *MBB;
MachineBasicBlock::iterator II;
@ -84,7 +84,7 @@ class MachineIRBuilder {
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II);
/// @}
/// Setters for the insertion point.
/// \name Setters for the insertion point.
/// @{
/// Set the MachineFunction where to build instructions.
void setMF(MachineFunction &);
@ -98,7 +98,7 @@ class MachineIRBuilder {
void setInstr(MachineInstr &MI);
/// @}
/// Control where instructions we create are recorded (typically for
/// \name Control where instructions we create are recorded (typically for
/// visiting again later during legalization).
/// @{
void recordInsertions(std::function<void(MachineInstr *)> InsertedInstr);

View File

@ -309,7 +309,7 @@ class RegBankSelect : public MachineFunctionPass {
Impossible
};
/// Convenient types for a list of insertion points.
/// \name Convenient types for a list of insertion points.
/// @{
typedef SmallVector<std::unique_ptr<InsertPoint>, 2> InsertionPoints;
typedef InsertionPoints::iterator insertpt_iterator;
@ -341,7 +341,7 @@ class RegBankSelect : public MachineFunctionPass {
const TargetRegisterInfo &TRI, Pass &P,
RepairingKind Kind = RepairingKind::Insert);
/// Getters.
/// \name Getters.
/// @{
RepairingKind getKind() const { return Kind; }
unsigned getOpIdx() const { return OpIdx; }
@ -349,7 +349,7 @@ class RegBankSelect : public MachineFunctionPass {
bool hasSplit() { return HasSplit; }
/// @}
/// Overloaded methods to add an insertion point.
/// \name Overloaded methods to add an insertion point.
/// @{
/// Add a MBBInsertionPoint to the list of InsertPoints.
void addInsertPoint(MachineBasicBlock &MBB, bool Beginning);
@ -362,7 +362,7 @@ class RegBankSelect : public MachineFunctionPass {
void addInsertPoint(InsertPoint &Point);
/// @}
/// Accessors related to the insertion points.
/// \name Accessors related to the insertion points.
/// @{
insertpt_iterator begin() { return InsertPoints.begin(); }
insertpt_iterator end() { return InsertPoints.end(); }
@ -561,7 +561,7 @@ class RegBankSelect : public MachineFunctionPass {
/// Find the best mapping for \p MI from \p PossibleMappings.
/// \return a reference on the best mapping in \p PossibleMappings.
RegisterBankInfo::InstructionMapping &
const RegisterBankInfo::InstructionMapping &
findBestMapping(MachineInstr &MI,
RegisterBankInfo::InstructionMappings &PossibleMappings,
SmallVectorImpl<RepairingPlacement> &RepairPts);

View File

@ -264,7 +264,7 @@ class RegisterBankInfo {
/// Convenient type to represent the alternatives for mapping an
/// instruction.
/// \todo When we move to TableGen this should be an array ref.
typedef SmallVector<InstructionMapping, 4> InstructionMappings;
typedef SmallVector<const InstructionMapping *, 4> InstructionMappings;
/// Helper class used to get/create the virtual registers that will be used
/// to replace the MachineOperand when applying a mapping.
@ -310,7 +310,7 @@ class RegisterBankInfo {
OperandsMapper(MachineInstr &MI, const InstructionMapping &InstrMapping,
MachineRegisterInfo &MRI);
/// Getters.
/// \name Getters.
/// @{
/// The MachineInstr being remapped.
MachineInstr &getMI() const { return MI; }
@ -378,15 +378,23 @@ class RegisterBankInfo {
/// Keep dynamically allocated PartialMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>> MapOfPartialMappings;
mutable DenseMap<unsigned, std::unique_ptr<const PartialMapping>>
MapOfPartialMappings;
/// Keep dynamically allocated ValueMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
mutable DenseMap<unsigned, std::unique_ptr<const ValueMapping> > MapOfValueMappings;
mutable DenseMap<unsigned, std::unique_ptr<const ValueMapping>>
MapOfValueMappings;
/// Keep dynamically allocated array of ValueMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>> MapOfOperandsMappings;
mutable DenseMap<unsigned, std::unique_ptr<ValueMapping[]>>
MapOfOperandsMappings;
/// Keep dynamically allocated InstructionMapping in a separate map.
/// This shouldn't be needed when everything gets TableGen'ed.
mutable DenseMap<unsigned, std::unique_ptr<const InstructionMapping>>
MapOfInstructionMappings;
/// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
/// RegisterBank instances.
@ -425,14 +433,14 @@ class RegisterBankInfo {
/// register, a register class, or a register bank.
/// In other words, this method will likely fail to find a mapping for
/// any generic opcode that has not been lowered by target specific code.
InstructionMapping getInstrMappingImpl(const MachineInstr &MI) const;
const InstructionMapping &getInstrMappingImpl(const MachineInstr &MI) const;
/// Get the uniquely generated PartialMapping for the
/// given arguments.
const PartialMapping &getPartialMapping(unsigned StartIdx, unsigned Length,
const RegisterBank &RegBank) const;
/// Methods to get a uniquely generated ValueMapping.
/// \name Methods to get a uniquely generated ValueMapping.
/// @{
/// The most common ValueMapping consists of a single PartialMapping.
@ -445,7 +453,7 @@ class RegisterBankInfo {
unsigned NumBreakDowns) const;
/// @}
/// Methods to get a uniquely generated array of ValueMapping.
/// \name Methods to get a uniquely generated array of ValueMapping.
/// @{
/// Get the uniquely generated array of ValueMapping for the
@ -478,6 +486,33 @@ class RegisterBankInfo {
std::initializer_list<const ValueMapping *> OpdsMapping) const;
/// @}
/// \name Methods to get a uniquely generated InstructionMapping.
/// @{
private:
/// Method to get a uniquely generated InstructionMapping.
const InstructionMapping &
getInstructionMappingImpl(bool IsInvalid, unsigned ID = InvalidMappingID,
unsigned Cost = 0,
const ValueMapping *OperandsMapping = nullptr,
unsigned NumOperands = 0) const;
public:
/// Method to get a uniquely generated InstructionMapping.
const InstructionMapping &
getInstructionMapping(unsigned ID, unsigned Cost,
const ValueMapping *OperandsMapping,
unsigned NumOperands) const {
return getInstructionMappingImpl(/*IsInvalid*/ false, ID, Cost,
OperandsMapping, NumOperands);
}
/// Method to get a uniquely generated invalid InstructionMapping.
const InstructionMapping &getInvalidInstructionMapping() const {
return getInstructionMappingImpl(/*IsInvalid*/ true);
}
/// @}
/// Get the register bank for the \p OpIdx-th operand of \p MI form
/// the encoding constraints, if any.
///
@ -603,7 +638,8 @@ class RegisterBankInfo {
///
/// \note If returnedVal does not verify MI, this would probably mean
/// that the target does not support that instruction.
virtual InstructionMapping getInstrMapping(const MachineInstr &MI) const;
virtual const InstructionMapping &
getInstrMapping(const MachineInstr &MI) const;
/// Get the alternative mappings for \p MI.
/// Alternative in the sense different from getInstrMapping.

View File

@ -17,9 +17,11 @@
namespace llvm {
class MachineBasicBlock;
class MachineFunction;
class Module;
class raw_ostream;
template <typename T> class SmallVectorImpl;
/// Print LLVM IR using the MIR serialization format to the given output stream.
void printMIR(raw_ostream &OS, const Module &M);
@ -28,6 +30,17 @@ void printMIR(raw_ostream &OS, const Module &M);
/// output stream.
void printMIR(raw_ostream &OS, const MachineFunction &MF);
/// Determine a possible list of successors of a basic block based on the
/// basic block machine operand being used inside the block. This should give
/// you the correct list of successor blocks in most cases except for things
/// like jump tables where the basic block references can't easily be found.
/// The MIRPRinter will skip printing successors if they match the result of
/// this funciton and the parser will use this function to construct a list if
/// it is missing.
void guessSuccessors(const MachineBasicBlock &MBB,
SmallVectorImpl<MachineBasicBlock*> &Successors,
bool &IsFallthrough);
} // end namespace llvm
#endif

View File

@ -520,6 +520,14 @@ class MachineFrameInfo {
bool hasTailCall() const { return HasTailCall; }
void setHasTailCall() { HasTailCall = true; }
/// Computes the maximum size of a callframe and the AdjustsStack property.
/// This only works for targets defining
/// TargetInstrInfo::getCallFrameSetupOpcode(), getCallFrameDestroyOpcode(),
/// and getFrameSize().
/// This is usually computed by the prologue epilogue inserter but some
/// targets may call this to compute it earlier.
void computeMaxCallFrameSize(const MachineFunction &MF);
/// Return the maximum size of a call frame that must be
/// allocated for an outgoing function call. This is only available if
/// CallFrameSetup/Destroy pseudo instructions are used by the target, and

View File

@ -116,7 +116,7 @@ class MachineModuleInfo : public ImmutablePass {
// TODO: Ideally, what we'd like is to have a switch that allows emitting
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
// even under this switch, we'd like .debug_frame to be precise when using.
// even under this switch, we'd like .debug_frame to be precise when using
// -g. At this moment, there's no way to specify that some CFI directives
// go into .eh_frame only, while others go into .debug_frame only.

View File

@ -21,7 +21,7 @@ namespace llvm {
namespace codeview {
class TypeDatabase {
public:
TypeDatabase() : TypeNameStorage(Allocator) {}
explicit TypeDatabase(uint32_t ExpectedSize);
/// Gets the type index for the next type record.
TypeIndex getNextTypeIndex() const;

View File

@ -310,6 +310,11 @@ class DWARFContextInMemory : public DWARFContext {
StringRef *MapSectionToMember(StringRef Name);
/// If Sec is compressed section, decompresses and updates its contents
/// provided by Data. Otherwise leaves it unchanged.
Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
StringRef &Data);
public:
DWARFContextInMemory(const object::ObjectFile &Obj,
const LoadedObjectInfo *L = nullptr);

View File

@ -39,20 +39,18 @@ class DWARFFormValue {
private:
struct ValueType {
ValueType() {
uval = 0;
}
ValueType() { uval = 0; }
union {
uint64_t uval;
int64_t sval;
const char* cstr;
const char *cstr;
};
const uint8_t* data = nullptr;
const uint8_t *data = nullptr;
};
dwarf::Form Form; // Form for this value.
ValueType Value; // Contains all data for the form.
dwarf::Form Form; // Form for this value.
ValueType Value; // Contains all data for the form.
const DWARFUnit *U = nullptr; // Remember the DWARFUnit at extract time.
public:
@ -84,7 +82,7 @@ class DWARFFormValue {
const DWARFUnit *U);
bool isInlinedCStr() const {
return Value.data != nullptr && Value.data == (const uint8_t*)Value.cstr;
return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr;
}
/// getAsFoo functions below return the extracted value as Foo if only
@ -135,45 +133,45 @@ class DWARFFormValue {
uint8_t AddrSize,
llvm::dwarf::DwarfFormat Format);
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
///
/// \param debug_info_data the .debug_info data to use to skip the value.
/// \param offset_ptr a reference to the offset that will be updated.
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param U the DWARFUnit to use when skipping the form in case the form
/// size differs according to data in the DWARFUnit.
/// \returns true on success, false if the form was not skipped.
bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr,
bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
const DWARFUnit *U) const;
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
///
/// \param form the DW_FORM enumeration that indicates the form to skip.
/// \param debug_info_data the .debug_info data to use to skip the value.
/// \param offset_ptr a reference to the offset that will be updated.
/// \param Form the DW_FORM enumeration that indicates the form to skip.
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param U the DWARFUnit to use when skipping the form in case the form
/// size differs according to data in the DWARFUnit.
/// \returns true on success, false if the form was not skipped.
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
uint32_t *offset_ptr, const DWARFUnit *U);
static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr, const DWARFUnit *U);
/// Skip a form in \p debug_info_data at offset specified by \p offset_ptr.
/// Skip a form in \p DebugInfoData at offset specified by \p OffsetPtr.
///
/// Skips the bytes for this form in the debug info and updates the offset.
///
/// \param form the DW_FORM enumeration that indicates the form to skip.
/// \param debug_info_data the .debug_info data to use to skip the value.
/// \param offset_ptr a reference to the offset that will be updated.
/// \param Form the DW_FORM enumeration that indicates the form to skip.
/// \param DebugInfoData the .debug_info data to use to skip the value.
/// \param OffsetPtr a reference to the offset that will be updated.
/// \param Version DWARF version number.
/// \param AddrSize size of an address in bytes.
/// \param Format enum value from llvm::dwarf::DwarfFormat.
/// \returns true on success, false if the form was not skipped.
static bool skipValue(dwarf::Form form, DataExtractor debug_info_data,
uint32_t *offset_ptr, uint16_t Version,
uint8_t AddrSize, llvm::dwarf::DwarfFormat Format);
static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
uint32_t *OffsetPtr, uint16_t Version, uint8_t AddrSize,
llvm::dwarf::DwarfFormat Format);
private:
void dumpString(raw_ostream &OS) const;
@ -181,149 +179,146 @@ class DWARFFormValue {
namespace dwarf {
/// Take an optional DWARFFormValue and try to extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and was a string.
inline Optional<const char*> toString(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsCString();
return None;
}
/// Take an optional DWARFFormValue and try to extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and was a string.
inline Optional<const char *> toString(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsCString();
return None;
}
/// Take an optional DWARFFormValue and extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the string value or Default if the V doesn't have a value or the
/// form value's encoding wasn't a string.
inline const char*
toString(const Optional<DWARFFormValue>& V, const char *Default) {
return toString(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the string value or Default if the V doesn't have a value or the
/// form value's encoding wasn't a string.
inline const char *toString(const Optional<DWARFFormValue> &V,
const char *Default) {
return toString(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract an unsigned constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a unsigned constant form.
inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsUnsignedConstant();
return None;
}
/// Take an optional DWARFFormValue and try to extract an unsigned constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a unsigned constant form.
inline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsUnsignedConstant();
return None;
}
/// Take an optional DWARFFormValue and extract a unsigned constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted unsigned value or Default if the V doesn't have a
/// value or the form value's encoding wasn't an unsigned constant form.
inline uint64_t
toUnsigned(const Optional<DWARFFormValue>& V, uint64_t Default) {
return toUnsigned(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a unsigned constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted unsigned value or Default if the V doesn't have a
/// value or the form value's encoding wasn't an unsigned constant form.
inline uint64_t toUnsigned(const Optional<DWARFFormValue> &V,
uint64_t Default) {
return toUnsigned(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract an reference.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a reference form.
inline Optional<uint64_t> toReference(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsReference();
return None;
}
/// Take an optional DWARFFormValue and try to extract an reference.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a reference form.
inline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsReference();
return None;
}
/// Take an optional DWARFFormValue and extract a reference.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted reference value or Default if the V doesn't have a
/// value or the form value's encoding wasn't a reference form.
inline uint64_t
toReference(const Optional<DWARFFormValue>& V, uint64_t Default) {
return toReference(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a reference.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted reference value or Default if the V doesn't have a
/// value or the form value's encoding wasn't a reference form.
inline uint64_t toReference(const Optional<DWARFFormValue> &V,
uint64_t Default) {
return toReference(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract an signed constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a signed constant form.
inline Optional<int64_t> toSigned(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsSignedConstant();
return None;
}
/// Take an optional DWARFFormValue and try to extract an signed constant.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a signed constant form.
inline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsSignedConstant();
return None;
}
/// Take an optional DWARFFormValue and extract a signed integer.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted signed integer value or Default if the V doesn't
/// have a value or the form value's encoding wasn't a signed integer form.
inline int64_t
toSigned(const Optional<DWARFFormValue>& V, int64_t Default) {
return toSigned(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a signed integer.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted signed integer value or Default if the V doesn't
/// have a value or the form value's encoding wasn't a signed integer form.
inline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) {
return toSigned(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract an address.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a address form.
inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsAddress();
return None;
}
/// Take an optional DWARFFormValue and try to extract an address.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a address form.
inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsAddress();
return None;
}
/// Take an optional DWARFFormValue and extract a address.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted address value or Default if the V doesn't have a
/// value or the form value's encoding wasn't an address form.
inline uint64_t
toAddress(const Optional<DWARFFormValue>& V, uint64_t Default) {
return toAddress(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a address.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted address value or Default if the V doesn't have a
/// value or the form value's encoding wasn't an address form.
inline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) {
return toAddress(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract an section offset.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a section offset form.
inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsSectionOffset();
return None;
}
/// Take an optional DWARFFormValue and try to extract an section offset.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a section offset form.
inline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsSectionOffset();
return None;
}
/// Take an optional DWARFFormValue and extract a section offset.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted section offset value or Default if the V doesn't
/// have a value or the form value's encoding wasn't a section offset form.
inline uint64_t
toSectionOffset(const Optional<DWARFFormValue>& V, uint64_t Default) {
return toSectionOffset(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and extract a section offset.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \param Default the default value to return in case of failure.
/// \returns the extracted section offset value or Default if the V doesn't
/// have a value or the form value's encoding wasn't a section offset form.
inline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V,
uint64_t Default) {
return toSectionOffset(V).getValueOr(Default);
}
/// Take an optional DWARFFormValue and try to extract block data.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a block form.
inline Optional<ArrayRef<uint8_t>>
toBlock(const Optional<DWARFFormValue>& V) {
if (V)
return V->getAsBlock();
return None;
}
/// Take an optional DWARFFormValue and try to extract block data.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
/// \returns an optional value that contains a value if the form value
/// was valid and has a block form.
inline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsBlock();
return None;
}
} // end namespace dwarf

View File

@ -53,14 +53,6 @@ class DbiModuleDescriptor {
const ModuleInfoHeader *Layout = nullptr;
};
struct ModuleInfoEx {
ModuleInfoEx(const DbiModuleDescriptor &Info) : Info(Info) {}
ModuleInfoEx(const ModuleInfoEx &Ex) = default;
DbiModuleDescriptor Info;
std::vector<StringRef> SourceFiles;
};
} // end namespace pdb
template <> struct VarStreamArrayExtractor<pdb::DbiModuleDescriptor> {

View File

@ -0,0 +1,114 @@
//===- DbiModuleList.h - PDB module information list ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H
#define LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>
namespace llvm {
namespace pdb {
class DbiModuleList;
struct FileInfoSubstreamHeader;
class DbiModuleSourceFilesIterator
: public iterator_facade_base<DbiModuleSourceFilesIterator,
std::random_access_iterator_tag, StringRef> {
typedef iterator_facade_base<DbiModuleSourceFilesIterator,
std::random_access_iterator_tag, StringRef>
BaseType;
public:
DbiModuleSourceFilesIterator(const DbiModuleList &Modules, uint32_t Modi,
uint16_t Filei);
DbiModuleSourceFilesIterator() = default;
DbiModuleSourceFilesIterator &
operator=(const DbiModuleSourceFilesIterator &R) = default;
bool operator==(const DbiModuleSourceFilesIterator &R) const;
const StringRef &operator*() const { return ThisValue; }
StringRef &operator*() { return ThisValue; }
bool operator<(const DbiModuleSourceFilesIterator &RHS) const;
std::ptrdiff_t operator-(const DbiModuleSourceFilesIterator &R) const;
DbiModuleSourceFilesIterator &operator+=(std::ptrdiff_t N);
DbiModuleSourceFilesIterator &operator-=(std::ptrdiff_t N);
private:
void setValue();
bool isEnd() const;
bool isCompatible(const DbiModuleSourceFilesIterator &R) const;
bool isUniversalEnd() const;
StringRef ThisValue;
const DbiModuleList *Modules{nullptr};
uint32_t Modi{0};
uint16_t Filei{0};
};
class DbiModuleList {
friend DbiModuleSourceFilesIterator;
public:
Error initialize(BinaryStreamRef ModInfo, BinaryStreamRef FileInfo);
Expected<StringRef> getFileName(uint32_t Index) const;
uint32_t getModuleCount() const;
uint32_t getSourceFileCount() const;
uint16_t getSourceFileCount(uint32_t Modi) const;
iterator_range<DbiModuleSourceFilesIterator>
source_files(uint32_t Modi) const;
DbiModuleDescriptor getModuleDescriptor(uint32_t Modi) const;
private:
Error initializeModInfo(BinaryStreamRef ModInfo);
Error initializeFileInfo(BinaryStreamRef FileInfo);
VarStreamArray<DbiModuleDescriptor> Descriptors;
FixedStreamArray<support::little32_t> FileNameOffsets;
FixedStreamArray<support::ulittle16_t> ModFileCountArray;
// For each module, there are multiple filenames, which can be obtained by
// knowing the index of the file. Given the index of the file, one can use
// that as an offset into the FileNameOffsets array, which contains the
// absolute offset of the file name in NamesBuffer. Thus, for each module
// we store the first index in the FileNameOffsets array for this module.
// The number of files for the corresponding module is stored in
// ModFileCountArray.
std::vector<uint32_t> ModuleInitialFileIndex;
// In order to provide random access into the Descriptors array, we iterate it
// once up front to find the offsets of the individual items and store them in
// this array.
std::vector<uint32_t> ModuleDescriptorOffsets;
const FileInfoSubstreamHeader *FileInfoHeader = nullptr;
BinaryStreamRef ModInfoSubstream;
BinaryStreamRef FileInfoSubstream;
BinaryStreamRef NamesBuffer;
};
}
}
#endif // LLVM_DEBUGINFO_PDB_RAW_DBIMODULELIST_H

View File

@ -13,6 +13,7 @@
#include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleList.h"
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
@ -68,9 +69,7 @@ class DbiStream {
/// not present, returns InvalidStreamIndex.
uint32_t getDebugStreamIndex(DbgHeaderType Type) const;
ArrayRef<ModuleInfoEx> modules() const;
Expected<StringRef> getFileNameForIndex(uint32_t Index) const;
const DbiModuleList &modules() const;
FixedStreamArray<object::coff_section> getSectionHeaders();
@ -80,27 +79,22 @@ class DbiStream {
void visitSectionContributions(ISectionContribVisitor &Visitor) const;
private:
Error initializeModInfoArray();
Error initializeSectionContributionData();
Error initializeSectionHeadersData();
Error initializeSectionMapData();
Error initializeFileInfo();
Error initializeFpoRecords();
PDBFile &Pdb;
std::unique_ptr<msf::MappedBlockStream> Stream;
std::vector<ModuleInfoEx> ModuleInfos;
PDBStringTable ECNames;
BinaryStreamRef ModInfoSubstream;
BinaryStreamRef SecContrSubstream;
BinaryStreamRef SecMapSubstream;
BinaryStreamRef FileInfoSubstream;
BinaryStreamRef TypeServerMapSubstream;
BinaryStreamRef ECSubstream;
BinaryStreamRef NamesBuffer;
DbiModuleList Modules;
FixedStreamArray<support::ulittle16_t> DbgStreams;
@ -108,7 +102,6 @@ class DbiStream {
FixedStreamArray<SectionContrib> SectionContribs;
FixedStreamArray<SectionContrib2> SectionContribs2;
FixedStreamArray<SecMapEntry> SectionMap;
FixedStreamArray<support::little32_t> FileNameOffsets;
std::unique_ptr<msf::MappedBlockStream> SectionHeaderStream;
FixedStreamArray<object::coff_section> SectionHeaders;

View File

@ -18,7 +18,7 @@ namespace pdb {
class NativeCompilandSymbol : public NativeRawSymbol {
public:
NativeCompilandSymbol(NativeSession &Session, const ModuleInfoEx &MI);
NativeCompilandSymbol(NativeSession &Session, DbiModuleDescriptor MI);
PDB_SymType getSymTag() const override;
bool isEditAndContinueEnabled() const override;
uint32_t getLexicalParentId() const override;
@ -26,7 +26,7 @@ class NativeCompilandSymbol : public NativeRawSymbol {
std::string getName() const override;
private:
ModuleInfoEx Module;
DbiModuleDescriptor Module;
};
} // namespace pdb

View File

@ -16,13 +16,13 @@
namespace llvm {
namespace pdb {
class DbiModuleList;
class NativeSession;
class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> {
public:
explicit NativeEnumModules(NativeSession &Session,
ArrayRef<ModuleInfoEx> Modules,
uint32_t Index = 0);
NativeEnumModules(NativeSession &Session, const DbiModuleList &Modules,
uint32_t Index = 0);
uint32_t getChildCount() const override;
std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
@ -32,7 +32,7 @@ class NativeEnumModules : public IPDBEnumChildren<PDBSymbol> {
private:
NativeSession &Session;
ArrayRef<ModuleInfoEx> Modules;
const DbiModuleList &Modules;
uint32_t Index;
};
}

View File

@ -211,7 +211,7 @@ struct ModInfoFlags {
};
/// The header preceeding each entry in the Module Info substream of the DBI
/// stream.
/// stream. Corresponds to the type MODI in the reference implementation.
struct ModuleInfoHeader {
/// Currently opened module. This field is a pointer in the reference
/// implementation, but that won't work on 64-bit systems, and anyway it
@ -243,9 +243,12 @@ struct ModuleInfoHeader {
/// Padding so the next field is 4-byte aligned.
char Padding1[2];
/// Array of [0..NumFiles) DBI name buffer offsets. This field is a pointer
/// in the reference implementation, but as with `Mod`, we ignore it for now
/// since it is unused.
/// Array of [0..NumFiles) DBI name buffer offsets. In the reference
/// implementation this field is a pointer. But since you can't portably
/// serialize a pointer, on 64-bit platforms they copy all the values except
/// this one into the 32-bit version of the struct and use that for
/// serialization. Regardless, this field is unused, it is only there to
/// store a pointer that can be accessed at runtime.
support::ulittle32_t FileNameOffs;
/// Name Index for src file name

View File

@ -40,12 +40,12 @@ class TpiStream {
uint32_t TypeIndexBegin() const;
uint32_t TypeIndexEnd() const;
uint32_t NumTypeRecords() const;
uint32_t getNumTypeRecords() const;
uint16_t getTypeHashStreamIndex() const;
uint16_t getTypeHashStreamAuxIndex() const;
uint32_t getHashKeySize() const;
uint32_t NumHashBuckets() const;
uint32_t getNumHashBuckets() const;
FixedStreamArray<support::ulittle32_t> getHashValues() const;
FixedStreamArray<TypeIndexOffset> getTypeIndexOffsets() const;
HashTable &getHashAdjusters();
@ -55,8 +55,6 @@ class TpiStream {
Error commit();
private:
Error verifyHashValues();
const PDBFile &Pdb;
std::unique_ptr<msf::MappedBlockStream> Stream;

View File

@ -10,6 +10,8 @@
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLDCHECKER_H
#include "llvm/ADT/Optional.h"
#include <cstdint>
#include <memory>
#include <string>
@ -97,6 +99,10 @@ class RuntimeDyldChecker {
StringRef SectionName,
bool LocalAddress);
/// \brief If there is a section at the given local address, return its load
/// address, otherwise return none.
Optional<uint64_t> getSectionLoadAddress(void *LocalAddress) const;
private:
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
};

View File

@ -244,7 +244,8 @@ class AttributeSet {
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp = false) const;
typedef const Attribute *iterator;
using iterator = const Attribute *;
iterator begin() const;
iterator end() const;
};
@ -479,7 +480,7 @@ class AttributeList {
/// \brief Return the attributes at the index as a string.
std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
typedef ArrayRef<Attribute>::iterator iterator;
using iterator = ArrayRef<Attribute>::iterator;
iterator begin(unsigned Slot) const;
iterator end(unsigned Slot) const;
@ -662,11 +663,11 @@ class AttrBuilder {
bool empty() const { return Attrs.none(); }
// Iterators for target-dependent attributes.
typedef std::pair<std::string, std::string> td_type;
typedef std::map<std::string, std::string>::iterator td_iterator;
typedef std::map<std::string, std::string>::const_iterator td_const_iterator;
typedef iterator_range<td_iterator> td_range;
typedef iterator_range<td_const_iterator> td_const_range;
using td_type = std::pair<std::string, std::string>;
using td_iterator = std::map<std::string, std::string>::iterator;
using td_const_iterator = std::map<std::string, std::string>::const_iterator;
using td_range = iterator_range<td_iterator>;
using td_const_range = iterator_range<td_const_iterator>;
td_iterator td_begin() { return TargetDepAttrs.begin(); }
td_iterator td_end() { return TargetDepAttrs.end(); }

View File

@ -21,6 +21,7 @@
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Compiler.h"
#include "llvm-c/Types.h"
#include <cassert>
#include <cstddef>
@ -31,7 +32,9 @@ class CallInst;
class Function;
class LandingPadInst;
class LLVMContext;
class Module;
class TerminatorInst;
class ValueSymbolTable;
/// \brief LLVM Basic Block Representation
///
@ -51,7 +54,7 @@ class TerminatorInst;
class BasicBlock : public Value, // Basic blocks are data objects also
public ilist_node_with_parent<BasicBlock, Function> {
public:
typedef SymbolTableList<Instruction> InstListType;
using InstListType = SymbolTableList<Instruction>;
private:
friend class BlockAddress;
@ -80,10 +83,10 @@ class BasicBlock : public Value, // Basic blocks are data objects also
LLVMContext &getContext() const;
/// Instruction iterators...
typedef InstListType::iterator iterator;
typedef InstListType::const_iterator const_iterator;
typedef InstListType::reverse_iterator reverse_iterator;
typedef InstListType::const_reverse_iterator const_reverse_iterator;
using iterator = InstListType::iterator;
using const_iterator = InstListType::const_iterator;
using reverse_iterator = InstListType::reverse_iterator;
using const_reverse_iterator = InstListType::const_reverse_iterator;
/// \brief Creates a new BasicBlock.
///

View File

@ -37,9 +37,9 @@ namespace llvm {
template <class Ptr, class USE_iterator> // Predecessor Iterator
class PredIterator : public std::iterator<std::forward_iterator_tag,
Ptr, ptrdiff_t, Ptr*, Ptr*> {
typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*,
Ptr*> super;
typedef PredIterator<Ptr, USE_iterator> Self;
using super =
std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, Ptr*>;
using Self = PredIterator<Ptr, USE_iterator>;
USE_iterator It;
inline void advancePastNonTerminators() {
@ -49,8 +49,8 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
}
public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
using pointer = typename super::pointer;
using reference = typename super::reference;
PredIterator() = default;
explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
@ -90,11 +90,11 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
}
};
typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator;
typedef PredIterator<const BasicBlock,
Value::const_user_iterator> const_pred_iterator;
typedef iterator_range<pred_iterator> pred_range;
typedef iterator_range<const_pred_iterator> pred_const_range;
using pred_iterator = PredIterator<BasicBlock, Value::user_iterator>;
using const_pred_iterator =
PredIterator<const BasicBlock, Value::const_user_iterator>;
using pred_range = iterator_range<pred_iterator>;
using pred_const_range = iterator_range<const_pred_iterator>;
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
@ -118,12 +118,12 @@ inline pred_const_range predecessors(const BasicBlock *BB) {
// BasicBlock succ_iterator helpers
//===----------------------------------------------------------------------===//
typedef TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>
succ_iterator;
typedef TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>
succ_const_iterator;
typedef iterator_range<succ_iterator> succ_range;
typedef iterator_range<succ_const_iterator> succ_const_range;
using succ_iterator =
TerminatorInst::SuccIterator<TerminatorInst *, BasicBlock>;
using succ_const_iterator =
TerminatorInst::SuccIterator<const TerminatorInst *, const BasicBlock>;
using succ_range = iterator_range<succ_iterator>;
using succ_const_range = iterator_range<succ_const_iterator>;
inline succ_iterator succ_begin(BasicBlock *BB) {
return succ_iterator(BB->getTerminator());
@ -160,8 +160,8 @@ struct isPodLike<TerminatorInst::SuccIterator<T, U>> {
// graph of basic blocks...
template <> struct GraphTraits<BasicBlock*> {
typedef BasicBlock *NodeRef;
typedef succ_iterator ChildIteratorType;
using NodeRef = BasicBlock *;
using ChildIteratorType = succ_iterator;
static NodeRef getEntryNode(BasicBlock *BB) { return BB; }
static ChildIteratorType child_begin(NodeRef N) { return succ_begin(N); }
@ -169,8 +169,8 @@ template <> struct GraphTraits<BasicBlock*> {
};
template <> struct GraphTraits<const BasicBlock*> {
typedef const BasicBlock *NodeRef;
typedef succ_const_iterator ChildIteratorType;
using NodeRef = const BasicBlock *;
using ChildIteratorType = succ_const_iterator;
static NodeRef getEntryNode(const BasicBlock *BB) { return BB; }
@ -184,16 +184,18 @@ template <> struct GraphTraits<const BasicBlock*> {
// instead of the successor edges.
//
template <> struct GraphTraits<Inverse<BasicBlock*>> {
typedef BasicBlock *NodeRef;
typedef pred_iterator ChildIteratorType;
using NodeRef = BasicBlock *;
using ChildIteratorType = pred_iterator;
static NodeRef getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
};
template <> struct GraphTraits<Inverse<const BasicBlock*>> {
typedef const BasicBlock *NodeRef;
typedef const_pred_iterator ChildIteratorType;
using NodeRef = const BasicBlock *;
using ChildIteratorType = const_pred_iterator;
static NodeRef getEntryNode(Inverse<const BasicBlock *> G) { return G.Graph; }
static ChildIteratorType child_begin(NodeRef N) { return pred_begin(N); }
static ChildIteratorType child_end(NodeRef N) { return pred_end(N); }
@ -211,7 +213,7 @@ template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
static NodeRef getEntryNode(Function *F) { return &F->getEntryBlock(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef pointer_iterator<Function::iterator> nodes_iterator;
using nodes_iterator = pointer_iterator<Function::iterator>;
static nodes_iterator nodes_begin(Function *F) {
return nodes_iterator(F->begin());
@ -228,7 +230,7 @@ template <> struct GraphTraits<const Function*> :
static NodeRef getEntryNode(const Function *F) { return &F->getEntryBlock(); }
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef pointer_iterator<Function::const_iterator> nodes_iterator;
using nodes_iterator = pointer_iterator<Function::const_iterator>;
static nodes_iterator nodes_begin(const Function *F) {
return nodes_iterator(F->begin());

View File

@ -207,7 +207,7 @@ class CallSiteBase {
/// The type of iterator to use when looping over actual arguments at this
/// call site.
typedef IterTy arg_iterator;
using arg_iterator = IterTy;
iterator_range<IterTy> args() const {
return make_range(arg_begin(), arg_end());
@ -231,7 +231,7 @@ class CallSiteBase {
/// Type of iterator to use when looping over data operands at this call site
/// (see below).
typedef IterTy data_operand_iterator;
using data_operand_iterator = IterTy;
/// data_operands_begin/data_operands_end - Return iterators iterating over
/// the call / invoke argument list and bundle operands. For invokes, this is

View File

@ -1,4 +1,4 @@
//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- C++ -*-===//
//===- llvm/CallingConv.h - LLVM Calling Conventions ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -20,8 +20,9 @@ namespace llvm {
/// the well-known calling conventions.
///
namespace CallingConv {
/// LLVM IR allows to use arbitrary numbers as calling convention identifiers.
typedef unsigned ID;
using ID = unsigned;
/// A set of enums which specify the assigned numeric values for known llvm
/// calling conventions.
@ -203,8 +204,9 @@ namespace CallingConv {
/// The highest possible calling convention ID. Must be some 2^k - 1.
MaxID = 1023
};
} // End CallingConv namespace
} // End llvm namespace
} // end namespace CallingConv
#endif
} // end namespace llvm
#endif // LLVM_IR_CALLINGCONV_H

View File

@ -41,7 +41,7 @@ namespace llvm {
class MDNode;
/// This class represents a range of values.
class ConstantRange {
class LLVM_NODISCARD ConstantRange {
APInt Lower, Upper;
public:
@ -167,7 +167,10 @@ class ConstantRange {
APInt getSetSize() const;
/// Compare set size of this range with the range CR.
bool isSizeStrictlySmallerThanOf(const ConstantRange &CR) const;
bool isSizeStrictlySmallerThan(const ConstantRange &CR) const;
// Compare set size of this range with Value.
bool isSizeLargerThan(uint64_t MaxSize) const;
/// Return the largest unsigned value contained in the ConstantRange.
APInt getUnsignedMax() const;

View File

@ -1,4 +1,4 @@
//===--------- llvm/DataLayout.h - Data size & alignment info ---*- C++ -*-===//
//===- llvm/DataLayout.h - Data size & alignment info -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -20,27 +20,32 @@
#ifndef LLVM_IR_DATALAYOUT_H
#define LLVM_IR_DATALAYOUT_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cstdint>
#include <string>
// This needs to be outside of the namespace, to avoid conflict with llvm-c
// decl.
typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
using LLVMTargetDataRef = struct LLVMOpaqueTargetData *;
namespace llvm {
class Value;
class StructType;
class StructLayout;
class Triple;
class GlobalVariable;
class LLVMContext;
template<typename T>
class ArrayRef;
class Module;
class StructLayout;
class Triple;
class Value;
/// Enum used to categorize the alignment types stored by LayoutAlignElem
enum AlignTypeEnum {
@ -72,6 +77,7 @@ struct LayoutAlignElem {
static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
bool operator==(const LayoutAlignElem &rhs) const;
};
@ -90,6 +96,7 @@ struct PointerAlignElem {
/// Initializer
static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
unsigned PrefAlign, uint32_t TypeByteWidth);
bool operator==(const PointerAlignElem &rhs) const;
};
@ -121,7 +128,7 @@ class DataLayout {
/// \brief Primitive type alignment data. This is sorted by type and bit
/// width during construction.
typedef SmallVector<LayoutAlignElem, 16> AlignmentsTy;
using AlignmentsTy = SmallVector<LayoutAlignElem, 16>;
AlignmentsTy Alignments;
AlignmentsTy::const_iterator
@ -136,7 +143,7 @@ class DataLayout {
/// \brief The string representation used to create this DataLayout
std::string StringRepresentation;
typedef SmallVector<PointerAlignElem, 8> PointersTy;
using PointersTy = SmallVector<PointerAlignElem, 8>;
PointersTy Pointers;
PointersTy::const_iterator
@ -147,7 +154,7 @@ class DataLayout {
PointersTy::iterator findPointerLowerBound(uint32_t AddressSpace);
// The StructType -> StructLayout map.
mutable void *LayoutMap;
mutable void *LayoutMap = nullptr;
/// Pointers in these address spaces are non-integral, and don't have a
/// well-defined bitwise representation.
@ -172,16 +179,16 @@ class DataLayout {
public:
/// Constructs a DataLayout from a specification string. See reset().
explicit DataLayout(StringRef LayoutDescription) : LayoutMap(nullptr) {
explicit DataLayout(StringRef LayoutDescription) {
reset(LayoutDescription);
}
/// Initialize target data from properties stored in the module.
explicit DataLayout(const Module *M);
void init(const Module *M);
DataLayout(const DataLayout &DL) { *this = DL; }
DataLayout(const DataLayout &DL) : LayoutMap(nullptr) { *this = DL; }
~DataLayout(); // Not virtual, do not subclass this class
DataLayout &operator=(const DataLayout &DL) {
clear();
@ -200,7 +207,7 @@ class DataLayout {
bool operator==(const DataLayout &Other) const;
bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
~DataLayout(); // Not virtual, do not subclass this class
void init(const Module *M);
/// Parse a data layout string (with fallback to default values).
void reset(StringRef LayoutDescription);
@ -489,6 +496,7 @@ class StructLayout {
unsigned IsPadded : 1;
unsigned NumElements : 31;
uint64_t MemberOffsets[1]; // variable sized array!
public:
uint64_t getSizeInBytes() const { return StructSize; }
@ -515,6 +523,7 @@ class StructLayout {
private:
friend class DataLayout; // Only DataLayout can create this class
StructLayout(StructType *ST, const DataLayout &DL);
};
@ -560,6 +569,6 @@ inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
}
}
} // End llvm namespace
} // end namespace llvm
#endif
#endif // LLVM_IR_DATALAYOUT_H

View File

@ -21,17 +21,12 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include <iterator>
namespace llvm {
class Module;
class DbgDeclareInst;
class DbgValueInst;
template <typename K, typename V, typename KeyInfoT, typename BucketT>
class DenseMap;
class Module;
/// \brief Find subprogram that is enclosing this scope.
DISubprogram *getDISubprogram(const MDNode *Scope);
@ -95,13 +90,13 @@ class DebugInfoFinder {
bool addScope(DIScope *Scope);
public:
typedef SmallVectorImpl<DICompileUnit *>::const_iterator
compile_unit_iterator;
typedef SmallVectorImpl<DISubprogram *>::const_iterator subprogram_iterator;
typedef SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator
global_variable_expression_iterator;
typedef SmallVectorImpl<DIType *>::const_iterator type_iterator;
typedef SmallVectorImpl<DIScope *>::const_iterator scope_iterator;
using compile_unit_iterator =
SmallVectorImpl<DICompileUnit *>::const_iterator;
using subprogram_iterator = SmallVectorImpl<DISubprogram *>::const_iterator;
using global_variable_expression_iterator =
SmallVectorImpl<DIGlobalVariableExpression *>::const_iterator;
using type_iterator = SmallVectorImpl<DIType *>::const_iterator;
using scope_iterator = SmallVectorImpl<DIScope *>::const_iterator;
iterator_range<compile_unit_iterator> compile_units() const {
return make_range(CUs.begin(), CUs.end());
@ -140,4 +135,4 @@ class DebugInfoFinder {
} // end namespace llvm
#endif
#endif // LLVM_IR_DEBUGINFO_H

View File

@ -42,7 +42,7 @@ extern template void Calculate<Function, Inverse<BasicBlock *>>(
DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT,
Function &F);
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;
using DomTreeNode = DomTreeNodeBase<BasicBlock>;
class BasicBlockEdge {
const BasicBlock *Start;
@ -70,7 +70,7 @@ class BasicBlockEdge {
};
template <> struct DenseMapInfo<BasicBlockEdge> {
typedef DenseMapInfo<const BasicBlock *> BBInfo;
using BBInfo = DenseMapInfo<const BasicBlock *>;
static unsigned getHashValue(const BasicBlockEdge *V);
@ -113,7 +113,7 @@ template <> struct DenseMapInfo<BasicBlockEdge> {
/// preceding statements; this is stated only to assist human understanding.
class DominatorTree : public DominatorTreeBase<BasicBlock> {
public:
typedef DominatorTreeBase<BasicBlock> Base;
using Base = DominatorTreeBase<BasicBlock>;
DominatorTree() : DominatorTreeBase<BasicBlock>(false) {}
explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) {
@ -168,9 +168,9 @@ class DominatorTree : public DominatorTreeBase<BasicBlock> {
// iterable by generic graph iterators.
template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase {
typedef Node *NodeRef;
typedef ChildIterator ChildIteratorType;
typedef df_iterator<Node *, df_iterator_default_set<Node*>> nodes_iterator;
using NodeRef = Node *;
using ChildIteratorType = ChildIterator;
using nodes_iterator = df_iterator<Node *, df_iterator_default_set<Node*>>;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
@ -212,7 +212,7 @@ class DominatorTreeAnalysis : public AnalysisInfoMixin<DominatorTreeAnalysis> {
public:
/// \brief Provide the result typedef for this analysis pass.
typedef DominatorTree Result;
using Result = DominatorTree;
/// \brief Run the analysis pass over a function and produce a dominator tree.
DominatorTree run(Function &F, FunctionAnalysisManager &);

View File

@ -466,7 +466,6 @@ class Function : public GlobalObject, public ilist_node<Function> {
/// @brief Determine if the parameter or return value is marked with NoAlias
/// attribute.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool returnDoesNotAlias() const {
return AttributeSets.hasAttribute(AttributeList::ReturnIndex,
Attribute::NoAlias);

View File

@ -95,7 +95,7 @@ class InlineAsm : public Value {
isClobber // '~x'
};
typedef std::vector<std::string> ConstraintCodeVector;
using ConstraintCodeVector = std::vector<std::string>;
struct SubConstraintInfo {
/// MatchingInput - If this is not -1, this is an output constraint where an
@ -112,9 +112,9 @@ class InlineAsm : public Value {
SubConstraintInfo() = default;
};
typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
using SubConstraintInfoVector = std::vector<SubConstraintInfo>;
struct ConstraintInfo;
typedef std::vector<ConstraintInfo> ConstraintInfoVector;
using ConstraintInfoVector = std::vector<ConstraintInfo>;
struct ConstraintInfo {
/// Type - The basic type of the constraint: input/output/clobber

View File

@ -31,20 +31,20 @@ namespace llvm {
// inst_iterator and const_inst_iterator's.
//
template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
typedef BB_t BBty;
typedef BB_i_t BBIty;
typedef BI_t BIty;
typedef II_t IIty;
using BBty = BB_t;
using BBIty = BB_i_t;
using BIty = BI_t;
using IIty = II_t;
BB_t *BBs; // BasicBlocksType
BB_i_t BB; // BasicBlocksType::iterator
BI_t BI; // BasicBlock::iterator
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef IIty value_type;
typedef signed difference_type;
typedef IIty* pointer;
typedef IIty& reference;
using iterator_category = std::bidirectional_iterator_tag;
using value_type = IIty;
using difference_type = signed;
using pointer = IIty *;
using reference = IIty &;
// Default constructor
InstIterator() = default;
@ -119,13 +119,15 @@ template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
}
};
typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
BasicBlock::iterator, Instruction> inst_iterator;
typedef InstIterator<const SymbolTableList<BasicBlock>,
Function::const_iterator, BasicBlock::const_iterator,
const Instruction> const_inst_iterator;
typedef iterator_range<inst_iterator> inst_range;
typedef iterator_range<const_inst_iterator> const_inst_range;
using inst_iterator =
InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
BasicBlock::iterator, Instruction>;
using const_inst_iterator =
InstIterator<const SymbolTableList<BasicBlock>,
Function::const_iterator, BasicBlock::const_iterator,
const Instruction>;
using inst_range = iterator_range<inst_iterator>;
using const_inst_range = iterator_range<const_inst_iterator>;
inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }

View File

@ -1,4 +1,4 @@
//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- C++ -*-===//
//===- llvm/InstrTypes.h - Important Instruction subclasses -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -29,7 +29,9 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@ -114,17 +116,17 @@ class TerminatorInst : public Instruction {
template <class Term, class BB> // Successor Iterator
class SuccIterator : public std::iterator<std::random_access_iterator_tag, BB,
int, BB *, BB *> {
typedef std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>
super;
using super =
std::iterator<std::random_access_iterator_tag, BB, int, BB *, BB *>;
public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
using pointer = typename super::pointer;
using reference = typename super::reference;
private:
Term TermInst;
unsigned idx;
typedef SuccIterator<Term, BB> Self;
using Self = SuccIterator<Term, BB>;
inline bool index_is_valid(unsigned idx) {
return idx < TermInst->getNumSuccessors();
@ -260,11 +262,11 @@ class TerminatorInst : public Instruction {
}
};
typedef SuccIterator<TerminatorInst *, BasicBlock> succ_iterator;
typedef SuccIterator<const TerminatorInst *, const BasicBlock>
succ_const_iterator;
typedef iterator_range<succ_iterator> succ_range;
typedef iterator_range<succ_const_iterator> succ_const_range;
using succ_iterator = SuccIterator<TerminatorInst *, BasicBlock>;
using succ_const_iterator =
SuccIterator<const TerminatorInst *, const BasicBlock>;
using succ_range = iterator_range<succ_iterator>;
using succ_const_range = iterator_range<succ_const_iterator>;
private:
inline succ_iterator succ_begin() { return succ_iterator(this); }
@ -341,14 +343,16 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
class BinaryOperator : public Instruction {
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, Instruction *InsertBefore);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty,
const Twine &Name, BasicBlock *InsertAtEnd);
void init(BinaryOps iType);
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
BinaryOperator *cloneImpl() const;
public:
@ -1125,8 +1129,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
//===----------------------------------------------------------------------===//
class FuncletPadInst : public Instruction {
private:
void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
FuncletPadInst(const FuncletPadInst &CPI);
explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
@ -1136,11 +1138,14 @@ class FuncletPadInst : public Instruction {
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
friend class CatchPadInst;
friend class CleanupPadInst;
FuncletPadInst *cloneImpl() const;
public:
@ -1261,7 +1266,8 @@ template <typename InputTy> class OperandBundleDefT {
ArrayRef<InputTy> inputs() const { return Inputs; }
typedef typename std::vector<InputTy>::const_iterator input_iterator;
using input_iterator = typename std::vector<InputTy>::const_iterator;
size_t input_size() const { return Inputs.size(); }
input_iterator input_begin() const { return Inputs.begin(); }
input_iterator input_end() const { return Inputs.end(); }
@ -1269,8 +1275,8 @@ template <typename InputTy> class OperandBundleDefT {
StringRef getTag() const { return Tag; }
};
typedef OperandBundleDefT<Value *> OperandBundleDef;
typedef OperandBundleDefT<const Value *> ConstOperandBundleDef;
using OperandBundleDef = OperandBundleDefT<Value *>;
using ConstOperandBundleDef = OperandBundleDefT<const Value *>;
/// \brief A mixin to add operand bundle functionality to llvm instruction
/// classes.
@ -1553,8 +1559,8 @@ template <typename InstrTy, typename OpIteratorTy> class OperandBundleUser {
return OperandBundleUse(BOI.Tag, Inputs);
}
typedef BundleOpInfo *bundle_op_iterator;
typedef const BundleOpInfo *const_bundle_op_iterator;
using bundle_op_iterator = BundleOpInfo *;
using const_bundle_op_iterator = const BundleOpInfo *;
/// \brief Return the start of the list of BundleOpInfo instances associated
/// with this OperandBundleUser.
@ -1654,6 +1660,6 @@ template <typename InstrTy, typename OpIteratorTy> class OperandBundleUser {
}
};
} // end llvm namespace
} // end namespace llvm
#endif // LLVM_IR_INSTRTYPES_H

View File

@ -795,6 +795,14 @@ def int_type_checked_load : Intrinsic<[llvm_ptr_ty, llvm_i1_ty],
def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
[IntrReadMem, IntrArgMemOnly]>;
// Xray intrinsics
//===----------------------------------------------------------------------===//
// Custom event logging for x-ray.
// Takes a pointer to a string and the length of the string.
def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
[NoCapture<0>, ReadOnly<0>, IntrWriteMem]>;
//===----------------------------------------------------------------------===//
//===------ Memory intrinsics with element-wise atomicity guarantees ------===//
//

View File

@ -22,12 +22,26 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
// and return value are essentially chains, used to force ordering during ISel.
def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// 16-bit multiplications
def int_arm_smulbb : GCCBuiltin<"__builtin_arm_smulbb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smulbt : GCCBuiltin<"__builtin_arm_smulbt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smultb : GCCBuiltin<"__builtin_arm_smultb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smultt : GCCBuiltin<"__builtin_arm_smultt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smulwb : GCCBuiltin<"__builtin_arm_smulwb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smulwt : GCCBuiltin<"__builtin_arm_smulwt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// Saturating Arithmetic
def int_arm_qadd : GCCBuiltin<"__builtin_arm_qadd">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, Commutative]>;
[Commutative, IntrNoMem]>;
def int_arm_qsub : GCCBuiltin<"__builtin_arm_qsub">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
@ -35,6 +49,176 @@ def int_arm_ssat : GCCBuiltin<"__builtin_arm_ssat">,
def int_arm_usat : GCCBuiltin<"__builtin_arm_usat">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Accumulating multiplications
def int_arm_smlabb : GCCBuiltin<"__builtin_arm_smlabb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlabt : GCCBuiltin<"__builtin_arm_smlabt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlatb : GCCBuiltin<"__builtin_arm_smlatb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlatt : GCCBuiltin<"__builtin_arm_smlatt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlawb : GCCBuiltin<"__builtin_arm_smlawb">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlawt : GCCBuiltin<"__builtin_arm_smlawt">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
// Parallel 16-bit saturation
def int_arm_ssat16 : GCCBuiltin<"__builtin_arm_ssat16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_usat16 : GCCBuiltin<"__builtin_arm_usat16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Packing and unpacking
def int_arm_sxtab16 : GCCBuiltin<"__builtin_arm_sxtab16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_sxtb16 : GCCBuiltin<"__builtin_arm_sxtb16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_arm_uxtab16 : GCCBuiltin<"__builtin_arm_uxtab16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uxtb16 : GCCBuiltin<"__builtin_arm_uxtb16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
// Parallel selection, reads the GE flags.
def int_arm_sel : GCCBuiltin<"__builtin_arm_sel">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>;
// Parallel 8-bit addition and subtraction
def int_arm_qadd8 : GCCBuiltin<"__builtin_arm_qadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_qsub8 : GCCBuiltin<"__builtin_arm_qsub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_sadd8 : GCCBuiltin<"__builtin_arm_sadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_shadd8 : GCCBuiltin<"__builtin_arm_shadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_shsub8 : GCCBuiltin<"__builtin_arm_shsub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_ssub8 : GCCBuiltin<"__builtin_arm_ssub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_uadd8 : GCCBuiltin<"__builtin_arm_uadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_uhadd8 : GCCBuiltin<"__builtin_arm_uhadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uhsub8 : GCCBuiltin<"__builtin_arm_uhsub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqadd8 : GCCBuiltin<"__builtin_arm_uqadd8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqsub8 : GCCBuiltin<"__builtin_arm_uqsub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_usub8 : GCCBuiltin<"__builtin_arm_usub8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Sum of 8-bit absolute differences
def int_arm_usad8 : GCCBuiltin<"__builtin_arm_usad8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_usada8 : GCCBuiltin<"__builtin_arm_usada8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
// Parallel 16-bit addition and subtraction
def int_arm_qadd16 : GCCBuiltin<"__builtin_arm_qadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_qasx : GCCBuiltin<"__builtin_arm_qasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_qsax : GCCBuiltin<"__builtin_arm_qsax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_qsub16 : GCCBuiltin<"__builtin_arm_qsub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_sadd16 : GCCBuiltin<"__builtin_arm_sadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_sasx : GCCBuiltin<"__builtin_arm_sasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_shadd16 : GCCBuiltin<"__builtin_arm_shadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_shasx : GCCBuiltin<"__builtin_arm_shasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_shsax : GCCBuiltin<"__builtin_arm_shsax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_shsub16 : GCCBuiltin<"__builtin_arm_shsub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_ssax : GCCBuiltin<"__builtin_arm_ssax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_ssub16 : GCCBuiltin<"__builtin_arm_ssub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_uadd16 : GCCBuiltin<"__builtin_arm_uadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_uasx : GCCBuiltin<"__builtin_arm_uasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
def int_arm_uhadd16 : GCCBuiltin<"__builtin_arm_uhadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uhasx : GCCBuiltin<"__builtin_arm_uhasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uhsax : GCCBuiltin<"__builtin_arm_uhsax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uhsub16 : GCCBuiltin<"__builtin_arm_uhsub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqadd16 : GCCBuiltin<"__builtin_arm_uqadd16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqasx : GCCBuiltin<"__builtin_arm_uqasx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqsax : GCCBuiltin<"__builtin_arm_uqsax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_uqsub16 : GCCBuiltin<"__builtin_arm_uqsub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
// Writes to the GE bits.
def int_arm_usax : GCCBuiltin<"__builtin_arm_usax">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Writes to the GE bits.
def int_arm_usub16 : GCCBuiltin<"__builtin_arm_usub16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], []>;
// Parallel 16-bit multiplication
def int_arm_smlad : GCCBuiltin<"__builtin_arm_smlad">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smladx : GCCBuiltin<"__builtin_arm_smladx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlald : GCCBuiltin<"__builtin_arm_smlald">,
Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_arm_smlaldx : GCCBuiltin<"__builtin_arm_smlaldx">,
Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_arm_smlsd : GCCBuiltin<"__builtin_arm_smlsd">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlsdx : GCCBuiltin<"__builtin_arm_smlsdx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
def int_arm_smlsld : GCCBuiltin<"__builtin_arm_smlsld">,
Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_arm_smlsldx : GCCBuiltin<"__builtin_arm_smlsldx">,
Intrinsic<[llvm_i64_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i64_ty],
[IntrNoMem]>;
def int_arm_smuad : GCCBuiltin<"__builtin_arm_smuad">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smuadx : GCCBuiltin<"__builtin_arm_smuadx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smusd : GCCBuiltin<"__builtin_arm_smusd">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_arm_smusdx : GCCBuiltin<"__builtin_arm_smusdx">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// Load, Store and Clear exclusive

View File

@ -45,58 +45,54 @@ struct CalleeInfo {
}
};
/// Struct to hold value either by GUID or GlobalValue*. Values in combined
/// indexes as well as indirect calls are GUIDs, all others are GlobalValues.
class GlobalValueSummary;
typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;
struct GlobalValueSummaryInfo {
/// The GlobalValue corresponding to this summary. This is only used in
/// per-module summaries.
const GlobalValue *GV = nullptr;
/// List of global value summary structures for a particular value held
/// in the GlobalValueMap. Requires a vector in the case of multiple
/// COMDAT values of the same name.
GlobalValueSummaryList SummaryList;
};
/// Map from global value GUID to corresponding summary structures. Use a
/// std::map rather than a DenseMap so that pointers to the map's value_type
/// (which are used by ValueInfo) are not invalidated by insertion. Also it will
/// likely incur less overhead, as the value type is not very small and the size
/// of the map is unknown, resulting in inefficiencies due to repeated
/// insertions and resizing.
typedef std::map<GlobalValue::GUID, GlobalValueSummaryInfo>
GlobalValueSummaryMapTy;
/// Struct that holds a reference to a particular GUID in a global value
/// summary.
struct ValueInfo {
/// The value representation used in this instance.
enum ValueInfoKind {
VI_GUID,
VI_Value,
};
const GlobalValueSummaryMapTy::value_type *Ref = nullptr;
ValueInfo() = default;
ValueInfo(const GlobalValueSummaryMapTy::value_type *Ref) : Ref(Ref) {}
operator bool() const { return Ref; }
/// Union of the two possible value types.
union ValueUnion {
GlobalValue::GUID Id;
const GlobalValue *GV;
ValueUnion(GlobalValue::GUID Id) : Id(Id) {}
ValueUnion(const GlobalValue *GV) : GV(GV) {}
};
/// The value being represented.
ValueUnion TheValue;
/// The value representation.
ValueInfoKind Kind;
/// Constructor for a GUID value
ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}
/// Constructor for a GlobalValue* value
ValueInfo(const GlobalValue *V) : TheValue(V), Kind(VI_Value) {}
/// Accessor for GUID value
GlobalValue::GUID getGUID() const {
assert(Kind == VI_GUID && "Not a GUID type");
return TheValue.Id;
GlobalValue::GUID getGUID() const { return Ref->first; }
const GlobalValue *getValue() const { return Ref->second.GV; }
ArrayRef<std::unique_ptr<GlobalValueSummary>> getSummaryList() const {
return Ref->second.SummaryList;
}
/// Accessor for GlobalValue* value
const GlobalValue *getValue() const {
assert(Kind == VI_Value && "Not a Value type");
return TheValue.GV;
}
bool isGUID() const { return Kind == VI_GUID; }
};
template <> struct DenseMapInfo<ValueInfo> {
static inline ValueInfo getEmptyKey() { return ValueInfo((GlobalValue *)-1); }
static inline ValueInfo getEmptyKey() {
return ValueInfo((GlobalValueSummaryMapTy::value_type *)-1);
}
static inline ValueInfo getTombstoneKey() {
return ValueInfo((GlobalValue *)-2);
}
static bool isEqual(ValueInfo L, ValueInfo R) {
if (L.isGUID() != R.isGUID())
return false;
return L.isGUID() ? (L.getGUID() == R.getGUID())
: (L.getValue() == R.getValue());
}
static unsigned getHashValue(ValueInfo I) {
return I.isGUID() ? I.getGUID() : (uintptr_t)I.getValue();
return ValueInfo((GlobalValueSummaryMapTy::value_type *)-2);
}
static bool isEqual(ValueInfo L, ValueInfo R) { return L.Ref == R.Ref; }
static unsigned getHashValue(ValueInfo I) { return (uintptr_t)I.Ref; }
};
/// \brief Function and variable summary information to aid decisions and
@ -483,19 +479,6 @@ struct TypeIdSummary {
/// 160 bits SHA1
typedef std::array<uint32_t, 5> ModuleHash;
/// List of global value summary structures for a particular value held
/// in the GlobalValueMap. Requires a vector in the case of multiple
/// COMDAT values of the same name.
typedef std::vector<std::unique_ptr<GlobalValueSummary>> GlobalValueSummaryList;
/// Map from global value GUID to corresponding summary structures.
/// Use a std::map rather than a DenseMap since it will likely incur
/// less overhead, as the value type is not very small and the size
/// of the map is unknown, resulting in inefficiencies due to repeated
/// insertions and resizing.
typedef std::map<GlobalValue::GUID, GlobalValueSummaryList>
GlobalValueSummaryMapTy;
/// Type used for iterating through the global value summary map.
typedef GlobalValueSummaryMapTy::const_iterator const_gvsummary_iterator;
typedef GlobalValueSummaryMapTy::iterator gvsummary_iterator;
@ -532,6 +515,11 @@ class ModuleSummaryIndex {
// YAML I/O support.
friend yaml::MappingTraits<ModuleSummaryIndex>;
GlobalValueSummaryMapTy::value_type *
getOrInsertValuePtr(GlobalValue::GUID GUID) {
return &*GlobalValueMap.emplace(GUID, GlobalValueSummaryInfo{}).first;
}
public:
gvsummary_iterator begin() { return GlobalValueMap.begin(); }
const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
@ -539,21 +527,22 @@ class ModuleSummaryIndex {
const_gvsummary_iterator end() const { return GlobalValueMap.end(); }
size_t size() const { return GlobalValueMap.size(); }
/// Get the list of global value summary objects for a given value name.
const GlobalValueSummaryList &getGlobalValueSummaryList(StringRef ValueName) {
return GlobalValueMap[GlobalValue::getGUID(ValueName)];
/// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
auto I = GlobalValueMap.find(GUID);
return ValueInfo(I == GlobalValueMap.end() ? nullptr : &*I);
}
/// Get the list of global value summary objects for a given value name.
const const_gvsummary_iterator
findGlobalValueSummaryList(StringRef ValueName) const {
return GlobalValueMap.find(GlobalValue::getGUID(ValueName));
/// Return a ValueInfo for \p GUID.
ValueInfo getOrInsertValueInfo(GlobalValue::GUID GUID) {
return ValueInfo(getOrInsertValuePtr(GUID));
}
/// Get the list of global value summary objects for a given value GUID.
const const_gvsummary_iterator
findGlobalValueSummaryList(GlobalValue::GUID ValueGUID) const {
return GlobalValueMap.find(ValueGUID);
/// Return a ValueInfo for \p GV and mark it as belonging to GV.
ValueInfo getOrInsertValueInfo(const GlobalValue *GV) {
auto VP = getOrInsertValuePtr(GV->getGUID());
VP->second.GV = GV;
return ValueInfo(VP);
}
/// Return the GUID for \p OriginalId in the OidGuidMap.
@ -565,17 +554,18 @@ class ModuleSummaryIndex {
/// Add a global value summary for a value of the given name.
void addGlobalValueSummary(StringRef ValueName,
std::unique_ptr<GlobalValueSummary> Summary) {
addOriginalName(GlobalValue::getGUID(ValueName),
Summary->getOriginalName());
GlobalValueMap[GlobalValue::getGUID(ValueName)].push_back(
std::move(Summary));
addGlobalValueSummary(getOrInsertValueInfo(GlobalValue::getGUID(ValueName)),
std::move(Summary));
}
/// Add a global value summary for a value of the given GUID.
void addGlobalValueSummary(GlobalValue::GUID ValueGUID,
/// Add a global value summary for the given ValueInfo.
void addGlobalValueSummary(ValueInfo VI,
std::unique_ptr<GlobalValueSummary> Summary) {
addOriginalName(ValueGUID, Summary->getOriginalName());
GlobalValueMap[ValueGUID].push_back(std::move(Summary));
addOriginalName(VI.getGUID(), Summary->getOriginalName());
// Here we have a notionally const VI, but the value it points to is owned
// by the non-const *this.
const_cast<GlobalValueSummaryMapTy::value_type *>(VI.Ref)
->second.SummaryList.push_back(std::move(Summary));
}
/// Add an original name for the value of the given GUID.
@ -593,16 +583,16 @@ class ModuleSummaryIndex {
/// not found.
GlobalValueSummary *findSummaryInModule(GlobalValue::GUID ValueGUID,
StringRef ModuleId) const {
auto CalleeInfoList = findGlobalValueSummaryList(ValueGUID);
if (CalleeInfoList == end()) {
auto CalleeInfo = getValueInfo(ValueGUID);
if (!CalleeInfo) {
return nullptr; // This function does not have a summary
}
auto Summary =
llvm::find_if(CalleeInfoList->second,
llvm::find_if(CalleeInfo.getSummaryList(),
[&](const std::unique_ptr<GlobalValueSummary> &Summary) {
return Summary->modulePath() == ModuleId;
});
if (Summary == CalleeInfoList->second.end())
if (Summary == CalleeInfo.getSummaryList().end())
return nullptr;
return Summary->get();
}

View File

@ -201,7 +201,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
for (auto &FSum : FSums) {
GlobalValueSummary::GVFlags GVFlags(GlobalValue::ExternalLinkage, false,
false);
Elem.push_back(llvm::make_unique<FunctionSummary>(
Elem.SummaryList.push_back(llvm::make_unique<FunctionSummary>(
GVFlags, 0, ArrayRef<ValueInfo>{},
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),
std::move(FSum.TypeTestAssumeVCalls),
@ -213,7 +213,7 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
static void output(IO &io, GlobalValueSummaryMapTy &V) {
for (auto &P : V) {
std::vector<FunctionSummaryYaml> FSums;
for (auto &Sum : P.second) {
for (auto &Sum : P.second.SummaryList) {
if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get()))
FSums.push_back(FunctionSummaryYaml{
FSum->type_tests(), FSum->type_test_assume_vcalls(),

View File

@ -63,6 +63,8 @@ class ConstantPool {
// Return true if the constant pool is empty
bool empty();
void clearCache();
};
class AssemblerConstantPools {
@ -86,6 +88,7 @@ class AssemblerConstantPools {
public:
void emitAll(MCStreamer &Streamer);
void emitForCurrentSection(MCStreamer &Streamer);
void clearCacheForCurrentSection(MCStreamer &Streamer);
const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr,
unsigned Size, SMLoc Loc);

View File

@ -20,7 +20,9 @@
#include "llvm/Object/Binary.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
@ -40,6 +42,7 @@ class DelayImportDirectoryEntryRef;
class ExportDirectoryEntryRef;
class ImportDirectoryEntryRef;
class ImportedSymbolRef;
class ResourceSectionRef;
using import_directory_iterator = content_iterator<ImportDirectoryEntryRef>;
using delay_import_directory_iterator =
@ -623,6 +626,26 @@ struct coff_base_reloc_block_entry {
int getOffset() const { return Data & ((1 << 12) - 1); }
};
struct coff_resource_dir_entry {
union {
support::ulittle32_t NameOffset;
support::ulittle32_t ID;
uint32_t getNameOffset() const {
return maskTrailingOnes<uint32_t>(31) & NameOffset;
}
} Identifier;
union {
support::ulittle32_t DataEntryOffset;
support::ulittle32_t SubdirOffset;
bool isSubDir() const { return SubdirOffset >> 31; }
uint32_t value() const {
return maskTrailingOnes<uint32_t>(31) & SubdirOffset;
}
} Offset;
};
struct coff_resource_dir_table {
support::ulittle32_t Characteristics;
support::ulittle32_t TimeDateStamp;
@ -1047,6 +1070,23 @@ class BaseRelocRef {
const COFFObjectFile *OwningObject = nullptr;
};
class ResourceSectionRef {
public:
ResourceSectionRef() = default;
explicit ResourceSectionRef(StringRef Ref) : BBS(Ref, support::little) {}
ErrorOr<ArrayRef<UTF16>> getEntryNameString(const coff_resource_dir_entry &Entry);
ErrorOr<const coff_resource_dir_table &>
getEntrySubDir(const coff_resource_dir_entry &Entry);
ErrorOr<const coff_resource_dir_table &> getBaseTable();
private:
BinaryByteStream BBS;
ErrorOr<const coff_resource_dir_table &> getTableAtOffset(uint32_t Offset);
ErrorOr<ArrayRef<UTF16>> getDirStringAtOffset(uint32_t Offset);
};
// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
struct FpoData {
support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code

View File

@ -41,10 +41,14 @@ class WasmSymbol {
DEBUG_FUNCTION_NAME,
};
WasmSymbol(StringRef Name, SymbolType Type) : Name(Name), Type(Type) {}
WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section,
uint32_t ElementIndex)
: Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {}
StringRef Name;
SymbolType Type;
uint32_t Section;
uint32_t ElementIndex;
};
class WasmSection {

View File

@ -97,6 +97,11 @@ struct DataSegment {
yaml::BinaryRef Content;
};
struct NameEntry {
uint32_t Index;
StringRef Name;
};
struct Signature {
Signature() : Form(wasm::WASM_TYPE_FUNC) {}
@ -122,6 +127,11 @@ struct CustomSection : Section {
StringRef Name;
yaml::BinaryRef Payload;
// The follow is used by the "name" custom section.
// TODO(sbc): Add support for more then just functions names. The wasm
// name section can support multiple sub-sections.
std::vector<NameEntry> FunctionNames;
};
struct TypeSection : Section {
@ -244,6 +254,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Global)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Function)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
namespace llvm {
@ -297,6 +308,10 @@ template <> struct MappingTraits<WasmYAML::Relocation> {
static void mapping(IO &IO, WasmYAML::Relocation &Relocation);
};
template <> struct MappingTraits<WasmYAML::NameEntry> {
static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
};
template <> struct MappingTraits<WasmYAML::LocalDecl> {
static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
};

View File

@ -20,8 +20,7 @@ AARCH64_ARCH("invalid", AK_INVALID, nullptr, nullptr,
ARMBuildAttrs::CPUArch::v8_A, FK_NONE, AArch64::AEK_NONE)
AARCH64_ARCH("armv8-a", AK_ARMV8A, "8-A", "v8", ARMBuildAttrs::CPUArch::v8_A,
FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD))
(AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_SIMD))
AARCH64_ARCH("armv8.1-a", AK_ARMV8_1A, "8.1-A", "v8.1a",
ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
@ -52,38 +51,37 @@ AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras")
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
#endif
AARCH64_CPU_NAME("cortex-a35", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a53", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true,
( AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a57", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a72", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a73", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cyclone", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRYPTO))
(AArch64::AEK_NONE))
AARCH64_CPU_NAME("exynos-m1", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("exynos-m2", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("exynos-m3", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("falkor", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("kryo", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO))
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("thunderx2t99", AK_ARMV8_1A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_LSE | AArch64::AEK_CRC |
AArch64::AEK_CRYPTO))
(AArch64::AEK_NONE))
AARCH64_CPU_NAME("thunderx", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE))
(AArch64::AEK_CRC | AArch64::AEK_PROFILE))
AARCH64_CPU_NAME("thunderxt88", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE))
(AArch64::AEK_CRC | AArch64::AEK_PROFILE))
AARCH64_CPU_NAME("thunderxt81", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE))
(AArch64::AEK_CRC | AArch64::AEK_PROFILE))
AARCH64_CPU_NAME("thunderxt83", AK_ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_SIMD | AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP | AArch64::AEK_PROFILE))
(AArch64::AEK_CRC | AArch64::AEK_PROFILE))
// Invalid CPU
AARCH64_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AArch64::AEK_INVALID)
#undef AARCH64_CPU_NAME

View File

@ -64,8 +64,10 @@ class VarStreamArrayIterator
public:
VarStreamArrayIterator() = default;
VarStreamArrayIterator(const ArrayType &Array, const WrappedCtx &Ctx,
BinaryStreamRef Stream, bool *HadError = nullptr)
: IterRef(Stream), Ctx(&Ctx), Array(&Array), HadError(HadError) {
BinaryStreamRef Stream, bool *HadError = nullptr,
uint32_t Offset = 0)
: IterRef(Stream), Ctx(&Ctx), Array(&Array), AbsOffset(Offset),
HadError(HadError) {
if (IterRef.getLength() == 0)
moveToEnd();
else {
@ -115,6 +117,7 @@ class VarStreamArrayIterator
for (unsigned I = 0; I < N; ++I) {
// We are done with the current record, discard it so that we are
// positioned at the next record.
AbsOffset += ThisLen;
IterRef = IterRef.drop_front(ThisLen);
if (IterRef.getLength() == 0) {
// There is nothing after the current record, we must make this an end
@ -135,6 +138,8 @@ class VarStreamArrayIterator
return *this;
}
uint32_t offset() const { return AbsOffset; }
private:
void moveToEnd() {
Array = nullptr;
@ -152,6 +157,7 @@ class VarStreamArrayIterator
const WrappedCtx *Ctx{nullptr};
const ArrayType *Array{nullptr};
uint32_t ThisLen{0};
uint32_t AbsOffset{0};
bool HasError{false};
bool *HadError{nullptr};
};
@ -234,7 +240,7 @@ class VarStreamArrayBase {
/// since the behavior is undefined if \p Offset does not refer to the
/// beginning of a valid record.
Iterator at(uint32_t Offset) const {
return Iterator(*this, Ctx, Stream.drop_front(Offset), nullptr);
return Iterator(*this, Ctx, Stream.drop_front(Offset), nullptr, Offset);
}
BinaryStreamRef getUnderlyingStream() const { return Stream; }
@ -338,7 +344,7 @@ template <typename T> class FixedStreamArray {
template <typename T>
class FixedStreamArrayIterator
: public iterator_facade_base<FixedStreamArrayIterator<T>,
std::random_access_iterator_tag, T> {
std::random_access_iterator_tag, const T> {
public:
FixedStreamArrayIterator(const FixedStreamArray<T> &Array, uint32_t Index)
@ -352,6 +358,7 @@ class FixedStreamArrayIterator
}
const T &operator*() const { return Array[Index]; }
const T &operator*() { return Array[Index]; }
bool operator==(const FixedStreamArrayIterator<T> &R) const {
assert(Array == R.Array);

View File

@ -152,6 +152,30 @@ namespace COFF {
IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
};
enum ResourceTypeID {
RID_Cursor = 1,
RID_Bitmap = 2,
RID_Icon = 3,
RID_Menu = 4,
RID_Dialog = 5,
RID_String = 6,
RID_FontDir = 7,
RID_Font = 8,
RID_Accelerator = 9,
RID_RCData = 10,
RID_MessageTable = 11,
RID_Group_Cursor = 12,
RID_Group_Icon = 14,
RID_Version = 16,
RID_DLGInclude = 17,
RID_PlugPlay = 19,
RID_VXD = 20,
RID_AniCursor = 21,
RID_AniIcon = 22,
RID_HTML = 23,
RID_Manifest = 24,
};
struct symbol {
char Name[NameSize];
uint32_t Value;
@ -349,6 +373,26 @@ namespace COFF {
IMAGE_REL_ARM_BLX23T = 0x0015
};
enum RelocationTypesARM64 {
IMAGE_REL_ARM64_ABSOLUTE = 0x0000,
IMAGE_REL_ARM64_ADDR32 = 0x0001,
IMAGE_REL_ARM64_ADDR32NB = 0x0002,
IMAGE_REL_ARM64_BRANCH26 = 0x0003,
IMAGE_REL_ARM64_PAGEBASE_REL2 = 0x0004,
IMAGE_REL_ARM64_REL21 = 0x0005,
IMAGE_REL_ARM64_PAGEOFFSET_12A = 0x0006,
IMAGE_REL_ARM64_PAGEOFFSET_12L = 0x0007,
IMAGE_REL_ARM64_SECREL = 0x0008,
IMAGE_REL_ARM64_SECREL_LOW12A = 0x0009,
IMAGE_REL_ARM64_SECREL_HIGH12A = 0x000A,
IMAGE_REL_ARM64_SECREL_LOW12L = 0x000B,
IMAGE_REL_ARM64_TOKEN = 0x000C,
IMAGE_REL_ARM64_SECTION = 0x000D,
IMAGE_REL_ARM64_ADDR64 = 0x000E,
IMAGE_REL_ARM64_BRANCH19 = 0x000F,
IMAGE_REL_ARM64_BRANCH14 = 0x0010,
};
enum COMDATType {
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
IMAGE_COMDAT_SELECT_ANY,

View File

@ -24,6 +24,12 @@ struct KnownBits {
APInt Zero;
APInt One;
private:
// Internal constructor for creating a ConstantRange from two APInts.
KnownBits(APInt Zero, APInt One)
: Zero(std::move(Zero)), One(std::move(One)) {}
public:
// Default construct Zero and One.
KnownBits() {}
@ -37,6 +43,55 @@ struct KnownBits {
return Zero.getBitWidth();
}
/// Returns true if there is conflicting information.
bool hasConflict() const { return Zero.intersects(One); }
/// Returns true if we know the value of all bits.
bool isConstant() const {
assert(!hasConflict() && "KnownBits conflict!");
return Zero.countPopulation() + One.countPopulation() == getBitWidth();
}
/// Returns the value when all bits have a known value. This just returns One
/// with a protective assertion.
const APInt &getConstant() const {
assert(isConstant() && "Can only get value when all bits are known");
return One;
}
/// Returns true if we don't know any bits.
bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); }
/// Resets the known state of all bits.
void resetAll() {
Zero.clearAllBits();
One.clearAllBits();
}
/// Returns true if value is all zero.
bool isZero() const {
assert(!hasConflict() && "KnownBits conflict!");
return Zero.isAllOnesValue();
}
/// Returns true if value is all one bits.
bool isAllOnes() const {
assert(!hasConflict() && "KnownBits conflict!");
return One.isAllOnesValue();
}
/// Make all bits known to be zero and discard any previous information.
void setAllZero() {
Zero.setAllBits();
One.clearAllBits();
}
/// Make all bits known to be one and discard any previous information.
void setAllOnes() {
Zero.clearAllBits();
One.setAllBits();
}
/// Returns true if this value is known to be negative.
bool isNegative() const { return One.isSignBitSet(); }
@ -54,6 +109,30 @@ struct KnownBits {
assert(!isNegative() && "Can't make a negative value non-negative");
Zero.setSignBit();
}
/// Truncate the underlying known Zero and One bits. This is equivalent
/// to truncating the value we're tracking.
KnownBits trunc(unsigned BitWidth) {
return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
}
/// Zero extends the underlying known Zero and One bits. This is equivalent
/// to zero extending the value we're tracking.
KnownBits zext(unsigned BitWidth) {
return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth));
}
/// Sign extends the underlying known Zero and One bits. This is equivalent
/// to sign extending the value we're tracking.
KnownBits sext(unsigned BitWidth) {
return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
}
/// Zero extends or truncates the underlying known Zero and One bits. This is
/// equivalent to zero extending or truncating the value we're tracking.
KnownBits zextOrTrunc(unsigned BitWidth) {
return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
}
};
} // end namespace llvm

View File

@ -214,6 +214,18 @@ template <typename T> T maskLeadingOnes(unsigned N) {
return ~maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
}
/// \brief Create a bitmask with the N right-most bits set to 0, and all other
/// bits set to 1. Only unsigned types are allowed.
template <typename T> T maskTrailingZeros(unsigned N) {
return maskLeadingOnes<T>(CHAR_BIT * sizeof(T) - N);
}
/// \brief Create a bitmask with the N left-most bits set to 0, and all other
/// bits set to 1. Only unsigned types are allowed.
template <typename T> T maskLeadingZeros(unsigned N) {
return maskTrailingOnes<T>(CHAR_BIT * sizeof(T) - N);
}
/// \brief Get the index of the last set bit starting from the least
/// significant bit.
///

View File

@ -25,25 +25,43 @@ class GINodeEquiv<Instruction i, SDNode node> {
SDNode Node = node;
}
def : GINodeEquiv<G_ZEXT, zext>;
// These are defined in the same order as the G_* instructions.
def : GINodeEquiv<G_ANYEXT, anyext>;
def : GINodeEquiv<G_SEXT, sext>;
def : GINodeEquiv<G_ZEXT, zext>;
def : GINodeEquiv<G_TRUNC, trunc>;
def : GINodeEquiv<G_BITCAST, bitconvert>;
// G_INTTOPTR - SelectionDAG has no equivalent.
// G_PTRTOINT - SelectionDAG has no equivalent.
// G_CONSTANT - Not needed since constants aren't operators.
// G_FCONSTANT - Not needed since constants aren't operators.
def : GINodeEquiv<G_ADD, add>;
def : GINodeEquiv<G_SUB, sub>;
def : GINodeEquiv<G_MUL, mul>;
def : GINodeEquiv<G_OR, or>;
def : GINodeEquiv<G_XOR, xor>;
def : GINodeEquiv<G_AND, and>;
def : GINodeEquiv<G_SHL, shl>;
def : GINodeEquiv<G_LSHR, srl>;
def : GINodeEquiv<G_ASHR, sra>;
def : GINodeEquiv<G_SDIV, sdiv>;
def : GINodeEquiv<G_UDIV, udiv>;
def : GINodeEquiv<G_SREM, srem>;
def : GINodeEquiv<G_UREM, urem>;
def : GINodeEquiv<G_AND, and>;
def : GINodeEquiv<G_OR, or>;
def : GINodeEquiv<G_XOR, xor>;
def : GINodeEquiv<G_SHL, shl>;
def : GINodeEquiv<G_LSHR, srl>;
def : GINodeEquiv<G_ASHR, sra>;
def : GINodeEquiv<G_SELECT, select>;
def : GINodeEquiv<G_FNEG, fneg>;
def : GINodeEquiv<G_FPEXT, fpextend>;
def : GINodeEquiv<G_FPTRUNC, ftrunc>;
def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
def : GINodeEquiv<G_SITOFP, sint_to_fp>;
def : GINodeEquiv<G_UITOFP, uint_to_fp>;
def : GINodeEquiv<G_FADD, fadd>;
def : GINodeEquiv<G_FSUB, fsub>;
def : GINodeEquiv<G_FMUL, fmul>;
def : GINodeEquiv<G_FDIV, fdiv>;
def : GINodeEquiv<G_FREM, frem>;
def : GINodeEquiv<G_FPOW, fpow>;
def : GINodeEquiv<G_BR, br>;
// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.

View File

@ -1002,6 +1002,16 @@ def PATCHABLE_TAIL_CALL : Instruction {
let hasSideEffects = 1;
let isReturn = 1;
}
def PATCHABLE_EVENT_CALL : Instruction {
let OutOperandList = (outs);
let InOperandList = (ins ptr_rc:$event, i8imm:$size);
let AsmString = "# XRay Custom Event Log.";
let usesCustomInserter = 1;
let isCall = 1;
let mayLoad = 1;
let mayStore = 1;
let hasSideEffects = 1;
}
def FENTRY_CALL : Instruction {
let OutOperandList = (outs unknown:$dst);
let InOperandList = (ins variable_ops);

View File

@ -182,6 +182,10 @@ HANDLE_TARGET_OPCODE(PATCHABLE_FUNCTION_EXIT)
/// PATCHABLE_RET which specifically only works for return instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_TAIL_CALL)
/// Wraps a logging call and its arguments with nop sleds. At runtime, this can be
/// patched to insert instrumentation instructions.
HANDLE_TARGET_OPCODE(PATCHABLE_EVENT_CALL)
/// The following generic opcodes are not supposed to appear after ISel.
/// This is something we might want to relax, but for now, this is convenient
/// to produce diagnostics.

View File

@ -177,6 +177,7 @@ struct SanitizerCoverageOptions {
bool Use8bitCounters = false;
bool TracePC = false;
bool TracePCGuard = false;
bool NoPrune = false;
SanitizerCoverageOptions() = default;
};

Some files were not shown because too many files have changed in this diff Show More