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

build glue.
This commit is contained in:
Dimitry Andric 2017-06-17 00:09:34 +00:00
commit 24d58133b7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang500-import/; revision=320041
436 changed files with 13639 additions and 8372 deletions

View File

@ -235,6 +235,8 @@ struct Allocator {
AllocatorCache fallback_allocator_cache; AllocatorCache fallback_allocator_cache;
QuarantineCache fallback_quarantine_cache; QuarantineCache fallback_quarantine_cache;
atomic_uint8_t rss_limit_exceeded;
// ------------------- Options -------------------------- // ------------------- Options --------------------------
atomic_uint16_t min_redzone; atomic_uint16_t min_redzone;
atomic_uint16_t max_redzone; atomic_uint16_t max_redzone;
@ -268,6 +270,14 @@ struct Allocator {
SharedInitCode(options); SharedInitCode(options);
} }
bool RssLimitExceeded() {
return atomic_load(&rss_limit_exceeded, memory_order_relaxed);
}
void SetRssLimitExceeded(bool limit_exceeded) {
atomic_store(&rss_limit_exceeded, limit_exceeded, memory_order_relaxed);
}
void RePoisonChunk(uptr chunk) { void RePoisonChunk(uptr chunk) {
// This could be a user-facing chunk (with redzones), or some internal // This could be a user-facing chunk (with redzones), or some internal
// housekeeping chunk, like TransferBatch. Start by assuming the former. // housekeeping chunk, like TransferBatch. Start by assuming the former.
@ -363,6 +373,8 @@ struct Allocator {
AllocType alloc_type, bool can_fill) { AllocType alloc_type, bool can_fill) {
if (UNLIKELY(!asan_inited)) if (UNLIKELY(!asan_inited))
AsanInitFromRtl(); AsanInitFromRtl();
if (RssLimitExceeded())
return allocator.ReturnNullOrDieOnOOM();
Flags &fl = *flags(); Flags &fl = *flags();
CHECK(stack); CHECK(stack);
const uptr min_alignment = SHADOW_GRANULARITY; const uptr min_alignment = SHADOW_GRANULARITY;
@ -400,16 +412,15 @@ struct Allocator {
AsanThread *t = GetCurrentThread(); AsanThread *t = GetCurrentThread();
void *allocated; void *allocated;
bool check_rss_limit = true;
if (t) { if (t) {
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage()); AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
allocated = allocated =
allocator.Allocate(cache, needed_size, 8, false, check_rss_limit); allocator.Allocate(cache, needed_size, 8, false);
} else { } else {
SpinMutexLock l(&fallback_mutex); SpinMutexLock l(&fallback_mutex);
AllocatorCache *cache = &fallback_allocator_cache; AllocatorCache *cache = &fallback_allocator_cache;
allocated = allocated =
allocator.Allocate(cache, needed_size, 8, false, check_rss_limit); allocator.Allocate(cache, needed_size, 8, false);
} }
if (!allocated) return allocator.ReturnNullOrDieOnOOM(); if (!allocated) return allocator.ReturnNullOrDieOnOOM();
@ -866,8 +877,8 @@ void asan_mz_force_unlock() {
instance.ForceUnlock(); instance.ForceUnlock();
} }
void AsanSoftRssLimitExceededCallback(bool exceeded) { void AsanSoftRssLimitExceededCallback(bool limit_exceeded) {
instance.allocator.SetRssLimitIsExceeded(exceeded); instance.SetRssLimitExceeded(limit_exceeded);
} }
} // namespace __asan } // namespace __asan

View File

@ -43,12 +43,12 @@ class CombinedAllocator {
} }
void *Allocate(AllocatorCache *cache, uptr size, uptr alignment, void *Allocate(AllocatorCache *cache, uptr size, uptr alignment,
bool cleared = false, bool check_rss_limit = false) { bool cleared = false) {
// Returning 0 on malloc(0) may break a lot of code. // Returning 0 on malloc(0) may break a lot of code.
if (size == 0) if (size == 0)
size = 1; size = 1;
if (size + alignment < size) return ReturnNullOrDieOnBadRequest(); if (size + alignment < size)
if (check_rss_limit && RssLimitIsExceeded()) return ReturnNullOrDieOnOOM(); return ReturnNullOrDieOnBadRequest();
uptr original_size = size; uptr original_size = size;
// If alignment requirements are to be fulfilled by the frontend allocator // If alignment requirements are to be fulfilled by the frontend allocator
// rather than by the primary or secondary, passing an alignment lower than // rather than by the primary or secondary, passing an alignment lower than
@ -89,7 +89,8 @@ class CombinedAllocator {
} }
void *ReturnNullOrDieOnOOM() { void *ReturnNullOrDieOnOOM() {
if (MayReturnNull()) return nullptr; if (MayReturnNull())
return nullptr;
ReportAllocatorCannotReturnNull(true); ReportAllocatorCannotReturnNull(true);
} }
@ -106,15 +107,6 @@ class CombinedAllocator {
primary_.SetReleaseToOSIntervalMs(release_to_os_interval_ms); primary_.SetReleaseToOSIntervalMs(release_to_os_interval_ms);
} }
bool RssLimitIsExceeded() {
return atomic_load(&rss_limit_is_exceeded_, memory_order_acquire);
}
void SetRssLimitIsExceeded(bool rss_limit_is_exceeded) {
atomic_store(&rss_limit_is_exceeded_, rss_limit_is_exceeded,
memory_order_release);
}
void Deallocate(AllocatorCache *cache, void *p) { void Deallocate(AllocatorCache *cache, void *p) {
if (!p) return; if (!p) return;
if (primary_.PointerIsMine(p)) if (primary_.PointerIsMine(p))
@ -228,6 +220,5 @@ class CombinedAllocator {
SecondaryAllocator secondary_; SecondaryAllocator secondary_;
AllocatorGlobalStats stats_; AllocatorGlobalStats stats_;
atomic_uint8_t may_return_null_; atomic_uint8_t may_return_null_;
atomic_uint8_t rss_limit_is_exceeded_;
}; };

View File

@ -36,9 +36,12 @@ class LargeMmapAllocator {
if (alignment > page_size_) if (alignment > page_size_)
map_size += alignment; map_size += alignment;
// Overflow. // Overflow.
if (map_size < size) return ReturnNullOrDieOnBadRequest(); if (map_size < size)
return ReturnNullOrDieOnBadRequest();
uptr map_beg = reinterpret_cast<uptr>( uptr map_beg = reinterpret_cast<uptr>(
MmapOrDie(map_size, "LargeMmapAllocator")); MmapOrDieOnFatalError(map_size, "LargeMmapAllocator"));
if (!map_beg)
return ReturnNullOrDieOnOOM();
CHECK(IsAligned(map_beg, page_size_)); CHECK(IsAligned(map_beg, page_size_));
MapUnmapCallback().OnMap(map_beg, map_size); MapUnmapCallback().OnMap(map_beg, map_size);
uptr map_end = map_beg + map_size; uptr map_end = map_beg + map_size;

View File

@ -85,6 +85,9 @@ INLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) {
return MmapOrDie(size, mem_type, /*raw_report*/ true); return MmapOrDie(size, mem_type, /*raw_report*/ true);
} }
void UnmapOrDie(void *addr, uptr size); void UnmapOrDie(void *addr, uptr size);
// Behaves just like MmapOrDie, but tolerates out of memory condition, in that
// case returns nullptr.
void *MmapOrDieOnFatalError(uptr size, const char *mem_type);
void *MmapFixedNoReserve(uptr fixed_addr, uptr size, void *MmapFixedNoReserve(uptr fixed_addr, uptr size,
const char *name = nullptr); const char *name = nullptr);
void *MmapNoReserveOrDie(uptr size, const char *mem_type); void *MmapNoReserveOrDie(uptr size, const char *mem_type);

View File

@ -93,6 +93,9 @@ COMMON_FLAG(HandleSignalMode, handle_sigill, kHandleSignalNo,
COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes, COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes,
COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE)) COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE))
#undef COMMON_FLAG_HANDLE_SIGNAL_HELP #undef COMMON_FLAG_HANDLE_SIGNAL_HELP
COMMON_FLAG(bool, allow_user_segv_handler, true,
"Deprecated. True has no effect, use handle_sigbus=1. If false, "
"handle_*=1 will be upgraded to handle_*=2.")
COMMON_FLAG(bool, use_sigaltstack, true, COMMON_FLAG(bool, use_sigaltstack, true,
"If set, uses alternate stack for signal handling.") "If set, uses alternate stack for signal handling.")
COMMON_FLAG(bool, detect_deadlocks, false, COMMON_FLAG(bool, detect_deadlocks, false,

View File

@ -1396,7 +1396,7 @@ AndroidApiLevel AndroidGetApiLevel() {
#endif #endif
HandleSignalMode GetHandleSignalMode(int signum) { static HandleSignalMode GetHandleSignalModeImpl(int signum) {
switch (signum) { switch (signum) {
case SIGABRT: case SIGABRT:
return common_flags()->handle_abort; return common_flags()->handle_abort;
@ -1412,6 +1412,13 @@ HandleSignalMode GetHandleSignalMode(int signum) {
return kHandleSignalNo; return kHandleSignalNo;
} }
HandleSignalMode GetHandleSignalMode(int signum) {
HandleSignalMode result = GetHandleSignalModeImpl(signum);
if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler)
return kHandleSignalExclusive;
return result;
}
#if !SANITIZER_GO #if !SANITIZER_GO
void *internal_start_thread(void(*func)(void *arg), void *arg) { void *internal_start_thread(void(*func)(void *arg), void *arg) {
// Start the thread with signals blocked, otherwise it can steal user signals. // Start the thread with signals blocked, otherwise it can steal user signals.

View File

@ -113,7 +113,6 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
my_pthread_attr_getstack(&attr, &stackaddr, &stacksize); my_pthread_attr_getstack(&attr, &stackaddr, &stacksize);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
CHECK_LE(stacksize, kMaxThreadStackSize); // Sanity check.
*stack_top = (uptr)stackaddr + stacksize; *stack_top = (uptr)stackaddr + stacksize;
*stack_bottom = (uptr)stackaddr; *stack_bottom = (uptr)stackaddr;
} }

View File

@ -414,10 +414,7 @@ void ListOfModules::init() {
memory_mapping.DumpListOfModules(&modules_); memory_mapping.DumpListOfModules(&modules_);
} }
HandleSignalMode GetHandleSignalMode(int signum) { static HandleSignalMode GetHandleSignalModeImpl(int signum) {
// Handling fatal signals on watchOS and tvOS devices is disallowed.
if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
return kHandleSignalNo;
switch (signum) { switch (signum) {
case SIGABRT: case SIGABRT:
return common_flags()->handle_abort; return common_flags()->handle_abort;
@ -433,6 +430,16 @@ HandleSignalMode GetHandleSignalMode(int signum) {
return kHandleSignalNo; return kHandleSignalNo;
} }
HandleSignalMode GetHandleSignalMode(int signum) {
// Handling fatal signals on watchOS and tvOS devices is disallowed.
if ((SANITIZER_WATCHOS || SANITIZER_TVOS) && !(SANITIZER_IOSSIM))
return kHandleSignalNo;
HandleSignalMode result = GetHandleSignalModeImpl(signum);
if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler)
return kHandleSignalExclusive;
return result;
}
MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED; MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED;
MacosVersion GetMacosVersionInternal() { MacosVersion GetMacosVersionInternal() {

View File

@ -22,6 +22,7 @@
#include "sanitizer_procmaps.h" #include "sanitizer_procmaps.h"
#include "sanitizer_stacktrace.h" #include "sanitizer_stacktrace.h"
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -145,6 +146,21 @@ void UnmapOrDie(void *addr, uptr size) {
DecreaseTotalMmap(size); DecreaseTotalMmap(size);
} }
void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
size = RoundUpTo(size, GetPageSizeCached());
uptr res = internal_mmap(nullptr, size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
int reserrno;
if (internal_iserror(res, &reserrno)) {
if (reserrno == ENOMEM)
return nullptr;
ReportMmapFailureAndDie(size, mem_type, "allocate", reserrno);
}
IncreaseTotalMmap(size);
return (void *)res;
}
// We want to map a chunk of address space aligned to 'alignment'. // We want to map a chunk of address space aligned to 'alignment'.
// We do it by maping a bit more and then unmaping redundant pieces. // We do it by maping a bit more and then unmaping redundant pieces.
// We probably can do it with fewer syscalls in some OS-dependent way. // We probably can do it with fewer syscalls in some OS-dependent way.

View File

@ -131,6 +131,16 @@ void UnmapOrDie(void *addr, uptr size) {
} }
} }
void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
void *rv = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (rv == 0) {
error_t last_error = GetLastError();
if (last_error != ERROR_NOT_ENOUGH_MEMORY)
ReportMmapFailureAndDie(size, mem_type, "allocate", last_error);
}
return rv;
}
// We want to map a chunk of address space aligned to 'alignment'. // We want to map a chunk of address space aligned to 'alignment'.
void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) { void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) {
CHECK(IsPowerOfTwo(size)); CHECK(IsPowerOfTwo(size));

View File

@ -92,7 +92,8 @@ static const char *ReportTypeString(ReportType typ, uptr tag) {
if (typ == ReportTypeVptrUseAfterFree) if (typ == ReportTypeVptrUseAfterFree)
return "heap-use-after-free (virtual call vs free)"; return "heap-use-after-free (virtual call vs free)";
if (typ == ReportTypeExternalRace) { if (typ == ReportTypeExternalRace) {
return GetReportHeaderFromTag(tag) ?: "race on external object"; const char *str = GetReportHeaderFromTag(tag);
return str ? str : "race on external object";
} }
if (typ == ReportTypeThreadLeak) if (typ == ReportTypeThreadLeak)
return "thread leak"; return "thread leak";
@ -170,8 +171,9 @@ static void PrintMop(const ReportMop *mop, bool first) {
MopDesc(first, mop->write, mop->atomic), mop->size, MopDesc(first, mop->write, mop->atomic), mop->size,
(void *)mop->addr, thread_name(thrbuf, mop->tid)); (void *)mop->addr, thread_name(thrbuf, mop->tid));
} else { } else {
const char *object_type = const char *object_type = GetObjectTypeFromTag(mop->external_tag);
GetObjectTypeFromTag(mop->external_tag) ?: "external object"; if (object_type == nullptr)
object_type = "external object";
Printf(" %s access of %s at %p by %s", Printf(" %s access of %s at %p by %s",
ExternalMopDesc(first, mop->write), object_type, ExternalMopDesc(first, mop->write), object_type,
(void *)mop->addr, thread_name(thrbuf, mop->tid)); (void *)mop->addr, thread_name(thrbuf, mop->tid));

View File

@ -83,7 +83,7 @@ struct SyncVar {
} }
bool IsFlagSet(u32 f) const { bool IsFlagSet(u32 f) const {
return atomic_load_relaxed(&flags); return atomic_load_relaxed(&flags) & f;
} }
void SetFlags(u32 f) { void SetFlags(u32 f) {

View File

@ -566,8 +566,14 @@ static void handlePointerOverflowImpl(PointerOverflowData *Data,
ScopedReport R(Opts, Loc, ET); ScopedReport R(Opts, Loc, ET);
Diag(Loc, DL_Error, "pointer index expression with base %0 overflowed to %1") if ((sptr(Base) >= 0) == (sptr(Result) >= 0))
<< (void *)Base << (void*)Result; Diag(Loc, DL_Error, "unsigned pointer index expression result is %0, "
"preceding its base %1")
<< (void *)Result << (void *)Base;
else
Diag(Loc, DL_Error,
"pointer index expression with base %0 overflowed to %1")
<< (void *)Base << (void *)Result;
} }
void __ubsan::__ubsan_handle_pointer_overflow(PointerOverflowData *Data, void __ubsan::__ubsan_handle_pointer_overflow(PointerOverflowData *Data,

View File

@ -197,9 +197,9 @@ struct VtablePrefix {
}; };
VtablePrefix *getVtablePrefix(void *Vtable) { VtablePrefix *getVtablePrefix(void *Vtable) {
VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable); VtablePrefix *Vptr = reinterpret_cast<VtablePrefix*>(Vtable);
if (!IsAccessibleMemoryRange((uptr)Vptr, sizeof(VtablePrefix)))
return nullptr;
VtablePrefix *Prefix = Vptr - 1; VtablePrefix *Prefix = Vptr - 1;
if (!IsAccessibleMemoryRange((uptr)Prefix, sizeof(VtablePrefix)))
return nullptr;
if (!Prefix->TypeInfo) if (!Prefix->TypeInfo)
// This can't possibly be a valid vtable. // This can't possibly be a valid vtable.
return nullptr; return nullptr;

View File

@ -15,6 +15,7 @@
#define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H #define _LIBCPP_BSD_LOCALE_FALLBACKS_DEFAULTS_H
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <memory> #include <memory>
_LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD

View File

@ -76,6 +76,9 @@
// its vtable and typeinfo to libc++ rather than having all other libraries // its vtable and typeinfo to libc++ rather than having all other libraries
// using that class define their own copies. // using that class define their own copies.
#define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION #define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
// Enable optimized version of __do_get_(un)signed which avoids redundant copies.
#define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
#elif _LIBCPP_ABI_VERSION == 1 #elif _LIBCPP_ABI_VERSION == 1
#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) #if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
// Enable compiling copies of now inline methods into the dylib to support // Enable compiling copies of now inline methods into the dylib to support
@ -289,7 +292,7 @@
# endif # endif
#endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN) #endif // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
#if __has_attribute(__no_sanitize__) #if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC)
#define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) #define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi")))
#else #else
#define _LIBCPP_NO_CFI #define _LIBCPP_NO_CFI
@ -1132,8 +1135,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# define _LIBCPP_HAS_NO_COROUTINES # define _LIBCPP_HAS_NO_COROUTINES
#endif #endif
#endif // __cplusplus
// Decide whether to use availability macros. // Decide whether to use availability macros.
#if !defined(_LIBCPP_BUILDING_LIBRARY) && \ #if !defined(_LIBCPP_BUILDING_LIBRARY) && \
!defined(_LIBCPP_DISABLE_AVAILABILITY) && \ !defined(_LIBCPP_DISABLE_AVAILABILITY) && \
@ -1237,4 +1238,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
# endif # endif
#endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO) #endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO)
#endif // __cplusplus
#endif // _LIBCPP_CONFIG #endif // _LIBCPP_CONFIG

View File

@ -704,7 +704,7 @@ function<_Rp()>::target()
{ {
if (__f_ == 0) if (__f_ == 0)
return (_Tp*)0; return (_Tp*)0;
return (_Tp*)__f_->target(typeid(_Tp)); return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
} }
template<class _Rp> template<class _Rp>
@ -980,7 +980,7 @@ function<_Rp(_A0)>::target()
{ {
if (__f_ == 0) if (__f_ == 0)
return (_Tp*)0; return (_Tp*)0;
return (_Tp*)__f_->target(typeid(_Tp)); return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
} }
template<class _Rp, class _A0> template<class _Rp, class _A0>
@ -1256,7 +1256,7 @@ function<_Rp(_A0, _A1)>::target()
{ {
if (__f_ == 0) if (__f_ == 0)
return (_Tp*)0; return (_Tp*)0;
return (_Tp*)__f_->target(typeid(_Tp)); return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
} }
template<class _Rp, class _A0, class _A1> template<class _Rp, class _A0, class _A1>
@ -1532,7 +1532,7 @@ function<_Rp(_A0, _A1, _A2)>::target()
{ {
if (__f_ == 0) if (__f_ == 0)
return (_Tp*)0; return (_Tp*)0;
return (_Tp*)__f_->target(typeid(_Tp)); return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
} }
template<class _Rp, class _A0, class _A1, class _A2> template<class _Rp, class _A0, class _A1, class _A2>

View File

@ -548,16 +548,13 @@ template <class _Tp> void cref(const _Tp&&) = delete;
#endif #endif
#if _LIBCPP_STD_VER > 11 #if _LIBCPP_STD_VER > 11
template <class _Tp1, class _Tp2 = void> template <class _Tp, class, class = void>
struct __is_transparent struct __is_transparent : false_type {};
{
private: template <class _Tp, class _Up>
struct __two {char __lx; char __lxx;}; struct __is_transparent<_Tp, _Up,
template <class _Up> static __two __test(...); typename __void_t<typename _Tp::is_transparent>::type>
template <class _Up> static char __test(typename _Up::is_transparent* = 0); : true_type {};
public:
static const bool value = sizeof(__test<_Tp1>(0)) == 1;
};
#endif #endif
// allocator_arg_t // allocator_arg_t

View File

@ -296,6 +296,7 @@ class _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
template <size_t _Ip, class _Tp, size_t _Size> template <size_t _Ip, class _Tp, size_t _Size>
class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> > class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
{ {
static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
public: public:
typedef _Tp type; typedef _Tp type;
}; };

View File

@ -250,9 +250,11 @@ public:
_LIBCPP_ALWAYS_INLINE _LIBCPP_ALWAYS_INLINE
static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT { static coroutine_handle from_promise(_Promise& __promise) _NOEXCEPT {
typedef typename remove_cv<_Promise>::type _RawPromise;
coroutine_handle __tmp; coroutine_handle __tmp;
__tmp.__handle_ = __builtin_coro_promise(_VSTD::addressof(__promise), __tmp.__handle_ = __builtin_coro_promise(
__alignof(_Promise), true); _VSTD::addressof(const_cast<_RawPromise&>(__promise)),
__alignof(_Promise), true);
return __tmp; return __tmp;
} }
}; };

View File

@ -617,7 +617,7 @@ basic_filebuf<_CharT, _Traits>::underflow()
static_cast<size_t>(__extbufend_ - __extbufnext_)); static_cast<size_t>(__extbufend_ - __extbufnext_));
codecvt_base::result __r; codecvt_base::result __r;
__st_last_ = __st_; __st_last_ = __st_;
size_t __nr = fread((void*)__extbufnext_, 1, __nmemb, __file_); size_t __nr = fread((void*) const_cast<char *>(__extbufnext_), 1, __nmemb, __file_);
if (__nr != 0) if (__nr != 0)
{ {
if (!__cv_) if (!__cv_)
@ -630,7 +630,8 @@ basic_filebuf<_CharT, _Traits>::underflow()
this->eback() + __ibs_, __inext); this->eback() + __ibs_, __inext);
if (__r == codecvt_base::noconv) if (__r == codecvt_base::noconv)
{ {
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
(char_type*)const_cast<char *>(__extbufend_));
__c = traits_type::to_int_type(*this->gptr()); __c = traits_type::to_int_type(*this->gptr());
} }
else if (__inext != this->eback() + __unget_sz) else if (__inext != this->eback() + __unget_sz)
@ -722,7 +723,7 @@ basic_filebuf<_CharT, _Traits>::overflow(int_type __c)
return traits_type::eof(); return traits_type::eof();
if (__r == codecvt_base::partial) if (__r == codecvt_base::partial)
{ {
this->setp((char_type*)__e, this->pptr()); this->setp(const_cast<char_type*>(__e), this->pptr());
this->pbump(this->epptr() - this->pbase()); this->pbump(this->epptr() - this->pbase());
} }
} }

View File

@ -1941,8 +1941,8 @@ _Tp*
function<_Rp(_ArgTypes...)>::target() _NOEXCEPT function<_Rp(_ArgTypes...)>::target() _NOEXCEPT
{ {
if (__f_ == 0) if (__f_ == 0)
return (_Tp*)0; return nullptr;
return (_Tp*)__f_->target(typeid(_Tp)); return (_Tp*) const_cast<void *>(__f_->target(typeid(_Tp)));
} }
template<class _Rp, class ..._ArgTypes> template<class _Rp, class ..._ArgTypes>
@ -1951,7 +1951,7 @@ const _Tp*
function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT function<_Rp(_ArgTypes...)>::target() const _NOEXCEPT
{ {
if (__f_ == 0) if (__f_ == 0)
return (const _Tp*)0; return nullptr;
return (const _Tp*)__f_->target(typeid(_Tp)); return (const _Tp*)__f_->target(typeid(_Tp));
} }

View File

@ -372,19 +372,57 @@ template <class _CharT>
struct __num_get struct __num_get
: protected __num_get_base : protected __num_get_base
{ {
static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point, static string __stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT& __decimal_point,
_CharT& __thousands_sep); _CharT& __thousands_sep);
static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp, static int __stage2_float_loop(_CharT __ct, bool& __in_units, char& __exp,
char* __a, char*& __a_end, char* __a, char*& __a_end,
_CharT __decimal_point, _CharT __thousands_sep, _CharT __decimal_point, _CharT __thousands_sep,
const string& __grouping, unsigned* __g, const string& __grouping, unsigned* __g,
unsigned*& __g_end, unsigned& __dc, _CharT* __atoms); unsigned*& __g_end, unsigned& __dc, _CharT* __atoms);
#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
static string __stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep);
static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, _CharT* __atoms);
#else
static string __stage2_int_prep(ios_base& __iob, _CharT& __thousands_sep)
{
locale __loc = __iob.getloc();
const numpunct<_CharT>& __np = use_facet<numpunct<_CharT> >(__loc);
__thousands_sep = __np.thousands_sep();
return __np.grouping();
}
const _CharT* __do_widen(ios_base& __iob, _CharT* __atoms) const
{
return __do_widen_p(__iob, __atoms);
}
static int __stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, const _CharT* __atoms);
private:
template<typename T>
const T* __do_widen_p(ios_base& __iob, T* __atoms) const
{
locale __loc = __iob.getloc();
use_facet<ctype<T> >(__loc).widen(__src, __src + 26, __atoms);
return __atoms;
}
const char* __do_widen_p(ios_base& __iob, char* __atoms) const
{
(void)__iob;
(void)__atoms;
return __src;
}
#endif
}; };
#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
template <class _CharT> template <class _CharT>
string string
__num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep) __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& __thousands_sep)
@ -395,6 +433,7 @@ __num_get<_CharT>::__stage2_int_prep(ios_base& __iob, _CharT* __atoms, _CharT& _
__thousands_sep = __np.thousands_sep(); __thousands_sep = __np.thousands_sep();
return __np.grouping(); return __np.grouping();
} }
#endif
template <class _CharT> template <class _CharT>
string string
@ -411,9 +450,16 @@ __num_get<_CharT>::__stage2_float_prep(ios_base& __iob, _CharT* __atoms, _CharT&
template <class _CharT> template <class _CharT>
int int
#ifndef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end, __num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping, unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, _CharT* __atoms) unsigned* __g, unsigned*& __g_end, _CharT* __atoms)
#else
__num_get<_CharT>::__stage2_int_loop(_CharT __ct, int __base, char* __a, char*& __a_end,
unsigned& __dc, _CharT __thousands_sep, const string& __grouping,
unsigned* __g, unsigned*& __g_end, const _CharT* __atoms)
#endif
{ {
if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25])) if (__a_end == __a && (__ct == __atoms[24] || __ct == __atoms[25]))
{ {
@ -849,9 +895,16 @@ num_get<_CharT, _InputIterator>::__do_get_signed(iter_type __b, iter_type __e,
// Stage 1 // Stage 1
int __base = this->__get_base(__iob); int __base = this->__get_base(__iob);
// Stage 2 // Stage 2
char_type __atoms[26];
char_type __thousands_sep; char_type __thousands_sep;
const int __atoms_size = 26;
#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
char_type __atoms1[__atoms_size];
const char_type *__atoms = this->__do_widen(__iob, __atoms1);
string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
#else
char_type __atoms[__atoms_size];
string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
#endif
string __buf; string __buf;
__buf.resize(__buf.capacity()); __buf.resize(__buf.capacity());
char* __a = &__buf[0]; char* __a = &__buf[0];
@ -899,9 +952,16 @@ num_get<_CharT, _InputIterator>::__do_get_unsigned(iter_type __b, iter_type __e,
// Stage 1 // Stage 1
int __base = this->__get_base(__iob); int __base = this->__get_base(__iob);
// Stage 2 // Stage 2
char_type __atoms[26];
char_type __thousands_sep; char_type __thousands_sep;
const int __atoms_size = 26;
#ifdef _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET
char_type __atoms1[__atoms_size];
const char_type *__atoms = this->__do_widen(__iob, __atoms1);
string __grouping = this->__stage2_int_prep(__iob, __thousands_sep);
#else
char_type __atoms[__atoms_size];
string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep); string __grouping = this->__stage2_int_prep(__iob, __atoms, __thousands_sep);
#endif
string __buf; string __buf;
__buf.resize(__buf.capacity()); __buf.resize(__buf.capacity());
char* __a = &__buf[0]; char* __a = &__buf[0];
@ -3960,7 +4020,8 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::underflow()
this->egptr(), __inext); this->egptr(), __inext);
if (__r == codecvt_base::noconv) if (__r == codecvt_base::noconv)
{ {
this->setg((char_type*)__extbuf_, (char_type*)__extbuf_, (char_type*)__extbufend_); this->setg((char_type*)__extbuf_, (char_type*)__extbuf_,
(char_type*) const_cast<char *>(__extbufend_));
__c = *this->gptr(); __c = *this->gptr();
} }
else if (__inext != this->eback() + __unget_sz) else if (__inext != this->eback() + __unget_sz)
@ -4048,7 +4109,7 @@ wbuffer_convert<_Codecvt, _Elem, _Tr>::overflow(int_type __c)
return traits_type::eof(); return traits_type::eof();
if (__r == codecvt_base::partial) if (__r == codecvt_base::partial)
{ {
this->setp((char_type*)__e, this->pptr()); this->setp(const_cast<char_type *>(__e), this->pptr());
this->pbump(this->epptr() - this->pbase()); this->pbump(this->epptr() - this->pbase());
} }
} }

