//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the SmallVector class. // //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/MemAlloc.h" #include <cstdint> #ifdef LLVM_ENABLE_EXCEPTIONS #include <stdexcept> #endif usingnamespacellvm; // Check that no bytes are wasted and everything is well-aligned. namespace { // These structures may cause binary compat warnings on AIX. Suppress the // warning since we are only using these types for the static assertions below. #if defined(_AIX) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Waix-compat" #endif struct Struct16B { … }; struct Struct32B { … }; #if defined(_AIX) #pragma GCC diagnostic pop #endif } static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; static_assert …; /// Report that MinSize doesn't fit into this vector's size type. Throws /// std::length_error or calls report_fatal_error. [[noreturn]] static void report_size_overflow(size_t MinSize, size_t MaxSize); static void report_size_overflow(size_t MinSize, size_t MaxSize) { … } /// Report that this vector is already at maximum capacity. Throws /// std::length_error or calls report_fatal_error. [[noreturn]] static void report_at_maximum_capacity(size_t MaxSize); static void report_at_maximum_capacity(size_t MaxSize) { … } // Note: Moving this function into the header may cause performance regression. template <class Size_T> static size_t getNewCapacity(size_t MinSize, size_t TSize, size_t OldCapacity) { … } /// If vector was first created with capacity 0, getFirstEl() points to the /// memory right after, an area unallocated. If a subsequent allocation, /// that grows the vector, happens to return the same pointer as getFirstEl(), /// get a new allocation, otherwise isSmall() will falsely return that no /// allocation was done (true) and the memory will not be freed in the /// destructor. If a VSize is given (vector size), also copy that many /// elements to the new allocation - used if realloca fails to increase /// space, and happens to allocate precisely at BeginX. /// This is unlikely to be called often, but resolves a memory leak when the /// situation does occur. static void *replaceAllocation(void *NewElts, size_t TSize, size_t NewCapacity, size_t VSize = 0) { … } // Note: Moving this function into the header may cause performance regression. template <class Size_T> void *SmallVectorBase<Size_T>::mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize, size_t &NewCapacity) { … } // Note: Moving this function into the header may cause performance regression. template <class Size_T> void SmallVectorBase<Size_T>::grow_pod(void *FirstEl, size_t MinSize, size_t TSize) { … } template class llvm::SmallVectorBase<uint32_t>; // Disable the uint64_t instantiation for 32-bit builds. // Both uint32_t and uint64_t instantiations are needed for 64-bit builds. // This instantiation will never be used in 32-bit builds, and will cause // warnings when sizeof(Size_T) > sizeof(size_t). #if SIZE_MAX > UINT32_MAX template class llvm::SmallVectorBase<uint64_t>; // Assertions to ensure this #if stays in sync with SmallVectorSizeType. static_assert …; #else static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t), "Expected SmallVectorBase<uint32_t> variant to be in use."); #endif