View File

@ -720,16 +720,12 @@ public:
// pointer_traits // pointer_traits
template <class _Tp, class = void>
struct __has_element_type : false_type {};
template <class _Tp> template <class _Tp>
struct __has_element_type struct __has_element_type<_Tp,
{ typename __void_t<typename _Tp::element_type>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::element_type* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Ptr, bool = __has_element_type<_Ptr>::value> template <class _Ptr, bool = __has_element_type<_Ptr>::value>
struct __pointer_traits_element_type; struct __pointer_traits_element_type;
@ -808,16 +804,12 @@ struct __pointer_traits_element_type<_Sp<_Tp, _A0, _A1, _A2>, false>
#endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_VARIADICS
template <class _Tp, class = void>
struct __has_difference_type : false_type {};
template <class _Tp> template <class _Tp>
struct __has_difference_type struct __has_difference_type<_Tp,
{ typename __void_t<typename _Tp::difference_type>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::difference_type* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Ptr, bool = __has_difference_type<_Ptr>::value> template <class _Ptr, bool = __has_difference_type<_Ptr>::value>
struct __pointer_traits_difference_type struct __pointer_traits_difference_type
@ -998,17 +990,12 @@ struct __rebind_pointer {
// allocator_traits // allocator_traits
struct __has_pointer_type_imp template <class _Tp, class = void>
{ struct __has_pointer_type : false_type {};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::pointer* = 0);
};
template <class _Tp> template <class _Tp>
struct __has_pointer_type struct __has_pointer_type<_Tp,
: public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1> typename __void_t<typename _Tp::pointer>::type> : true_type {};
{
};
namespace __pointer_type_imp namespace __pointer_type_imp
{ {
@ -1033,16 +1020,12 @@ struct __pointer_type
typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type; typedef typename __pointer_type_imp::__pointer_type<_Tp, typename remove_reference<_Dp>::type>::type type;
}; };
template <class _Tp, class = void>
struct __has_const_pointer : false_type {};
template <class _Tp> template <class _Tp>
struct __has_const_pointer struct __has_const_pointer<_Tp,
{ typename __void_t<typename _Tp::const_pointer>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::const_pointer* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value> template <class _Tp, class _Ptr, class _Alloc, bool = __has_const_pointer<_Alloc>::value>
struct __const_pointer struct __const_pointer
@ -1060,16 +1043,12 @@ struct __const_pointer<_Tp, _Ptr, _Alloc, false>
#endif #endif
}; };
template <class _Tp, class = void>
struct __has_void_pointer : false_type {};
template <class _Tp> template <class _Tp>
struct __has_void_pointer struct __has_void_pointer<_Tp,
{ typename __void_t<typename _Tp::void_pointer>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::void_pointer* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value> template <class _Ptr, class _Alloc, bool = __has_void_pointer<_Alloc>::value>
struct __void_pointer struct __void_pointer
@ -1087,16 +1066,12 @@ struct __void_pointer<_Ptr, _Alloc, false>
#endif #endif
}; };
template <class _Tp, class = void>
struct __has_const_void_pointer : false_type {};
template <class _Tp> template <class _Tp>
struct __has_const_void_pointer struct __has_const_void_pointer<_Tp,
{ typename __void_t<typename _Tp::const_void_pointer>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::const_void_pointer* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value> template <class _Ptr, class _Alloc, bool = __has_const_void_pointer<_Alloc>::value>
struct __const_void_pointer struct __const_void_pointer
@ -1130,16 +1105,12 @@ __to_raw_pointer(_Pointer __p) _NOEXCEPT
return _VSTD::__to_raw_pointer(__p.operator->()); return _VSTD::__to_raw_pointer(__p.operator->());
} }
template <class _Tp, class = void>
struct __has_size_type : false_type {};
template <class _Tp> template <class _Tp>
struct __has_size_type struct __has_size_type<_Tp,
{ typename __void_t<typename _Tp::size_type>::type> : true_type {};
private:
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::size_type* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value> template <class _Alloc, class _DiffType, bool = __has_size_type<_Alloc>::value>
struct __size_type struct __size_type
@ -1153,16 +1124,13 @@ struct __size_type<_Alloc, _DiffType, true>
typedef typename _Alloc::size_type type; typedef typename _Alloc::size_type type;
}; };
template <class _Tp, class = void>
struct __has_propagate_on_container_copy_assignment : false_type {};
template <class _Tp> template <class _Tp>
struct __has_propagate_on_container_copy_assignment struct __has_propagate_on_container_copy_assignment<_Tp,
{ typename __void_t<typename _Tp::propagate_on_container_copy_assignment>::type>
private: : true_type {};
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::propagate_on_container_copy_assignment* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value> template <class _Alloc, bool = __has_propagate_on_container_copy_assignment<_Alloc>::value>
struct __propagate_on_container_copy_assignment struct __propagate_on_container_copy_assignment
@ -1176,16 +1144,13 @@ struct __propagate_on_container_copy_assignment<_Alloc, true>
typedef typename _Alloc::propagate_on_container_copy_assignment type; typedef typename _Alloc::propagate_on_container_copy_assignment type;
}; };
template <class _Tp, class = void>
struct __has_propagate_on_container_move_assignment : false_type {};
template <class _Tp> template <class _Tp>
struct __has_propagate_on_container_move_assignment struct __has_propagate_on_container_move_assignment<_Tp,
{ typename __void_t<typename _Tp::propagate_on_container_move_assignment>::type>
private: : true_type {};
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::propagate_on_container_move_assignment* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value> template <class _Alloc, bool = __has_propagate_on_container_move_assignment<_Alloc>::value>
struct __propagate_on_container_move_assignment struct __propagate_on_container_move_assignment
@ -1199,16 +1164,13 @@ struct __propagate_on_container_move_assignment<_Alloc, true>
typedef typename _Alloc::propagate_on_container_move_assignment type; typedef typename _Alloc::propagate_on_container_move_assignment type;
}; };
template <class _Tp, class = void>
struct __has_propagate_on_container_swap : false_type {};
template <class _Tp> template <class _Tp>
struct __has_propagate_on_container_swap struct __has_propagate_on_container_swap<_Tp,
{ typename __void_t<typename _Tp::propagate_on_container_swap>::type>
private: : true_type {};
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::propagate_on_container_swap* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value> template <class _Alloc, bool = __has_propagate_on_container_swap<_Alloc>::value>
struct __propagate_on_container_swap struct __propagate_on_container_swap
@ -1222,16 +1184,13 @@ struct __propagate_on_container_swap<_Alloc, true>
typedef typename _Alloc::propagate_on_container_swap type; typedef typename _Alloc::propagate_on_container_swap type;
}; };
template <class _Tp, class = void>
struct __has_is_always_equal : false_type {};
template <class _Tp> template <class _Tp>
struct __has_is_always_equal struct __has_is_always_equal<_Tp,
{ typename __void_t<typename _Tp::is_always_equal>::type>
private: : true_type {};
struct __two {char __lx; char __lxx;};
template <class _Up> static __two __test(...);
template <class _Up> static char __test(typename _Up::is_always_equal* = 0);
public:
static const bool value = sizeof(__test<_Tp>(0)) == 1;
};
template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value> template <class _Alloc, bool = __has_is_always_equal<_Alloc>::value>
struct __is_always_equal struct __is_always_equal
@ -1884,7 +1843,7 @@ public:
return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp))); return static_cast<pointer>(_VSTD::__allocate(__n * sizeof(_Tp)));
} }
_LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT _LIBCPP_INLINE_VISIBILITY void deallocate(pointer __p, size_type) _NOEXCEPT
{_VSTD::__libcpp_deallocate((void*)__p);} {_VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p));}
_LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);} {return size_type(~0) / sizeof(_Tp);}
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) #if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
@ -1900,7 +1859,7 @@ public:
void void
construct(pointer __p) construct(pointer __p)
{ {
::new((void*)__p) _Tp(); ::new((void*) const_cast<_Tp *>(__p)) _Tp();
} }
# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) # if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
@ -1909,14 +1868,14 @@ public:
void void
construct(pointer __p, _A0& __a0) construct(pointer __p, _A0& __a0)
{ {
::new((void*)__p) _Tp(__a0); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
} }
template <class _A0> template <class _A0>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void void
construct(pointer __p, const _A0& __a0) construct(pointer __p, const _A0& __a0)
{ {
::new((void*)__p) _Tp(__a0); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0);
} }
# endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) # endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <class _A0, class _A1> template <class _A0, class _A1>
@ -1924,28 +1883,28 @@ public:
void void
construct(pointer __p, _A0& __a0, _A1& __a1) construct(pointer __p, _A0& __a0, _A1& __a1)
{ {
::new((void*)__p) _Tp(__a0, __a1); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
} }
template <class _A0, class _A1> template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void void
construct(pointer __p, const _A0& __a0, _A1& __a1) construct(pointer __p, const _A0& __a0, _A1& __a1)
{ {
::new((void*)__p) _Tp(__a0, __a1); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
} }
template <class _A0, class _A1> template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void void
construct(pointer __p, _A0& __a0, const _A1& __a1) construct(pointer __p, _A0& __a0, const _A1& __a1)
{ {
::new((void*)__p) _Tp(__a0, __a1); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
} }
template <class _A0, class _A1> template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
void void
construct(pointer __p, const _A0& __a0, const _A1& __a1) construct(pointer __p, const _A0& __a0, const _A1& __a1)
{ {
::new((void*)__p) _Tp(__a0, __a1); ::new((void*) const_cast<_Tp *>(__p)) _Tp(__a0, __a1);
} }
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) #endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();} _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
@ -3890,7 +3849,9 @@ public:
template <class _Dp> template <class _Dp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_INLINE_VISIBILITY
_Dp* __get_deleter() const _NOEXCEPT _Dp* __get_deleter() const _NOEXCEPT
{return (_Dp*)(__cntrl_ ? __cntrl_->__get_deleter(typeid(_Dp)) : 0);} {return static_cast<_Dp*>(__cntrl_
? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
: nullptr);}
#endif // _LIBCPP_NO_RTTI #endif // _LIBCPP_NO_RTTI
#ifndef _LIBCPP_HAS_NO_VARIADICS #ifndef _LIBCPP_HAS_NO_VARIADICS

View File

@ -25,6 +25,18 @@ template <class InputIterator, class T, class BinaryOperation>
T T
accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);
template<class InputIterator>
typename iterator_traits<InputIterator>::value_type
reduce(InputIterator first, InputIterator last); // C++17
template<class InputIterator, class T>
T
reduce(InputIterator first, InputIterator last, T init); // C++17
template<class InputIterator, class T, class BinaryOperation>
T
reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op); // C++17
template <class InputIterator1, class InputIterator2, class T> template <class InputIterator1, class InputIterator2, class T>
T T
inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init);
@ -34,6 +46,23 @@ template <class InputIterator1, class InputIterator2, class T, class BinaryOpera
inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,
T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2);
template<class InputIterator1, class InputIterator2, class T>
T
transform_reduce(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init); // C++17
template<class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2>
T
transform_reduce(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, T init,
BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); // C++17
template<class InputIterator, class T, class BinaryOperation, class UnaryOperation>
T
transform_reduce(InputIterator first, InputIterator last, T init,
BinaryOperation binary_op, UnaryOperation unary_op); // C++17
template <class InputIterator, class OutputIterator> template <class InputIterator, class OutputIterator>
OutputIterator OutputIterator
partial_sum(InputIterator first, InputIterator last, OutputIterator result); partial_sum(InputIterator first, InputIterator last, OutputIterator result);
@ -114,6 +143,35 @@ accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOpe
return __init; return __init;
} }
#if _LIBCPP_STD_VER > 14
template <class _InputIterator, class _Tp, class _BinaryOp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
reduce(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOp __b)
{
for (; __first != __last; ++__first)
__init = __b(__init, *__first);
return __init;
}
template <class _InputIterator, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
reduce(_InputIterator __first, _InputIterator __last, _Tp __init)
{
return _VSTD::reduce(__first, __last, __init, _VSTD::plus<>());
}
template <class _InputIterator>
inline _LIBCPP_INLINE_VISIBILITY
typename iterator_traits<_InputIterator>::value_type
reduce(_InputIterator __first, _InputIterator __last)
{
return _VSTD::reduce(__first, __last,
typename iterator_traits<_InputIterator>::value_type{});
}
#endif
template <class _InputIterator1, class _InputIterator2, class _Tp> template <class _InputIterator1, class _InputIterator2, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
_Tp _Tp
@ -135,6 +193,41 @@ inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2
return __init; return __init;
} }
#if _LIBCPP_STD_VER > 14
template <class _InputIterator, class _Tp, class _BinaryOp, class _UnaryOp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
transform_reduce(_InputIterator __first, _InputIterator __last,
_Tp __init, _BinaryOp __b, _UnaryOp __u)
{
for (; __first != __last; ++__first)
__init = __b(__init, __u(*__first));
return __init;
}
template <class _InputIterator1, class _InputIterator2,
class _Tp, class _BinaryOp1, class _BinaryOp2>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init, _BinaryOp1 __b1, _BinaryOp2 __b2)
{
for (; __first1 != __last1; ++__first1, (void) ++__first2)
__init = __b1(__init, __b2(*__first1, *__first2));
return __init;
}
template <class _InputIterator1, class _InputIterator2, class _Tp>
inline _LIBCPP_INLINE_VISIBILITY
_Tp
transform_reduce(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)
{
return _VSTD::transform_reduce(__first1, __last1, __first2, __init,
_VSTD::plus<>(), _VSTD::multiplies<>());
}
#endif
template <class _InputIterator, class _OutputIterator> template <class _InputIterator, class _OutputIterator>
inline _LIBCPP_INLINE_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
_OutputIterator _OutputIterator

View File

@ -653,6 +653,12 @@ template <class _T1, class _T2>
class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > class _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> >
: public integral_constant<size_t, 2> {}; : public integral_constant<size_t, 2> {};
template <size_t _Ip, class _T1, class _T2>
class _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> >
{
static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
};
template <class _T1, class _T2> template <class _T1, class _T2>
class _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > class _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> >
{ {
@ -924,6 +930,12 @@ template <class _Tp> struct __is_inplace_type_imp<in_place_type_t<_Tp>> : true_t
template <class _Tp> template <class _Tp>
using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>; using __is_inplace_type = __is_inplace_type_imp<__uncvref_t<_Tp>>;
template <class _Tp> struct __is_inplace_index_imp : false_type {};
template <size_t _Idx> struct __is_inplace_index_imp<in_place_index_t<_Idx>> : true_type {};
template <class _Tp>
using __is_inplace_index = __is_inplace_index_imp<__uncvref_t<_Tp>>;
#endif // _LIBCPP_STD_VER > 14 #endif // _LIBCPP_STD_VER > 14
template <class _Arg, class _Result> template <class _Arg, class _Result>

View File

@ -278,7 +278,7 @@ struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, const volatile _Tp>
template <size_t _Ip, class... _Types> template <size_t _Ip, class... _Types>
struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> { struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
static_assert(_Ip < sizeof...(_Types)); static_assert(_Ip < sizeof...(_Types), "Index out of bounds in std::variant_alternative<>");
using type = __type_pack_element<_Ip, _Types...>; using type = __type_pack_element<_Ip, _Types...>;
}; };

View File

@ -842,7 +842,7 @@ void __rename(const path& from, const path& to, std::error_code *ec) {
} }
void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) { void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) {
if (::truncate(p.c_str(), static_cast<long>(size)) == -1) if (::truncate(p.c_str(), static_cast<::off_t>(size)) == -1)
set_or_throw(ec, "resize_file", p); set_or_throw(ec, "resize_file", p);
else if (ec) else if (ec)
ec->clear(); ec->clear();

View File

@ -6158,6 +6158,4 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t,
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
_LIBCPP_END_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD

View File

@ -0,0 +1,16 @@
//===------------------------- vector.cpp ---------------------------------===//
//
// 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 "vector"
_LIBCPP_BEGIN_NAMESPACE_STD
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>;
_LIBCPP_END_NAMESPACE_STD

View File

@ -10,10 +10,16 @@
#ifndef LLVM_ADT_ALLOCATORLIST_H #ifndef LLVM_ADT_ALLOCATORLIST_H
#define LLVM_ADT_ALLOCATORLIST_H #define LLVM_ADT_ALLOCATORLIST_H
#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include "llvm/ADT/simple_ilist.h" #include "llvm/ADT/simple_ilist.h"
#include "llvm/Support/Allocator.h" #include "llvm/Support/Allocator.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits> #include <type_traits>
#include <utility>
namespace llvm { namespace llvm {
@ -39,7 +45,8 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
T V; T V;
}; };
typedef simple_ilist<Node> list_type; using list_type = simple_ilist<Node>;
list_type List; list_type List;
AllocatorT &getAlloc() { return *this; } AllocatorT &getAlloc() { return *this; }
@ -51,13 +58,17 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
struct Cloner { struct Cloner {
AllocatorList &AL; AllocatorList &AL;
Cloner(AllocatorList &AL) : AL(AL) {} Cloner(AllocatorList &AL) : AL(AL) {}
Node *operator()(const Node &N) const { return AL.create(N.V); } Node *operator()(const Node &N) const { return AL.create(N.V); }
}; };
struct Disposer { struct Disposer {
AllocatorList &AL; AllocatorList &AL;
Disposer(AllocatorList &AL) : AL(AL) {} Disposer(AllocatorList &AL) : AL(AL) {}
void operator()(Node *N) const { void operator()(Node *N) const {
N->~Node(); N->~Node();
AL.getAlloc().Deallocate(N); AL.getAlloc().Deallocate(N);
@ -65,13 +76,13 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
}; };
public: public:
typedef T value_type; using value_type = T;
typedef T *pointer; using pointer = T *;
typedef T &reference; using reference = T &;
typedef const T *const_pointer; using const_pointer = const T *;
typedef const T &const_reference; using const_reference = const T &;
typedef typename list_type::size_type size_type; using size_type = typename list_type::size_type;
typedef typename list_type::difference_type difference_type; using difference_type = typename list_type::difference_type;
private: private:
template <class ValueT, class IteratorBase> template <class ValueT, class IteratorBase>
@ -83,20 +94,18 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
friend class IteratorImpl; friend class IteratorImpl;
friend AllocatorList; friend AllocatorList;
typedef iterator_adaptor_base<IteratorImpl<ValueT, IteratorBase>, using base_type =
IteratorBase, std::bidirectional_iterator_tag, iterator_adaptor_base<IteratorImpl<ValueT, IteratorBase>, IteratorBase,
ValueT> std::bidirectional_iterator_tag, ValueT>;
base_type;
public: public:
typedef ValueT value_type; using value_type = ValueT;
typedef ValueT *pointer; using pointer = ValueT *;
typedef ValueT &reference; using reference = ValueT &;
IteratorImpl() = default; IteratorImpl() = default;
IteratorImpl(const IteratorImpl &) = default; IteratorImpl(const IteratorImpl &) = default;
IteratorImpl &operator=(const IteratorImpl &) = default; IteratorImpl &operator=(const IteratorImpl &) = default;
~IteratorImpl() = default;
explicit IteratorImpl(const IteratorBase &I) : base_type(I) {} explicit IteratorImpl(const IteratorBase &I) : base_type(I) {}
@ -106,6 +115,8 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
OtherIteratorBase, IteratorBase>::value>::type * = nullptr) OtherIteratorBase, IteratorBase>::value>::type * = nullptr)
: base_type(X.wrapped()) {} : base_type(X.wrapped()) {}
~IteratorImpl() = default;
reference operator*() const { return base_type::wrapped()->V; } reference operator*() const { return base_type::wrapped()->V; }
pointer operator->() const { return &operator*(); } pointer operator->() const { return &operator*(); }
@ -118,30 +129,34 @@ template <class T, class AllocatorT> class AllocatorList : AllocatorT {
}; };
public: public:
typedef IteratorImpl<T, typename list_type::iterator> iterator; using iterator = IteratorImpl<T, typename list_type::iterator>;
typedef IteratorImpl<T, typename list_type::reverse_iterator> using reverse_iterator =
reverse_iterator; IteratorImpl<T, typename list_type::reverse_iterator>;
typedef IteratorImpl<const T, typename list_type::const_iterator> using const_iterator =
const_iterator; IteratorImpl<const T, typename list_type::const_iterator>;
typedef IteratorImpl<const T, typename list_type::const_reverse_iterator> using const_reverse_iterator =
const_reverse_iterator; IteratorImpl<const T, typename list_type::const_reverse_iterator>;
AllocatorList() = default; AllocatorList() = default;
AllocatorList(AllocatorList &&X) AllocatorList(AllocatorList &&X)
: AllocatorT(std::move(X.getAlloc())), List(std::move(X.List)) {} : AllocatorT(std::move(X.getAlloc())), List(std::move(X.List)) {}
AllocatorList(const AllocatorList &X) { AllocatorList(const AllocatorList &X) {
List.cloneFrom(X.List, Cloner(*this), Disposer(*this)); List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
} }
AllocatorList &operator=(AllocatorList &&X) { AllocatorList &operator=(AllocatorList &&X) {
clear(); // Dispose of current nodes explicitly. clear(); // Dispose of current nodes explicitly.
List = std::move(X.List); List = std::move(X.List);
getAlloc() = std::move(X.getAlloc()); getAlloc() = std::move(X.getAlloc());
return *this; return *this;
} }
AllocatorList &operator=(const AllocatorList &X) { AllocatorList &operator=(const AllocatorList &X) {
List.cloneFrom(X.List, Cloner(*this), Disposer(*this)); List.cloneFrom(X.List, Cloner(*this), Disposer(*this));
return *this; return *this;
} }
~AllocatorList() { clear(); } ~AllocatorList() { clear(); }
void swap(AllocatorList &RHS) { void swap(AllocatorList &RHS) {

View File

@ -1,4 +1,4 @@
//===--- ArrayRef.h - Array Reference Wrapper -------------------*- C++ -*-===// //===- ArrayRef.h - Array Reference Wrapper ---------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -12,12 +12,21 @@
#include "llvm/ADT/Hashing.h" #include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h" #include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <array> #include <array>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <type_traits>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
/// ArrayRef - Represent a constant reference to an array (0 or more elements /// ArrayRef - Represent a constant reference to an array (0 or more elements
/// consecutively in memory), i.e. a start pointer and a length. It allows /// consecutively in memory), i.e. a start pointer and a length. It allows
/// various APIs to take consecutive elements easily and conveniently. /// various APIs to take consecutive elements easily and conveniently.
@ -32,28 +41,27 @@ namespace llvm {
template<typename T> template<typename T>
class LLVM_NODISCARD ArrayRef { class LLVM_NODISCARD ArrayRef {
public: public:
typedef const T *iterator; using iterator = const T *;
typedef const T *const_iterator; using const_iterator = const T *;
typedef size_t size_type; using size_type = size_t;
using reverse_iterator = std::reverse_iterator<iterator>;
typedef std::reverse_iterator<iterator> reverse_iterator;
private: private:
/// The start of the array, in an external buffer. /// The start of the array, in an external buffer.
const T *Data; const T *Data = nullptr;
/// The number of elements. /// The number of elements.
size_type Length; size_type Length = 0;
public: public:
/// @name Constructors /// @name Constructors
/// @{ /// @{
/// Construct an empty ArrayRef. /// Construct an empty ArrayRef.
/*implicit*/ ArrayRef() : Data(nullptr), Length(0) {} /*implicit*/ ArrayRef() = default;
/// Construct an empty ArrayRef from None. /// Construct an empty ArrayRef from None.
/*implicit*/ ArrayRef(NoneType) : Data(nullptr), Length(0) {} /*implicit*/ ArrayRef(NoneType) {}
/// Construct an ArrayRef from a single element. /// Construct an ArrayRef from a single element.
/*implicit*/ ArrayRef(const T &OneElt) /*implicit*/ ArrayRef(const T &OneElt)
@ -282,9 +290,8 @@ namespace llvm {
template<typename T> template<typename T>
class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> { class LLVM_NODISCARD MutableArrayRef : public ArrayRef<T> {
public: public:
typedef T *iterator; using iterator = T *;
using reverse_iterator = std::reverse_iterator<iterator>;
typedef std::reverse_iterator<iterator> reverse_iterator;
/// Construct an empty MutableArrayRef. /// Construct an empty MutableArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {} /*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
@ -416,19 +423,23 @@ namespace llvm {
/// This is a MutableArrayRef that owns its array. /// This is a MutableArrayRef that owns its array.
template <typename T> class OwningArrayRef : public MutableArrayRef<T> { template <typename T> class OwningArrayRef : public MutableArrayRef<T> {
public: public:
OwningArrayRef() {} OwningArrayRef() = default;
OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {} OwningArrayRef(size_t Size) : MutableArrayRef<T>(new T[Size], Size) {}
OwningArrayRef(ArrayRef<T> Data) OwningArrayRef(ArrayRef<T> Data)
: MutableArrayRef<T>(new T[Data.size()], Data.size()) { : MutableArrayRef<T>(new T[Data.size()], Data.size()) {
std::copy(Data.begin(), Data.end(), this->begin()); std::copy(Data.begin(), Data.end(), this->begin());
} }
OwningArrayRef(OwningArrayRef &&Other) { *this = Other; } OwningArrayRef(OwningArrayRef &&Other) { *this = Other; }
OwningArrayRef &operator=(OwningArrayRef &&Other) { OwningArrayRef &operator=(OwningArrayRef &&Other) {
delete[] this->data(); delete[] this->data();
this->MutableArrayRef<T>::operator=(Other); this->MutableArrayRef<T>::operator=(Other);
Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>()); Other.MutableArrayRef<T>::operator=(MutableArrayRef<T>());
return *this; return *this;
} }
~OwningArrayRef() { delete[] this->data(); } ~OwningArrayRef() { delete[] this->data(); }
}; };
@ -517,13 +528,14 @@ namespace llvm {
// ArrayRefs can be treated like a POD type. // ArrayRefs can be treated like a POD type.
template <typename T> struct isPodLike; template <typename T> struct isPodLike;
template <typename T> struct isPodLike<ArrayRef<T> > { template <typename T> struct isPodLike<ArrayRef<T>> {
static const bool value = true; static const bool value = true;
}; };
template <typename T> hash_code hash_value(ArrayRef<T> S) { template <typename T> hash_code hash_value(ArrayRef<T> S) {
return hash_combine_range(S.begin(), S.end()); return hash_combine_range(S.begin(), S.end());
} }
} // end namespace llvm } // end namespace llvm
#endif // LLVM_ADT_ARRAYREF_H #endif // LLVM_ADT_ARRAYREF_H

View File

@ -25,7 +25,6 @@
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include <iterator> #include <iterator>
#include <queue> #include <queue>
#include <set>
#include <utility> #include <utility>
namespace llvm { namespace llvm {
@ -49,13 +48,13 @@ template <class GraphT,
class bf_iterator class bf_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>, : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
public bf_iterator_storage<SetType> { public bf_iterator_storage<SetType> {
typedef std::iterator<std::forward_iterator_tag, typename GT::NodeRef> super; using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
typedef typename GT::NodeRef NodeRef; using NodeRef = typename GT::NodeRef;
typedef typename GT::ChildIteratorType ChildItTy; using ChildItTy = typename GT::ChildIteratorType;
// First element is the node reference, second is the next child to visit. // First element is the node reference, second is the next child to visit.
typedef std::pair<NodeRef, Optional<ChildItTy>> QueueElement; using QueueElement = std::pair<NodeRef, Optional<ChildItTy>>;
// Visit queue - used to maintain BFS ordering. // Visit queue - used to maintain BFS ordering.
// Optional<> because we need markers for levels. // Optional<> because we need markers for levels.
@ -109,7 +108,7 @@ class bf_iterator
} }
public: public:
typedef typename super::pointer pointer; using pointer = typename super::pointer;
// Provide static begin and end methods as our public "constructors" // Provide static begin and end methods as our public "constructors"
static bf_iterator begin(const GraphT &G) { static bf_iterator begin(const GraphT &G) {

View File

@ -1,4 +1,4 @@
//===--- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ----*- C++ -*--===// //===- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ------*- C++ -*--===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -40,12 +40,12 @@ class DAGDeltaAlgorithm {
virtual void anchor(); virtual void anchor();
public: public:
typedef unsigned change_ty; using change_ty = unsigned;
typedef std::pair<change_ty, change_ty> edge_ty; using edge_ty = std::pair<change_ty, change_ty>;
// FIXME: Use a decent data structure. // FIXME: Use a decent data structure.
typedef std::set<change_ty> changeset_ty; using changeset_ty = std::set<change_ty>;
typedef std::vector<changeset_ty> changesetlist_ty; using changesetlist_ty = std::vector<changeset_ty>;
public: public:
virtual ~DAGDeltaAlgorithm() = default; virtual ~DAGDeltaAlgorithm() = default;

View File

@ -1,4 +1,4 @@
//===--- DeltaAlgorithm.h - A Set Minimization Algorithm -------*- C++ -*--===// //===- DeltaAlgorithm.h - A Set Minimization Algorithm ---------*- C++ -*--===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -35,10 +35,10 @@ namespace llvm {
/// predicate. /// predicate.
class DeltaAlgorithm { class DeltaAlgorithm {
public: public:
typedef unsigned change_ty; using change_ty = unsigned;
// FIXME: Use a decent data structure. // FIXME: Use a decent data structure.
typedef std::set<change_ty> changeset_ty; using changeset_ty = std::set<change_ty>;
typedef std::vector<changeset_ty> changesetlist_ty; using changesetlist_ty = std::vector<changeset_ty>;
private: private:
/// Cache of failed test results. Successful test results are never cached /// Cache of failed test results. Successful test results are never cached
@ -90,4 +90,4 @@ class DeltaAlgorithm {
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_ADT_DELTAALGORITHM_H

View File

@ -25,8 +25,8 @@
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <iterator> #include <iterator>
#include <limits>
#include <new> #include <new>
#include <type_traits>
#include <utility> #include <utility>
namespace llvm { namespace llvm {
@ -57,14 +57,15 @@ class DenseMapBase : public DebugEpochBase {
using const_arg_type_t = typename const_pointer_or_const_ref<T>::type; using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
public: public:
typedef unsigned size_type; using size_type = unsigned;
typedef KeyT key_type; using key_type = KeyT;
typedef ValueT mapped_type; using mapped_type = ValueT;
typedef BucketT value_type; using value_type = BucketT;
using iterator = DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT>;
using const_iterator =
DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>;
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT> iterator;
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>
const_iterator;
inline iterator begin() { inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this); return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
@ -387,15 +388,18 @@ class DenseMapBase : public DebugEpochBase {
static unsigned getHashValue(const KeyT &Val) { static unsigned getHashValue(const KeyT &Val) {
return KeyInfoT::getHashValue(Val); return KeyInfoT::getHashValue(Val);
} }
template<typename LookupKeyT> template<typename LookupKeyT>
static unsigned getHashValue(const LookupKeyT &Val) { static unsigned getHashValue(const LookupKeyT &Val) {
return KeyInfoT::getHashValue(Val); return KeyInfoT::getHashValue(Val);
} }
static const KeyT getEmptyKey() { static const KeyT getEmptyKey() {
static_assert(std::is_base_of<DenseMapBase, DerivedT>::value, static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
"Must pass the derived type to this template!"); "Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey(); return KeyInfoT::getEmptyKey();
} }
static const KeyT getTombstoneKey() { static const KeyT getTombstoneKey() {
return KeyInfoT::getTombstoneKey(); return KeyInfoT::getTombstoneKey();
} }
@ -404,39 +408,51 @@ class DenseMapBase : public DebugEpochBase {
unsigned getNumEntries() const { unsigned getNumEntries() const {
return static_cast<const DerivedT *>(this)->getNumEntries(); return static_cast<const DerivedT *>(this)->getNumEntries();
} }
void setNumEntries(unsigned Num) { void setNumEntries(unsigned Num) {
static_cast<DerivedT *>(this)->setNumEntries(Num); static_cast<DerivedT *>(this)->setNumEntries(Num);
} }
void incrementNumEntries() { void incrementNumEntries() {
setNumEntries(getNumEntries() + 1); setNumEntries(getNumEntries() + 1);
} }
void decrementNumEntries() { void decrementNumEntries() {
setNumEntries(getNumEntries() - 1); setNumEntries(getNumEntries() - 1);
} }
unsigned getNumTombstones() const { unsigned getNumTombstones() const {
return static_cast<const DerivedT *>(this)->getNumTombstones(); return static_cast<const DerivedT *>(this)->getNumTombstones();
} }
void setNumTombstones(unsigned Num) { void setNumTombstones(unsigned Num) {
static_cast<DerivedT *>(this)->setNumTombstones(Num); static_cast<DerivedT *>(this)->setNumTombstones(Num);
} }
void incrementNumTombstones() { void incrementNumTombstones() {
setNumTombstones(getNumTombstones() + 1); setNumTombstones(getNumTombstones() + 1);
} }
void decrementNumTombstones() { void decrementNumTombstones() {
setNumTombstones(getNumTombstones() - 1); setNumTombstones(getNumTombstones() - 1);
} }
const BucketT *getBuckets() const { const BucketT *getBuckets() const {
return static_cast<const DerivedT *>(this)->getBuckets(); return static_cast<const DerivedT *>(this)->getBuckets();
} }
BucketT *getBuckets() { BucketT *getBuckets() {
return static_cast<DerivedT *>(this)->getBuckets(); return static_cast<DerivedT *>(this)->getBuckets();
} }
unsigned getNumBuckets() const { unsigned getNumBuckets() const {
return static_cast<const DerivedT *>(this)->getNumBuckets(); return static_cast<const DerivedT *>(this)->getNumBuckets();
} }
BucketT *getBucketsEnd() { BucketT *getBucketsEnd() {
return getBuckets() + getNumBuckets(); return getBuckets() + getNumBuckets();
} }
const BucketT *getBucketsEnd() const { const BucketT *getBucketsEnd() const {
return getBuckets() + getNumBuckets(); return getBuckets() + getNumBuckets();
} }
@ -587,10 +603,11 @@ template <typename KeyT, typename ValueT,
typename BucketT = detail::DenseMapPair<KeyT, ValueT>> typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>, class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
KeyT, ValueT, KeyInfoT, BucketT> { KeyT, ValueT, KeyInfoT, BucketT> {
friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
// Lift some types from the dependent base class into this class for // Lift some types from the dependent base class into this class for
// simplicity of referring to them. // simplicity of referring to them.
typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT; using BaseT = DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
BucketT *Buckets; BucketT *Buckets;
unsigned NumEntries; unsigned NumEntries;
@ -705,6 +722,7 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
unsigned getNumEntries() const { unsigned getNumEntries() const {
return NumEntries; return NumEntries;
} }
void setNumEntries(unsigned Num) { void setNumEntries(unsigned Num) {
NumEntries = Num; NumEntries = Num;
} }
@ -712,6 +730,7 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
unsigned getNumTombstones() const { unsigned getNumTombstones() const {
return NumTombstones; return NumTombstones;
} }
void setNumTombstones(unsigned Num) { void setNumTombstones(unsigned Num) {
NumTombstones = Num; NumTombstones = Num;
} }
@ -743,10 +762,12 @@ class SmallDenseMap
: public DenseMapBase< : public DenseMapBase<
SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT, SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
ValueT, KeyInfoT, BucketT> { ValueT, KeyInfoT, BucketT> {
friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
// Lift some types from the dependent base class into this class for // Lift some types from the dependent base class into this class for
// simplicity of referring to them. // simplicity of referring to them.
typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT; using BaseT = DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
static_assert(isPowerOf2_64(InlineBuckets), static_assert(isPowerOf2_64(InlineBuckets),
"InlineBuckets must be a power of 2."); "InlineBuckets must be a power of 2.");
@ -972,6 +993,7 @@ class SmallDenseMap
unsigned getNumEntries() const { unsigned getNumEntries() const {
return NumEntries; return NumEntries;
} }
void setNumEntries(unsigned Num) { void setNumEntries(unsigned Num) {
// NumEntries is hardcoded to be 31 bits wide. // NumEntries is hardcoded to be 31 bits wide.
assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries"); assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries");
@ -981,6 +1003,7 @@ class SmallDenseMap
unsigned getNumTombstones() const { unsigned getNumTombstones() const {
return NumTombstones; return NumTombstones;
} }
void setNumTombstones(unsigned Num) { void setNumTombstones(unsigned Num) {
NumTombstones = Num; NumTombstones = Num;
} }
@ -992,15 +1015,18 @@ class SmallDenseMap
// 'storage.buffer' static type is 'char *'. // 'storage.buffer' static type is 'char *'.
return reinterpret_cast<const BucketT *>(storage.buffer); return reinterpret_cast<const BucketT *>(storage.buffer);
} }
BucketT *getInlineBuckets() { BucketT *getInlineBuckets() {
return const_cast<BucketT *>( return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getInlineBuckets()); const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
} }
const LargeRep *getLargeRep() const { const LargeRep *getLargeRep() const {
assert(!Small); assert(!Small);
// Note, same rule about aliasing as with getInlineBuckets. // Note, same rule about aliasing as with getInlineBuckets.
return reinterpret_cast<const LargeRep *>(storage.buffer); return reinterpret_cast<const LargeRep *>(storage.buffer);
} }
LargeRep *getLargeRep() { LargeRep *getLargeRep() {
return const_cast<LargeRep *>( return const_cast<LargeRep *>(
const_cast<const SmallDenseMap *>(this)->getLargeRep()); const_cast<const SmallDenseMap *>(this)->getLargeRep());
@ -1009,10 +1035,12 @@ class SmallDenseMap
const BucketT *getBuckets() const { const BucketT *getBuckets() const {
return Small ? getInlineBuckets() : getLargeRep()->Buckets; return Small ? getInlineBuckets() : getLargeRep()->Buckets;
} }
BucketT *getBuckets() { BucketT *getBuckets() {
return const_cast<BucketT *>( return const_cast<BucketT *>(
const_cast<const SmallDenseMap *>(this)->getBuckets()); const_cast<const SmallDenseMap *>(this)->getBuckets());
} }
unsigned getNumBuckets() const { unsigned getNumBuckets() const {
return Small ? InlineBuckets : getLargeRep()->NumBuckets; return Small ? InlineBuckets : getLargeRep()->NumBuckets;
} }
@ -1037,23 +1065,25 @@ class SmallDenseMap
template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket, template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
bool IsConst> bool IsConst>
class DenseMapIterator : DebugEpochBase::HandleBase { class DenseMapIterator : DebugEpochBase::HandleBase {
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>; friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>; friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
using ConstIterator = DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
public: public:
typedef ptrdiff_t difference_type; using difference_type = ptrdiff_t;
typedef typename std::conditional<IsConst, const Bucket, Bucket>::type using value_type =
value_type; typename std::conditional<IsConst, const Bucket, Bucket>::type;
typedef value_type *pointer; using pointer = value_type *;
typedef value_type &reference; using reference = value_type &;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
private: private:
pointer Ptr, End; pointer Ptr = nullptr;
pointer End = nullptr;
public: public:
DenseMapIterator() : Ptr(nullptr), End(nullptr) {} DenseMapIterator() = default;
DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch,
bool NoAdvance = false) bool NoAdvance = false)

View File

@ -18,7 +18,10 @@
#include "llvm/ADT/Hashing.h" #include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/PointerLikeTypeTraits.h"
#include "llvm/Support/type_traits.h" #include <cassert>
#include <cstddef>
#include <cstdint>
#include <utility>
namespace llvm { namespace llvm {
@ -38,15 +41,18 @@ struct DenseMapInfo<T*> {
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val); return reinterpret_cast<T*>(Val);
} }
static inline T* getTombstoneKey() { static inline T* getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2); uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable; Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
return reinterpret_cast<T*>(Val); return reinterpret_cast<T*>(Val);
} }
static unsigned getHashValue(const T *PtrVal) { static unsigned getHashValue(const T *PtrVal) {
return (unsigned((uintptr_t)PtrVal) >> 4) ^ return (unsigned((uintptr_t)PtrVal) >> 4) ^
(unsigned((uintptr_t)PtrVal) >> 9); (unsigned((uintptr_t)PtrVal) >> 9);
} }
static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
}; };
@ -55,6 +61,7 @@ template<> struct DenseMapInfo<char> {
static inline char getEmptyKey() { return ~0; } static inline char getEmptyKey() { return ~0; }
static inline char getTombstoneKey() { return ~0 - 1; } static inline char getTombstoneKey() { return ~0 - 1; }
static unsigned getHashValue(const char& Val) { return Val * 37U; } static unsigned getHashValue(const char& Val) { return Val * 37U; }
static bool isEqual(const char &LHS, const char &RHS) { static bool isEqual(const char &LHS, const char &RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -65,6 +72,7 @@ template <> struct DenseMapInfo<unsigned short> {
static inline unsigned short getEmptyKey() { return 0xFFFF; } static inline unsigned short getEmptyKey() { return 0xFFFF; }
static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; } static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; }
static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; } static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; }
static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) { static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -75,6 +83,7 @@ template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0U; } static inline unsigned getEmptyKey() { return ~0U; }
static inline unsigned getTombstoneKey() { return ~0U - 1; } static inline unsigned getTombstoneKey() { return ~0U - 1; }
static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } static unsigned getHashValue(const unsigned& Val) { return Val * 37U; }
static bool isEqual(const unsigned& LHS, const unsigned& RHS) { static bool isEqual(const unsigned& LHS, const unsigned& RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -84,9 +93,11 @@ template<> struct DenseMapInfo<unsigned> {
template<> struct DenseMapInfo<unsigned long> { template<> struct DenseMapInfo<unsigned long> {
static inline unsigned long getEmptyKey() { return ~0UL; } static inline unsigned long getEmptyKey() { return ~0UL; }
static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } static inline unsigned long getTombstoneKey() { return ~0UL - 1L; }
static unsigned getHashValue(const unsigned long& Val) { static unsigned getHashValue(const unsigned long& Val) {
return (unsigned)(Val * 37UL); return (unsigned)(Val * 37UL);
} }
static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -96,9 +107,11 @@ template<> struct DenseMapInfo<unsigned long> {
template<> struct DenseMapInfo<unsigned long long> { template<> struct DenseMapInfo<unsigned long long> {
static inline unsigned long long getEmptyKey() { return ~0ULL; } static inline unsigned long long getEmptyKey() { return ~0ULL; }
static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; }
static unsigned getHashValue(const unsigned long long& Val) { static unsigned getHashValue(const unsigned long long& Val) {
return (unsigned)(Val * 37ULL); return (unsigned)(Val * 37ULL);
} }
static bool isEqual(const unsigned long long& LHS, static bool isEqual(const unsigned long long& LHS,
const unsigned long long& RHS) { const unsigned long long& RHS) {
return LHS == RHS; return LHS == RHS;
@ -118,6 +131,7 @@ template<> struct DenseMapInfo<int> {
static inline int getEmptyKey() { return 0x7fffffff; } static inline int getEmptyKey() { return 0x7fffffff; }
static inline int getTombstoneKey() { return -0x7fffffff - 1; } static inline int getTombstoneKey() { return -0x7fffffff - 1; }
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); }
static bool isEqual(const int& LHS, const int& RHS) { static bool isEqual(const int& LHS, const int& RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -128,10 +142,13 @@ template<> struct DenseMapInfo<long> {
static inline long getEmptyKey() { static inline long getEmptyKey() {
return (1UL << (sizeof(long) * 8 - 1)) - 1UL; return (1UL << (sizeof(long) * 8 - 1)) - 1UL;
} }
static inline long getTombstoneKey() { return getEmptyKey() - 1L; } static inline long getTombstoneKey() { return getEmptyKey() - 1L; }
static unsigned getHashValue(const long& Val) { static unsigned getHashValue(const long& Val) {
return (unsigned)(Val * 37UL); return (unsigned)(Val * 37UL);
} }
static bool isEqual(const long& LHS, const long& RHS) { static bool isEqual(const long& LHS, const long& RHS) {
return LHS == RHS; return LHS == RHS;
} }
@ -141,9 +158,11 @@ template<> struct DenseMapInfo<long> {
template<> struct DenseMapInfo<long long> { template<> struct DenseMapInfo<long long> {
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; }
static unsigned getHashValue(const long long& Val) { static unsigned getHashValue(const long long& Val) {
return (unsigned)(Val * 37ULL); return (unsigned)(Val * 37ULL);
} }
static bool isEqual(const long long& LHS, static bool isEqual(const long long& LHS,
const long long& RHS) { const long long& RHS) {
return LHS == RHS; return LHS == RHS;
@ -152,19 +171,21 @@ template<> struct DenseMapInfo<long long> {
// Provide DenseMapInfo for all pairs whose members have info. // Provide DenseMapInfo for all pairs whose members have info.
template<typename T, typename U> template<typename T, typename U>
struct DenseMapInfo<std::pair<T, U> > { struct DenseMapInfo<std::pair<T, U>> {
typedef std::pair<T, U> Pair; using Pair = std::pair<T, U>;
typedef DenseMapInfo<T> FirstInfo; using FirstInfo = DenseMapInfo<T>;
typedef DenseMapInfo<U> SecondInfo; using SecondInfo = DenseMapInfo<U>;
static inline Pair getEmptyKey() { static inline Pair getEmptyKey() {
return std::make_pair(FirstInfo::getEmptyKey(), return std::make_pair(FirstInfo::getEmptyKey(),
SecondInfo::getEmptyKey()); SecondInfo::getEmptyKey());
} }
static inline Pair getTombstoneKey() { static inline Pair getTombstoneKey() {
return std::make_pair(FirstInfo::getTombstoneKey(), return std::make_pair(FirstInfo::getTombstoneKey(),
SecondInfo::getTombstoneKey()); SecondInfo::getTombstoneKey());
} }
static unsigned getHashValue(const Pair& PairVal) { static unsigned getHashValue(const Pair& PairVal) {
uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
| (uint64_t)SecondInfo::getHashValue(PairVal.second); | (uint64_t)SecondInfo::getHashValue(PairVal.second);
@ -178,6 +199,7 @@ struct DenseMapInfo<std::pair<T, U> > {
key ^= (key >> 31); key ^= (key >> 31);
return (unsigned)key; return (unsigned)key;
} }
static bool isEqual(const Pair &LHS, const Pair &RHS) { static bool isEqual(const Pair &LHS, const Pair &RHS) {
return FirstInfo::isEqual(LHS.first, RHS.first) && return FirstInfo::isEqual(LHS.first, RHS.first) &&
SecondInfo::isEqual(LHS.second, RHS.second); SecondInfo::isEqual(LHS.second, RHS.second);
@ -190,16 +212,19 @@ template <> struct DenseMapInfo<StringRef> {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)), return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)),
0); 0);
} }
static inline StringRef getTombstoneKey() { static inline StringRef getTombstoneKey() {
return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), return StringRef(reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)),
0); 0);
} }
static unsigned getHashValue(StringRef Val) { static unsigned getHashValue(StringRef Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() && assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!"); "Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val)); return (unsigned)(hash_value(Val));
} }
static bool isEqual(StringRef LHS, StringRef RHS) { static bool isEqual(StringRef LHS, StringRef RHS) {
if (RHS.data() == getEmptyKey().data()) if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data(); return LHS.data() == getEmptyKey().data();
@ -215,16 +240,19 @@ template <typename T> struct DenseMapInfo<ArrayRef<T>> {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)), return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
size_t(0)); size_t(0));
} }
static inline ArrayRef<T> getTombstoneKey() { static inline ArrayRef<T> getTombstoneKey() {
return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)), return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
size_t(0)); size_t(0));
} }
static unsigned getHashValue(ArrayRef<T> Val) { static unsigned getHashValue(ArrayRef<T> Val) {
assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!"); assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
assert(Val.data() != getTombstoneKey().data() && assert(Val.data() != getTombstoneKey().data() &&
"Cannot hash the tombstone key!"); "Cannot hash the tombstone key!");
return (unsigned)(hash_value(Val)); return (unsigned)(hash_value(Val));
} }
static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) { static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
if (RHS.data() == getEmptyKey().data()) if (RHS.data() == getEmptyKey().data())
return LHS.data() == getEmptyKey().data(); return LHS.data() == getEmptyKey().data();
@ -236,4 +264,4 @@ template <typename T> struct DenseMapInfo<ArrayRef<T>> {
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_ADT_DENSEMAPINFO_H

View File

@ -15,11 +15,18 @@
#define LLVM_ADT_DENSESET_H #define LLVM_ADT_DENSESET_H
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cstddef>
#include <initializer_list> #include <initializer_list>
#include <iterator>
#include <utility>
namespace llvm { namespace llvm {
namespace detail { namespace detail {
struct DenseSetEmpty {}; struct DenseSetEmpty {};
// Use the empty base class trick so we can create a DenseMap where the buckets // Use the empty base class trick so we can create a DenseMap where the buckets
@ -48,13 +55,14 @@ class DenseSetImpl {
static_assert(sizeof(typename MapTy::value_type) == sizeof(ValueT), static_assert(sizeof(typename MapTy::value_type) == sizeof(ValueT),
"DenseMap buckets unexpectedly large!"); "DenseMap buckets unexpectedly large!");
MapTy TheMap; MapTy TheMap;
template <typename T> template <typename T>
using const_arg_type_t = typename const_pointer_or_const_ref<T>::type; using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
public: public:
typedef ValueT key_type; using key_type = ValueT;
typedef ValueT value_type; using value_type = ValueT;
typedef unsigned size_type; using size_type = unsigned;
explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {} explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {}
@ -100,11 +108,11 @@ class DenseSetImpl {
friend class ConstIterator; friend class ConstIterator;
public: public:
typedef typename MapTy::iterator::difference_type difference_type; using difference_type = typename MapTy::iterator::difference_type;
typedef ValueT value_type; using value_type = ValueT;
typedef value_type *pointer; using pointer = value_type *;
typedef value_type &reference; using reference = value_type &;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
Iterator() = default; Iterator() = default;
Iterator(const typename MapTy::iterator &i) : I(i) {} Iterator(const typename MapTy::iterator &i) : I(i) {}
@ -126,16 +134,14 @@ class DenseSetImpl {
friend class Iterator; friend class Iterator;
public: public:
typedef typename MapTy::const_iterator::difference_type difference_type; using difference_type = typename MapTy::const_iterator::difference_type;
typedef ValueT value_type; using value_type = ValueT;
typedef value_type *pointer; using pointer = value_type *;
typedef value_type &reference; using reference = value_type &;
typedef std::forward_iterator_tag iterator_category; using iterator_category = std::forward_iterator_tag;
ConstIterator(const Iterator &B) : I(B.I) {}
ConstIterator() = default; ConstIterator() = default;
ConstIterator(const Iterator &B) : I(B.I) {}
ConstIterator(const typename MapTy::const_iterator &i) : I(i) {} ConstIterator(const typename MapTy::const_iterator &i) : I(i) {}
const ValueT &operator*() const { return I->getFirst(); } const ValueT &operator*() const { return I->getFirst(); }
@ -147,8 +153,8 @@ class DenseSetImpl {
bool operator!=(const ConstIterator& X) const { return I != X.I; } bool operator!=(const ConstIterator& X) const { return I != X.I; }
}; };
typedef Iterator iterator; using iterator = Iterator;
typedef ConstIterator const_iterator; using const_iterator = ConstIterator;
iterator begin() { return Iterator(TheMap.begin()); } iterator begin() { return Iterator(TheMap.begin()); }
iterator end() { return Iterator(TheMap.end()); } iterator end() { return Iterator(TheMap.end()); }
@ -208,7 +214,7 @@ class DenseSetImpl {
} }
}; };
} // namespace detail } // end namespace detail
/// Implements a dense probed hash-table based set. /// Implements a dense probed hash-table based set.
template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>> template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>>
@ -246,4 +252,4 @@ class SmallDenseSet
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_ADT_DENSESET_H

View File

@ -68,13 +68,14 @@ class df_iterator_storage<SetType, true> {
// cross edges in the spanning tree but is not used in the common case. // cross edges in the spanning tree but is not used in the common case.
template <typename NodeRef, unsigned SmallSize=8> template <typename NodeRef, unsigned SmallSize=8>
struct df_iterator_default_set : public SmallPtrSet<NodeRef, SmallSize> { struct df_iterator_default_set : public SmallPtrSet<NodeRef, SmallSize> {
typedef SmallPtrSet<NodeRef, SmallSize> BaseSet; using BaseSet = SmallPtrSet<NodeRef, SmallSize>;
typedef typename BaseSet::iterator iterator; using iterator = typename BaseSet::iterator;
std::pair<iterator,bool> insert(NodeRef N) { return BaseSet::insert(N) ; }
std::pair<iterator,bool> insert(NodeRef N) { return BaseSet::insert(N); }
template <typename IterT> template <typename IterT>
void insert(IterT Begin, IterT End) { BaseSet::insert(Begin,End); } void insert(IterT Begin, IterT End) { BaseSet::insert(Begin,End); }
void completed(NodeRef) { } void completed(NodeRef) {}
}; };
// Generic Depth First Iterator // Generic Depth First Iterator
@ -85,15 +86,14 @@ template <class GraphT,
class df_iterator class df_iterator
: public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>, : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
public df_iterator_storage<SetType, ExtStorage> { public df_iterator_storage<SetType, ExtStorage> {
typedef std::iterator<std::forward_iterator_tag, typename GT::NodeRef> super; using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
using NodeRef = typename GT::NodeRef;
typedef typename GT::NodeRef NodeRef; using ChildItTy = typename GT::ChildIteratorType;
typedef typename GT::ChildIteratorType ChildItTy;
// First element is node reference, second is the 'next child' to visit. // First element is node reference, second is the 'next child' to visit.
// The second child is initialized lazily to pick up graph changes during the // The second child is initialized lazily to pick up graph changes during the
// DFS. // DFS.
typedef std::pair<NodeRef, Optional<ChildItTy>> StackElement; using StackElement = std::pair<NodeRef, Optional<ChildItTy>>;
// VisitStack - Used to maintain the ordering. Top = current block // VisitStack - Used to maintain the ordering. Top = current block
std::vector<StackElement> VisitStack; std::vector<StackElement> VisitStack;
@ -103,12 +103,15 @@ class df_iterator
this->Visited.insert(Node); this->Visited.insert(Node);
VisitStack.push_back(StackElement(Node, None)); VisitStack.push_back(StackElement(Node, None));
} }
inline df_iterator() = default; // End is when stack is empty inline df_iterator() = default; // End is when stack is empty
inline df_iterator(NodeRef Node, SetType &S) inline df_iterator(NodeRef Node, SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) { : df_iterator_storage<SetType, ExtStorage>(S) {
if (this->Visited.insert(Node).second) if (this->Visited.insert(Node).second)
VisitStack.push_back(StackElement(Node, None)); VisitStack.push_back(StackElement(Node, None));
} }
inline df_iterator(SetType &S) inline df_iterator(SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) { : df_iterator_storage<SetType, ExtStorage>(S) {
// End is when stack is empty // End is when stack is empty
@ -142,7 +145,7 @@ class df_iterator
} }
public: public:
typedef typename super::pointer pointer; using pointer = typename super::pointer;
// Provide static begin and end methods as our public "constructors" // Provide static begin and end methods as our public "constructors"
static df_iterator begin(const GraphT &G) { static df_iterator begin(const GraphT &G) {

View File

@ -1,4 +1,4 @@
//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===// //===- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes ---*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -69,6 +69,7 @@ class EquivalenceClasses {
/// leader is determined by a bit stolen from one of the pointers. /// leader is determined by a bit stolen from one of the pointers.
class ECValue { class ECValue {
friend class EquivalenceClasses; friend class EquivalenceClasses;
mutable const ECValue *Leader, *Next; mutable const ECValue *Leader, *Next;
ElemTy Data; ElemTy Data;
@ -141,14 +142,14 @@ class EquivalenceClasses {
// //
/// iterator* - Provides a way to iterate over all values in the set. /// iterator* - Provides a way to iterate over all values in the set.
typedef typename std::set<ECValue>::const_iterator iterator; using iterator = typename std::set<ECValue>::const_iterator;
iterator begin() const { return TheMapping.begin(); } iterator begin() const { return TheMapping.begin(); }
iterator end() const { return TheMapping.end(); } iterator end() const { return TheMapping.end(); }
bool empty() const { return TheMapping.empty(); } bool empty() const { return TheMapping.empty(); }
/// member_* Iterate over the members of an equivalence class. /// member_* Iterate over the members of an equivalence class.
///
class member_iterator; class member_iterator;
member_iterator member_begin(iterator I) const { member_iterator member_begin(iterator I) const {
// Only leaders provide anything to iterate over. // Only leaders provide anything to iterate over.
@ -204,7 +205,6 @@ class EquivalenceClasses {
/// equivalence class it is in. This does the path-compression part that /// equivalence class it is in. This does the path-compression part that
/// makes union-find "union findy". This returns an end iterator if the value /// makes union-find "union findy". This returns an end iterator if the value
/// is not in the equivalence class. /// is not in the equivalence class.
///
member_iterator findLeader(iterator I) const { member_iterator findLeader(iterator I) const {
if (I == TheMapping.end()) return member_end(); if (I == TheMapping.end()) return member_end();
return member_iterator(I->getLeader()); return member_iterator(I->getLeader());
@ -241,15 +241,17 @@ class EquivalenceClasses {
class member_iterator : public std::iterator<std::forward_iterator_tag, class member_iterator : public std::iterator<std::forward_iterator_tag,
const ElemTy, ptrdiff_t> { const ElemTy, ptrdiff_t> {
typedef std::iterator<std::forward_iterator_tag,
const ElemTy, ptrdiff_t> super;
const ECValue *Node;
friend class EquivalenceClasses; friend class EquivalenceClasses;
using super = std::iterator<std::forward_iterator_tag,
const ElemTy, ptrdiff_t>;
const ECValue *Node;
public: public:
typedef size_t size_type; using size_type = size_t;
typedef typename super::pointer pointer; using pointer = typename super::pointer;
typedef typename super::reference reference; using reference = typename super::reference;
explicit member_iterator() = default; explicit member_iterator() = default;
explicit member_iterator(const ECValue *N) : Node(N) {} explicit member_iterator(const ECValue *N) : Node(N) {}

View File

@ -40,7 +40,7 @@ namespace llvm {
/// FoldingSetNode. The node class must also define a Profile method used to /// FoldingSetNode. The node class must also define a Profile method used to
/// establish the unique bits of data for the node. The Profile method is /// establish the unique bits of data for the node. The Profile method is
/// passed a FoldingSetNodeID object which is used to gather the bits. Just /// passed a FoldingSetNodeID object which is used to gather the bits. Just
/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class. /// call one of the Add* functions defined in the FoldingSetBase::NodeID class.
/// NOTE: That the folding set does not own the nodes and it is the /// NOTE: That the folding set does not own the nodes and it is the
/// responsibility of the user to dispose of the nodes. /// responsibility of the user to dispose of the nodes.
/// ///
@ -104,13 +104,13 @@ class FoldingSetNodeID;
class StringRef; class StringRef;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSetImpl - Implements the folding set functionality. The main /// FoldingSetBase - Implements the folding set functionality. The main
/// structure is an array of buckets. Each bucket is indexed by the hash of /// structure is an array of buckets. Each bucket is indexed by the hash of
/// the nodes it contains. The bucket itself points to the nodes contained /// the nodes it contains. The bucket itself points to the nodes contained
/// in the bucket via a singly linked list. The last node in the list points /// in the bucket via a singly linked list. The last node in the list points
/// back to the bucket to facilitate node removal. /// back to the bucket to facilitate node removal.
/// ///
class FoldingSetImpl { class FoldingSetBase {
virtual void anchor(); // Out of line virtual method. virtual void anchor(); // Out of line virtual method.
protected: protected:
@ -126,10 +126,10 @@ class FoldingSetImpl {
/// is greater than twice the number of buckets. /// is greater than twice the number of buckets.
unsigned NumNodes; unsigned NumNodes;
explicit FoldingSetImpl(unsigned Log2InitSize = 6); explicit FoldingSetBase(unsigned Log2InitSize = 6);
FoldingSetImpl(FoldingSetImpl &&Arg); FoldingSetBase(FoldingSetBase &&Arg);
FoldingSetImpl &operator=(FoldingSetImpl &&RHS); FoldingSetBase &operator=(FoldingSetBase &&RHS);
~FoldingSetImpl(); ~FoldingSetBase();
public: public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@ -152,33 +152,6 @@ class FoldingSetImpl {
/// clear - Remove all nodes from the folding set. /// clear - Remove all nodes from the folding set.
void clear(); void clear();
/// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set.
bool RemoveNode(Node *N);
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and return
/// it instead.
Node *GetOrInsertNode(Node *N);
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos.
void InsertNode(Node *N, void *InsertPos);
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set.
void InsertNode(Node *N) {
Node *Inserted = GetOrInsertNode(N);
(void)Inserted;
assert(Inserted == N && "Node already inserted!");
}
/// size - Returns the number of nodes in the folding set. /// size - Returns the number of nodes in the folding set.
unsigned size() const { return NumNodes; } unsigned size() const { return NumNodes; }
@ -220,6 +193,28 @@ class FoldingSetImpl {
/// ComputeNodeHash - Instantiations of the FoldingSet template implement /// ComputeNodeHash - Instantiations of the FoldingSet template implement
/// this function to compute a hash value for the given node. /// this function to compute a hash value for the given node.
virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0; virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
// The below methods are protected to encourage subclasses to provide a more
// type-safe API.
/// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set.
bool RemoveNode(Node *N);
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and return
/// it instead.
Node *GetOrInsertNode(Node *N);
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos.
void InsertNode(Node *N, void *InsertPos);
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -293,7 +288,7 @@ class FoldingSetNodeIDRef {
FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {} FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef, /// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
/// used to lookup the node in the FoldingSetImpl. /// used to lookup the node in the FoldingSetBase.
unsigned ComputeHash() const; unsigned ComputeHash() const;
bool operator==(FoldingSetNodeIDRef) const; bool operator==(FoldingSetNodeIDRef) const;
@ -345,7 +340,7 @@ class FoldingSetNodeID {
inline void clear() { Bits.clear(); } inline void clear() { Bits.clear(); }
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
/// to lookup the node in the FoldingSetImpl. /// to lookup the node in the FoldingSetBase.
unsigned ComputeHash() const; unsigned ComputeHash() const;
/// operator== - Used to compare two nodes to each other. /// operator== - Used to compare two nodes to each other.
@ -368,7 +363,7 @@ class FoldingSetNodeID {
}; };
// Convenience type to hide the implementation of the folding set. // Convenience type to hide the implementation of the folding set.
typedef FoldingSetImpl::Node FoldingSetNode; typedef FoldingSetBase::Node FoldingSetNode;
template<class T> class FoldingSetIterator; template<class T> class FoldingSetIterator;
template<class T> class FoldingSetBucketIterator; template<class T> class FoldingSetBucketIterator;
@ -407,6 +402,71 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
return TempID.ComputeHash(); return TempID.ComputeHash();
} }
//===----------------------------------------------------------------------===//
/// FoldingSetImpl - An implementation detail that lets us share code between
/// FoldingSet and ContextualFoldingSet.
template <class T> class FoldingSetImpl : public FoldingSetBase {
protected:
explicit FoldingSetImpl(unsigned Log2InitSize)
: FoldingSetBase(Log2InitSize) {}
FoldingSetImpl(FoldingSetImpl &&Arg) = default;
FoldingSetImpl &operator=(FoldingSetImpl &&RHS) = default;
~FoldingSetImpl() = default;
public:
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); }
typedef FoldingSetIterator<const T> const_iterator;
const_iterator begin() const { return const_iterator(Buckets); }
const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
typedef FoldingSetBucketIterator<T> bucket_iterator;
bucket_iterator bucket_begin(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
}
bucket_iterator bucket_end(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
}
/// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set.
bool RemoveNode(T *N) { return FoldingSetBase::RemoveNode(N); }
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and
/// return it instead.
T *GetOrInsertNode(T *N) {
return static_cast<T *>(FoldingSetBase::GetOrInsertNode(N));
}
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(ID, InsertPos));
}
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos.
void InsertNode(T *N, void *InsertPos) {
FoldingSetBase::InsertNode(N, InsertPos);
}
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set.
void InsertNode(T *N) {
T *Inserted = GetOrInsertNode(N);
(void)Inserted;
assert(Inserted == N && "Node already inserted!");
}
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// FoldingSet - This template class is used to instantiate a specialized /// FoldingSet - This template class is used to instantiate a specialized
/// implementation of the folding set to the node class T. T must be a /// implementation of the folding set to the node class T. T must be a
@ -416,8 +476,10 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
/// moved-from state is not a valid state for anything other than /// moved-from state is not a valid state for anything other than
/// move-assigning and destroying. This is primarily to enable movable APIs /// move-assigning and destroying. This is primarily to enable movable APIs
/// that incorporate these objects. /// that incorporate these objects.
template <class T> class FoldingSet final : public FoldingSetImpl { template <class T> class FoldingSet final : public FoldingSetImpl<T> {
private: using Super = FoldingSetImpl<T>;
using Node = typename Super::Node;
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier. /// way to convert nodes into a unique specifier.
void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override { void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
@ -442,45 +504,10 @@ template <class T> class FoldingSet final : public FoldingSetImpl {
public: public:
explicit FoldingSet(unsigned Log2InitSize = 6) explicit FoldingSet(unsigned Log2InitSize = 6)
: FoldingSetImpl(Log2InitSize) {} : Super(Log2InitSize) {}
FoldingSet(FoldingSet &&Arg) : FoldingSetImpl(std::move(Arg)) {} FoldingSet(FoldingSet &&Arg) = default;
FoldingSet &operator=(FoldingSet &&RHS) { FoldingSet &operator=(FoldingSet &&RHS) = default;
(void)FoldingSetImpl::operator=(std::move(RHS));
return *this;
}
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); }
typedef FoldingSetIterator<const T> const_iterator;
const_iterator begin() const { return const_iterator(Buckets); }
const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
typedef FoldingSetBucketIterator<T> bucket_iterator;
bucket_iterator bucket_begin(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
}
bucket_iterator bucket_end(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
}
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and
/// return it instead.
T *GetOrInsertNode(Node *N) {
return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
}
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
}
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -493,74 +520,42 @@ template <class T> class FoldingSet final : public FoldingSetImpl {
/// function with signature /// function with signature
/// void Profile(FoldingSetNodeID &, Ctx); /// void Profile(FoldingSetNodeID &, Ctx);
template <class T, class Ctx> template <class T, class Ctx>
class ContextualFoldingSet final : public FoldingSetImpl { class ContextualFoldingSet final : public FoldingSetImpl<T> {
// Unfortunately, this can't derive from FoldingSet<T> because the // Unfortunately, this can't derive from FoldingSet<T> because the
// construction vtable for FoldingSet<T> requires // construction of the vtable for FoldingSet<T> requires
// FoldingSet<T>::GetNodeProfile to be instantiated, which in turn // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
// requires a single-argument T::Profile(). // requires a single-argument T::Profile().
private: using Super = FoldingSetImpl<T>;
using Node = typename Super::Node;
Ctx Context; Ctx Context;
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier. /// way to convert nodes into a unique specifier.
void GetNodeProfile(FoldingSetImpl::Node *N, void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
FoldingSetNodeID &ID) const override {
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context); ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
} }
bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID, bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
unsigned IDHash, FoldingSetNodeID &TempID) const override { FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID, return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
Context); Context);
} }
unsigned ComputeNodeHash(FoldingSetImpl::Node *N, unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N); T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context); return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
} }
public: public:
explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6) explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
: FoldingSetImpl(Log2InitSize), Context(Context) : Super(Log2InitSize), Context(Context)
{} {}
Ctx getContext() const { return Context; } Ctx getContext() const { return Context; }
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); }
typedef FoldingSetIterator<const T> const_iterator;
const_iterator begin() const { return const_iterator(Buckets); }
const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
typedef FoldingSetBucketIterator<T> bucket_iterator;
bucket_iterator bucket_begin(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
}
bucket_iterator bucket_end(unsigned hash) {
return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
}
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N'
/// and return it instead.
T *GetOrInsertNode(Node *N) {
return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
}
/// FindNodeOrInsertPos - Look up the node specified by ID. If it
/// exists, return it. If not, return the insertion token that will
/// make insertion faster.
T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
}
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -1,4 +1,4 @@
//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===// //===- llvm/ADT/GraphTraits.h - Graph traits template -----------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -41,7 +41,6 @@ struct GraphTraits {
// static ChildIteratorType child_end (NodeRef) // static ChildIteratorType child_end (NodeRef)
// Return iterators that point to the beginning and ending of the child // Return iterators that point to the beginning and ending of the child
// node list for the specified node. // node list for the specified node.
//
// typedef ...iterator nodes_iterator; - dereference to a NodeRef // typedef ...iterator nodes_iterator; - dereference to a NodeRef
// static nodes_iterator nodes_begin(GraphType *G) // static nodes_iterator nodes_begin(GraphType *G)
@ -50,7 +49,6 @@ struct GraphTraits {
// static unsigned size (GraphType *G) // static unsigned size (GraphType *G)
// Return total number of nodes in the graph // Return total number of nodes in the graph
//
// If anyone tries to use this class without having an appropriate // If anyone tries to use this class without having an appropriate
// specialization, make an error. If you get this error, it's because you // specialization, make an error. If you get this error, it's because you
@ -58,11 +56,9 @@ struct GraphTraits {
// graph, or you need to define it for a new graph type. Either that or // graph, or you need to define it for a new graph type. Either that or
// your argument to XXX_begin(...) is unknown or needs to have the proper .h // your argument to XXX_begin(...) is unknown or needs to have the proper .h
// file #include'd. // file #include'd.
// using NodeRef = typename GraphType::UnknownGraphTypeError;
typedef typename GraphType::UnknownGraphTypeError NodeRef;
}; };
// Inverse - This class is used as a little marker class to tell the graph // Inverse - This class is used as a little marker class to tell the graph
// iterator to iterate over the graph in a graph defined "Inverse" ordering. // iterator to iterate over the graph in a graph defined "Inverse" ordering.
// Not all graphs define an inverse ordering, and if they do, it depends on // Not all graphs define an inverse ordering, and if they do, it depends on
@ -73,7 +69,7 @@ struct GraphTraits {
// for (; I != E; ++I) { ... } // for (; I != E; ++I) { ... }
// //
// Which is equivalent to: // Which is equivalent to:
// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M); // df_iterator<Inverse<Method*>> I = idf_begin(M), E = idf_end(M);
// for (; I != E; ++I) { ... } // for (; I != E; ++I) { ... }
// //
template <class GraphType> template <class GraphType>
@ -114,6 +110,7 @@ inverse_children(const typename GraphTraits<GraphType>::NodeRef &G) {
return make_range(GraphTraits<Inverse<GraphType>>::child_begin(G), return make_range(GraphTraits<Inverse<GraphType>>::child_begin(G),
GraphTraits<Inverse<GraphType>>::child_end(G)); GraphTraits<Inverse<GraphType>>::child_end(G));
} }
} // End llvm namespace
#endif } // end namespace llvm
#endif // LLVM_ADT_GRAPHTRAITS_H

View File

@ -63,8 +63,8 @@ class ImmutableListImpl : public FoldingSetNode {
template <typename T> template <typename T>
class ImmutableList { class ImmutableList {
public: public:
typedef T value_type; using value_type = T;
typedef ImmutableListFactory<T> Factory; using Factory = ImmutableListFactory<T>;
private: private:
const ImmutableListImpl<T>* X; const ImmutableListImpl<T>* X;
@ -141,8 +141,8 @@ class ImmutableList {
template <typename T> template <typename T>
class ImmutableListFactory { class ImmutableListFactory {
typedef ImmutableListImpl<T> ListTy; using ListTy = ImmutableListImpl<T>;
typedef FoldingSet<ListTy> CacheTy; using CacheTy = FoldingSet<ListTy>;
CacheTy Cache; CacheTy Cache;
uintptr_t Allocator; uintptr_t Allocator;

View File

@ -26,12 +26,12 @@ namespace llvm {
/// only the first element (the key) is used by isEqual and isLess. /// only the first element (the key) is used by isEqual and isLess.
template <typename T, typename S> template <typename T, typename S>
struct ImutKeyValueInfo { struct ImutKeyValueInfo {
typedef const std::pair<T,S> value_type; using value_type = const std::pair<T,S>;
typedef const value_type& value_type_ref; using value_type_ref = const value_type&;
typedef const T key_type; using key_type = const T;
typedef const T& key_type_ref; using key_type_ref = const T&;
typedef const S data_type; using data_type = const S;
typedef const S& data_type_ref; using data_type_ref = const S&;
static inline key_type_ref KeyOfValue(value_type_ref V) { static inline key_type_ref KeyOfValue(value_type_ref V) {
return V.first; return V.first;
@ -62,13 +62,13 @@ template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT>> typename ValInfo = ImutKeyValueInfo<KeyT,ValT>>
class ImmutableMap { class ImmutableMap {
public: public:
typedef typename ValInfo::value_type value_type; using value_type = typename ValInfo::value_type;
typedef typename ValInfo::value_type_ref value_type_ref; using value_type_ref = typename ValInfo::value_type_ref;
typedef typename ValInfo::key_type key_type; using key_type = typename ValInfo::key_type;
typedef typename ValInfo::key_type_ref key_type_ref; using key_type_ref = typename ValInfo::key_type_ref;
typedef typename ValInfo::data_type data_type; using data_type = typename ValInfo::data_type;
typedef typename ValInfo::data_type_ref data_type_ref; using data_type_ref = typename ValInfo::data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy; using TreeTy = ImutAVLTree<ValInfo>;
protected: protected:
TreeTy* Root; TreeTy* Root;
@ -86,6 +86,10 @@ class ImmutableMap {
if (Root) { Root->retain(); } if (Root) { Root->retain(); }
} }
~ImmutableMap() {
if (Root) { Root->release(); }
}
ImmutableMap &operator=(const ImmutableMap &X) { ImmutableMap &operator=(const ImmutableMap &X) {
if (Root != X.Root) { if (Root != X.Root) {
if (X.Root) { X.Root->retain(); } if (X.Root) { X.Root->retain(); }
@ -95,10 +99,6 @@ class ImmutableMap {
return *this; return *this;
} }
~ImmutableMap() {
if (Root) { Root->release(); }
}
class Factory { class Factory {
typename TreeTy::Factory F; typename TreeTy::Factory F;
const bool Canonicalize; const bool Canonicalize;
@ -166,12 +166,14 @@ class ImmutableMap {
template <typename Callback> template <typename Callback>
struct CBWrapper { struct CBWrapper {
Callback C; Callback C;
void operator()(value_type_ref V) { C(V.first,V.second); } void operator()(value_type_ref V) { C(V.first,V.second); }
}; };
template <typename Callback> template <typename Callback>
struct CBWrapperRef { struct CBWrapperRef {
Callback &C; Callback &C;
CBWrapperRef(Callback& c) : C(c) {} CBWrapperRef(Callback& c) : C(c) {}
void operator()(value_type_ref V) { C(V.first,V.second); } void operator()(value_type_ref V) { C(V.first,V.second); }
@ -254,14 +256,14 @@ template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT>> typename ValInfo = ImutKeyValueInfo<KeyT,ValT>>
class ImmutableMapRef { class ImmutableMapRef {
public: public:
typedef typename ValInfo::value_type value_type; using value_type = typename ValInfo::value_type;
typedef typename ValInfo::value_type_ref value_type_ref; using value_type_ref = typename ValInfo::value_type_ref;
typedef typename ValInfo::key_type key_type; using key_type = typename ValInfo::key_type;
typedef typename ValInfo::key_type_ref key_type_ref; using key_type_ref = typename ValInfo::key_type_ref;
typedef typename ValInfo::data_type data_type; using data_type = typename ValInfo::data_type;
typedef typename ValInfo::data_type_ref data_type_ref; using data_type_ref = typename ValInfo::data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy; using TreeTy = ImutAVLTree<ValInfo>;
typedef typename TreeTy::Factory FactoryTy; using FactoryTy = typename TreeTy::Factory;
protected: protected:
TreeTy *Root; TreeTy *Root;
@ -292,6 +294,11 @@ class ImmutableMapRef {
} }
} }
~ImmutableMapRef() {
if (Root)
Root->release();
}
ImmutableMapRef &operator=(const ImmutableMapRef &X) { ImmutableMapRef &operator=(const ImmutableMapRef &X) {
if (Root != X.Root) { if (Root != X.Root) {
if (X.Root) if (X.Root)
@ -306,11 +313,6 @@ class ImmutableMapRef {
return *this; return *this;
} }
~ImmutableMapRef() {
if (Root)
Root->release();
}
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) { static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
return ImmutableMapRef(0, F); return ImmutableMapRef(0, F);
} }

View File

@ -41,18 +41,16 @@ template <typename ImutInfo> class ImutAVLTreeGenericIterator;
template <typename ImutInfo > template <typename ImutInfo >
class ImutAVLTree { class ImutAVLTree {
public: public:
typedef typename ImutInfo::key_type_ref key_type_ref; using key_type_ref = typename ImutInfo::key_type_ref;
typedef typename ImutInfo::value_type value_type; using value_type = typename ImutInfo::value_type;
typedef typename ImutInfo::value_type_ref value_type_ref; using value_type_ref = typename ImutInfo::value_type_ref;
using Factory = ImutAVLFactory<ImutInfo>;
using iterator = ImutAVLTreeInOrderIterator<ImutInfo>;
typedef ImutAVLFactory<ImutInfo> Factory;
friend class ImutAVLFactory<ImutInfo>; friend class ImutAVLFactory<ImutInfo>;
friend class ImutIntervalAVLFactory<ImutInfo>; friend class ImutIntervalAVLFactory<ImutInfo>;
friend class ImutAVLTreeGenericIterator<ImutInfo>; friend class ImutAVLTreeGenericIterator<ImutInfo>;
typedef ImutAVLTreeInOrderIterator<ImutInfo> iterator;
//===----------------------------------------------------===// //===----------------------------------------------------===//
// Public Interface. // Public Interface.
//===----------------------------------------------------===// //===----------------------------------------------------===//
@ -225,17 +223,17 @@ class ImutAVLTree {
Factory *factory; Factory *factory;
ImutAVLTree *left; ImutAVLTree *left;
ImutAVLTree *right; ImutAVLTree *right;
ImutAVLTree *prev; ImutAVLTree *prev = nullptr;
ImutAVLTree *next; ImutAVLTree *next = nullptr;
unsigned height : 28; unsigned height : 28;
unsigned IsMutable : 1; bool IsMutable : 1;
unsigned IsDigestCached : 1; bool IsDigestCached : 1;
unsigned IsCanonicalized : 1; bool IsCanonicalized : 1;
value_type value; value_type value;
uint32_t digest; uint32_t digest = 0;
uint32_t refCount; uint32_t refCount = 0;
//===----------------------------------------------------===// //===----------------------------------------------------===//
// Internal methods (node manipulation; used by Factory). // Internal methods (node manipulation; used by Factory).
@ -246,9 +244,8 @@ class ImutAVLTree {
/// ImutAVLFactory. /// ImutAVLFactory.
ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, ImutAVLTree(Factory *f, ImutAVLTree* l, ImutAVLTree* r, value_type_ref v,
unsigned height) unsigned height)
: factory(f), left(l), right(r), prev(nullptr), next(nullptr), : factory(f), left(l), right(r), height(height), IsMutable(true),
height(height), IsMutable(true), IsDigestCached(false), IsDigestCached(false), IsCanonicalized(false), value(v)
IsCanonicalized(0), value(v), digest(0), refCount(0)
{ {
if (left) left->retain(); if (left) left->retain();
if (right) right->retain(); if (right) right->retain();
@ -369,11 +366,11 @@ class ImutAVLTree {
template <typename ImutInfo > template <typename ImutInfo >
class ImutAVLFactory { class ImutAVLFactory {
friend class ImutAVLTree<ImutInfo>; friend class ImutAVLTree<ImutInfo>;
typedef ImutAVLTree<ImutInfo> TreeTy;
typedef typename TreeTy::value_type_ref value_type_ref;
typedef typename TreeTy::key_type_ref key_type_ref;
typedef DenseMap<unsigned, TreeTy*> CacheTy; using TreeTy = ImutAVLTree<ImutInfo>;
using value_type_ref = typename TreeTy::value_type_ref;
using key_type_ref = typename TreeTy::key_type_ref;
using CacheTy = DenseMap<unsigned, TreeTy*>;
CacheTy Cache; CacheTy Cache;
uintptr_t Allocator; uintptr_t Allocator;
@ -659,7 +656,7 @@ class ImutAVLTreeGenericIterator
enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
Flags=0x3 }; Flags=0x3 };
typedef ImutAVLTree<ImutInfo> TreeTy; using TreeTy = ImutAVLTree<ImutInfo>;
ImutAVLTreeGenericIterator() = default; ImutAVLTreeGenericIterator() = default;
ImutAVLTreeGenericIterator(const TreeTy *Root) { ImutAVLTreeGenericIterator(const TreeTy *Root) {
@ -764,11 +761,12 @@ template <typename ImutInfo>
class ImutAVLTreeInOrderIterator class ImutAVLTreeInOrderIterator
: public std::iterator<std::bidirectional_iterator_tag, : public std::iterator<std::bidirectional_iterator_tag,
ImutAVLTree<ImutInfo>> { ImutAVLTree<ImutInfo>> {
typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy; using InternalIteratorTy = ImutAVLTreeGenericIterator<ImutInfo>;
InternalIteratorTy InternalItr; InternalIteratorTy InternalItr;
public: public:
typedef ImutAVLTree<ImutInfo> TreeTy; using TreeTy = ImutAVLTree<ImutInfo>;
ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
if (Root) if (Root)
@ -840,8 +838,8 @@ struct ImutAVLValueIterator
/// and generic handling of pointers is done below. /// and generic handling of pointers is done below.
template <typename T> template <typename T>
struct ImutProfileInfo { struct ImutProfileInfo {
typedef const T value_type; using value_type = const T;
typedef const T& value_type_ref; using value_type_ref = const T&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) { static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
FoldingSetTrait<T>::Profile(X,ID); FoldingSetTrait<T>::Profile(X,ID);
@ -851,8 +849,8 @@ struct ImutProfileInfo {
/// Profile traits for integers. /// Profile traits for integers.
template <typename T> template <typename T>
struct ImutProfileInteger { struct ImutProfileInteger {
typedef const T value_type; using value_type = const T;
typedef const T& value_type_ref; using value_type_ref = const T&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) { static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddInteger(X); ID.AddInteger(X);
@ -878,8 +876,8 @@ PROFILE_INTEGER_INFO(unsigned long long)
/// Profile traits for booleans. /// Profile traits for booleans.
template <> template <>
struct ImutProfileInfo<bool> { struct ImutProfileInfo<bool> {
typedef const bool value_type; using value_type = const bool;
typedef const bool& value_type_ref; using value_type_ref = const bool&;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) { static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddBoolean(X); ID.AddBoolean(X);
@ -890,8 +888,8 @@ struct ImutProfileInfo<bool> {
/// references to unique objects. /// references to unique objects.
template <typename T> template <typename T>
struct ImutProfileInfo<T*> { struct ImutProfileInfo<T*> {
typedef const T* value_type; using value_type = const T*;
typedef value_type value_type_ref; using value_type_ref = value_type;
static void Profile(FoldingSetNodeID &ID, value_type_ref X) { static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddPointer(X); ID.AddPointer(X);
@ -910,12 +908,12 @@ struct ImutProfileInfo<T*> {
/// std::equal_to<> and std::less<> to perform comparison of elements. /// std::equal_to<> and std::less<> to perform comparison of elements.
template <typename T> template <typename T>
struct ImutContainerInfo : public ImutProfileInfo<T> { struct ImutContainerInfo : public ImutProfileInfo<T> {
typedef typename ImutProfileInfo<T>::value_type value_type; using value_type = typename ImutProfileInfo<T>::value_type;
typedef typename ImutProfileInfo<T>::value_type_ref value_type_ref; using value_type_ref = typename ImutProfileInfo<T>::value_type_ref;
typedef value_type key_type; using key_type = value_type;
typedef value_type_ref key_type_ref; using key_type_ref = value_type_ref;
typedef bool data_type; using data_type = bool;
typedef bool data_type_ref; using data_type_ref = bool;
static key_type_ref KeyOfValue(value_type_ref D) { return D; } static key_type_ref KeyOfValue(value_type_ref D) { return D; }
static data_type_ref DataOfValue(value_type_ref) { return true; } static data_type_ref DataOfValue(value_type_ref) { return true; }
@ -936,12 +934,12 @@ struct ImutContainerInfo : public ImutProfileInfo<T> {
/// their addresses. /// their addresses.
template <typename T> template <typename T>
struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> { struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
typedef typename ImutProfileInfo<T*>::value_type value_type; using value_type = typename ImutProfileInfo<T*>::value_type;
typedef typename ImutProfileInfo<T*>::value_type_ref value_type_ref; using value_type_ref = typename ImutProfileInfo<T*>::value_type_ref;
typedef value_type key_type; using key_type = value_type;
typedef value_type_ref key_type_ref; using key_type_ref = value_type_ref;
typedef bool data_type; using data_type = bool;
typedef bool data_type_ref; using data_type_ref = bool;
static key_type_ref KeyOfValue(value_type_ref D) { return D; } static key_type_ref KeyOfValue(value_type_ref D) { return D; }
static data_type_ref DataOfValue(value_type_ref) { return true; } static data_type_ref DataOfValue(value_type_ref) { return true; }
@ -960,9 +958,9 @@ struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>> template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
class ImmutableSet { class ImmutableSet {
public: public:
typedef typename ValInfo::value_type value_type; using value_type = typename ValInfo::value_type;
typedef typename ValInfo::value_type_ref value_type_ref; using value_type_ref = typename ValInfo::value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy; using TreeTy = ImutAVLTree<ValInfo>;
private: private:
TreeTy *Root; TreeTy *Root;
@ -980,6 +978,10 @@ class ImmutableSet {
if (Root) { Root->retain(); } if (Root) { Root->retain(); }
} }
~ImmutableSet() {
if (Root) { Root->release(); }
}
ImmutableSet &operator=(const ImmutableSet &X) { ImmutableSet &operator=(const ImmutableSet &X) {
if (Root != X.Root) { if (Root != X.Root) {
if (X.Root) { X.Root->retain(); } if (X.Root) { X.Root->retain(); }
@ -989,10 +991,6 @@ class ImmutableSet {
return *this; return *this;
} }
~ImmutableSet() {
if (Root) { Root->release(); }
}
class Factory { class Factory {
typename TreeTy::Factory F; typename TreeTy::Factory F;
const bool Canonicalize; const bool Canonicalize;
@ -1084,7 +1082,7 @@ class ImmutableSet {
// Iterators. // Iterators.
//===--------------------------------------------------===// //===--------------------------------------------------===//
typedef ImutAVLValueIterator<ImmutableSet> iterator; using iterator = ImutAVLValueIterator<ImmutableSet>;
iterator begin() const { return iterator(Root); } iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); } iterator end() const { return iterator(); }
@ -1112,10 +1110,10 @@ class ImmutableSet {
template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>> template <typename ValT, typename ValInfo = ImutContainerInfo<ValT>>
class ImmutableSetRef { class ImmutableSetRef {
public: public:
typedef typename ValInfo::value_type value_type; using value_type = typename ValInfo::value_type;
typedef typename ValInfo::value_type_ref value_type_ref; using value_type_ref = typename ValInfo::value_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy; using TreeTy = ImutAVLTree<ValInfo>;
typedef typename TreeTy::Factory FactoryTy; using FactoryTy = typename TreeTy::Factory;
private: private:
TreeTy *Root; TreeTy *Root;
@ -1138,6 +1136,10 @@ class ImmutableSetRef {
if (Root) { Root->retain(); } if (Root) { Root->retain(); }
} }
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
ImmutableSetRef &operator=(const ImmutableSetRef &X) { ImmutableSetRef &operator=(const ImmutableSetRef &X) {
if (Root != X.Root) { if (Root != X.Root) {
if (X.Root) { X.Root->retain(); } if (X.Root) { X.Root->retain(); }
@ -1147,9 +1149,6 @@ class ImmutableSetRef {
} }
return *this; return *this;
} }
~ImmutableSetRef() {
if (Root) { Root->release(); }
}
static ImmutableSetRef getEmptySet(FactoryTy *F) { static ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F); return ImmutableSetRef(0, F);
@ -1196,7 +1195,7 @@ class ImmutableSetRef {
// Iterators. // Iterators.
//===--------------------------------------------------===// //===--------------------------------------------------===//
typedef ImutAVLValueIterator<ImmutableSetRef> iterator; using iterator = ImutAVLValueIterator<ImmutableSetRef>;
iterator begin() const { return iterator(Root); } iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); } iterator end() const { return iterator(); }

View File

@ -20,28 +20,28 @@
#ifndef LLVM_ADT_INDEXEDMAP_H #ifndef LLVM_ADT_INDEXEDMAP_H
#define LLVM_ADT_INDEXEDMAP_H #define LLVM_ADT_INDEXEDMAP_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include <cassert> #include <cassert>
#include <functional>
namespace llvm { namespace llvm {
template <typename T, typename ToIndexT = llvm::identity<unsigned> > template <typename T, typename ToIndexT = identity<unsigned>>
class IndexedMap { class IndexedMap {
typedef typename ToIndexT::argument_type IndexT; using IndexT = typename ToIndexT::argument_type;
// Prefer SmallVector with zero inline storage over std::vector. IndexedMaps // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
// can grow very large and SmallVector grows more efficiently as long as T // can grow very large and SmallVector grows more efficiently as long as T
// is trivially copyable. // is trivially copyable.
typedef SmallVector<T, 0> StorageT; using StorageT = SmallVector<T, 0>;
StorageT storage_; StorageT storage_;
T nullVal_; T nullVal_;
ToIndexT toIndex_; ToIndexT toIndex_;
public: public:
IndexedMap() : nullVal_(T()) { } IndexedMap() : nullVal_(T()) {}
explicit IndexedMap(const T& val) : nullVal_(val) { } explicit IndexedMap(const T& val) : nullVal_(val) {}
typename StorageT::reference operator[](IndexT n) { typename StorageT::reference operator[](IndexT n) {
assert(toIndex_(n) < storage_.size() && "index out of bounds!"); assert(toIndex_(n) < storage_.size() && "index out of bounds!");
@ -80,6 +80,6 @@ template <typename T, typename ToIndexT = llvm::identity<unsigned> >
} }
}; };
} // End llvm namespace } // end namespace llvm
#endif #endif // LLVM_ADT_INDEXEDMAP_H

View File

@ -106,6 +106,7 @@
#include "llvm/Support/RecyclingAllocator.h" #include "llvm/Support/RecyclingAllocator.h"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstdint>
#include <iterator> #include <iterator>
#include <new> #include <new>
#include <utility> #include <utility>
@ -186,7 +187,7 @@ struct IntervalMapHalfOpenInfo {
/// It should be considered private to the implementation. /// It should be considered private to the implementation.
namespace IntervalMapImpl { namespace IntervalMapImpl {
typedef std::pair<unsigned,unsigned> IdxPair; using IdxPair = std::pair<unsigned,unsigned>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//--- IntervalMapImpl::NodeBase ---// //--- IntervalMapImpl::NodeBase ---//
@ -445,7 +446,7 @@ struct NodeSizer {
LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize LeafSize = DesiredLeafSize > MinLeafSize ? DesiredLeafSize : MinLeafSize
}; };
typedef NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize> LeafBase; using LeafBase = NodeBase<std::pair<KeyT, KeyT>, ValT, LeafSize>;
enum { enum {
// Now that we have the leaf branching factor, compute the actual allocation // Now that we have the leaf branching factor, compute the actual allocation
@ -461,8 +462,8 @@ struct NodeSizer {
/// This typedef is very likely to be identical for all IntervalMaps with /// This typedef is very likely to be identical for all IntervalMaps with
/// reasonably sized entries, so the same allocator can be shared among /// reasonably sized entries, so the same allocator can be shared among
/// different kinds of maps. /// different kinds of maps.
typedef RecyclingAllocator<BumpPtrAllocator, char, using Allocator =
AllocBytes, CacheLineBytes> Allocator; RecyclingAllocator<BumpPtrAllocator, char, AllocBytes, CacheLineBytes>;
}; };
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -930,12 +931,12 @@ template <typename KeyT, typename ValT,
unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize, unsigned N = IntervalMapImpl::NodeSizer<KeyT, ValT>::LeafSize,
typename Traits = IntervalMapInfo<KeyT>> typename Traits = IntervalMapInfo<KeyT>>
class IntervalMap { class IntervalMap {
typedef IntervalMapImpl::NodeSizer<KeyT, ValT> Sizer; using Sizer = IntervalMapImpl::NodeSizer<KeyT, ValT>;
typedef IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits> Leaf; using Leaf = IntervalMapImpl::LeafNode<KeyT, ValT, Sizer::LeafSize, Traits>;
typedef IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits> using Branch =
Branch; IntervalMapImpl::BranchNode<KeyT, ValT, Sizer::BranchSize, Traits>;
typedef IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits> RootLeaf; using RootLeaf = IntervalMapImpl::LeafNode<KeyT, ValT, N, Traits>;
typedef IntervalMapImpl::IdxPair IdxPair; using IdxPair = IntervalMapImpl::IdxPair;
// The RootLeaf capacity is given as a template parameter. We must compute the // The RootLeaf capacity is given as a template parameter. We must compute the
// corresponding RootBranch capacity. // corresponding RootBranch capacity.
@ -945,8 +946,8 @@ class IntervalMap {
RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1 RootBranchCap = DesiredRootBranchCap ? DesiredRootBranchCap : 1
}; };
typedef IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits> using RootBranch =
RootBranch; IntervalMapImpl::BranchNode<KeyT, ValT, RootBranchCap, Traits>;
// When branched, we store a global start key as well as the branch node. // When branched, we store a global start key as well as the branch node.
struct RootBranchData { struct RootBranchData {
@ -955,10 +956,10 @@ class IntervalMap {
}; };
public: public:
typedef typename Sizer::Allocator Allocator; using Allocator = typename Sizer::Allocator;
typedef KeyT KeyType; using KeyType = KeyT;
typedef ValT ValueType; using ValueType = ValT;
typedef Traits KeyTraits; using KeyTraits = Traits;
private: private:
// The root data is either a RootLeaf or a RootBranchData instance. // The root data is either a RootLeaf or a RootBranchData instance.
@ -1290,7 +1291,7 @@ class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
friend class IntervalMap; friend class IntervalMap;
// The map referred to. // The map referred to.
IntervalMap *map; IntervalMap *map = nullptr;
// We store a full path from the root to the current position. // We store a full path from the root to the current position.
// The path may be partially filled, but never between iterator calls. // The path may be partially filled, but never between iterator calls.
@ -1338,7 +1339,7 @@ class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
public: public:
/// const_iterator - Create an iterator that isn't pointing anywhere. /// const_iterator - Create an iterator that isn't pointing anywhere.
const_iterator() : map(nullptr) {} const_iterator() = default;
/// setMap - Change the map iterated over. This call must be followed by a /// setMap - Change the map iterated over. This call must be followed by a
/// call to goToBegin(), goToEnd(), or find() /// call to goToBegin(), goToEnd(), or find()
@ -1509,7 +1510,8 @@ const_iterator::treeAdvanceTo(KeyT x) {
template <typename KeyT, typename ValT, unsigned N, typename Traits> template <typename KeyT, typename ValT, unsigned N, typename Traits>
class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator { class IntervalMap<KeyT, ValT, N, Traits>::iterator : public const_iterator {
friend class IntervalMap; friend class IntervalMap;
typedef IntervalMapImpl::IdxPair IdxPair;
using IdxPair = IntervalMapImpl::IdxPair;
explicit iterator(IntervalMap &map) : const_iterator(map) {} explicit iterator(IntervalMap &map) : const_iterator(map) {}
@ -2003,7 +2005,7 @@ iterator::overflow(unsigned Level) {
// Elements have been rearranged, now update node sizes and stops. // Elements have been rearranged, now update node sizes and stops.
bool SplitRoot = false; bool SplitRoot = false;
unsigned Pos = 0; unsigned Pos = 0;
for (;;) { while (true) {
KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1); KeyT Stop = Node[Pos]->stop(NewSize[Pos]-1);
if (NewNode && Pos == NewNode) { if (NewNode && Pos == NewNode) {
SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop); SplitRoot = insertNode(Level, NodeRef(Node[Pos], NewSize[Pos]), Stop);
@ -2045,8 +2047,9 @@ iterator::overflow(unsigned Level) {
/// ///
template <typename MapA, typename MapB> template <typename MapA, typename MapB>
class IntervalMapOverlaps { class IntervalMapOverlaps {
typedef typename MapA::KeyType KeyType; using KeyType = typename MapA::KeyType;
typedef typename MapA::KeyTraits Traits; using Traits = typename MapA::KeyTraits;
typename MapA::const_iterator posA; typename MapA::const_iterator posA;
typename MapB::const_iterator posB; typename MapB::const_iterator posB;
@ -2071,7 +2074,7 @@ class IntervalMapOverlaps {
// Already overlapping. // Already overlapping.
return; return;
for (;;) { while (true) {
// Make a.end > b.start. // Make a.end > b.start.
posA.advanceTo(posB.start()); posA.advanceTo(posB.start());
if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start())) if (!posA.valid() || !Traits::stopLess(posB.stop(), posA.start()))

View File

@ -1,4 +1,4 @@
//== llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer ---*- C++ -*-==// //==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -73,9 +73,10 @@ template <class Derived> class RefCountedBase {
public: public:
RefCountedBase() = default; RefCountedBase() = default;
RefCountedBase(const RefCountedBase &) : RefCount(0) {} RefCountedBase(const RefCountedBase &) {}
void Retain() const { ++RefCount; } void Retain() const { ++RefCount; }
void Release() const { void Release() const {
assert(RefCount > 0 && "Reference count is already zero."); assert(RefCount > 0 && "Reference count is already zero.");
if (--RefCount == 0) if (--RefCount == 0)
@ -136,7 +137,7 @@ template <typename T> class IntrusiveRefCntPtr {
T *Obj = nullptr; T *Obj = nullptr;
public: public:
typedef T element_type; using element_type = T;
explicit IntrusiveRefCntPtr() = default; explicit IntrusiveRefCntPtr() = default;
IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); } IntrusiveRefCntPtr(T *obj) : Obj(obj) { retain(); }
@ -153,13 +154,13 @@ template <typename T> class IntrusiveRefCntPtr {
retain(); retain();
} }
~IntrusiveRefCntPtr() { release(); }
IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) { IntrusiveRefCntPtr &operator=(IntrusiveRefCntPtr S) {
swap(S); swap(S);
return *this; return *this;
} }
~IntrusiveRefCntPtr() { release(); }
T &operator*() const { return *Obj; } T &operator*() const { return *Obj; }
T *operator->() const { return Obj; } T *operator->() const { return Obj; }
T *get() const { return Obj; } T *get() const { return Obj; }
@ -183,6 +184,7 @@ template <typename T> class IntrusiveRefCntPtr {
if (Obj) if (Obj)
IntrusiveRefCntPtrInfo<T>::retain(Obj); IntrusiveRefCntPtrInfo<T>::retain(Obj);
} }
void release() { void release() {
if (Obj) if (Obj)
IntrusiveRefCntPtrInfo<T>::release(Obj); IntrusiveRefCntPtrInfo<T>::release(Obj);
@ -248,14 +250,16 @@ bool operator!=(const IntrusiveRefCntPtr<T> &A, std::nullptr_t B) {
template <typename From> struct simplify_type; template <typename From> struct simplify_type;
template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> { template <class T> struct simplify_type<IntrusiveRefCntPtr<T>> {
typedef T *SimpleType; using SimpleType = T *;
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) { static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T> &Val) {
return Val.get(); return Val.get();
} }
}; };
template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> { template <class T> struct simplify_type<const IntrusiveRefCntPtr<T>> {
typedef /*const*/ T *SimpleType; using SimpleType = /*const*/ T *;
static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) { static SimpleType getSimplifiedValue(const IntrusiveRefCntPtr<T> &Val) {
return Val.get(); return Val.get();
} }

View File

@ -19,6 +19,12 @@
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <iterator>
#include <type_traits>
#include <utility>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
@ -27,20 +33,20 @@ namespace llvm {
/// in a deterministic order. The values are kept in a std::vector and the /// in a deterministic order. The values are kept in a std::vector and the
/// mapping is done with DenseMap from Keys to indexes in that vector. /// mapping is done with DenseMap from Keys to indexes in that vector.
template<typename KeyT, typename ValueT, template<typename KeyT, typename ValueT,
typename MapType = llvm::DenseMap<KeyT, unsigned>, typename MapType = DenseMap<KeyT, unsigned>,
typename VectorType = std::vector<std::pair<KeyT, ValueT> > > typename VectorType = std::vector<std::pair<KeyT, ValueT>>>
class MapVector { class MapVector {
typedef typename VectorType::value_type value_type; using value_type = typename VectorType::value_type;
typedef typename VectorType::size_type size_type; using size_type = typename VectorType::size_type;
MapType Map; MapType Map;
VectorType Vector; VectorType Vector;
public: public:
typedef typename VectorType::iterator iterator; using iterator = typename VectorType::iterator;
typedef typename VectorType::const_iterator const_iterator; using const_iterator = typename VectorType::const_iterator;
typedef typename VectorType::reverse_iterator reverse_iterator; using reverse_iterator = typename VectorType::reverse_iterator;
typedef typename VectorType::const_reverse_iterator const_reverse_iterator; using const_reverse_iterator = typename VectorType::const_reverse_iterator;
/// Clear the MapVector and return the underlying vector. /// Clear the MapVector and return the underlying vector.
VectorType takeVector() { VectorType takeVector() {
@ -220,4 +226,4 @@ struct SmallMapVector
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_ADT_MAPVECTOR_H

View File

@ -1,4 +1,4 @@
//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=// //===- Optional.h - Simple variant for passing optional values --*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -19,6 +19,8 @@
#include "llvm/ADT/None.h" #include "llvm/ADT/None.h"
#include "llvm/Support/AlignOf.h" #include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <new> #include <new>
#include <utility> #include <utility>
@ -28,15 +30,18 @@ namespace llvm {
template<typename T> template<typename T>
class Optional { class Optional {
AlignedCharArrayUnion<T> storage; AlignedCharArrayUnion<T> storage;
bool hasVal; bool hasVal = false;
public:
typedef T value_type; public:
using value_type = T;
Optional(NoneType) {}
explicit Optional() {}
Optional(NoneType) : hasVal(false) {}
explicit Optional() : hasVal(false) {}
Optional(const T &y) : hasVal(true) { Optional(const T &y) : hasVal(true) {
new (storage.buffer) T(y); new (storage.buffer) T(y);
} }
Optional(const Optional &O) : hasVal(O.hasVal) { Optional(const Optional &O) : hasVal(O.hasVal) {
if (hasVal) if (hasVal)
new (storage.buffer) T(*O); new (storage.buffer) T(*O);
@ -45,12 +50,18 @@ class Optional {
Optional(T &&y) : hasVal(true) { Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y)); new (storage.buffer) T(std::forward<T>(y));
} }
Optional(Optional<T> &&O) : hasVal(O) { Optional(Optional<T> &&O) : hasVal(O) {
if (O) { if (O) {
new (storage.buffer) T(std::move(*O)); new (storage.buffer) T(std::move(*O));
O.reset(); O.reset();
} }
} }
~Optional() {
reset();
}
Optional &operator=(T &&y) { Optional &operator=(T &&y) {
if (hasVal) if (hasVal)
**this = std::move(y); **this = std::move(y);
@ -60,6 +71,7 @@ class Optional {
} }
return *this; return *this;
} }
Optional &operator=(Optional &&O) { Optional &operator=(Optional &&O) {
if (!O) if (!O)
reset(); reset();
@ -112,10 +124,6 @@ class Optional {
} }
} }
~Optional() {
reset();
}
const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); } const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); } T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
@ -144,8 +152,7 @@ class Optional {
#endif #endif
}; };
template <typename T> struct isPodLike; template <typename T> struct isPodLike<Optional<T>> {
template <typename T> struct isPodLike<Optional<T> > {
// An Optional<T> is pod-like if T is. // An Optional<T> is pod-like if T is.
static const bool value = isPodLike<T>::value; static const bool value = isPodLike<T>::value;
}; };
@ -284,6 +291,6 @@ template <typename T> bool operator>=(const T &X, const Optional<T> &Y) {
return !(X < Y); return !(X < Y);
} }
} // end llvm namespace } // end namespace llvm
#endif #endif // LLVM_ADT_OPTIONAL_H

View File

@ -76,8 +76,8 @@ template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy, class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> { std::numeric_limits<T>::is_signed> {
BitVectorTy Bits; BitVectorTy Bits;
typedef PackedVectorBase<T, BitNum, BitVectorTy, using base = PackedVectorBase<T, BitNum, BitVectorTy,
std::numeric_limits<T>::is_signed> base; std::numeric_limits<T>::is_signed>;
public: public:
class reference { class reference {
@ -99,7 +99,7 @@ class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
}; };
PackedVector() = default; PackedVector() = default;
explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { } explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) {}
bool empty() const { return Bits.empty(); } bool empty() const { return Bits.empty(); }

View File

@ -13,7 +13,10 @@
#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
#include <climits> #include <climits>
#include <cstdint>
#include <type_traits>
namespace llvm { namespace llvm {
@ -29,7 +32,7 @@ namespace llvm {
/// Also, the default constructed value zero initializes the integer. /// Also, the default constructed value zero initializes the integer.
template <typename IntT, int Bits = sizeof(IntT) * CHAR_BIT> template <typename IntT, int Bits = sizeof(IntT) * CHAR_BIT>
class PointerEmbeddedInt { class PointerEmbeddedInt {
uintptr_t Value; uintptr_t Value = 0;
// Note: This '<' is correct; using '<=' would result in some shifts // Note: This '<' is correct; using '<=' would result in some shifts
// overflowing their storage types. // overflowing their storage types.
@ -54,15 +57,12 @@ class PointerEmbeddedInt {
explicit PointerEmbeddedInt(uintptr_t Value, RawValueTag) : Value(Value) {} explicit PointerEmbeddedInt(uintptr_t Value, RawValueTag) : Value(Value) {}
public: public:
PointerEmbeddedInt() : Value(0) {} PointerEmbeddedInt() = default;
PointerEmbeddedInt(IntT I) { PointerEmbeddedInt(IntT I) { *this = I; }
*this = I;
}
PointerEmbeddedInt &operator=(IntT I) { PointerEmbeddedInt &operator=(IntT I) {
assert((std::is_signed<IntT>::value ? llvm::isInt<Bits>(I) assert((std::is_signed<IntT>::value ? isInt<Bits>(I) : isUInt<Bits>(I)) &&
: llvm::isUInt<Bits>(I)) &&
"Integer has bits outside those preserved!"); "Integer has bits outside those preserved!");
Value = static_cast<uintptr_t>(I) << Shift; Value = static_cast<uintptr_t>(I) << Shift;
return *this; return *this;
@ -81,15 +81,17 @@ class PointerEmbeddedInt {
// types. // types.
template <typename IntT, int Bits> template <typename IntT, int Bits>
class PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> { class PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
typedef PointerEmbeddedInt<IntT, Bits> T; using T = PointerEmbeddedInt<IntT, Bits>;
public: public:
static inline void *getAsVoidPointer(const T &P) { static inline void *getAsVoidPointer(const T &P) {
return reinterpret_cast<void *>(P.Value); return reinterpret_cast<void *>(P.Value);
} }
static inline T getFromVoidPointer(void *P) { static inline T getFromVoidPointer(void *P) {
return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag()); return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
} }
static inline T getFromVoidPointer(const void *P) { static inline T getFromVoidPointer(const void *P) {
return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag()); return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
} }
@ -101,17 +103,19 @@ class PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
// itself can be a key. // itself can be a key.
template <typename IntT, int Bits> template <typename IntT, int Bits>
struct DenseMapInfo<PointerEmbeddedInt<IntT, Bits>> { struct DenseMapInfo<PointerEmbeddedInt<IntT, Bits>> {
typedef PointerEmbeddedInt<IntT, Bits> T; using T = PointerEmbeddedInt<IntT, Bits>;
using IntInfo = DenseMapInfo<IntT>;
typedef DenseMapInfo<IntT> IntInfo;
static inline T getEmptyKey() { return IntInfo::getEmptyKey(); } static inline T getEmptyKey() { return IntInfo::getEmptyKey(); }
static inline T getTombstoneKey() { return IntInfo::getTombstoneKey(); } static inline T getTombstoneKey() { return IntInfo::getTombstoneKey(); }
static unsigned getHashValue(const T &Arg) { static unsigned getHashValue(const T &Arg) {
return IntInfo::getHashValue(Arg); return IntInfo::getHashValue(Arg);
} }
static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; } static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; }
}; };
}
#endif } // end namespace llvm
#endif // LLVM_ADT_POINTEREMBEDDEDINT_H

View File

@ -158,7 +158,7 @@ template <typename PT1, typename PT2> class PointerUnion {
assert( assert(
get<PT1>() == Val.getPointer() && get<PT1>() == Val.getPointer() &&
"Can't get the address because PointerLikeTypeTraits changes the ptr"); "Can't get the address because PointerLikeTypeTraits changes the ptr");
return (PT1 *)Val.getAddrOfPointer(); return const_cast<PT1 *>(reinterpret_cast<const PT1 *>(Val.getAddrOfPointer()));
} }
/// Assignment from nullptr which just clears the union. /// Assignment from nullptr which just clears the union.

View File

@ -109,6 +109,7 @@ class ScopedHashTableScope {
ScopedHashTableVal<K, V> *getLastValInScope() { ScopedHashTableVal<K, V> *getLastValInScope() {
return LastValInScope; return LastValInScope;
} }
void setLastValInScope(ScopedHashTableVal<K, V> *Val) { void setLastValInScope(ScopedHashTableVal<K, V> *Val) {
LastValInScope = Val; LastValInScope = Val;
} }
@ -151,13 +152,14 @@ class ScopedHashTable {
public: public:
/// ScopeTy - This is a helpful typedef that allows clients to get easy access /// ScopeTy - This is a helpful typedef that allows clients to get easy access
/// to the name of the scope for this hash table. /// to the name of the scope for this hash table.
typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy; using ScopeTy = ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
typedef unsigned size_type; using size_type = unsigned;
private: private:
friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>; friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
typedef ScopedHashTableVal<K, V> ValTy; using ValTy = ScopedHashTableVal<K, V>;
DenseMap<K, ValTy*, KInfo> TopLevelMap; DenseMap<K, ValTy*, KInfo> TopLevelMap;
ScopeTy *CurScope = nullptr; ScopeTy *CurScope = nullptr;
@ -165,7 +167,7 @@ class ScopedHashTable {
public: public:
ScopedHashTable() = default; ScopedHashTable() = default;
ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {} ScopedHashTable(AllocatorTy A) : Allocator(A) {}
ScopedHashTable(const ScopedHashTable &) = delete; ScopedHashTable(const ScopedHashTable &) = delete;
ScopedHashTable &operator=(const ScopedHashTable &) = delete; ScopedHashTable &operator=(const ScopedHashTable &) = delete;
@ -194,7 +196,7 @@ class ScopedHashTable {
insertIntoScope(CurScope, Key, Val); insertIntoScope(CurScope, Key, Val);
} }
typedef ScopedHashTableIterator<K, V, KInfo> iterator; using iterator = ScopedHashTableIterator<K, V, KInfo>;
iterator end() { return iterator(0); } iterator end() { return iterator(0); }

View File

@ -15,8 +15,15 @@
#define LLVM_ADT_SMALLBITVECTOR_H #define LLVM_ADT_SMALLBITVECTOR_H
#include "llvm/ADT/BitVector.h" #include "llvm/ADT/BitVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cassert> #include <cassert>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <utility>
namespace llvm { namespace llvm {
@ -29,7 +36,7 @@ class SmallBitVector {
// TODO: In "large" mode, a pointer to a BitVector is used, leading to an // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
// unnecessary level of indirection. It would be more efficient to use a // unnecessary level of indirection. It would be more efficient to use a
// pointer to memory containing size, allocation size, and the array of bits. // pointer to memory containing size, allocation size, and the array of bits.
uintptr_t X; uintptr_t X = 1;
enum { enum {
// The number of bits in this class. // The number of bits in this class.
@ -54,7 +61,8 @@ class SmallBitVector {
"Unsupported word size"); "Unsupported word size");
public: public:
typedef unsigned size_type; using size_type = unsigned;
// Encapsulation of a single bit. // Encapsulation of a single bit.
class reference { class reference {
SmallBitVector &TheVector; SmallBitVector &TheVector;
@ -134,21 +142,8 @@ class SmallBitVector {
} }
public: public:
typedef const_set_bits_iterator_impl<SmallBitVector> const_set_bits_iterator;
typedef const_set_bits_iterator set_iterator;
const_set_bits_iterator set_bits_begin() const {
return const_set_bits_iterator(*this);
}
const_set_bits_iterator set_bits_end() const {
return const_set_bits_iterator(*this, -1);
}
iterator_range<const_set_bits_iterator> set_bits() const {
return make_range(set_bits_begin(), set_bits_end());
}
/// Creates an empty bitvector. /// Creates an empty bitvector.
SmallBitVector() : X(1) {} SmallBitVector() = default;
/// Creates a bitvector of specified number of bits. All bits are initialized /// Creates a bitvector of specified number of bits. All bits are initialized
/// to the specified value. /// to the specified value.
@ -176,6 +171,21 @@ class SmallBitVector {
delete getPointer(); delete getPointer();
} }
using const_set_bits_iterator = const_set_bits_iterator_impl<SmallBitVector>;
using set_iterator = const_set_bits_iterator;
const_set_bits_iterator set_bits_begin() const {
return const_set_bits_iterator(*this);
}
const_set_bits_iterator set_bits_end() const {
return const_set_bits_iterator(*this, -1);
}
iterator_range<const_set_bits_iterator> set_bits() const {
return make_range(set_bits_begin(), set_bits_end());
}
/// Tests whether there are no bits in this bitvector. /// Tests whether there are no bits in this bitvector.
bool empty() const { bool empty() const {
return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
@ -677,14 +687,16 @@ operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
return Result; return Result;
} }
} // End llvm namespace } // end namespace llvm
namespace std { namespace std {
/// Implement std::swap in terms of BitVector swap.
inline void /// Implement std::swap in terms of BitVector swap.
swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { inline void
LHS.swap(RHS); swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
} LHS.swap(RHS);
} }
#endif } // end namespace std
#endif // LLVM_ADT_SMALLBITVECTOR_H

View File

@ -39,8 +39,9 @@ class SmallSet {
/// we will never use. /// we will never use.
SmallVector<T, N> Vector; SmallVector<T, N> Vector;
std::set<T, C> Set; std::set<T, C> Set;
typedef typename SmallVector<T, N>::const_iterator VIterator;
typedef typename SmallVector<T, N>::iterator mutable_iterator; using VIterator = typename SmallVector<T, N>::const_iterator;
using mutable_iterator = typename SmallVector<T, N>::iterator;
// In small mode SmallPtrSet uses linear search for the elements, so it is // In small mode SmallPtrSet uses linear search for the elements, so it is
// not a good idea to choose this value too high. You may consider using a // not a good idea to choose this value too high. You may consider using a
@ -48,7 +49,7 @@ class SmallSet {
static_assert(N <= 32, "N should be small"); static_assert(N <= 32, "N should be small");
public: public:
typedef size_t size_type; using size_type = size_t;
SmallSet() = default; SmallSet() = default;

View File

@ -14,6 +14,7 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H #ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
@ -40,6 +41,11 @@ static inline StringRef toStringRef(bool B) {
return StringRef(B ? "true" : "false"); return StringRef(B ? "true" : "false");
} }
/// Construct a string ref from an array ref of unsigned chars.
static inline StringRef toStringRef(ArrayRef<uint8_t> Input) {
return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size());
}
/// Interpret the given character \p C as a hexadecimal digit and return its /// Interpret the given character \p C as a hexadecimal digit and return its
/// value. /// value.
/// ///
@ -68,7 +74,7 @@ static inline std::string utohexstr(uint64_t X, bool LowerCase = false) {
/// Convert buffer \p Input to its hexadecimal representation. /// Convert buffer \p Input to its hexadecimal representation.
/// The returned string is double the size of \p Input. /// The returned string is double the size of \p Input.
static inline std::string toHex(StringRef Input) { inline std::string toHex(StringRef Input) {
static const char *const LUT = "0123456789ABCDEF"; static const char *const LUT = "0123456789ABCDEF";
size_t Length = Input.size(); size_t Length = Input.size();
@ -82,6 +88,10 @@ static inline std::string toHex(StringRef Input) {
return Output; return Output;
} }
inline std::string toHex(ArrayRef<uint8_t> Input) {
return toHex(toStringRef(Input));
}
static inline uint8_t hexFromNibbles(char MSB, char LSB) { static inline uint8_t hexFromNibbles(char MSB, char LSB) {
unsigned U1 = hexDigitValue(MSB); unsigned U1 = hexDigitValue(MSB);
unsigned U2 = hexDigitValue(LSB); unsigned U2 = hexDigitValue(LSB);

View File

@ -239,7 +239,9 @@ class Triple {
/// Default constructor is the same as an empty string and leaves all /// Default constructor is the same as an empty string and leaves all
/// triple fields unknown. /// triple fields unknown.
Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {} Triple()
: Data(), Arch(), SubArch(), Vendor(), OS(), Environment(),
ObjectFormat() {}
explicit Triple(const Twine &Str); explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr); Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);

View File

@ -1,4 +1,4 @@
//===- llvm/ADT/ilist_base.h - Intrusive List Base ---------------*- C++ -*-==// //===- llvm/ADT/ilist_base.h - Intrusive List Base --------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -12,15 +12,13 @@
#include "llvm/ADT/ilist_node_base.h" #include "llvm/ADT/ilist_node_base.h"
#include <cassert> #include <cassert>
#include <cstddef>
#include <type_traits>
namespace llvm { namespace llvm {
/// Implementations of list algorithms using ilist_node_base. /// Implementations of list algorithms using ilist_node_base.
template <bool EnableSentinelTracking> class ilist_base { template <bool EnableSentinelTracking> class ilist_base {
public: public:
typedef ilist_node_base<EnableSentinelTracking> node_base_type; using node_base_type = ilist_node_base<EnableSentinelTracking>;
static void insertBeforeImpl(node_base_type &Next, node_base_type &N) { static void insertBeforeImpl(node_base_type &Next, node_base_type &N) {
node_base_type &Prev = *Next.getPrev(); node_base_type &Prev = *Next.getPrev();

View File

@ -1,4 +1,4 @@
//===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator -------*- C++ -*-==// //===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator ------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -23,28 +23,30 @@ namespace ilist_detail {
/// Find const-correct node types. /// Find const-correct node types.
template <class OptionsT, bool IsConst> struct IteratorTraits; template <class OptionsT, bool IsConst> struct IteratorTraits;
template <class OptionsT> struct IteratorTraits<OptionsT, false> { template <class OptionsT> struct IteratorTraits<OptionsT, false> {
typedef typename OptionsT::value_type value_type; using value_type = typename OptionsT::value_type;
typedef typename OptionsT::pointer pointer; using pointer = typename OptionsT::pointer;
typedef typename OptionsT::reference reference; using reference = typename OptionsT::reference;
typedef ilist_node_impl<OptionsT> *node_pointer; using node_pointer = ilist_node_impl<OptionsT> *;
typedef ilist_node_impl<OptionsT> &node_reference; using node_reference = ilist_node_impl<OptionsT> &;
}; };
template <class OptionsT> struct IteratorTraits<OptionsT, true> { template <class OptionsT> struct IteratorTraits<OptionsT, true> {
typedef const typename OptionsT::value_type value_type; using value_type = const typename OptionsT::value_type;
typedef typename OptionsT::const_pointer pointer; using pointer = typename OptionsT::const_pointer;
typedef typename OptionsT::const_reference reference; using reference = typename OptionsT::const_reference;
typedef const ilist_node_impl<OptionsT> *node_pointer; using node_pointer = const ilist_node_impl<OptionsT> *;
typedef const ilist_node_impl<OptionsT> &node_reference; using node_reference = const ilist_node_impl<OptionsT> &;
}; };
template <bool IsReverse> struct IteratorHelper; template <bool IsReverse> struct IteratorHelper;
template <> struct IteratorHelper<false> : ilist_detail::NodeAccess { template <> struct IteratorHelper<false> : ilist_detail::NodeAccess {
typedef ilist_detail::NodeAccess Access; using Access = ilist_detail::NodeAccess;
template <class T> static void increment(T *&I) { I = Access::getNext(*I); } template <class T> static void increment(T *&I) { I = Access::getNext(*I); }
template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); } template <class T> static void decrement(T *&I) { I = Access::getPrev(*I); }
}; };
template <> struct IteratorHelper<true> : ilist_detail::NodeAccess { template <> struct IteratorHelper<true> : ilist_detail::NodeAccess {
typedef ilist_detail::NodeAccess Access; using Access = ilist_detail::NodeAccess;
template <class T> static void increment(T *&I) { I = Access::getPrev(*I); } template <class T> static void increment(T *&I) { I = Access::getPrev(*I); }
template <class T> static void decrement(T *&I) { I = Access::getNext(*I); } template <class T> static void decrement(T *&I) { I = Access::getNext(*I); }
}; };
@ -58,24 +60,23 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
friend ilist_iterator<OptionsT, !IsReverse, IsConst>; friend ilist_iterator<OptionsT, !IsReverse, IsConst>;
friend ilist_iterator<OptionsT, !IsReverse, !IsConst>; friend ilist_iterator<OptionsT, !IsReverse, !IsConst>;
typedef ilist_detail::IteratorTraits<OptionsT, IsConst> Traits; using Traits = ilist_detail::IteratorTraits<OptionsT, IsConst>;
typedef ilist_detail::SpecificNodeAccess<OptionsT> Access; using Access = ilist_detail::SpecificNodeAccess<OptionsT>;
public: public:
typedef typename Traits::value_type value_type; using value_type = typename Traits::value_type;
typedef typename Traits::pointer pointer; using pointer = typename Traits::pointer;
typedef typename Traits::reference reference; using reference = typename Traits::reference;
typedef ptrdiff_t difference_type; using difference_type = ptrdiff_t;
typedef std::bidirectional_iterator_tag iterator_category; using iterator_category = std::bidirectional_iterator_tag;
using const_pointer = typename OptionsT::const_pointer;
typedef typename OptionsT::const_pointer const_pointer; using const_reference = typename OptionsT::const_reference;
typedef typename OptionsT::const_reference const_reference;
private: private:
typedef typename Traits::node_pointer node_pointer; using node_pointer = typename Traits::node_pointer;
typedef typename Traits::node_reference node_reference; using node_reference = typename Traits::node_reference;
node_pointer NodePtr; node_pointer NodePtr = nullptr;
public: public:
/// Create from an ilist_node. /// Create from an ilist_node.
@ -83,7 +84,7 @@ class ilist_iterator : ilist_detail::SpecificNodeAccess<OptionsT> {
explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {} explicit ilist_iterator(pointer NP) : NodePtr(Access::getNodePtr(NP)) {}
explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {} explicit ilist_iterator(reference NR) : NodePtr(Access::getNodePtr(&NR)) {}
ilist_iterator() : NodePtr(nullptr) {} ilist_iterator() = default;
// This is templated so that we can allow constructing a const iterator from // This is templated so that we can allow constructing a const iterator from
// a nonconst iterator... // a nonconst iterator...
@ -184,8 +185,8 @@ template <typename From> struct simplify_type;
/// FIXME: remove this, since there is no implicit conversion to NodeTy. /// FIXME: remove this, since there is no implicit conversion to NodeTy.
template <class OptionsT, bool IsConst> template <class OptionsT, bool IsConst>
struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> { struct simplify_type<ilist_iterator<OptionsT, false, IsConst>> {
typedef ilist_iterator<OptionsT, false, IsConst> iterator; using iterator = ilist_iterator<OptionsT, false, IsConst>;
typedef typename iterator::pointer SimpleType; using SimpleType = typename iterator::pointer;
static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; } static SimpleType getSimplifiedValue(const iterator &Node) { return &*Node; }
}; };

View File

@ -1,4 +1,4 @@
//==-- llvm/ADT/ilist_node.h - Intrusive Linked List Helper ------*- C++ -*-==// //===- llvm/ADT/ilist_node.h - Intrusive Linked List Helper -----*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -21,11 +21,10 @@
namespace llvm { namespace llvm {
namespace ilist_detail { namespace ilist_detail {
struct NodeAccess;
} // end namespace ilist_detail
template<typename NodeTy> struct NodeAccess;
struct ilist_traits;
} // end namespace ilist_detail
template <class OptionsT, bool IsReverse, bool IsConst> class ilist_iterator; template <class OptionsT, bool IsReverse, bool IsConst> class ilist_iterator;
template <class OptionsT> class ilist_sentinel; template <class OptionsT> class ilist_sentinel;
@ -39,9 +38,9 @@ template <class OptionsT> class ilist_sentinel;
/// provide type safety: you can't insert nodes of \a ilist_node_impl into the /// provide type safety: you can't insert nodes of \a ilist_node_impl into the
/// wrong \a simple_ilist or \a iplist. /// wrong \a simple_ilist or \a iplist.
template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type { template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
typedef typename OptionsT::value_type value_type; using value_type = typename OptionsT::value_type;
typedef typename OptionsT::node_base_type node_base_type; using node_base_type = typename OptionsT::node_base_type;
typedef typename OptionsT::list_base_type list_base_type; using list_base_type = typename OptionsT::list_base_type;
friend typename OptionsT::list_base_type; friend typename OptionsT::list_base_type;
friend struct ilist_detail::NodeAccess; friend struct ilist_detail::NodeAccess;
@ -52,17 +51,18 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
friend class ilist_iterator<OptionsT, true, true>; friend class ilist_iterator<OptionsT, true, true>;
protected: protected:
ilist_node_impl() = default; using self_iterator = ilist_iterator<OptionsT, false, false>;
using const_self_iterator = ilist_iterator<OptionsT, false, true>;
using reverse_self_iterator = ilist_iterator<OptionsT, true, false>;
using const_reverse_self_iterator = ilist_iterator<OptionsT, true, true>;
typedef ilist_iterator<OptionsT, false, false> self_iterator; ilist_node_impl() = default;
typedef ilist_iterator<OptionsT, false, true> const_self_iterator;
typedef ilist_iterator<OptionsT, true, false> reverse_self_iterator;
typedef ilist_iterator<OptionsT, true, true> const_reverse_self_iterator;
private: private:
ilist_node_impl *getPrev() { ilist_node_impl *getPrev() {
return static_cast<ilist_node_impl *>(node_base_type::getPrev()); return static_cast<ilist_node_impl *>(node_base_type::getPrev());
} }
ilist_node_impl *getNext() { ilist_node_impl *getNext() {
return static_cast<ilist_node_impl *>(node_base_type::getNext()); return static_cast<ilist_node_impl *>(node_base_type::getNext());
} }
@ -70,6 +70,7 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
const ilist_node_impl *getPrev() const { const ilist_node_impl *getPrev() const {
return static_cast<ilist_node_impl *>(node_base_type::getPrev()); return static_cast<ilist_node_impl *>(node_base_type::getPrev());
} }
const ilist_node_impl *getNext() const { const ilist_node_impl *getNext() const {
return static_cast<ilist_node_impl *>(node_base_type::getNext()); return static_cast<ilist_node_impl *>(node_base_type::getNext());
} }
@ -80,9 +81,11 @@ template <class OptionsT> class ilist_node_impl : OptionsT::node_base_type {
public: public:
self_iterator getIterator() { return self_iterator(*this); } self_iterator getIterator() { return self_iterator(*this); }
const_self_iterator getIterator() const { return const_self_iterator(*this); } const_self_iterator getIterator() const { return const_self_iterator(*this); }
reverse_self_iterator getReverseIterator() { reverse_self_iterator getReverseIterator() {
return reverse_self_iterator(*this); return reverse_self_iterator(*this);
} }
const_reverse_self_iterator getReverseIterator() const { const_reverse_self_iterator getReverseIterator() const {
return const_reverse_self_iterator(*this); return const_reverse_self_iterator(*this);
} }
@ -151,6 +154,7 @@ class ilist_node
}; };
namespace ilist_detail { namespace ilist_detail {
/// An access class for ilist_node private API. /// An access class for ilist_node private API.
/// ///
/// This gives access to the private parts of ilist nodes. Nodes for an ilist /// This gives access to the private parts of ilist nodes. Nodes for an ilist
@ -163,15 +167,18 @@ struct NodeAccess {
static ilist_node_impl<OptionsT> *getNodePtr(typename OptionsT::pointer N) { static ilist_node_impl<OptionsT> *getNodePtr(typename OptionsT::pointer N) {
return N; return N;
} }
template <class OptionsT> template <class OptionsT>
static const ilist_node_impl<OptionsT> * static const ilist_node_impl<OptionsT> *
getNodePtr(typename OptionsT::const_pointer N) { getNodePtr(typename OptionsT::const_pointer N) {
return N; return N;
} }
template <class OptionsT> template <class OptionsT>
static typename OptionsT::pointer getValuePtr(ilist_node_impl<OptionsT> *N) { static typename OptionsT::pointer getValuePtr(ilist_node_impl<OptionsT> *N) {
return static_cast<typename OptionsT::pointer>(N); return static_cast<typename OptionsT::pointer>(N);
} }
template <class OptionsT> template <class OptionsT>
static typename OptionsT::const_pointer static typename OptionsT::const_pointer
getValuePtr(const ilist_node_impl<OptionsT> *N) { getValuePtr(const ilist_node_impl<OptionsT> *N) {
@ -182,15 +189,18 @@ struct NodeAccess {
static ilist_node_impl<OptionsT> *getPrev(ilist_node_impl<OptionsT> &N) { static ilist_node_impl<OptionsT> *getPrev(ilist_node_impl<OptionsT> &N) {
return N.getPrev(); return N.getPrev();
} }
template <class OptionsT> template <class OptionsT>
static ilist_node_impl<OptionsT> *getNext(ilist_node_impl<OptionsT> &N) { static ilist_node_impl<OptionsT> *getNext(ilist_node_impl<OptionsT> &N) {
return N.getNext(); return N.getNext();
} }
template <class OptionsT> template <class OptionsT>
static const ilist_node_impl<OptionsT> * static const ilist_node_impl<OptionsT> *
getPrev(const ilist_node_impl<OptionsT> &N) { getPrev(const ilist_node_impl<OptionsT> &N) {
return N.getPrev(); return N.getPrev();
} }
template <class OptionsT> template <class OptionsT>
static const ilist_node_impl<OptionsT> * static const ilist_node_impl<OptionsT> *
getNext(const ilist_node_impl<OptionsT> &N) { getNext(const ilist_node_impl<OptionsT> &N) {
@ -200,23 +210,27 @@ struct NodeAccess {
template <class OptionsT> struct SpecificNodeAccess : NodeAccess { template <class OptionsT> struct SpecificNodeAccess : NodeAccess {
protected: protected:
typedef typename OptionsT::pointer pointer; using pointer = typename OptionsT::pointer;
typedef typename OptionsT::const_pointer const_pointer; using const_pointer = typename OptionsT::const_pointer;
typedef ilist_node_impl<OptionsT> node_type; using node_type = ilist_node_impl<OptionsT>;
static node_type *getNodePtr(pointer N) { static node_type *getNodePtr(pointer N) {
return NodeAccess::getNodePtr<OptionsT>(N); return NodeAccess::getNodePtr<OptionsT>(N);
} }
static const node_type *getNodePtr(const_pointer N) { static const node_type *getNodePtr(const_pointer N) {
return NodeAccess::getNodePtr<OptionsT>(N); return NodeAccess::getNodePtr<OptionsT>(N);
} }
static pointer getValuePtr(node_type *N) { static pointer getValuePtr(node_type *N) {
return NodeAccess::getValuePtr<OptionsT>(N); return NodeAccess::getValuePtr<OptionsT>(N);
} }
static const_pointer getValuePtr(const node_type *N) { static const_pointer getValuePtr(const node_type *N) {
return NodeAccess::getValuePtr<OptionsT>(N); return NodeAccess::getValuePtr<OptionsT>(N);
} }
}; };
} // end namespace ilist_detail } // end namespace ilist_detail
template <class OptionsT> template <class OptionsT>
@ -265,6 +279,7 @@ class ilist_node_with_parent : public ilist_node<NodeTy, Options...> {
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr)); getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getPrevNode(*static_cast<NodeTy *>(this)); return List.getPrevNode(*static_cast<NodeTy *>(this));
} }
/// \brief Get the previous node, or \c nullptr for the list head. /// \brief Get the previous node, or \c nullptr for the list head.
const NodeTy *getPrevNode() const { const NodeTy *getPrevNode() const {
return const_cast<ilist_node_with_parent *>(this)->getPrevNode(); return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
@ -278,6 +293,7 @@ class ilist_node_with_parent : public ilist_node<NodeTy, Options...> {
getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr)); getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
return List.getNextNode(*static_cast<NodeTy *>(this)); return List.getNextNode(*static_cast<NodeTy *>(this));
} }
/// \brief Get the next node, or \c nullptr for the list tail. /// \brief Get the next node, or \c nullptr for the list tail.
const NodeTy *getNextNode() const { const NodeTy *getNextNode() const {
return const_cast<ilist_node_with_parent *>(this)->getNextNode(); return const_cast<ilist_node_with_parent *>(this)->getNextNode();
@ -285,6 +301,6 @@ class ilist_node_with_parent : public ilist_node<NodeTy, Options...> {
/// @} /// @}
}; };
} // End llvm namespace } // end namespace llvm
#endif #endif // LLVM_ADT_ILIST_NODE_H

View File

@ -11,9 +11,11 @@
#define LLVM_ADT_ITERATOR_H #define LLVM_ADT_ITERATOR_H
#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/iterator_range.h"
#include <algorithm>
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <type_traits> #include <type_traits>
#include <utility>
namespace llvm { namespace llvm {
@ -206,7 +208,7 @@ template <
class iterator_adaptor_base class iterator_adaptor_base
: public iterator_facade_base<DerivedT, IteratorCategoryT, T, : public iterator_facade_base<DerivedT, IteratorCategoryT, T,
DifferenceTypeT, PointerT, ReferenceT> { DifferenceTypeT, PointerT, ReferenceT> {
typedef typename iterator_adaptor_base::iterator_facade_base BaseT; using BaseT = typename iterator_adaptor_base::iterator_facade_base;
protected: protected:
WrappedIteratorT I; WrappedIteratorT I;
@ -221,7 +223,7 @@ class iterator_adaptor_base
const WrappedIteratorT &wrapped() const { return I; } const WrappedIteratorT &wrapped() const { return I; }
public: public:
typedef DifferenceTypeT difference_type; using difference_type = DifferenceTypeT;
DerivedT &operator+=(difference_type n) { DerivedT &operator+=(difference_type n) {
static_assert( static_assert(
@ -279,7 +281,7 @@ class iterator_adaptor_base
/// which is implemented with some iterator over T*s: /// which is implemented with some iterator over T*s:
/// ///
/// \code /// \code
/// typedef pointee_iterator<SmallVectorImpl<T *>::iterator> iterator; /// using iterator = pointee_iterator<SmallVectorImpl<T *>::iterator>;
/// \endcode /// \endcode
template <typename WrappedIteratorT, template <typename WrappedIteratorT,
typename T = typename std::remove_reference< typename T = typename std::remove_reference<

View File

@ -13,9 +13,14 @@
#include "llvm/ADT/ilist_base.h" #include "llvm/ADT/ilist_base.h"
#include "llvm/ADT/ilist_iterator.h" #include "llvm/ADT/ilist_iterator.h"
#include "llvm/ADT/ilist_node.h" #include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/ilist_node_options.h"
#include "llvm/Support/Compiler.h"
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <functional>
#include <iterator>
#include <utility>
namespace llvm { namespace llvm {
@ -77,23 +82,23 @@ class simple_ilist
typename ilist_detail::compute_node_options<T, Options...>::type> { typename ilist_detail::compute_node_options<T, Options...>::type> {
static_assert(ilist_detail::check_options<Options...>::value, static_assert(ilist_detail::check_options<Options...>::value,
"Unrecognized node option!"); "Unrecognized node option!");
typedef using OptionsT =
typename ilist_detail::compute_node_options<T, Options...>::type OptionsT; typename ilist_detail::compute_node_options<T, Options...>::type;
typedef typename OptionsT::list_base_type list_base_type; using list_base_type = typename OptionsT::list_base_type;
ilist_sentinel<OptionsT> Sentinel; ilist_sentinel<OptionsT> Sentinel;
public: public:
typedef typename OptionsT::value_type value_type; using value_type = typename OptionsT::value_type;
typedef typename OptionsT::pointer pointer; using pointer = typename OptionsT::pointer;
typedef typename OptionsT::reference reference; using reference = typename OptionsT::reference;
typedef typename OptionsT::const_pointer const_pointer; using const_pointer = typename OptionsT::const_pointer;
typedef typename OptionsT::const_reference const_reference; using const_reference = typename OptionsT::const_reference;
typedef ilist_iterator<OptionsT, false, false> iterator; using iterator = ilist_iterator<OptionsT, false, false>;
typedef ilist_iterator<OptionsT, false, true> const_iterator; using const_iterator = ilist_iterator<OptionsT, false, true>;
typedef ilist_iterator<OptionsT, true, false> reverse_iterator; using reverse_iterator = ilist_iterator<OptionsT, true, false>;
typedef ilist_iterator<OptionsT, true, true> const_reverse_iterator; using const_reverse_iterator = ilist_iterator<OptionsT, true, true>;
typedef size_t size_type; using size_type = size_t;
typedef ptrdiff_t difference_type; using difference_type = ptrdiff_t;
simple_ilist() = default; simple_ilist() = default;
~simple_ilist() = default; ~simple_ilist() = default;

View File

@ -147,7 +147,6 @@ class MemoryAccess
MemoryAccess(const MemoryAccess &) = delete; MemoryAccess(const MemoryAccess &) = delete;
MemoryAccess &operator=(const MemoryAccess &) = delete; MemoryAccess &operator=(const MemoryAccess &) = delete;
void *operator new(size_t, unsigned) = delete;
void *operator new(size_t) = delete; void *operator new(size_t) = delete;
BasicBlock *getBlock() const { return Block; } BasicBlock *getBlock() const { return Block; }
@ -232,7 +231,6 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) {
/// MemoryDef instead. /// MemoryDef instead.
class MemoryUseOrDef : public MemoryAccess { class MemoryUseOrDef : public MemoryAccess {
public: public:
void *operator new(size_t, unsigned) = delete;
void *operator new(size_t) = delete; void *operator new(size_t) = delete;
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess); DECLARE_TRANSPARENT_OPERAND_ACCESSORS(MemoryAccess);
@ -298,7 +296,6 @@ class MemoryUse final : public MemoryUseOrDef {
// allocate space for exactly one operand // allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); } void *operator new(size_t s) { return User::operator new(s, 1); }
void *operator new(size_t, unsigned) = delete;
static inline bool classof(const Value *MA) { static inline bool classof(const Value *MA) {
return MA->getValueID() == MemoryUseVal; return MA->getValueID() == MemoryUseVal;
@ -355,7 +352,6 @@ class MemoryDef final : public MemoryUseOrDef {
// allocate space for exactly one operand // allocate space for exactly one operand
void *operator new(size_t s) { return User::operator new(s, 1); } void *operator new(size_t s) { return User::operator new(s, 1); }
void *operator new(size_t, unsigned) = delete;
static inline bool classof(const Value *MA) { static inline bool classof(const Value *MA) {
return MA->getValueID() == MemoryDefVal; return MA->getValueID() == MemoryDefVal;
@ -438,8 +434,6 @@ class MemoryPhi final : public MemoryAccess {
allocHungoffUses(ReservedSpace); allocHungoffUses(ReservedSpace);
} }
void *operator new(size_t, unsigned) = delete;
// Block iterator interface. This provides access to the list of incoming // Block iterator interface. This provides access to the list of incoming
// basic blocks, which parallels the list of incoming values. // basic blocks, which parallels the list of incoming values.
typedef BasicBlock **block_iterator; typedef BasicBlock **block_iterator;

View File

@ -1214,26 +1214,31 @@ class ScalarEvolution {
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0); unsigned Depth = 0);
const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0) {
SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; SmallVector<const SCEV *, 2> Ops = {LHS, RHS};
return getAddExpr(Ops, Flags); return getAddExpr(Ops, Flags, Depth);
} }
const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, const SCEV *getAddExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0) {
SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2};
return getAddExpr(Ops, Flags); return getAddExpr(Ops, Flags, Depth);
} }
const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops, const SCEV *getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0);
const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS, const SCEV *getMulExpr(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0) {
SmallVector<const SCEV *, 2> Ops = {LHS, RHS}; SmallVector<const SCEV *, 2> Ops = {LHS, RHS};
return getMulExpr(Ops, Flags); return getMulExpr(Ops, Flags, Depth);
} }
const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0) {
SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2}; SmallVector<const SCEV *, 3> Ops = {Op0, Op1, Op2};
return getMulExpr(Ops, Flags); return getMulExpr(Ops, Flags, Depth);
} }
const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getUDivExactExpr(const SCEV *LHS, const SCEV *RHS);
@ -1287,7 +1292,8 @@ class ScalarEvolution {
/// Return LHS-RHS. Minus is represented in SCEV as A+B*-1. /// Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS, const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0);
/// Return a SCEV corresponding to a conversion of the input value to the /// Return a SCEV corresponding to a conversion of the input value to the
/// specified type. If the type must be extended, it is zero extended. /// specified type. If the type must be extended, it is zero extended.
@ -1693,10 +1699,14 @@ class ScalarEvolution {
bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride, bool IsSigned, bool doesIVOverflowOnGT(const SCEV *RHS, const SCEV *Stride, bool IsSigned,
bool NoWrap); bool NoWrap);
/// Get add expr already created or create a new one /// Get add expr already created or create a new one.
const SCEV *getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops, const SCEV *getOrCreateAddExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags); SCEV::NoWrapFlags Flags);
/// Get mul expr already created or create a new one.
const SCEV *getOrCreateMulExpr(SmallVectorImpl<const SCEV *> &Ops,
SCEV::NoWrapFlags Flags);
private: private:
FoldingSet<SCEV> UniqueSCEVs; FoldingSet<SCEV> UniqueSCEVs;
FoldingSet<SCEVPredicate> UniquePreds; FoldingSet<SCEVPredicate> UniquePreds;

View File

@ -235,6 +235,11 @@ class TargetTransformInfo {
/// starting with the sources of divergence. /// starting with the sources of divergence.
bool isSourceOfDivergence(const Value *V) const; bool isSourceOfDivergence(const Value *V) const;
// \brief Returns true for the target specific
// set of operations which produce uniform result
// even taking non-unform arguments
bool isAlwaysUniform(const Value *V) const;
/// Returns the address space ID for a target's 'flat' address space. Note /// Returns the address space ID for a target's 'flat' address space. Note
/// this is not necessarily the same as addrspace(0), which LLVM sometimes /// this is not necessarily the same as addrspace(0), which LLVM sometimes
/// refers to as the generic address space. The flat address space is a /// refers to as the generic address space. The flat address space is a
@ -821,6 +826,7 @@ class TargetTransformInfo::Concept {
virtual int getUserCost(const User *U) = 0; virtual int getUserCost(const User *U) = 0;
virtual bool hasBranchDivergence() = 0; virtual bool hasBranchDivergence() = 0;
virtual bool isSourceOfDivergence(const Value *V) = 0; virtual bool isSourceOfDivergence(const Value *V) = 0;
virtual bool isAlwaysUniform(const Value *V) = 0;
virtual unsigned getFlatAddressSpace() = 0; virtual unsigned getFlatAddressSpace() = 0;
virtual bool isLoweredToCall(const Function *F) = 0; virtual bool isLoweredToCall(const Function *F) = 0;
virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0; virtual void getUnrollingPreferences(Loop *L, UnrollingPreferences &UP) = 0;
@ -873,7 +879,7 @@ class TargetTransformInfo::Concept {
virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
Type *Ty) = 0; Type *Ty) = 0;
virtual unsigned getNumberOfRegisters(bool Vector) = 0; virtual unsigned getNumberOfRegisters(bool Vector) = 0;
virtual unsigned getRegisterBitWidth(bool Vector) = 0; virtual unsigned getRegisterBitWidth(bool Vector) const = 0;
virtual unsigned getMinVectorRegisterBitWidth() = 0; virtual unsigned getMinVectorRegisterBitWidth() = 0;
virtual bool shouldConsiderAddressTypePromotion( virtual bool shouldConsiderAddressTypePromotion(
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0; const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0;
@ -998,6 +1004,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
return Impl.isSourceOfDivergence(V); return Impl.isSourceOfDivergence(V);
} }
bool isAlwaysUniform(const Value *V) override {
return Impl.isAlwaysUniform(V);
}
unsigned getFlatAddressSpace() override { unsigned getFlatAddressSpace() override {
return Impl.getFlatAddressSpace(); return Impl.getFlatAddressSpace();
} }
@ -1119,7 +1129,7 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
unsigned getNumberOfRegisters(bool Vector) override { unsigned getNumberOfRegisters(bool Vector) override {
return Impl.getNumberOfRegisters(Vector); return Impl.getNumberOfRegisters(Vector);
} }
unsigned getRegisterBitWidth(bool Vector) override { unsigned getRegisterBitWidth(bool Vector) const override {
return Impl.getRegisterBitWidth(Vector); return Impl.getRegisterBitWidth(Vector);
} }
unsigned getMinVectorRegisterBitWidth() override { unsigned getMinVectorRegisterBitWidth() override {

View File

@ -177,6 +177,8 @@ class TargetTransformInfoImplBase {
bool isSourceOfDivergence(const Value *V) { return false; } bool isSourceOfDivergence(const Value *V) { return false; }
bool isAlwaysUniform(const Value *V) { return false; }
unsigned getFlatAddressSpace () { unsigned getFlatAddressSpace () {
return -1; return -1;
} }
@ -320,7 +322,7 @@ class TargetTransformInfoImplBase {
unsigned getNumberOfRegisters(bool Vector) { return 8; } unsigned getNumberOfRegisters(bool Vector) { return 8; }
unsigned getRegisterBitWidth(bool Vector) { return 32; } unsigned getRegisterBitWidth(bool Vector) const { return 32; }
unsigned getMinVectorRegisterBitWidth() { return 128; } unsigned getMinVectorRegisterBitWidth() { return 128; }

View File

@ -20,6 +20,13 @@
namespace llvm { namespace llvm {
/// The type of CFI jumptable needed for a function.
enum CfiFunctionLinkage {
CFL_Definition = 0,
CFL_Declaration = 1,
CFL_WeakDeclaration = 2
};
/// A call site that could be devirtualized. /// A call site that could be devirtualized.
struct DevirtCallSite { struct DevirtCallSite {
/// The offset from the address point to the virtual function. /// The offset from the address point to the virtual function.

View File

@ -249,8 +249,8 @@ template <typename T> class ArrayRef;
}; };
/// Returns true if the value \p V is a pointer into a ContantDataArray. /// Returns true if the value \p V is a pointer into a ContantDataArray.
/// If successfull \p Index will point to a ConstantDataArray info object /// If successful \p Index will point to a ConstantDataArray info object
/// with an apropriate offset. /// with an appropriate offset.
bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice, bool getConstantDataArrayInfo(const Value *V, ConstantDataArraySlice &Slice,
unsigned ElementSize, uint64_t Offset = 0); unsigned ElementSize, uint64_t Offset = 0);

View File

@ -1,4 +1,4 @@
//===-- llvm/BinaryFormat/ELF.h - ELF constants and structures --*- C++ -*-===// //===- llvm/BinaryFormat/ELF.h - ELF constants and structures ---*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -20,27 +20,25 @@
#ifndef LLVM_BINARYFORMAT_ELF_H #ifndef LLVM_BINARYFORMAT_ELF_H
#define LLVM_BINARYFORMAT_ELF_H #define LLVM_BINARYFORMAT_ELF_H
#include "llvm/Support/Compiler.h" #include <cstdint>
#include "llvm/Support/DataTypes.h"
#include <cstring> #include <cstring>
namespace llvm { namespace llvm {
namespace ELF { namespace ELF {
typedef uint32_t Elf32_Addr; // Program address using Elf32_Addr = uint32_t; // Program address
typedef uint32_t Elf32_Off; // File offset using Elf32_Off = uint32_t; // File offset
typedef uint16_t Elf32_Half; using Elf32_Half = uint16_t;
typedef uint32_t Elf32_Word; using Elf32_Word = uint32_t;
typedef int32_t Elf32_Sword; using Elf32_Sword = int32_t;
typedef uint64_t Elf64_Addr; using Elf64_Addr = uint64_t;
typedef uint64_t Elf64_Off; using Elf64_Off = uint64_t;
typedef uint16_t Elf64_Half; using Elf64_Half = uint16_t;
typedef uint32_t Elf64_Word; using Elf64_Word = uint32_t;
typedef int32_t Elf64_Sword; using Elf64_Sword = int32_t;
typedef uint64_t Elf64_Xword; using Elf64_Xword = uint64_t;
typedef int64_t Elf64_Sxword; using Elf64_Sxword = int64_t;
// Object file magic string. // Object file magic string.
static const char ElfMagic[] = {0x7f, 'E', 'L', 'F', '\0'}; static const char ElfMagic[] = {0x7f, 'E', 'L', 'F', '\0'};
@ -75,9 +73,11 @@ struct Elf32_Ehdr {
Elf32_Half e_shentsize; // Size of an entry in the section header table Elf32_Half e_shentsize; // Size of an entry in the section header table
Elf32_Half e_shnum; // Number of entries in the section header table Elf32_Half e_shnum; // Number of entries in the section header table
Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
bool checkMagic() const { bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0; return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
} }
unsigned char getFileClass() const { return e_ident[EI_CLASS]; } unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; } unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
}; };
@ -99,9 +99,11 @@ struct Elf64_Ehdr {
Elf64_Half e_shentsize; Elf64_Half e_shentsize;
Elf64_Half e_shnum; Elf64_Half e_shnum;
Elf64_Half e_shstrndx; Elf64_Half e_shstrndx;
bool checkMagic() const { bool checkMagic() const {
return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0; return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0;
} }
unsigned char getFileClass() const { return e_ident[EI_CLASS]; } unsigned char getFileClass() const { return e_ident[EI_CLASS]; }
unsigned char getDataEncoding() const { return e_ident[EI_DATA]; } unsigned char getDataEncoding() const { return e_ident[EI_DATA]; }
}; };
@ -683,6 +685,7 @@ enum : unsigned {
SHT_GROUP = 17, // Section group. SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries. SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type. SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes. SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table. SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions. SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
@ -1356,7 +1359,6 @@ enum {
}; };
} // end namespace ELF } // end namespace ELF
} // end namespace llvm } // end namespace llvm
#endif #endif // LLVM_BINARYFORMAT_ELF_H

View File

@ -42,6 +42,12 @@ namespace llvm {
struct BitcodeFileContents; struct BitcodeFileContents;
/// Basic information extracted from a bitcode module to be used for LTO.
struct BitcodeLTOInfo {
bool IsThinLTO;
bool HasSummary;
};
/// Represents a module in a bitcode file. /// Represents a module in a bitcode file.
class BitcodeModule { class BitcodeModule {
// This covers the identification (if present) and module blocks. // This covers the identification (if present) and module blocks.
@ -90,15 +96,17 @@ namespace llvm {
/// Read the entire bitcode module and return it. /// Read the entire bitcode module and return it.
Expected<std::unique_ptr<Module>> parseModule(LLVMContext &Context); Expected<std::unique_ptr<Module>> parseModule(LLVMContext &Context);
/// Check if the given bitcode buffer contains a summary block. /// Returns information about the module to be used for LTO: whether to
Expected<bool> hasSummary(); /// compile with ThinLTO, and whether it has a summary.
Expected<BitcodeLTOInfo> getLTOInfo();
/// Parse the specified bitcode buffer, returning the module summary index. /// Parse the specified bitcode buffer, returning the module summary index.
Expected<std::unique_ptr<ModuleSummaryIndex>> getSummary(); Expected<std::unique_ptr<ModuleSummaryIndex>> getSummary();
/// Parse the specified bitcode buffer and merge its module summary index /// Parse the specified bitcode buffer and merge its module summary index
/// into CombinedIndex. /// into CombinedIndex.
Error readSummary(ModuleSummaryIndex &CombinedIndex, unsigned ModuleId); Error readSummary(ModuleSummaryIndex &CombinedIndex, StringRef ModulePath,
uint64_t ModuleId);
}; };
struct BitcodeFileContents { struct BitcodeFileContents {
@ -147,8 +155,8 @@ namespace llvm {
Expected<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer, Expected<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer,
LLVMContext &Context); LLVMContext &Context);
/// Check if the given bitcode buffer contains a summary block. /// Returns LTO information for the specified bitcode file.
Expected<bool> hasGlobalValueSummary(MemoryBufferRef Buffer); Expected<BitcodeLTOInfo> getBitcodeLTOInfo(MemoryBufferRef Buffer);
/// Parse the specified bitcode buffer, returning the module summary index. /// Parse the specified bitcode buffer, returning the module summary index.
Expected<std::unique_ptr<ModuleSummaryIndex>> Expected<std::unique_ptr<ModuleSummaryIndex>>
@ -157,7 +165,7 @@ namespace llvm {
/// Parse the specified bitcode buffer and merge the index into CombinedIndex. /// Parse the specified bitcode buffer and merge the index into CombinedIndex.
Error readModuleSummaryIndex(MemoryBufferRef Buffer, Error readModuleSummaryIndex(MemoryBufferRef Buffer,
ModuleSummaryIndex &CombinedIndex, ModuleSummaryIndex &CombinedIndex,
unsigned ModuleId); uint64_t ModuleId);
/// Parse the module summary index out of an IR file and return the module /// Parse the module summary index out of an IR file and return the module
/// summary index object if found, or an empty summary if not. If Path refers /// summary index object if found, or an empty summary if not. If Path refers

View File

@ -67,6 +67,10 @@ namespace llvm {
void writeModule(const Module *M, bool ShouldPreserveUseListOrder = false, void writeModule(const Module *M, bool ShouldPreserveUseListOrder = false,
const ModuleSummaryIndex *Index = nullptr, const ModuleSummaryIndex *Index = nullptr,
bool GenerateHash = false, ModuleHash *ModHash = nullptr); bool GenerateHash = false, ModuleHash *ModHash = nullptr);
void writeIndex(
const ModuleSummaryIndex *Index,
const std::map<std::string, GVSummaryMapTy> *ModuleToSummariesForIndex);
}; };
/// \brief Write the specified module to the specified raw output stream. /// \brief Write the specified module to the specified raw output stream.

View File

@ -240,6 +240,14 @@ enum GlobalValueSummarySymtabCodes {
// summaries, but it can also appear in per-module summaries for PGO data. // summaries, but it can also appear in per-module summaries for PGO data.
// [valueid, guid] // [valueid, guid]
FS_VALUE_GUID = 16, FS_VALUE_GUID = 16,
// The list of local functions with CFI jump tables. Function names are
// strings in strtab.
// [n * name]
FS_CFI_FUNCTION_DEFS = 17,
// The list of external functions with CFI jump tables. Function names are
// strings in strtab.
// [n * name]
FS_CFI_FUNCTION_DECLS = 18,
}; };
enum MetadataCodes { enum MetadataCodes {

View File

@ -93,6 +93,8 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
bool isSourceOfDivergence(const Value *V) { return false; } bool isSourceOfDivergence(const Value *V) { return false; }
bool isAlwaysUniform(const Value *V) { return false; }
unsigned getFlatAddressSpace() { unsigned getFlatAddressSpace() {
// Return an invalid address space. // Return an invalid address space.
return -1; return -1;
@ -346,7 +348,7 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; } unsigned getNumberOfRegisters(bool Vector) { return Vector ? 0 : 1; }
unsigned getRegisterBitWidth(bool Vector) { return 32; } unsigned getRegisterBitWidth(bool Vector) const { return 32; }
/// Estimate the overhead of scalarizing an instruction. Insert and Extract /// Estimate the overhead of scalarizing an instruction. Insert and Extract
/// are set if the result needs to be inserted and/or extracted from vectors. /// are set if the result needs to be inserted and/or extracted from vectors.

View File

@ -82,6 +82,11 @@ class FunctionLoweringInfo {
DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned> DenseMap<std::pair<const MachineBasicBlock *, const Value *>, unsigned>
SwiftErrorVRegUpwardsUse; SwiftErrorVRegUpwardsUse;
/// A map from instructions that define/use a swifterror value to the virtual
/// register that represents that def/use.
llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, unsigned>
SwiftErrorVRegDefUses;
/// The swifterror argument of the current function. /// The swifterror argument of the current function.
const Value *SwiftErrorArg; const Value *SwiftErrorArg;
@ -101,6 +106,13 @@ class FunctionLoweringInfo {
void setCurrentSwiftErrorVReg(const MachineBasicBlock *MBB, const Value *, void setCurrentSwiftErrorVReg(const MachineBasicBlock *MBB, const Value *,
unsigned); unsigned);
/// Get or create the swifterror value virtual register for a def of a
/// swifterror by an instruction.
std::pair<unsigned, bool> getOrCreateSwiftErrorVRegDefAt(const Instruction *);
std::pair<unsigned, bool>
getOrCreateSwiftErrorVRegUseAt(const Instruction *, const MachineBasicBlock *,
const Value *);
/// ValueMap - Since we emit code for the function a basic block at a time, /// ValueMap - Since we emit code for the function a basic block at a time,
/// we must remember which virtual registers hold the values for /// we must remember which virtual registers hold the values for
/// cross-basic-block values. /// cross-basic-block values.

View File

@ -21,9 +21,11 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H #ifndef LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
#define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H #define LLVM_CODEGEN_GLOBALISEL_MACHINELEGALIZEHELPER_H
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/LowLevelType.h" #include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
namespace llvm { namespace llvm {
// Forward declarations. // Forward declarations.
@ -99,6 +101,12 @@ class LegalizerHelper {
const LegalizerInfo &LI; const LegalizerInfo &LI;
}; };
/// Helper function that replaces \p MI with a libcall.
LegalizerHelper::LegalizeResult
replaceWithLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder,
RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result,
ArrayRef<CallLowering::ArgInfo> Args);
} // End namespace llvm. } // End namespace llvm.
#endif #endif

View File

@ -40,8 +40,8 @@ class MachineIRBuilder {
MachineFunction *MF; MachineFunction *MF;
/// Information used to access the description of the opcodes. /// Information used to access the description of the opcodes.
const TargetInstrInfo *TII; const TargetInstrInfo *TII;
/// Information used to verify types are consistent. /// Information used to verify types are consistent and to create virtual registers.
const MachineRegisterInfo *MRI; MachineRegisterInfo *MRI;
/// Debug location to be set to any instruction we create. /// Debug location to be set to any instruction we create.
DebugLoc DL; DebugLoc DL;
@ -229,6 +229,26 @@ class MachineIRBuilder {
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0,
unsigned Op1); unsigned Op1);
/// Materialize and insert \p Res<def> = G_GEP \p Op0, (G_CONSTANT \p Value)
///
/// G_GEP adds \p Value bytes to the pointer specified by \p Op0,
/// storing the resulting pointer in \p Res. If \p Value is zero then no
/// G_GEP or G_CONSTANT will be created and \pre Op0 will be assigned to
/// \p Res.
///
/// \pre setBasicBlock or setMI must have been called.
/// \pre \p Op0 must be a generic virtual register with pointer type.
/// \pre \p ValueTy must be a scalar type.
/// \pre \p Res must be 0. This is to detect confusion between
/// materializeGEP() and buildGEP().
/// \post \p Res will either be a new generic virtual register of the same
/// type as \p Op0 or \p Op0 itself.
///
/// \return a MachineInstrBuilder for the newly created instruction.
Optional<MachineInstrBuilder> materializeGEP(unsigned &Res, unsigned Op0,
const LLT &ValueTy,
uint64_t Value);
/// Build and insert \p Res<def> = G_PTR_MASK \p Op0, \p NumBits /// Build and insert \p Res<def> = G_PTR_MASK \p Op0, \p NumBits
/// ///
/// G_PTR_MASK clears the low bits of a pointer operand without destroying its /// G_PTR_MASK clears the low bits of a pointer operand without destroying its

View File

@ -333,12 +333,12 @@ namespace RTLIB {
MEMSET, MEMSET,
MEMMOVE, MEMMOVE,
// ELEMENT-WISE ATOMIC MEMORY // ELEMENT-WISE UNORDERED-ATOMIC MEMORY of different element sizes
MEMCPY_ELEMENT_ATOMIC_1, MEMCPY_ELEMENT_UNORDERED_ATOMIC_1,
MEMCPY_ELEMENT_ATOMIC_2, MEMCPY_ELEMENT_UNORDERED_ATOMIC_2,
MEMCPY_ELEMENT_ATOMIC_4, MEMCPY_ELEMENT_UNORDERED_ATOMIC_4,
MEMCPY_ELEMENT_ATOMIC_8, MEMCPY_ELEMENT_UNORDERED_ATOMIC_8,
MEMCPY_ELEMENT_ATOMIC_16, MEMCPY_ELEMENT_UNORDERED_ATOMIC_16,
// EXCEPTION HANDLING // EXCEPTION HANDLING
UNWIND_RESUME, UNWIND_RESUME,
@ -511,9 +511,10 @@ namespace RTLIB {
/// UNKNOWN_LIBCALL if there is none. /// UNKNOWN_LIBCALL if there is none.
Libcall getSYNC(unsigned Opc, MVT VT); Libcall getSYNC(unsigned Opc, MVT VT);
/// getMEMCPY_ELEMENT_ATOMIC - Return MEMCPY_ELEMENT_ATOMIC_* value for the /// getMEMCPY_ELEMENT_UNORDERED_ATOMIC - Return
/// given element size or UNKNOW_LIBCALL if there is none. /// MEMCPY_ELEMENT_UNORDERED_ATOMIC_* value for the given element size or
Libcall getMEMCPY_ELEMENT_ATOMIC(uint64_t ElementSize); /// UNKNOW_LIBCALL if there is none.
Libcall getMEMCPY_ELEMENT_UNORDERED_ATOMIC(uint64_t ElementSize);
} }
} }

View File

@ -1217,6 +1217,12 @@ class SelectionDAG {
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To, void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
unsigned Num); unsigned Num);
/// If an existing load has uses of its chain, create a token factor node with
/// that chain and the new memory node's chain and update users of the old
/// chain to the token factor. This ensures that the new memory node will have
/// the same relative memory dependency position as the old load.
void makeEquivalentMemoryOrdering(LoadSDNode *Old, SDValue New);
/// Topological-sort the AllNodes list and a /// Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their /// assign a unique node id for each node in the DAG based on their
/// topological order. Returns the number of nodes. /// topological order. Returns the number of nodes.

View File

@ -42,9 +42,8 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
~TargetLoweringObjectFileELF() override = default; ~TargetLoweringObjectFileELF() override = default;
/// Emit Obj-C garbage collection and linker options. /// Emit Obj-C garbage collection and linker options.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM,
const MCSymbol *Sym) const override; const MCSymbol *Sym) const override;
@ -99,9 +98,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
void Initialize(MCContext &Ctx, const TargetMachine &TM) override; void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
/// Emit the module flags that specify the garbage collection information. /// Emit the module flags that specify the garbage collection information.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind, MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override; const TargetMachine &TM) const override;
@ -155,9 +153,8 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
const TargetMachine &TM) const override; const TargetMachine &TM) const override;
/// Emit Obj-C garbage collection and linker options. /// Emit Obj-C garbage collection and linker options.
void emitModuleFlags(MCStreamer &Streamer, void emitModuleMetadata(MCStreamer &Streamer, Module &M,
ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const override;
const TargetMachine &TM) const override;
MCSection *getStaticCtorSection(unsigned Priority, MCSection *getStaticCtorSection(unsigned Priority,
const MCSymbol *KeySym) const override; const MCSymbol *KeySym) const override;

View File

@ -418,6 +418,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ProcSymFlags)
/// Corresponds to COMPILESYM2::Flags bitfield. /// Corresponds to COMPILESYM2::Flags bitfield.
enum class CompileSym2Flags : uint32_t { enum class CompileSym2Flags : uint32_t {
None = 0,
SourceLanguageMask = 0xFF,
EC = 1 << 8, EC = 1 << 8,
NoDbgInfo = 1 << 9, NoDbgInfo = 1 << 9,
LTCG = 1 << 10, LTCG = 1 << 10,
@ -432,6 +434,8 @@ CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym2Flags)
/// Corresponds to COMPILESYM3::Flags bitfield. /// Corresponds to COMPILESYM3::Flags bitfield.
enum class CompileSym3Flags : uint32_t { enum class CompileSym3Flags : uint32_t {
None = 0,
SourceLanguageMask = 0xFF,
EC = 1 << 8, EC = 1 << 8,
NoDbgInfo = 1 << 9, NoDbgInfo = 1 << 9,
LTCG = 1 << 10, LTCG = 1 << 10,
@ -448,6 +452,7 @@ enum class CompileSym3Flags : uint32_t {
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags) CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(CompileSym3Flags)
enum class ExportFlags : uint16_t { enum class ExportFlags : uint16_t {
None = 0,
IsConstant = 1 << 0, IsConstant = 1 << 0,
IsData = 1 << 1, IsData = 1 << 1,
IsPrivate = 1 << 2, IsPrivate = 1 << 2,

View File

@ -49,6 +49,7 @@ class DebugFrameDataSubsection final : public DebugSubsection {
Error commit(BinaryStreamWriter &Writer) const override; Error commit(BinaryStreamWriter &Writer) const override;
void addFrameData(const FrameData &Frame); void addFrameData(const FrameData &Frame);
void setFrames(ArrayRef<FrameData> Frames);
private: private:
std::vector<FrameData> Frames; std::vector<FrameData> Frames;

View File

@ -19,7 +19,7 @@
namespace llvm { namespace llvm {
namespace codeview { namespace codeview {
class DebugInlineeLinesSubsectionsRef; class DebugInlineeLinesSubsectionRef;
class DebugChecksumsSubsection; class DebugChecksumsSubsection;
enum class InlineeLinesSignature : uint32_t { enum class InlineeLinesSignature : uint32_t {

View File

@ -49,13 +49,13 @@ class DebugSubsectionRecord {
class DebugSubsectionRecordBuilder { class DebugSubsectionRecordBuilder {
public: public:
DebugSubsectionRecordBuilder(std::unique_ptr<DebugSubsection> Subsection, DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
CodeViewContainer Container); CodeViewContainer Container);
uint32_t calculateSerializedLength(); uint32_t calculateSerializedLength();
Error commit(BinaryStreamWriter &Writer) const; Error commit(BinaryStreamWriter &Writer) const;
private: private:
std::unique_ptr<DebugSubsection> Subsection; std::shared_ptr<DebugSubsection> Subsection;
CodeViewContainer Container; CodeViewContainer Container;
}; };
@ -64,6 +64,9 @@ class DebugSubsectionRecordBuilder {
template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> { template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
Error operator()(BinaryStreamRef Stream, uint32_t &Length, Error operator()(BinaryStreamRef Stream, uint32_t &Length,
codeview::DebugSubsectionRecord &Info) { codeview::DebugSubsectionRecord &Info) {
// FIXME: We need to pass the container type through to this function. In
// practice this isn't super important since the subsection header describes
// its length and we can just skip it. It's more important when writing.
if (auto EC = codeview::DebugSubsectionRecord::initialize( if (auto EC = codeview::DebugSubsectionRecord::initialize(
Stream, Info, codeview::CodeViewContainer::Pdb)) Stream, Info, codeview::CodeViewContainer::Pdb))
return EC; return EC;

View File

@ -12,6 +12,7 @@
#include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include <cstdint> #include <cstdint>
@ -30,56 +31,7 @@ class DebugStringTableSubsectionRef;
class DebugSymbolRVASubsectionRef; class DebugSymbolRVASubsectionRef;
class DebugSymbolsSubsectionRef; class DebugSymbolsSubsectionRef;
class DebugUnknownSubsectionRef; class DebugUnknownSubsectionRef;
class StringsAndChecksumsRef;
struct DebugSubsectionState {
public:
// If no subsections are known about initially, we find as much as we can.
DebugSubsectionState();
// If only a string table subsection is given, we find a checksums subsection.
explicit DebugSubsectionState(const DebugStringTableSubsectionRef &Strings);
// If both subsections are given, we don't need to find anything.
DebugSubsectionState(const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums);
template <typename T> void initialize(T &&FragmentRange) {
for (const DebugSubsectionRecord &R : FragmentRange) {
if (Strings && Checksums)
return;
if (R.kind() == DebugSubsectionKind::FileChecksums) {
initializeChecksums(R);
continue;
}
if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
// While in practice we should never encounter a string table even
// though the string table is already initialized, in theory it's
// possible. PDBs are supposed to have one global string table and
// then this subsection should not appear. Whereas object files are
// supposed to have this subsection appear exactly once. However,
// for testing purposes it's nice to be able to test this subsection
// independently of one format or the other, so for some tests we
// manually construct a PDB that contains this subsection in addition
// to a global string table.
initializeStrings(R);
continue;
}
}
}
const DebugStringTableSubsectionRef &strings() const { return *Strings; }
const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
private:
void initializeStrings(const DebugSubsectionRecord &SR);
void initializeChecksums(const DebugSubsectionRecord &FCR);
std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
const DebugStringTableSubsectionRef *Strings = nullptr;
const DebugChecksumsSubsectionRef *Checksums = nullptr;
};
class DebugSubsectionVisitor { class DebugSubsectionVisitor {
public: public:
@ -89,38 +41,38 @@ class DebugSubsectionVisitor {
return Error::success(); return Error::success();
} }
virtual Error visitLines(DebugLinesSubsectionRef &Lines, virtual Error visitLines(DebugLinesSubsectionRef &Lines,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums, virtual Error visitFileChecksums(DebugChecksumsSubsectionRef &Checksums,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees, virtual Error visitInlineeLines(DebugInlineeLinesSubsectionRef &Inlinees,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error virtual Error
visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE, visitCrossModuleExports(DebugCrossModuleExportsSubsectionRef &CSE,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error virtual Error
visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE, visitCrossModuleImports(DebugCrossModuleImportsSubsectionRef &CSE,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitStringTable(DebugStringTableSubsectionRef &ST, virtual Error visitStringTable(DebugStringTableSubsectionRef &ST,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE, virtual Error visitSymbols(DebugSymbolsSubsectionRef &CSE,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD, virtual Error visitFrameData(DebugFrameDataSubsectionRef &FD,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs, virtual Error visitCOFFSymbolRVAs(DebugSymbolRVASubsectionRef &RVAs,
const DebugSubsectionState &State) = 0; const StringsAndChecksumsRef &State) = 0;
}; };
Error visitDebugSubsection(const DebugSubsectionRecord &R, Error visitDebugSubsection(const DebugSubsectionRecord &R,
DebugSubsectionVisitor &V, DebugSubsectionVisitor &V,
const DebugSubsectionState &State); const StringsAndChecksumsRef &State);
namespace detail { namespace detail {
template <typename T> template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
DebugSubsectionState &State) { StringsAndChecksumsRef &State) {
State.initialize(std::forward<T>(FragmentRange)); State.initialize(std::forward<T>(FragmentRange));
for (const DebugSubsectionRecord &L : FragmentRange) { for (const DebugSubsectionRecord &L : FragmentRange) {
@ -133,7 +85,7 @@ Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
template <typename T> template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) { Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
DebugSubsectionState State; StringsAndChecksumsRef State;
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State); State);
} }
@ -141,7 +93,7 @@ Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V) {
template <typename T> template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings) { const DebugStringTableSubsectionRef &Strings) {
DebugSubsectionState State(Strings); StringsAndChecksumsRef State(Strings);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State); State);
} }
@ -150,7 +102,7 @@ template <typename T>
Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V, Error visitDebugSubsections(T &&FragmentRange, DebugSubsectionVisitor &V,
const DebugStringTableSubsectionRef &Strings, const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums) { const DebugChecksumsSubsectionRef &Checksums) {
DebugSubsectionState State(Strings, Checksums); StringsAndChecksumsRef State(Strings, Checksums);
return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V, return detail::visitDebugSubsections(std::forward<T>(FragmentRange), V,
State); State);
} }

View File

@ -12,7 +12,10 @@
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/FormatVariadic.h"
namespace llvm { namespace llvm {
namespace codeview { namespace codeview {
@ -35,6 +38,20 @@ inline detail::GuidAdapter fmt_guid(ArrayRef<uint8_t> Item) {
return detail::GuidAdapter(Item); return detail::GuidAdapter(Item);
} }
} }
template <> struct format_provider<codeview::TypeIndex> {
public:
static void format(const codeview::TypeIndex &V, llvm::raw_ostream &Stream,
StringRef Style) {
if (V.isNoneType())
Stream << "<no type>";
else {
Stream << formatv("{0:X+4}", V.getIndex());
if (V.isSimple())
Stream << " (" << codeview::TypeIndex::simpleTypeName(V) << ")";
}
}
};
} }
#endif #endif

View File

@ -0,0 +1,106 @@
//===- StringsAndChecksums.h ------------------------------------*- 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_CODEVIEW_STRINGS_AND_CHECKSUMS_H
#define LLVM_DEBUGINFO_CODEVIEW_STRINGS_AND_CHECKSUMS_H
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
#include <memory>
namespace llvm {
namespace codeview {
class DebugSubsectionRecord;
class DebugChecksumsSubsectionRef;
class DebugStringTableSubsectionRef;
class DebugChecksumsSubsection;
class DebugStringTableSubsection;
class StringsAndChecksumsRef {
public:
// If no subsections are known about initially, we find as much as we can.
StringsAndChecksumsRef();
// If only a string table subsection is given, we find a checksums subsection.
explicit StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings);
// If both subsections are given, we don't need to find anything.
StringsAndChecksumsRef(const DebugStringTableSubsectionRef &Strings,
const DebugChecksumsSubsectionRef &Checksums);
void setChecksums(const DebugChecksumsSubsectionRef &CS);
template <typename T> void initialize(T &&FragmentRange) {
for (const DebugSubsectionRecord &R : FragmentRange) {
if (Strings && Checksums)
return;
if (R.kind() == DebugSubsectionKind::FileChecksums) {
initializeChecksums(R);
continue;
}
if (R.kind() == DebugSubsectionKind::StringTable && !Strings) {
// While in practice we should never encounter a string table even
// though the string table is already initialized, in theory it's
// possible. PDBs are supposed to have one global string table and
// then this subsection should not appear. Whereas object files are
// supposed to have this subsection appear exactly once. However,
// for testing purposes it's nice to be able to test this subsection
// independently of one format or the other, so for some tests we
// manually construct a PDB that contains this subsection in addition
// to a global string table.
initializeStrings(R);
continue;
}
}
}
const DebugStringTableSubsectionRef &strings() const { return *Strings; }
const DebugChecksumsSubsectionRef &checksums() const { return *Checksums; }
bool hasStrings() const { return Strings != nullptr; }
bool hasChecksums() const { return Checksums != nullptr; }
private:
void initializeStrings(const DebugSubsectionRecord &SR);
void initializeChecksums(const DebugSubsectionRecord &FCR);
std::unique_ptr<DebugStringTableSubsectionRef> OwnedStrings;
std::unique_ptr<DebugChecksumsSubsectionRef> OwnedChecksums;
const DebugStringTableSubsectionRef *Strings = nullptr;
const DebugChecksumsSubsectionRef *Checksums = nullptr;
};
class StringsAndChecksums {
public:
using StringsPtr = std::shared_ptr<DebugStringTableSubsection>;
using ChecksumsPtr = std::shared_ptr<DebugChecksumsSubsection>;
// If no subsections are known about initially, we find as much as we can.
StringsAndChecksums() {}
void setStrings(const StringsPtr &SP) { Strings = SP; }
void setChecksums(const ChecksumsPtr &CP) { Checksums = CP; }
const StringsPtr &strings() const { return Strings; }
const ChecksumsPtr &checksums() const { return Checksums; }
bool hasStrings() const { return Strings != nullptr; }
bool hasChecksums() const { return Checksums != nullptr; }
private:
StringsPtr Strings;
ChecksumsPtr Checksums;
};
} // namespace codeview
} // namespace llvm
#endif

View File

@ -363,7 +363,7 @@ class PublicSym32 : public SymbolRecord {
: SymbolRecord(SymbolRecordKind::PublicSym32), : SymbolRecord(SymbolRecordKind::PublicSym32),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
uint32_t Index; TypeIndex Index;
uint32_t Offset; uint32_t Offset;
uint16_t Segment; uint16_t Segment;
StringRef Name; StringRef Name;
@ -379,7 +379,7 @@ class RegisterSym : public SymbolRecord {
: SymbolRecord(SymbolRecordKind::RegisterSym), : SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
uint32_t Index; TypeIndex Index;
RegisterId Register; RegisterId Register;
StringRef Name; StringRef Name;
@ -679,7 +679,7 @@ class FileStaticSym : public SymbolRecord {
: SymbolRecord(SymbolRecordKind::FileStaticSym), : SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {} RecordOffset(RecordOffset) {}
uint32_t Index; TypeIndex Index;
uint32_t ModFilenameOffset; uint32_t ModFilenameOffset;
LocalSymFlags Flags; LocalSymFlags Flags;
StringRef Name; StringRef Name;
@ -814,7 +814,7 @@ class FrameCookieSym : public SymbolRecord {
uint32_t CodeOffset; uint32_t CodeOffset;
uint16_t Register; uint16_t Register;
uint8_t CookieKind; FrameCookieKind CookieKind;
uint8_t Flags; uint8_t Flags;
uint32_t RecordOffset; uint32_t RecordOffset;
@ -871,7 +871,7 @@ class RegRelativeSym : public SymbolRecord {
uint32_t Offset; uint32_t Offset;
TypeIndex Type; TypeIndex Type;
uint16_t Register; RegisterId Register;
StringRef Name; StringRef Name;
uint32_t RecordOffset; uint32_t RecordOffset;

View File

@ -248,6 +248,8 @@ class TypeIndex {
return A.toArrayIndex() - B.toArrayIndex(); return A.toArrayIndex() - B.toArrayIndex();
} }
static StringRef simpleTypeName(TypeIndex TI);
private: private:
support::ulittle32_t Index; support::ulittle32_t Index;
}; };

View File

@ -50,6 +50,10 @@ class DWARFAcceleratorTable {
: AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {} : AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {}
bool extract(); bool extract();
uint32_t getNumBuckets();
uint32_t getNumHashes();
uint32_t getSizeHdr();
uint32_t getHeaderDataLength();
void dump(raw_ostream &OS) const; void dump(raw_ostream &OS) const;
}; };

View File

@ -20,6 +20,7 @@ struct DWARFAttribute;
class DWARFContext; class DWARFContext;
class DWARFDie; class DWARFDie;
class DWARFUnit; class DWARFUnit;
class DWARFAcceleratorTable;
/// A class that verifies DWARF debug information given a DWARF Context. /// A class that verifies DWARF debug information given a DWARF Context.
class DWARFVerifier { class DWARFVerifier {
@ -29,8 +30,9 @@ class DWARFVerifier {
/// can verify each reference points to a valid DIE and not an offset that /// can verify each reference points to a valid DIE and not an offset that
/// lies between to valid DIEs. /// lies between to valid DIEs.
std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets; std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
uint32_t NumDebugInfoErrors; uint32_t NumDebugInfoErrors = 0;
uint32_t NumDebugLineErrors; uint32_t NumDebugLineErrors = 0;
uint32_t NumAppleNamesErrors = 0;
/// Verifies the attribute's DWARF attribute and its value. /// Verifies the attribute's DWARF attribute and its value.
/// ///
@ -38,8 +40,8 @@ class DWARFVerifier {
/// - DW_AT_ranges values is a valid .debug_ranges offset /// - DW_AT_ranges values is a valid .debug_ranges offset
/// - DW_AT_stmt_list is a valid .debug_line offset /// - DW_AT_stmt_list is a valid .debug_line offset
/// ///
/// @param Die The DWARF DIE that owns the attribute value /// \param Die The DWARF DIE that owns the attribute value
/// @param AttrValue The DWARF attribute value to check /// \param AttrValue The DWARF attribute value to check
void verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue); void verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue);
/// Verifies the attribute's DWARF form. /// Verifies the attribute's DWARF form.
@ -49,8 +51,8 @@ class DWARFVerifier {
/// - All DW_FORM_ref_addr values have valid .debug_info offsets /// - All DW_FORM_ref_addr values have valid .debug_info offsets
/// - All DW_FORM_strp values have valid .debug_str offsets /// - All DW_FORM_strp values have valid .debug_str offsets
/// ///
/// @param Die The DWARF DIE that owns the attribute value /// \param Die The DWARF DIE that owns the attribute value
/// @param AttrValue The DWARF attribute value to check /// \param AttrValue The DWARF attribute value to check
void verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue); void verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
/// Verifies the all valid references that were found when iterating through /// Verifies the all valid references that were found when iterating through
@ -75,13 +77,13 @@ class DWARFVerifier {
public: public:
DWARFVerifier(raw_ostream &S, DWARFContext &D) DWARFVerifier(raw_ostream &S, DWARFContext &D)
: OS(S), DCtx(D), NumDebugInfoErrors(0), NumDebugLineErrors(0) {} : OS(S), DCtx(D) {}
/// Verify the information in the .debug_info section. /// Verify the information in the .debug_info section.
/// ///
/// Any errors are reported to the stream that was this object was /// Any errors are reported to the stream that was this object was
/// constructed with. /// constructed with.
/// ///
/// @return True if the .debug_info verifies successfully, false otherwise. /// \returns true if the .debug_info verifies successfully, false otherwise.
bool handleDebugInfo(); bool handleDebugInfo();
/// Verify the information in the .debug_line section. /// Verify the information in the .debug_line section.
@ -89,8 +91,16 @@ class DWARFVerifier {
/// Any errors are reported to the stream that was this object was /// Any errors are reported to the stream that was this object was
/// constructed with. /// constructed with.
/// ///
/// @return True if the .debug_line verifies successfully, false otherwise. /// \returns true if the .debug_line verifies successfully, false otherwise.
bool handleDebugLine(); bool handleDebugLine();
/// Verify the information in the .apple_names accelerator table.
///
/// Any errors are reported to the stream that was this object was
/// constructed with.
///
/// \returns true if the .apple_names verifies successfully, false otherwise.
bool handleAppleNames();
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -50,12 +50,14 @@ class DbiModuleDescriptorBuilder {
void addSymbol(codeview::CVSymbol Symbol); void addSymbol(codeview::CVSymbol Symbol);
void void
addDebugSubsection(std::unique_ptr<codeview::DebugSubsection> Subsection); addDebugSubsection(std::shared_ptr<codeview::DebugSubsection> Subsection);
uint16_t getStreamIndex() const; uint16_t getStreamIndex() const;
StringRef getModuleName() const { return ModuleName; } StringRef getModuleName() const { return ModuleName; }
StringRef getObjFileName() const { return ObjFileName; } StringRef getObjFileName() const { return ObjFileName; }
unsigned getModuleIndex() const { return Layout.Mod; }
ArrayRef<std::string> source_files() const { ArrayRef<std::string> source_files() const {
return makeArrayRef(SourceFiles); return makeArrayRef(SourceFiles);
} }

View File

@ -12,6 +12,7 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator.h"
#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
#include "llvm/Support/BinaryStreamArray.h" #include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h" #include "llvm/Support/BinaryStreamRef.h"
@ -21,6 +22,7 @@
#include <vector> #include <vector>
namespace llvm { namespace llvm {
namespace codeview {}
namespace pdb { namespace pdb {
class DbiModuleList; class DbiModuleList;

View File

@ -49,7 +49,6 @@ class DbiStreamBuilder {
void setPdbDllRbld(uint16_t R); void setPdbDllRbld(uint16_t R);
void setFlags(uint16_t F); void setFlags(uint16_t F);
void setMachineType(PDB_Machine M); void setMachineType(PDB_Machine M);
void setSectionContribs(ArrayRef<SectionContrib> SecMap);
void setSectionMap(ArrayRef<SecMapEntry> SecMap); void setSectionMap(ArrayRef<SecMapEntry> SecMap);
// Add given bytes as a new stream. // Add given bytes as a new stream.
@ -65,10 +64,8 @@ class DbiStreamBuilder {
Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer); Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer);
// A helper function to create Section Contributions from COFF input void addSectionContrib(DbiModuleDescriptorBuilder *ModuleDbi,
// section headers. const llvm::object::coff_section *SecHdr);
static std::vector<SectionContrib>
createSectionContribs(ArrayRef<llvm::object::coff_section> SecHdrs);
// A helper function to create a Section Map from a COFF section header. // A helper function to create a Section Map from a COFF section header.
static std::vector<SecMapEntry> static std::vector<SecMapEntry>
@ -112,7 +109,7 @@ class DbiStreamBuilder {
WritableBinaryStreamRef NamesBuffer; WritableBinaryStreamRef NamesBuffer;
MutableBinaryByteStream FileInfoBuffer; MutableBinaryByteStream FileInfoBuffer;
ArrayRef<SectionContrib> SectionContribs; std::vector<SectionContrib> SectionContribs;
ArrayRef<SecMapEntry> SectionMap; ArrayRef<SecMapEntry> SectionMap;
llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams; llvm::SmallVector<DebugStream, (int)DbgHeaderType::Max> DbgStreams;
}; };

View File

@ -35,6 +35,7 @@ class InfoStream {
uint32_t getStreamSize() const; uint32_t getStreamSize() const;
bool containsIdStream() const;
PdbRaw_ImplVer getVersion() const; PdbRaw_ImplVer getVersion() const;
uint32_t getSignature() const; uint32_t getSignature() const;
uint32_t getAge() const; uint32_t getAge() const;

View File

@ -31,6 +31,7 @@ class ModuleDebugStreamRef {
public: public:
ModuleDebugStreamRef(const DbiModuleDescriptor &Module, ModuleDebugStreamRef(const DbiModuleDescriptor &Module,
std::unique_ptr<msf::MappedBlockStream> Stream); std::unique_ptr<msf::MappedBlockStream> Stream);
ModuleDebugStreamRef(ModuleDebugStreamRef &&Other) = default;
~ModuleDebugStreamRef(); ~ModuleDebugStreamRef();
Error reload(); Error reload();
@ -40,6 +41,12 @@ class ModuleDebugStreamRef {
iterator_range<codeview::CVSymbolArray::Iterator> iterator_range<codeview::CVSymbolArray::Iterator>
symbols(bool *HadError) const; symbols(bool *HadError) const;
const codeview::CVSymbolArray &getSymbolArray() const {
return SymbolsSubstream;
}
ModuleDebugStreamRef &operator=(ModuleDebugStreamRef &&Other) = default;
llvm::iterator_range<DebugSubsectionIterator> subsections() const; llvm::iterator_range<DebugSubsectionIterator> subsections() const;
bool hasDebugSubsections() const; bool hasDebugSubsections() const;
@ -54,7 +61,7 @@ class ModuleDebugStreamRef {
uint32_t Signature; uint32_t Signature;
std::unique_ptr<msf::MappedBlockStream> Stream; std::shared_ptr<msf::MappedBlockStream> Stream;
codeview::CVSymbolArray SymbolsSubstream; codeview::CVSymbolArray SymbolsSubstream;
BinaryStreamRef C11LinesSubstream; BinaryStreamRef C11LinesSubstream;

View File

@ -108,6 +108,8 @@ class PDBFile : public msf::IMSFFile {
bool hasPDBTpiStream() const; bool hasPDBTpiStream() const;
bool hasPDBStringTable(); bool hasPDBStringTable();
uint32_t getPointerSize();
private: private:
Expected<std::unique_ptr<msf::MappedBlockStream>> Expected<std::unique_ptr<msf::MappedBlockStream>>
safelyCreateIndexedStream(const msf::MSFLayout &Layout, safelyCreateIndexedStream(const msf::MSFLayout &Layout,

View File

@ -45,7 +45,7 @@ class PDBStringTable {
FixedStreamArray<support::ulittle32_t> name_ids() const; FixedStreamArray<support::ulittle32_t> name_ids() const;
codeview::DebugStringTableSubsectionRef getStringTable() const; const codeview::DebugStringTableSubsectionRef &getStringTable() const;
private: private:
Error readHeader(BinaryStreamReader &Reader); Error readHeader(BinaryStreamReader &Reader);

View File

@ -41,10 +41,7 @@ class PDBStringTableBuilder {
uint32_t calculateSerializedSize() const; uint32_t calculateSerializedSize() const;
Error commit(BinaryStreamWriter &Writer) const; Error commit(BinaryStreamWriter &Writer) const;
codeview::DebugStringTableSubsection &getStrings() { return Strings; } void setStrings(const codeview::DebugStringTableSubsection &Strings);
const codeview::DebugStringTableSubsection &getStrings() const {
return Strings;
}
private: private:
uint32_t calculateHashTableSize() const; uint32_t calculateHashTableSize() const;

View File

@ -35,6 +35,7 @@ class PublicsStream {
uint32_t getSymHash() const; uint32_t getSymHash() const;
uint32_t getAddrMap() const; uint32_t getAddrMap() const;
uint32_t getNumBuckets() const { return NumBuckets; } uint32_t getNumBuckets() const { return NumBuckets; }
Expected<const codeview::CVSymbolArray &> getSymbolArray() const;
iterator_range<codeview::CVSymbolArray::Iterator> iterator_range<codeview::CVSymbolArray::Iterator>
getSymbols(bool *HadError) const; getSymbols(bool *HadError) const;
FixedStreamArray<support::ulittle32_t> getHashBuckets() const { FixedStreamArray<support::ulittle32_t> getHashBuckets() const {

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