diff options
Diffstat (limited to 'include/llvm/ADT')
78 files changed, 1066 insertions, 855 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index c6fa5ad674f6..a9648d35cf5d 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -1,9 +1,8 @@ //===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// @@ -148,6 +147,17 @@ struct APFloatBase { /// \name Floating Point Semantics. /// @{ + enum Semantics { + S_IEEEhalf, + S_IEEEsingle, + S_IEEEdouble, + S_x87DoubleExtended, + S_IEEEquad, + S_PPCDoubleDouble + }; + + static const llvm::fltSemantics &EnumToSemantics(Semantics S); + static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem); static const fltSemantics &IEEEhalf() LLVM_READNONE; static const fltSemantics &IEEEsingle() LLVM_READNONE; diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 6e106ff8bf5d..2381b75e08b1 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// @@ -2213,6 +2212,15 @@ Optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, // See friend declaration above. This additional declaration is required in // order to compile LLVM with IBM xlC compiler. hash_code hash_value(const APInt &Arg); -} // End of llvm namespace + +/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst +/// with the integer held in IntVal. +void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes); + +/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting +/// from Src into IntVal, which is assumed to be wide enough and to hold zero. +void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes); + +} // namespace llvm #endif diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 7ee2c4c62fce..0f991826c457 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -43,6 +42,24 @@ public: /// \param Str the string to be interpreted. explicit APSInt(StringRef Str); + /// Determine sign of this APSInt. + /// + /// \returns true if this APSInt is negative, false otherwise + bool isNegative() const { return isSigned() && APInt::isNegative(); } + + /// Determine if this APSInt Value is non-negative (>= 0) + /// + /// \returns true if this APSInt is non-negative, false otherwise + bool isNonNegative() const { return !isNegative(); } + + /// Determine if this APSInt Value is positive. + /// + /// This tests if the value of this APSInt is positive (> 0). Note + /// that 0 is not a positive value. + /// + /// \returns true if this APSInt is positive. + bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); } + APSInt &operator=(APInt RHS) { // Retain our current sign. APInt::operator=(std::move(RHS)); diff --git a/include/llvm/ADT/AllocatorList.h b/include/llvm/ADT/AllocatorList.h index 178c6742a87b..405a2e4264df 100644 --- a/include/llvm/ADT/AllocatorList.h +++ b/include/llvm/ADT/AllocatorList.h @@ -1,9 +1,8 @@ //===- llvm/ADT/AllocatorList.h - Custom allocator list ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/Any.h b/include/llvm/ADT/Any.h index 7faa4c963d3d..5dcd6e73c54f 100644 --- a/include/llvm/ADT/Any.h +++ b/include/llvm/ADT/Any.h @@ -1,9 +1,8 @@ //===- Any.h - Generic type erased holder of any type -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 9cb25b09c6cb..773c88f7c9f9 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -1,9 +1,8 @@ //===- ArrayRef.h - Array Reference Wrapper ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -431,7 +430,7 @@ namespace llvm { std::copy(Data.begin(), Data.end(), this->begin()); } - OwningArrayRef(OwningArrayRef &&Other) { *this = Other; } + OwningArrayRef(OwningArrayRef &&Other) { *this = std::move(Other); } OwningArrayRef &operator=(OwningArrayRef &&Other) { delete[] this->data(); @@ -526,12 +525,6 @@ namespace llvm { /// @} - // ArrayRefs can be treated like a POD type. - template <typename T> struct isPodLike; - template <typename T> struct isPodLike<ArrayRef<T>> { - static const bool value = true; - }; - template <typename T> hash_code hash_value(ArrayRef<T> S) { return hash_combine_range(S.begin(), S.end()); } diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 9ab1da7c6913..fabf5d9cd348 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/BitmaskEnum.h b/include/llvm/ADT/BitmaskEnum.h index 18c6ba5a3eb8..1a18bc721b21 100644 --- a/include/llvm/ADT/BitmaskEnum.h +++ b/include/llvm/ADT/BitmaskEnum.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/BitmaskEnum.h ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/BreadthFirstIterator.h b/include/llvm/ADT/BreadthFirstIterator.h index 6bc63c283b09..e97d76680db8 100644 --- a/include/llvm/ADT/BreadthFirstIterator.h +++ b/include/llvm/ADT/BreadthFirstIterator.h @@ -1,9 +1,8 @@ //===- llvm/ADT/BreadthFirstIterator.h - Breadth First iterator -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -125,7 +124,7 @@ public: const NodeRef &operator*() const { return VisitQueue.front()->first; } - // This is a nonstandard operator-> that dereferenfces the pointer an extra + // This is a nonstandard operator-> that dereferences the pointer an extra // time so that you can actually call methods on the node, because the // contained type is a pointer. NodeRef operator->() const { return **this; } diff --git a/include/llvm/ADT/CachedHashString.h b/include/llvm/ADT/CachedHashString.h index d8f0e7afdd49..80144fb87e0e 100644 --- a/include/llvm/ADT/CachedHashString.h +++ b/include/llvm/ADT/CachedHashString.h @@ -1,9 +1,8 @@ //===- llvm/ADT/CachedHashString.h - Prehashed string/StringRef -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/DAGDeltaAlgorithm.h b/include/llvm/ADT/DAGDeltaAlgorithm.h index 41fdd43efb8a..d4cdc3c86048 100644 --- a/include/llvm/ADT/DAGDeltaAlgorithm.h +++ b/include/llvm/ADT/DAGDeltaAlgorithm.h @@ -1,9 +1,8 @@ //===- DAGDeltaAlgorithm.h - A DAG Minimization Algorithm ------*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_DAGDELTAALGORITHM_H diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h index 6becb2a60104..114b95499530 100644 --- a/include/llvm/ADT/DeltaAlgorithm.h +++ b/include/llvm/ADT/DeltaAlgorithm.h @@ -1,9 +1,8 @@ //===- DeltaAlgorithm.h - A Set Minimization Algorithm ---------*- C++ -*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_DELTAALGORITHM_H diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 1f50502fff92..a05cf8130d3c 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -1,9 +1,8 @@ //===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -64,7 +63,7 @@ struct DenseMapPair : public std::pair<KeyT, ValueT> { template <typename AltPairT> DenseMapPair(AltPairT &&AltPair, typename std::enable_if<std::is_convertible< - AltPairT, std::pair<KeyT, ValueT>>::value>::type * = 0) + AltPairT, std::pair<KeyT, ValueT>>::value>::type * = nullptr) : std::pair<KeyT, ValueT>(std::forward<AltPairT>(AltPair)) {} KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; } @@ -146,7 +145,8 @@ public: } const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) { + if (is_trivially_copyable<KeyT>::value && + is_trivially_copyable<ValueT>::value) { // Use a simpler loop when these are trivial types. for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) P->getFirst() = EmptyKey; @@ -422,7 +422,8 @@ protected: setNumEntries(other.getNumEntries()); setNumTombstones(other.getNumTombstones()); - if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) + if (is_trivially_copyable<KeyT>::value && + is_trivially_copyable<ValueT>::value) memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(), getNumBuckets() * sizeof(BucketT)); else diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 5d12b424fb37..5ef6f3ad1b04 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -1,9 +1,8 @@ //===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -18,6 +17,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/ScalableSize.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -269,6 +269,21 @@ template <> struct DenseMapInfo<hash_code> { static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; } }; +template <> struct DenseMapInfo<ElementCount> { + static inline ElementCount getEmptyKey() { return {~0U, true}; } + static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; } + static unsigned getHashValue(const ElementCount& EltCnt) { + if (EltCnt.Scalable) + return (EltCnt.Min * 37U) - 1U; + + return EltCnt.Min * 37U; + } + + static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) { + return LHS == RHS; + } +}; + } // end namespace llvm #endif // LLVM_ADT_DENSEMAPINFO_H diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index e85a38587e41..9afb715ae1db 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/DenseSet.h - Dense probed hash table ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -131,7 +130,7 @@ public: class ConstIterator { typename MapTy::const_iterator I; - friend class DenseSet; + friend class DenseSetImpl; friend class Iterator; public: diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h index 1f3766d3c9de..11967f5eefcc 100644 --- a/include/llvm/ADT/DepthFirstIterator.h +++ b/include/llvm/ADT/DepthFirstIterator.h @@ -1,9 +1,8 @@ //===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h index 49ef192364e8..a782b4756898 100644 --- a/include/llvm/ADT/EpochTracker.h +++ b/include/llvm/ADT/EpochTracker.h @@ -1,9 +1,8 @@ //===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index e3f48433c69f..2cb7108c0794 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -1,9 +1,8 @@ //===- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index e363e69d032a..d5837e51bcfc 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/FoldingSet.h - Uniquing Hash Set ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/FunctionExtras.h b/include/llvm/ADT/FunctionExtras.h index 2b75dc6ac219..121aa527a5da 100644 --- a/include/llvm/ADT/FunctionExtras.h +++ b/include/llvm/ADT/FunctionExtras.h @@ -1,9 +1,8 @@ //===- FunctionExtras.h - Function type erasure utilities -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h index d39b50fdc488..3ce91225d80d 100644 --- a/include/llvm/ADT/GraphTraits.h +++ b/include/llvm/ADT/GraphTraits.h @@ -1,9 +1,8 @@ //===- llvm/ADT/GraphTraits.h - Graph traits template -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 9175c545b7c9..008188bfa210 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/Hashing.h - Utilities for hashing --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -192,7 +191,7 @@ inline uint64_t hash_1to3_bytes(const char *s, size_t len, uint64_t seed) { uint8_t b = s[len >> 1]; uint8_t c = s[len - 1]; uint32_t y = static_cast<uint32_t>(a) + (static_cast<uint32_t>(b) << 8); - uint32_t z = len + (static_cast<uint32_t>(c) << 2); + uint32_t z = static_cast<uint32_t>(len) + (static_cast<uint32_t>(c) << 2); return shift_mix(y * k2 ^ z * k3 ^ seed) * k2; } diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h index 0541dc2566ed..c9ee494734e7 100644 --- a/include/llvm/ADT/ImmutableList.h +++ b/include/llvm/ADT/ImmutableList.h @@ -1,9 +1,8 @@ //==--- ImmutableList.h - Immutable (functional) list interface --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -242,10 +241,6 @@ template<typename T> struct DenseMapInfo<ImmutableList<T>> { } }; -template <typename T> struct isPodLike; -template <typename T> -struct isPodLike<ImmutableList<T>> { static const bool value = true; }; - } // end namespace llvm #endif // LLVM_ADT_IMMUTABLELIST_H diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index cbc27ff17ccf..86fd7fefaec3 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -1,9 +1,8 @@ //===--- ImmutableMap.h - Immutable (functional) map interface --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index b1d5f4ac42e4..587105431533 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -1,9 +1,8 @@ //===--- ImmutableSet.h - Immutable (functional) set interface --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h index 2ee80d2cde63..b44f16b91d76 100644 --- a/include/llvm/ADT/IndexedMap.h +++ b/include/llvm/ADT/IndexedMap.h @@ -1,9 +1,8 @@ //===- llvm/ADT/IndexedMap.h - An index map implementation ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/IntEqClasses.h b/include/llvm/ADT/IntEqClasses.h index 0baee2f11a79..08f46a3079ef 100644 --- a/include/llvm/ADT/IntEqClasses.h +++ b/include/llvm/ADT/IntEqClasses.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/IntEqClasses.h - Equiv. Classes of Integers ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 2af61049e5af..12828c4cfdab 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -1,9 +1,8 @@ //===- llvm/ADT/IntervalMap.h - A sorted interval map -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h index 430ef86afbd9..6d97fe15db8b 100644 --- a/include/llvm/ADT/IntrusiveRefCntPtr.h +++ b/include/llvm/ADT/IntrusiveRefCntPtr.h @@ -1,9 +1,8 @@ //==- llvm/ADT/IntrusiveRefCntPtr.h - Smart Refcounting Pointer --*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index 47b4987f210a..1de1124f4ea2 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h index 4b6bc1e005b5..004ca0ac50ac 100644 --- a/include/llvm/ADT/None.h +++ b/include/llvm/ADT/None.h @@ -1,9 +1,8 @@ //===-- None.h - Simple null value for implicit construction ------*- C++ -*-=// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index 76937d632ae1..b45a74002e10 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -1,9 +1,8 @@ //===- Optional.h - Simple variant for passing optional values --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,94 +16,197 @@ #define LLVM_ADT_OPTIONAL_H #include "llvm/ADT/None.h" -#include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" -#include <algorithm> #include <cassert> +#include <memory> #include <new> #include <utility> namespace llvm { +class raw_ostream; + namespace optional_detail { + +struct in_place_t {}; + /// Storage for any type. -template <typename T, bool = isPodLike<T>::value> struct OptionalStorage { - AlignedCharArrayUnion<T> storage; - bool hasVal = false; +template <typename T, bool = is_trivially_copyable<T>::value> +class OptionalStorage { + union { + char empty; + T value; + }; + bool hasVal; - OptionalStorage() = default; +public: + ~OptionalStorage() { reset(); } - OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); } - OptionalStorage(const OptionalStorage &O) : hasVal(O.hasVal) { - if (hasVal) - new (storage.buffer) T(*O.getPointer()); + OptionalStorage() noexcept : empty(), hasVal(false) {} + + OptionalStorage(OptionalStorage const &other) : OptionalStorage() { + if (other.hasValue()) { + emplace(other.value); + } } - OptionalStorage(T &&y) : hasVal(true) { - new (storage.buffer) T(std::forward<T>(y)); + OptionalStorage(OptionalStorage &&other) : OptionalStorage() { + if (other.hasValue()) { + emplace(std::move(other.value)); + } } - OptionalStorage(OptionalStorage &&O) : hasVal(O.hasVal) { - if (O.hasVal) { - new (storage.buffer) T(std::move(*O.getPointer())); + + template <class... Args> + explicit OptionalStorage(in_place_t, Args &&... args) + : value(std::forward<Args>(args)...), hasVal(true) {} + + void reset() noexcept { + if (hasVal) { + value.~T(); + hasVal = false; } } - OptionalStorage &operator=(T &&y) { - if (hasVal) - *getPointer() = std::move(y); - else { - new (storage.buffer) T(std::move(y)); + bool hasValue() const noexcept { return hasVal; } + + T &getValue() LLVM_LVALUE_FUNCTION noexcept { + assert(hasVal); + return value; + } + T const &getValue() const LLVM_LVALUE_FUNCTION noexcept { + assert(hasVal); + return value; + } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + T &&getValue() && noexcept { + assert(hasVal); + return std::move(value); + } +#endif + + template <class... Args> void emplace(Args &&... args) { + reset(); + ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...); + hasVal = true; + } + + OptionalStorage &operator=(T const &y) { + if (hasValue()) { + value = y; + } else { + ::new ((void *)std::addressof(value)) T(y); hasVal = true; } return *this; } - OptionalStorage &operator=(OptionalStorage &&O) { - if (!O.hasVal) - reset(); - else { - *this = std::move(*O.getPointer()); + OptionalStorage &operator=(T &&y) { + if (hasValue()) { + value = std::move(y); + } else { + ::new ((void *)std::addressof(value)) T(std::move(y)); + hasVal = true; } return *this; } - // FIXME: these assignments (& the equivalent const T&/const Optional& ctors) - // could be made more efficient by passing by value, possibly unifying them - // with the rvalue versions above - but this could place a different set of - // requirements (notably: the existence of a default ctor) when implemented - // in that way. Careful SFINAE to avoid such pitfalls would be required. - OptionalStorage &operator=(const T &y) { - if (hasVal) - *getPointer() = y; - else { - new (storage.buffer) T(y); - hasVal = true; + OptionalStorage &operator=(OptionalStorage const &other) { + if (other.hasValue()) { + if (hasValue()) { + value = other.value; + } else { + ::new ((void *)std::addressof(value)) T(other.value); + hasVal = true; + } + } else { + reset(); } return *this; } - OptionalStorage &operator=(const OptionalStorage &O) { - if (!O.hasVal) + + OptionalStorage &operator=(OptionalStorage &&other) { + if (other.hasValue()) { + if (hasValue()) { + value = std::move(other.value); + } else { + ::new ((void *)std::addressof(value)) T(std::move(other.value)); + hasVal = true; + } + } else { reset(); - else - *this = *O.getPointer(); + } return *this; } +}; - ~OptionalStorage() { reset(); } +template <typename T> class OptionalStorage<T, true> { + union { + char empty; + T value; + }; + bool hasVal = false; + +public: + ~OptionalStorage() = default; + + OptionalStorage() noexcept : empty{} {} + + OptionalStorage(OptionalStorage const &other) = default; + OptionalStorage(OptionalStorage &&other) = default; + + OptionalStorage &operator=(OptionalStorage const &other) = default; + OptionalStorage &operator=(OptionalStorage &&other) = default; + + template <class... Args> + explicit OptionalStorage(in_place_t, Args &&... args) + : value(std::forward<Args>(args)...), hasVal(true) {} - void reset() { + void reset() noexcept { if (hasVal) { - (*getPointer()).~T(); + value.~T(); hasVal = false; } } - T *getPointer() { + bool hasValue() const noexcept { return hasVal; } + + T &getValue() LLVM_LVALUE_FUNCTION noexcept { assert(hasVal); - return reinterpret_cast<T *>(storage.buffer); + return value; } - const T *getPointer() const { + T const &getValue() const LLVM_LVALUE_FUNCTION noexcept { assert(hasVal); - return reinterpret_cast<const T *>(storage.buffer); + return value; + } +#if LLVM_HAS_RVALUE_REFERENCE_THIS + T &&getValue() && noexcept { + assert(hasVal); + return std::move(value); + } +#endif + + template <class... Args> void emplace(Args &&... args) { + reset(); + ::new ((void *)std::addressof(value)) T(std::forward<Args>(args)...); + hasVal = true; + } + + OptionalStorage &operator=(T const &y) { + if (hasValue()) { + value = y; + } else { + ::new ((void *)std::addressof(value)) T(y); + hasVal = true; + } + return *this; + } + OptionalStorage &operator=(T &&y) { + if (hasValue()) { + value = std::move(y); + } else { + ::new ((void *)std::addressof(value)) T(std::move(y)); + hasVal = true; + } + return *this; } }; @@ -119,10 +221,10 @@ public: constexpr Optional() {} constexpr Optional(NoneType) {} - Optional(const T &y) : Storage(y) {} + Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {} Optional(const Optional &O) = default; - Optional(T &&y) : Storage(std::forward<T>(y)) {} + Optional(T &&y) : Storage(optional_detail::in_place_t{}, std::move(y)) {} Optional(Optional &&O) = default; Optional &operator=(T &&y) { @@ -133,9 +235,7 @@ public: /// Create a new object by constructing it in place with the given arguments. template <typename... ArgTypes> void emplace(ArgTypes &&... Args) { - reset(); - Storage.hasVal = true; - new (getPointer()) T(std::forward<ArgTypes>(Args)...); + Storage.emplace(std::forward<ArgTypes>(Args)...); } static inline Optional create(const T *y) { @@ -150,23 +250,17 @@ public: void reset() { Storage.reset(); } - const T *getPointer() const { - assert(Storage.hasVal); - return reinterpret_cast<const T *>(Storage.storage.buffer); - } - T *getPointer() { - assert(Storage.hasVal); - return reinterpret_cast<T *>(Storage.storage.buffer); - } - const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); } - T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); } + const T *getPointer() const { return &Storage.getValue(); } + T *getPointer() { return &Storage.getValue(); } + const T &getValue() const LLVM_LVALUE_FUNCTION { return Storage.getValue(); } + T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); } - explicit operator bool() const { return Storage.hasVal; } - bool hasValue() const { return Storage.hasVal; } + explicit operator bool() const { return hasValue(); } + bool hasValue() const { return Storage.hasValue(); } const T *operator->() const { return getPointer(); } T *operator->() { return getPointer(); } - const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); } - T &operator*() LLVM_LVALUE_FUNCTION { return *getPointer(); } + const T &operator*() const LLVM_LVALUE_FUNCTION { return getValue(); } + T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); } template <typename U> constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION { @@ -174,8 +268,8 @@ public: } #if LLVM_HAS_RVALUE_REFERENCE_THIS - T &&getValue() && { return std::move(*getPointer()); } - T &&operator*() && { return std::move(*getPointer()); } + T &&getValue() && { return std::move(Storage.getValue()); } + T &&operator*() && { return std::move(Storage.getValue()); } template <typename U> T getValueOr(U &&value) && { @@ -184,11 +278,6 @@ public: #endif }; -template <typename T> struct isPodLike<Optional<T>> { - // An Optional<T> is pod-like if T is. - static const bool value = isPodLike<T>::value; -}; - template <typename T, typename U> bool operator==(const Optional<T> &X, const Optional<U> &Y) { if (X && Y) @@ -323,6 +412,18 @@ template <typename T> bool operator>=(const T &X, const Optional<T> &Y) { return !(X < Y); } +raw_ostream &operator<<(raw_ostream &OS, NoneType); + +template <typename T, typename = decltype(std::declval<raw_ostream &>() + << std::declval<const T &>())> +raw_ostream &operator<<(raw_ostream &OS, const Optional<T> &O) { + if (O) + OS << *O; + else + OS << None; + return OS; +} + } // end namespace llvm #endif // LLVM_ADT_OPTIONAL_H diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h index 3d53c49536d0..ae7f8cc85743 100644 --- a/include/llvm/ADT/PackedVector.h +++ b/include/llvm/ADT/PackedVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/PointerEmbeddedInt.h b/include/llvm/ADT/PointerEmbeddedInt.h index ab4e1048a5bc..3eb6edb03430 100644 --- a/include/llvm/ADT/PointerEmbeddedInt.h +++ b/include/llvm/ADT/PointerEmbeddedInt.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PointerEmbeddedInt.h ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 6d1b53a90ad2..24a2bb67a36e 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -15,6 +14,7 @@ #define LLVM_ADT_POINTERINTPAIR_H #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" #include <cassert> #include <cstdint> #include <limits> @@ -126,6 +126,19 @@ public: } }; +// Specialize is_trivially_copyable to avoid limitation of llvm::is_trivially_copyable +// when compiled with gcc 4.9. +template <typename PointerTy, unsigned IntBits, typename IntType, + typename PtrTraits, + typename Info> +struct is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>> : std::true_type { +#ifdef HAVE_STD_IS_TRIVIALLY_COPYABLE + static_assert(std::is_trivially_copyable<PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>::value, + "inconsistent behavior between llvm:: and std:: implementation of is_trivially_copyable"); +#endif +}; + + template <typename PointerT, unsigned IntBits, typename PtrTraits> struct PointerIntPairInfo { static_assert(PtrTraits::NumLowBitsAvailable < @@ -176,12 +189,6 @@ struct PointerIntPairInfo { } }; -template <typename T> struct isPodLike; -template <typename PointerTy, unsigned IntBits, typename IntType> -struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> { - static const bool value = true; -}; - // Provide specialization of DenseMapInfo for PointerIntPair. template <typename PointerTy, unsigned IntBits, typename IntType> struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> { diff --git a/include/llvm/ADT/PointerSumType.h b/include/llvm/ADT/PointerSumType.h index a19e45a46218..d467f83f58ac 100644 --- a/include/llvm/ADT/PointerSumType.h +++ b/include/llvm/ADT/PointerSumType.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PointerSumType.h --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 315e58336cba..2bcdf546c6e4 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -54,22 +53,98 @@ struct PointerUnionTypeSelectorReturn< typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return; }; -/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion -/// for the two template arguments. -template <typename PT1, typename PT2> class PointerUnionUIntTraits { -public: - static inline void *getAsVoidPointer(void *P) { return P; } - static inline void *getFromVoidPointer(void *P) { return P; } +namespace pointer_union_detail { + constexpr int constexprMin(int a, int b) { return a < b ? a : b; } + /// Determine the number of bits required to store integers with values < n. + /// This is ceil(log2(n)). + constexpr int bitsRequired(unsigned n) { + return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; + } + + // FIXME: In C++14, replace this with + // std::min({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}) + template <typename T> constexpr int lowBitsAvailable() { + return PointerLikeTypeTraits<T>::NumLowBitsAvailable; + } + template <typename T1, typename T2, typename... Ts> + constexpr int lowBitsAvailable() { + return constexprMin(lowBitsAvailable<T1>(), lowBitsAvailable<T2, Ts...>()); + } - enum { - PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable), - PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable), - NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv + /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index + /// is the index of T in Us, or sizeof...(Us) if T does not appear in the + /// list. + template <typename T, typename ...Us> struct TypeIndex; + template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> { + static constexpr int Index = 0; }; -}; + template <typename T, typename U, typename... Us> + struct TypeIndex<T, U, Us...> { + static constexpr int Index = 1 + TypeIndex<T, Us...>::Index; + }; + template <typename T> struct TypeIndex<T> { + static constexpr int Index = 0; + }; + + /// Find the first type in a list of types. + template <typename T, typename...> struct GetFirstType { + using type = T; + }; + + /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion + /// for the template arguments. + template <typename ...PTs> class PointerUnionUIntTraits { + public: + static inline void *getAsVoidPointer(void *P) { return P; } + static inline void *getFromVoidPointer(void *P) { return P; } + static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>(); + }; + + /// Implement assigment in terms of construction. + template <typename Derived, typename T> struct AssignableFrom { + Derived &operator=(T t) { + return static_cast<Derived &>(*this) = Derived(t); + } + }; + + template <typename Derived, typename ValTy, int I, typename ...Types> + class PointerUnionMembers; -/// A discriminated union of two pointer types, with the discriminator in the -/// low bit of the pointer. + template <typename Derived, typename ValTy, int I> + class PointerUnionMembers<Derived, ValTy, I> { + protected: + ValTy Val; + PointerUnionMembers() = default; + PointerUnionMembers(ValTy Val) : Val(Val) {} + + friend struct PointerLikeTypeTraits<Derived>; + }; + + template <typename Derived, typename ValTy, int I, typename Type, + typename ...Types> + class PointerUnionMembers<Derived, ValTy, I, Type, Types...> + : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> { + using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>; + public: + using Base::Base; + PointerUnionMembers() = default; + PointerUnionMembers(Type V) + : Base(ValTy(const_cast<void *>( + PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), + I)) {} + + using Base::operator=; + Derived &operator=(Type V) { + this->Val = ValTy( + const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), + I); + return static_cast<Derived &>(*this); + }; + }; +} + +/// A discriminated union of two or more pointer types, with the discriminator +/// in the low bit of the pointer. /// /// This implementation is extremely efficient in space due to leveraging the /// low bits of the pointer, while exposing a natural and type-safe API. @@ -84,49 +159,44 @@ public: /// P = (float*)0; /// Y = P.get<float*>(); // ok. /// X = P.get<int*>(); // runtime assertion failure. -template <typename PT1, typename PT2> class PointerUnion { -public: - using ValTy = - PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>>; - -private: - ValTy Val; - - struct IsPT1 { - static const int Num = 0; - }; - struct IsPT2 { - static const int Num = 1; - }; - template <typename T> struct UNION_DOESNT_CONTAIN_TYPE {}; +template <typename... PTs> +class PointerUnion + : public pointer_union_detail::PointerUnionMembers< + PointerUnion<PTs...>, + PointerIntPair< + void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, + pointer_union_detail::PointerUnionUIntTraits<PTs...>>, + 0, PTs...> { + // The first type is special in some ways, but we don't want PointerUnion to + // be a 'template <typename First, typename ...Rest>' because it's much more + // convenient to have a name for the whole pack. So split off the first type + // here. + using First = typename pointer_union_detail::GetFirstType<PTs...>::type; + using Base = typename PointerUnion::PointerUnionMembers; public: PointerUnion() = default; - PointerUnion(PT1 V) - : Val(const_cast<void *>( - PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {} - PointerUnion(PT2 V) - : Val(const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), - 1) {} + + PointerUnion(std::nullptr_t) : PointerUnion() {} + using Base::Base; /// Test if the pointer held in the union is null, regardless of /// which type it is. bool isNull() const { // Convert from the void* to one of the pointer types, to make sure that // we recursively strip off low bits if we have a nested PointerUnion. - return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer()); + return !PointerLikeTypeTraits<First>::getFromVoidPointer( + this->Val.getPointer()); } explicit operator bool() const { return !isNull(); } /// Test if the Union currently holds the type matching T. template <typename T> int is() const { - using Ty = typename ::llvm::PointerUnionTypeSelector< - PT1, T, IsPT1, - ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2, - UNION_DOESNT_CONTAIN_TYPE<T>>>::Return; - int TyNo = Ty::Num; - return static_cast<int>(Val.getInt()) == TyNo; + constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index; + static_assert(Index < sizeof...(PTs), + "PointerUnion::is<T> given type not in the union"); + return this->Val.getInt() == Index; } /// Returns the value of the specified pointer type. @@ -134,7 +204,7 @@ public: /// If the specified pointer type is incorrect, assert. template <typename T> T get() const { assert(is<T>() && "Invalid accessor called"); - return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer()); + return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer()); } /// Returns the current pointer if it is of the specified pointer type, @@ -147,342 +217,100 @@ public: /// If the union is set to the first pointer type get an address pointing to /// it. - PT1 const *getAddrOfPtr1() const { + First const *getAddrOfPtr1() const { return const_cast<PointerUnion *>(this)->getAddrOfPtr1(); } /// If the union is set to the first pointer type get an address pointing to /// it. - PT1 *getAddrOfPtr1() { - assert(is<PT1>() && "Val is not the first pointer"); + First *getAddrOfPtr1() { + assert(is<First>() && "Val is not the first pointer"); assert( - get<PT1>() == Val.getPointer() && + get<First>() == this->Val.getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"); - return const_cast<PT1 *>( - reinterpret_cast<const PT1 *>(Val.getAddrOfPointer())); + return const_cast<First *>( + reinterpret_cast<const First *>(this->Val.getAddrOfPointer())); } /// Assignment from nullptr which just clears the union. const PointerUnion &operator=(std::nullptr_t) { - Val.initWithPointer(nullptr); + this->Val.initWithPointer(nullptr); return *this; } - /// Assignment operators - Allow assigning into this union from either - /// pointer type, setting the discriminator to remember what it came from. - const PointerUnion &operator=(const PT1 &RHS) { - Val.initWithPointer( - const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS))); - return *this; - } - const PointerUnion &operator=(const PT2 &RHS) { - Val.setPointerAndInt( - const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)), - 1); - return *this; - } + /// Assignment from elements of the union. + using Base::operator=; - void *getOpaqueValue() const { return Val.getOpaqueValue(); } + void *getOpaqueValue() const { return this->Val.getOpaqueValue(); } static inline PointerUnion getFromOpaqueValue(void *VP) { PointerUnion V; - V.Val = ValTy::getFromOpaqueValue(VP); + V.Val = decltype(V.Val)::getFromOpaqueValue(VP); return V; } }; -template <typename PT1, typename PT2> -bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) { +template <typename ...PTs> +bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { return lhs.getOpaqueValue() == rhs.getOpaqueValue(); } -template <typename PT1, typename PT2> -bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) { +template <typename ...PTs> +bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { return lhs.getOpaqueValue() != rhs.getOpaqueValue(); } -template <typename PT1, typename PT2> -bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) { +template <typename ...PTs> +bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { return lhs.getOpaqueValue() < rhs.getOpaqueValue(); } // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. -template <typename PT1, typename PT2> -struct PointerLikeTypeTraits<PointerUnion<PT1, PT2>> { - static inline void *getAsVoidPointer(const PointerUnion<PT1, PT2> &P) { +template <typename ...PTs> +struct PointerLikeTypeTraits<PointerUnion<PTs...>> { + static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) { return P.getOpaqueValue(); } - static inline PointerUnion<PT1, PT2> getFromVoidPointer(void *P) { - return PointerUnion<PT1, PT2>::getFromOpaqueValue(P); + static inline PointerUnion<PTs...> getFromVoidPointer(void *P) { + return PointerUnion<PTs...>::getFromOpaqueValue(P); } - // The number of bits available are the min of the two pointer types. - enum { - NumLowBitsAvailable = PointerLikeTypeTraits< - typename PointerUnion<PT1, PT2>::ValTy>::NumLowBitsAvailable - }; + // The number of bits available are the min of the pointer types minus the + // bits needed for the discriminator. + static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype( + PointerUnion<PTs...>::Val)>::NumLowBitsAvailable; }; /// A pointer union of three pointer types. See documentation for PointerUnion /// for usage. -template <typename PT1, typename PT2, typename PT3> class PointerUnion3 { -public: - using InnerUnion = PointerUnion<PT1, PT2>; - using ValTy = PointerUnion<InnerUnion, PT3>; - -private: - ValTy Val; - - struct IsInnerUnion { - ValTy Val; - - IsInnerUnion(ValTy val) : Val(val) {} - - template <typename T> int is() const { - return Val.template is<InnerUnion>() && - Val.template get<InnerUnion>().template is<T>(); - } - - template <typename T> T get() const { - return Val.template get<InnerUnion>().template get<T>(); - } - }; - - struct IsPT3 { - ValTy Val; - - IsPT3(ValTy val) : Val(val) {} - - template <typename T> int is() const { return Val.template is<T>(); } - template <typename T> T get() const { return Val.template get<T>(); } - }; - -public: - PointerUnion3() = default; - PointerUnion3(PT1 V) { Val = InnerUnion(V); } - PointerUnion3(PT2 V) { Val = InnerUnion(V); } - PointerUnion3(PT3 V) { Val = V; } - - /// Test if the pointer held in the union is null, regardless of - /// which type it is. - bool isNull() const { return Val.isNull(); } - explicit operator bool() const { return !isNull(); } - - /// Test if the Union currently holds the type matching T. - template <typename T> int is() const { - // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. - using Ty = typename ::llvm::PointerUnionTypeSelector< - PT1, T, IsInnerUnion, - ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return; - return Ty(Val).template is<T>(); - } - - /// Returns the value of the specified pointer type. - /// - /// If the specified pointer type is incorrect, assert. - template <typename T> T get() const { - assert(is<T>() && "Invalid accessor called"); - // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. - using Ty = typename ::llvm::PointerUnionTypeSelector< - PT1, T, IsInnerUnion, - ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return; - return Ty(Val).template get<T>(); - } - - /// Returns the current pointer if it is of the specified pointer type, - /// otherwises returns null. - template <typename T> T dyn_cast() const { - if (is<T>()) - return get<T>(); - return T(); - } - - /// Assignment from nullptr which just clears the union. - const PointerUnion3 &operator=(std::nullptr_t) { - Val = nullptr; - return *this; - } - - /// Assignment operators - Allow assigning into this union from either - /// pointer type, setting the discriminator to remember what it came from. - const PointerUnion3 &operator=(const PT1 &RHS) { - Val = InnerUnion(RHS); - return *this; - } - const PointerUnion3 &operator=(const PT2 &RHS) { - Val = InnerUnion(RHS); - return *this; - } - const PointerUnion3 &operator=(const PT3 &RHS) { - Val = RHS; - return *this; - } - - void *getOpaqueValue() const { return Val.getOpaqueValue(); } - static inline PointerUnion3 getFromOpaqueValue(void *VP) { - PointerUnion3 V; - V.Val = ValTy::getFromOpaqueValue(VP); - return V; - } -}; - -// Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has -// # low bits available = min(PT1bits,PT2bits,PT2bits)-2. template <typename PT1, typename PT2, typename PT3> -struct PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> { - static inline void *getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) { - return P.getOpaqueValue(); - } - - static inline PointerUnion3<PT1, PT2, PT3> getFromVoidPointer(void *P) { - return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P); - } - - // The number of bits available are the min of the two pointer types. - enum { - NumLowBitsAvailable = PointerLikeTypeTraits< - typename PointerUnion3<PT1, PT2, PT3>::ValTy>::NumLowBitsAvailable - }; -}; - -template <typename PT1, typename PT2, typename PT3> -bool operator<(PointerUnion3<PT1, PT2, PT3> lhs, - PointerUnion3<PT1, PT2, PT3> rhs) { - return lhs.getOpaqueValue() < rhs.getOpaqueValue(); -} +using PointerUnion3 = PointerUnion<PT1, PT2, PT3>; /// A pointer union of four pointer types. See documentation for PointerUnion /// for usage. template <typename PT1, typename PT2, typename PT3, typename PT4> -class PointerUnion4 { -public: - using InnerUnion1 = PointerUnion<PT1, PT2>; - using InnerUnion2 = PointerUnion<PT3, PT4>; - using ValTy = PointerUnion<InnerUnion1, InnerUnion2>; - -private: - ValTy Val; - -public: - PointerUnion4() = default; - PointerUnion4(PT1 V) { Val = InnerUnion1(V); } - PointerUnion4(PT2 V) { Val = InnerUnion1(V); } - PointerUnion4(PT3 V) { Val = InnerUnion2(V); } - PointerUnion4(PT4 V) { Val = InnerUnion2(V); } - - /// Test if the pointer held in the union is null, regardless of - /// which type it is. - bool isNull() const { return Val.isNull(); } - explicit operator bool() const { return !isNull(); } - - /// Test if the Union currently holds the type matching T. - template <typename T> int is() const { - // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. - using Ty = typename ::llvm::PointerUnionTypeSelector< - PT1, T, InnerUnion1, - ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, - InnerUnion2>>::Return; - return Val.template is<Ty>() && Val.template get<Ty>().template is<T>(); - } - - /// Returns the value of the specified pointer type. - /// - /// If the specified pointer type is incorrect, assert. - template <typename T> T get() const { - assert(is<T>() && "Invalid accessor called"); - // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. - using Ty = typename ::llvm::PointerUnionTypeSelector< - PT1, T, InnerUnion1, - ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, - InnerUnion2>>::Return; - return Val.template get<Ty>().template get<T>(); - } - - /// Returns the current pointer if it is of the specified pointer type, - /// otherwises returns null. - template <typename T> T dyn_cast() const { - if (is<T>()) - return get<T>(); - return T(); - } - - /// Assignment from nullptr which just clears the union. - const PointerUnion4 &operator=(std::nullptr_t) { - Val = nullptr; - return *this; - } - - /// Assignment operators - Allow assigning into this union from either - /// pointer type, setting the discriminator to remember what it came from. - const PointerUnion4 &operator=(const PT1 &RHS) { - Val = InnerUnion1(RHS); - return *this; - } - const PointerUnion4 &operator=(const PT2 &RHS) { - Val = InnerUnion1(RHS); - return *this; - } - const PointerUnion4 &operator=(const PT3 &RHS) { - Val = InnerUnion2(RHS); - return *this; - } - const PointerUnion4 &operator=(const PT4 &RHS) { - Val = InnerUnion2(RHS); - return *this; - } - - void *getOpaqueValue() const { return Val.getOpaqueValue(); } - static inline PointerUnion4 getFromOpaqueValue(void *VP) { - PointerUnion4 V; - V.Val = ValTy::getFromOpaqueValue(VP); - return V; - } -}; - -// Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has -// # low bits available = min(PT1bits,PT2bits,PT2bits)-2. -template <typename PT1, typename PT2, typename PT3, typename PT4> -struct PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> { - static inline void * - getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) { - return P.getOpaqueValue(); - } - - static inline PointerUnion4<PT1, PT2, PT3, PT4> getFromVoidPointer(void *P) { - return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P); - } - - // The number of bits available are the min of the two pointer types. - enum { - NumLowBitsAvailable = PointerLikeTypeTraits< - typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>::NumLowBitsAvailable - }; -}; +using PointerUnion4 = PointerUnion<PT1, PT2, PT3, PT4>; // Teach DenseMap how to use PointerUnions as keys. -template <typename T, typename U> struct DenseMapInfo<PointerUnion<T, U>> { - using Pair = PointerUnion<T, U>; - using FirstInfo = DenseMapInfo<T>; - using SecondInfo = DenseMapInfo<U>; +template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { + using Union = PointerUnion<PTs...>; + using FirstInfo = + DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; - static inline Pair getEmptyKey() { return Pair(FirstInfo::getEmptyKey()); } + static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } - static inline Pair getTombstoneKey() { - return Pair(FirstInfo::getTombstoneKey()); + static inline Union getTombstoneKey() { + return Union(FirstInfo::getTombstoneKey()); } - static unsigned getHashValue(const Pair &PairVal) { - intptr_t key = (intptr_t)PairVal.getOpaqueValue(); + static unsigned getHashValue(const Union &UnionVal) { + intptr_t key = (intptr_t)UnionVal.getOpaqueValue(); return DenseMapInfo<intptr_t>::getHashValue(key); } - static bool isEqual(const Pair &LHS, const Pair &RHS) { - return LHS.template is<T>() == RHS.template is<T>() && - (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(), - RHS.template get<T>()) - : SecondInfo::isEqual(LHS.template get<U>(), - RHS.template get<U>())); + static bool isEqual(const Union &LHS, const Union &RHS) { + return LHS == RHS; } }; diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index d77b12228cb1..2fe7447a8e77 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/PriorityQueue.h b/include/llvm/ADT/PriorityQueue.h index 8ba871e25304..cf79ee10ba7f 100644 --- a/include/llvm/ADT/PriorityQueue.h +++ b/include/llvm/ADT/PriorityQueue.h @@ -1,9 +1,8 @@ //===- llvm/ADT/PriorityQueue.h - Priority queues ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/PriorityWorklist.h b/include/llvm/ADT/PriorityWorklist.h index aa531f3337d9..96d22c87557e 100644 --- a/include/llvm/ADT/PriorityWorklist.h +++ b/include/llvm/ADT/PriorityWorklist.h @@ -1,9 +1,8 @@ //===- PriorityWorklist.h - Worklist with insertion priority ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index ab1dc4613be0..eb1a5d0938cf 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -1,9 +1,8 @@ //===- ADT/SCCIterator.h - Strongly Connected Comp. Iter. -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index f66ca7c08a73..81dce0168c79 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -1,9 +1,8 @@ //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -241,6 +240,13 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) { return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F)); } +template <class ContainerTy, class FuncTy> +auto map_range(ContainerTy &&C, FuncTy F) + -> decltype(make_range(map_iterator(C.begin(), F), + map_iterator(C.end(), F))) { + return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F)); +} + /// Helper to determine if type T has a member called rbegin(). template <typename Ty> class has_rbegin_impl { using yes = char[1]; @@ -1278,29 +1284,52 @@ auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) { /// Provide wrappers to std::lower_bound which take ranges instead of having to /// pass begin/end explicitly. -template <typename R, typename ForwardIt> -auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) { - return std::lower_bound(adl_begin(Range), adl_end(Range), I); +template <typename R, typename T> +auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) { + return std::lower_bound(adl_begin(Range), adl_end(Range), + std::forward<T>(Value)); } -template <typename R, typename ForwardIt, typename Compare> -auto lower_bound(R &&Range, ForwardIt I, Compare C) +template <typename R, typename T, typename Compare> +auto lower_bound(R &&Range, T &&Value, Compare C) -> decltype(adl_begin(Range)) { - return std::lower_bound(adl_begin(Range), adl_end(Range), I, C); + return std::lower_bound(adl_begin(Range), adl_end(Range), + std::forward<T>(Value), C); } /// Provide wrappers to std::upper_bound which take ranges instead of having to /// pass begin/end explicitly. -template <typename R, typename ForwardIt> -auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) { - return std::upper_bound(adl_begin(Range), adl_end(Range), I); +template <typename R, typename T> +auto upper_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) { + return std::upper_bound(adl_begin(Range), adl_end(Range), + std::forward<T>(Value)); } -template <typename R, typename ForwardIt, typename Compare> -auto upper_bound(R &&Range, ForwardIt I, Compare C) +template <typename R, typename T, typename Compare> +auto upper_bound(R &&Range, T &&Value, Compare C) -> decltype(adl_begin(Range)) { - return std::upper_bound(adl_begin(Range), adl_end(Range), I, C); + return std::upper_bound(adl_begin(Range), adl_end(Range), + std::forward<T>(Value), C); +} + +template <typename R> +void stable_sort(R &&Range) { + std::stable_sort(adl_begin(Range), adl_end(Range)); +} + +template <typename R, typename Compare> +void stable_sort(R &&Range, Compare C) { + std::stable_sort(adl_begin(Range), adl_end(Range), C); +} + +/// Binary search for the first iterator in a range where a predicate is false. +/// Requires that C is always true below some limit, and always false above it. +template <typename R, typename Predicate, + typename Val = decltype(*adl_begin(std::declval<R>()))> +auto partition_point(R &&Range, Predicate P) -> decltype(adl_begin(Range)) { + return std::partition_point(adl_begin(Range), adl_end(Range), P); } + /// Wrapper function around std::equal to detect if all elements /// in a container are same. template <typename R> @@ -1331,6 +1360,33 @@ void erase_if(Container &C, UnaryPredicate P) { C.erase(remove_if(C, P), C.end()); } +/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with +/// the range [ValIt, ValEnd) (which is not from the same container). +template<typename Container, typename RandomAccessIterator> +void replace(Container &Cont, typename Container::iterator ContIt, + typename Container::iterator ContEnd, RandomAccessIterator ValIt, + RandomAccessIterator ValEnd) { + while (true) { + if (ValIt == ValEnd) { + Cont.erase(ContIt, ContEnd); + return; + } else if (ContIt == ContEnd) { + Cont.insert(ContIt, ValIt, ValEnd); + return; + } + *ContIt++ = *ValIt++; + } +} + +/// Given a sequence container Cont, replace the range [ContIt, ContEnd) with +/// the range R. +template<typename Container, typename Range = std::initializer_list< + typename Container::value_type>> +void replace(Container &Cont, typename Container::iterator ContIt, + typename Container::iterator ContEnd, Range R) { + replace(Cont, ContIt, ContEnd, R.begin(), R.end()); +} + //===----------------------------------------------------------------------===// // Extra additions to <memory> //===----------------------------------------------------------------------===// @@ -1418,6 +1474,9 @@ namespace detail { template <typename R> class enumerator_iter; template <typename R> struct result_pair { + using value_reference = + typename std::iterator_traits<IterOfRange<R>>::reference; + friend class enumerator_iter<R>; result_pair() = default; @@ -1431,8 +1490,8 @@ template <typename R> struct result_pair { } std::size_t index() const { return Index; } - const ValueOfRange<R> &value() const { return *Iter; } - ValueOfRange<R> &value() { return *Iter; } + const value_reference value() const { return *Iter; } + value_reference value() { return *Iter; } private: std::size_t Index = std::numeric_limits<std::size_t>::max(); @@ -1577,6 +1636,19 @@ bool hasNItemsOrMore( return true; } +/// Returns a raw pointer that represents the same address as the argument. +/// +/// The late bound return should be removed once we move to C++14 to better +/// align with the C++20 declaration. Also, this implementation can be removed +/// once we move to C++20 where it's defined as std::to_addres() +/// +/// The std::pointer_traits<>::to_address(p) variations of these overloads has +/// not been implemented. +template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) { + return P.operator->(); +} +template <class T> constexpr T *to_address(T *P) { return P; } + } // end namespace llvm #endif // LLVM_ADT_STLEXTRAS_H diff --git a/include/llvm/ADT/ScopeExit.h b/include/llvm/ADT/ScopeExit.h index bd13755fa999..712d91237739 100644 --- a/include/llvm/ADT/ScopeExit.h +++ b/include/llvm/ADT/ScopeExit.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ScopeExit.h - Execute code at scope exit --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h index 22b0c1bdaf4d..40c49ebc0be1 100644 --- a/include/llvm/ADT/ScopedHashTable.h +++ b/include/llvm/ADT/ScopedHashTable.h @@ -1,9 +1,8 @@ //===- ScopedHashTable.h - A simple scoped hash table -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/Sequence.h b/include/llvm/ADT/Sequence.h index 3d4a897bf9a9..8c505f2010dd 100644 --- a/include/llvm/ADT/Sequence.h +++ b/include/llvm/ADT/Sequence.h @@ -1,9 +1,8 @@ //===- Sequence.h - Utility for producing sequences of values ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h index 7c9f2fbe066e..037256a860b2 100644 --- a/include/llvm/ADT/SetOperations.h +++ b/include/llvm/ADT/SetOperations.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index 3d6781041320..d0a0d28d1c81 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 0a73dbd60671..742450e6a951 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index db08e40257ba..913518230d2d 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h index 5d84627714bc..6b128c2e2992 100644 --- a/include/llvm/ADT/SmallSet.h +++ b/include/llvm/ADT/SmallSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h index ff46e85ccb09..898be80d0324 100644 --- a/include/llvm/ADT/SmallString.h +++ b/include/llvm/ADT/SmallString.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 0636abbb1fbf..17586904d212 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -42,8 +41,8 @@ protected: unsigned Size = 0, Capacity; SmallVectorBase() = delete; - SmallVectorBase(void *FirstEl, size_t Capacity) - : BeginX(FirstEl), Capacity(Capacity) {} + SmallVectorBase(void *FirstEl, size_t TotalCapacity) + : BeginX(FirstEl), Capacity(TotalCapacity) {} /// This is an implementation of the grow() method which only works /// on POD-like data types and is out of line to reduce code duplication. @@ -64,9 +63,9 @@ public: /// of the buffer when they know that more elements are available, and only /// update the size later. This avoids the cost of value initializing elements /// which will only be overwritten. - void set_size(size_t Size) { - assert(Size <= capacity()); - this->Size = Size; + void set_size(size_t N) { + assert(N <= capacity()); + Size = N; } }; @@ -125,13 +124,9 @@ public: using const_pointer = const T *; // forward iterator creation methods. - LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin() { return (iterator)this->BeginX; } - LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator begin() const { return (const_iterator)this->BeginX; } - LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end() { return begin() + size(); } - LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator end() const { return begin() + size(); } // reverse iterator creation methods. @@ -150,12 +145,10 @@ public: /// Return a pointer to the vector's buffer, even if empty(). const_pointer data() const { return const_pointer(begin()); } - LLVM_ATTRIBUTE_ALWAYS_INLINE reference operator[](size_type idx) { assert(idx < size()); return begin()[idx]; } - LLVM_ATTRIBUTE_ALWAYS_INLINE const_reference operator[](size_type idx) const { assert(idx < size()); return begin()[idx]; @@ -180,9 +173,9 @@ public: } }; -/// SmallVectorTemplateBase<isPodLike = false> - This is where we put method +/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method /// implementations that are designed to work with non-POD-like T's. -template <typename T, bool = isPodLike<T>::value> +template <typename T, bool = is_trivially_copyable<T>::value> class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> { protected: SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {} @@ -236,8 +229,8 @@ public: }; // Define this out-of-line to dissuade the C++ compiler from inlining it. -template <typename T, bool isPodLike> -void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { +template <typename T, bool TriviallyCopyable> +void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) { if (MinSize > UINT32_MAX) report_bad_alloc_error("SmallVector capacity overflow during allocation"); @@ -260,9 +253,8 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { this->Capacity = NewCapacity; } - -/// SmallVectorTemplateBase<isPodLike = true> - This is where we put method -/// implementations that are designed to work with POD-like T's. +/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put +/// method implementations that are designed to work with POD-like T's. template <typename T> class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> { protected: @@ -326,12 +318,13 @@ class SmallVectorImpl : public SmallVectorTemplateBase<T> { public: using iterator = typename SuperClass::iterator; using const_iterator = typename SuperClass::const_iterator; + using reference = typename SuperClass::reference; using size_type = typename SuperClass::size_type; protected: // Default ctor - Initialize to empty. explicit SmallVectorImpl(unsigned N) - : SmallVectorTemplateBase<T, isPodLike<T>::value>(N) {} + : SmallVectorTemplateBase<T>(N) {} public: SmallVectorImpl(const SmallVectorImpl &) = delete; @@ -393,22 +386,18 @@ public: std::input_iterator_tag>::value>::type> void append(in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); - // Grow allocated space if needed. if (NumInputs > this->capacity() - this->size()) this->grow(this->size()+NumInputs); - // Copy the new elements over. this->uninitialized_copy(in_start, in_end, this->end()); this->set_size(this->size() + NumInputs); } - /// Add the specified range to the end of the SmallVector. + /// Append \p NumInputs copies of \p Elt to the end. void append(size_type NumInputs, const T &Elt) { - // Grow allocated space if needed. if (NumInputs > this->capacity() - this->size()) this->grow(this->size()+NumInputs); - // Copy the new elements over. std::uninitialized_fill_n(this->end(), NumInputs, Elt); this->set_size(this->size() + NumInputs); } @@ -649,11 +638,12 @@ public: insert(I, IL.begin(), IL.end()); } - template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) { + template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) { if (LLVM_UNLIKELY(this->size() >= this->capacity())) this->grow(); ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...); this->set_size(this->size() + 1); + return this->back(); } SmallVectorImpl &operator=(const SmallVectorImpl &RHS); diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h index 84e73bcbace8..12850e14f4ed 100644 --- a/include/llvm/ADT/SparseBitVector.h +++ b/include/llvm/ADT/SparseBitVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h index 3c8637621510..d9d3ff459267 100644 --- a/include/llvm/ADT/SparseMultiSet.h +++ b/include/llvm/ADT/SparseMultiSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SparseMultiSet.h - Sparse multiset --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h index 74cc6dab8c74..a6eb9b942e80 100644 --- a/include/llvm/ADT/SparseSet.h +++ b/include/llvm/ADT/SparseSet.h @@ -1,9 +1,8 @@ //===- llvm/ADT/SparseSet.h - Sparse set ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 90c2eefceb6c..2ac59da596ef 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 60a03633a8a6..16ac90bd6c89 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -1,9 +1,8 @@ //===- llvm/ADT/StringExtras.h - Useful string functions --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index a9f83d3f5091..8a586fc26709 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -1,9 +1,8 @@ //===- StringMap.h - String Hash table map interface ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -360,6 +359,11 @@ public: return find(Key) == end() ? 0 : 1; } + template <typename InputTy> + size_type count(const StringMapEntry<InputTy> &MapEntry) const { + return count(MapEntry.getKey()); + } + /// insert - Insert the specified key/value pair into the map. If the key /// already exists in the map, return false and ignore the request, otherwise /// insert it and return true. diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index a5ba5b59b5a3..4661b1e68b2f 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -1,9 +1,8 @@ //===- StringRef.h - Constant String Reference Wrapper ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -63,7 +62,6 @@ namespace llvm { // Workaround memcmp issue with null pointers (undefined behavior) // by providing a specialized version - LLVM_ATTRIBUTE_ALWAYS_INLINE static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) { if (Length == 0) { return 0; } return ::memcmp(Lhs,Rhs,Length); @@ -81,17 +79,14 @@ namespace llvm { StringRef(std::nullptr_t) = delete; /// Construct a string ref from a cstring. - LLVM_ATTRIBUTE_ALWAYS_INLINE /*implicit*/ StringRef(const char *Str) : Data(Str), Length(Str ? ::strlen(Str) : 0) {} /// Construct a string ref from a pointer and length. - LLVM_ATTRIBUTE_ALWAYS_INLINE /*implicit*/ constexpr StringRef(const char *data, size_t length) : Data(data), Length(length) {} /// Construct a string ref from an std::string. - LLVM_ATTRIBUTE_ALWAYS_INLINE /*implicit*/ StringRef(const std::string &Str) : Data(Str.data()), Length(Str.length()) {} @@ -124,17 +119,14 @@ namespace llvm { /// data - Get a pointer to the start of the string (which may not be null /// terminated). LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE const char *data() const { return Data; } /// empty - Check if the string is empty. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const { return Length == 0; } /// size - Get the string size. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const { return Length; } /// front - Get the first character in the string. @@ -165,7 +157,6 @@ namespace llvm { /// equals - Check for string equality, this is more efficient than /// compare() when the relative ordering of inequal strings isn't needed. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const { return (Length == RHS.Length && compareMemory(Data, RHS.Data, RHS.Length) == 0); @@ -180,7 +171,6 @@ namespace llvm { /// compare - Compare two strings; the result is -1, 0, or 1 if this string /// is lexicographically less than, equal to, or greater than the \p RHS. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE int compare(StringRef RHS) const { // Check the prefix for a mismatch. if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length))) @@ -263,7 +253,6 @@ namespace llvm { /// Check if this string starts with the given \p Prefix. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const { return Length >= Prefix.Length && compareMemory(Data, Prefix.Data, Prefix.Length) == 0; @@ -275,7 +264,6 @@ namespace llvm { /// Check if this string ends with the given \p Suffix. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const { return Length >= Suffix.Length && compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; @@ -294,7 +282,6 @@ namespace llvm { /// \returns The index of the first occurrence of \p C, or npos if not /// found. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From = 0) const { size_t FindBegin = std::min(From, Length); if (FindBegin < Length) { // Avoid calling memchr with nullptr. @@ -317,7 +304,6 @@ namespace llvm { /// \returns The index of the first character satisfying \p F starting from /// \p From, or npos if not found. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find_if(function_ref<bool(char)> F, size_t From = 0) const { StringRef S = drop_front(From); while (!S.empty()) { @@ -333,7 +319,6 @@ namespace llvm { /// \returns The index of the first character not satisfying \p F starting /// from \p From, or npos if not found. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const { return find_if([F](char c) { return !F(c); }, From); } @@ -444,19 +429,16 @@ namespace llvm { /// Return true if the given string is a substring of *this, and false /// otherwise. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(StringRef Other) const { return find(Other) != npos; } /// Return true if the given character is contained in *this, and false /// otherwise. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains(char C) const { return find_first_of(C) != npos; } /// Return true if the given string is a substring of *this, and false /// otherwise. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains_lower(StringRef Other) const { return find_lower(Other) != npos; } @@ -464,7 +446,6 @@ namespace llvm { /// Return true if the given character is contained in *this, and false /// otherwise. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE bool contains_lower(char C) const { return find_lower(C) != npos; } /// @} @@ -594,7 +575,6 @@ namespace llvm { /// exceeds the number of characters remaining in the string, the string /// suffix (starting with \p Start) will be returned. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N = npos) const { Start = std::min(Start, Length); return StringRef(Data + Start, std::min(N, Length - Start)); @@ -604,7 +584,6 @@ namespace llvm { /// elements remaining. If \p N is greater than the length of the /// string, the entire string is returned. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N = 1) const { if (N >= size()) return *this; @@ -615,7 +594,6 @@ namespace llvm { /// elements remaining. If \p N is greater than the length of the /// string, the entire string is returned. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_back(size_t N = 1) const { if (N >= size()) return *this; @@ -625,7 +603,6 @@ namespace llvm { /// Return the longest prefix of 'this' such that every character /// in the prefix satisfies the given predicate. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_while(function_ref<bool(char)> F) const { return substr(0, find_if_not(F)); } @@ -633,7 +610,6 @@ namespace llvm { /// Return the longest prefix of 'this' such that no character in /// the prefix satisfies the given predicate. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_until(function_ref<bool(char)> F) const { return substr(0, find_if(F)); } @@ -641,7 +617,6 @@ namespace llvm { /// Return a StringRef equal to 'this' but with the first \p N elements /// dropped. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N = 1) const { assert(size() >= N && "Dropping more elements than exist"); return substr(N); @@ -650,7 +625,6 @@ namespace llvm { /// Return a StringRef equal to 'this' but with the last \p N elements /// dropped. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N = 1) const { assert(size() >= N && "Dropping more elements than exist"); return substr(0, size()-N); @@ -659,7 +633,6 @@ namespace llvm { /// Return a StringRef equal to 'this', but with all characters satisfying /// the given predicate dropped from the beginning of the string. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_while(function_ref<bool(char)> F) const { return substr(find_if_not(F)); } @@ -667,14 +640,12 @@ namespace llvm { /// Return a StringRef equal to 'this', but with all characters not /// satisfying the given predicate dropped from the beginning of the string. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_until(function_ref<bool(char)> F) const { return substr(find_if(F)); } /// Returns true if this StringRef has the given prefix and removes that /// prefix. - LLVM_ATTRIBUTE_ALWAYS_INLINE bool consume_front(StringRef Prefix) { if (!startswith(Prefix)) return false; @@ -685,7 +656,6 @@ namespace llvm { /// Returns true if this StringRef has the given suffix and removes that /// suffix. - LLVM_ATTRIBUTE_ALWAYS_INLINE bool consume_back(StringRef Suffix) { if (!endswith(Suffix)) return false; @@ -706,7 +676,6 @@ namespace llvm { /// will be returned. If this is less than \p Start, an empty string will /// be returned. LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const { Start = std::min(Start, Length); End = std::min(std::max(Start, End), Length); @@ -894,12 +863,10 @@ namespace llvm { /// @name StringRef Comparison Operators /// @{ - LLVM_ATTRIBUTE_ALWAYS_INLINE inline bool operator==(StringRef LHS, StringRef RHS) { return LHS.equals(RHS); } - LLVM_ATTRIBUTE_ALWAYS_INLINE inline bool operator!=(StringRef LHS, StringRef RHS) { return !(LHS == RHS); } inline bool operator<(StringRef LHS, StringRef RHS) { @@ -928,10 +895,6 @@ namespace llvm { LLVM_NODISCARD hash_code hash_value(StringRef S); - // StringRefs can be treated like a POD type. - template <typename T> struct isPodLike; - template <> struct isPodLike<StringRef> { static const bool value = true; }; - } // end namespace llvm #endif // LLVM_ADT_STRINGREF_H diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h index 9af44c07df79..af3a44a7b32c 100644 --- a/include/llvm/ADT/StringSet.h +++ b/include/llvm/ADT/StringSet.h @@ -1,9 +1,8 @@ //===- StringSet.h - The LLVM Compiler Driver -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -34,6 +33,7 @@ namespace llvm { for (StringRef X : S) insert(X); } + explicit StringSet(AllocatorTy A) : base(A) {} std::pair<typename base::iterator, bool> insert(StringRef Key) { assert(!Key.empty()); @@ -45,6 +45,12 @@ namespace llvm { for (auto It = Begin; It != End; ++It) base::insert(std::make_pair(*It, '\0')); } + + template <typename ValueTy> + std::pair<typename base::iterator, bool> + insert(const StringMapEntry<ValueTy> &MapEntry) { + return insert(MapEntry.getKey()); + } }; } // end namespace llvm diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h index b7860b98ce5d..fea911f6928b 100644 --- a/include/llvm/ADT/StringSwitch.h +++ b/include/llvm/ADT/StringSwitch.h @@ -1,9 +1,8 @@ //===--- StringSwitch.h - Switch-on-literal-string Construct --------------===/ // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 StringSwitch template, which mimics a switch() @@ -49,7 +48,6 @@ class StringSwitch { Optional<T> Result; public: - LLVM_ATTRIBUTE_ALWAYS_INLINE explicit StringSwitch(StringRef S) : Str(S), Result() { } @@ -66,7 +64,6 @@ public: ~StringSwitch() = default; // Case-sensitive case matchers - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Case(StringLiteral S, T Value) { if (!Result && Str == S) { Result = std::move(Value); @@ -74,7 +71,6 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch& EndsWith(StringLiteral S, T Value) { if (!Result && Str.endswith(S)) { Result = std::move(Value); @@ -82,7 +78,6 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch& StartsWith(StringLiteral S, T Value) { if (!Result && Str.startswith(S)) { Result = std::move(Value); @@ -90,51 +85,43 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) { return Case(S0, Value).Case(S1, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value) { return Case(S0, Value).Cases(S1, S2, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value) { return Case(S0, Value).Cases(S1, S2, S3, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, T Value) { return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, @@ -142,7 +129,6 @@ public: return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, @@ -151,7 +137,6 @@ public: } // Case-insensitive case matchers. - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CaseLower(StringLiteral S, T Value) { if (!Result && Str.equals_lower(S)) Result = std::move(Value); @@ -159,7 +144,6 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &EndsWithLower(StringLiteral S, T Value) { if (!Result && Str.endswith_lower(S)) Result = Value; @@ -167,7 +151,6 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &StartsWithLower(StringLiteral S, T Value) { if (!Result && Str.startswith_lower(S)) Result = std::move(Value); @@ -175,31 +158,26 @@ public: return *this; } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) { return CaseLower(S0, Value).CaseLower(S1, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value) { return CaseLower(S0, Value).CasesLower(S1, S2, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value) { return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value); } - LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value) { return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value); } LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value) { if (Result) return std::move(*Result); @@ -207,7 +185,6 @@ public: } LLVM_NODISCARD - LLVM_ATTRIBUTE_ALWAYS_INLINE operator R() { assert(Result && "Fell off the end of a string-switch"); return std::move(*Result); diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index 1b8e9aa658c3..ac82451a9b21 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index e06a68e27317..edeb31efab80 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/Triple.h - Target triple helper class ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -50,6 +49,7 @@ public: armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be + aarch64_32, // AArch64 (little endian) ILP32: aarch64_32 arc, // ARC: Synopsys ARC avr, // AVR: Atmel AVR microcontroller bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) @@ -109,6 +109,7 @@ public: ARMSubArch_v8r, ARMSubArch_v8m_baseline, ARMSubArch_v8m_mainline, + ARMSubArch_v8_1m_mainline, ARMSubArch_v7, ARMSubArch_v7em, ARMSubArch_v7m, @@ -187,7 +188,8 @@ public: HermitCore, // HermitCore Unikernel/Multikernel Hurd, // GNU/Hurd WASI, // Experimental WebAssembly OS - LastOSType = WASI + Emscripten, + LastOSType = Emscripten }; enum EnvironmentType { UnknownEnvironment, @@ -201,6 +203,8 @@ public: CODE16, EABI, EABIHF, + ELFv1, + ELFv2, Android, Musl, MuslEABI, @@ -210,8 +214,9 @@ public: Itanium, Cygnus, CoreCLR, - Simulator, // Simulator variants of other systems, e.g., Apple's iOS - LastEnvironmentType = Simulator + Simulator, // Simulator variants of other systems, e.g., Apple's iOS + MacABI, // Mac Catalyst variant of Apple's iOS deployment target. + LastEnvironmentType = MacABI }; enum ObjectFormatType { UnknownObjectFormat, @@ -220,6 +225,7 @@ public: ELF, MachO, Wasm, + XCOFF, }; private: @@ -415,7 +421,7 @@ public: if (LHS[1] != Minor) return LHS[1] < Minor; if (LHS[2] != Micro) - return LHS[1] < Micro; + return LHS[2] < Micro; return false; } @@ -480,6 +486,10 @@ public: return getEnvironment() == Triple::Simulator; } + bool isMacCatalystEnvironment() const { + return getEnvironment() == Triple::MacABI; + } + bool isOSNetBSD() const { return getOS() == Triple::NetBSD; } @@ -524,32 +534,36 @@ public: return getOS() == Triple::Haiku; } - /// Checks if the environment could be MSVC. - bool isWindowsMSVCEnvironment() const { - return getOS() == Triple::Win32 && - (getEnvironment() == Triple::UnknownEnvironment || - getEnvironment() == Triple::MSVC); + /// Tests whether the OS is Windows. + bool isOSWindows() const { + return getOS() == Triple::Win32; } /// Checks if the environment is MSVC. bool isKnownWindowsMSVCEnvironment() const { - return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC; + return isOSWindows() && getEnvironment() == Triple::MSVC; + } + + /// Checks if the environment could be MSVC. + bool isWindowsMSVCEnvironment() const { + return isKnownWindowsMSVCEnvironment() || + (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment); } bool isWindowsCoreCLREnvironment() const { - return getOS() == Triple::Win32 && getEnvironment() == Triple::CoreCLR; + return isOSWindows() && getEnvironment() == Triple::CoreCLR; } bool isWindowsItaniumEnvironment() const { - return getOS() == Triple::Win32 && getEnvironment() == Triple::Itanium; + return isOSWindows() && getEnvironment() == Triple::Itanium; } bool isWindowsCygwinEnvironment() const { - return getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus; + return isOSWindows() && getEnvironment() == Triple::Cygnus; } bool isWindowsGNUEnvironment() const { - return getOS() == Triple::Win32 && getEnvironment() == Triple::GNU; + return isOSWindows() && getEnvironment() == Triple::GNU; } /// Tests for either Cygwin or MinGW OS @@ -563,11 +577,6 @@ public: isWindowsItaniumEnvironment(); } - /// Tests whether the OS is Windows. - bool isOSWindows() const { - return getOS() == Triple::Win32; - } - /// Tests whether the OS is NaCl (Native Client) bool isOSNaCl() const { return getOS() == Triple::NaCl; @@ -593,6 +602,11 @@ public: return getOS() == Triple::WASI; } + /// Tests whether the OS is Emscripten. + bool isOSEmscripten() const { + return getOS() == Triple::Emscripten; + } + /// Tests whether the OS uses glibc. bool isOSGlibc() const { return (getOS() == Triple::Linux || getOS() == Triple::KFreeBSD || @@ -600,6 +614,11 @@ public: !isAndroid(); } + /// Tests whether the OS is AIX. + bool isOSAIX() const { + return getOS() == Triple::AIX; + } + /// Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return getObjectFormat() == Triple::ELF; @@ -620,6 +639,11 @@ public: return getObjectFormat() == Triple::Wasm; } + /// Tests whether the OS uses the XCOFF binary format. + bool isOSBinFormatXCOFF() const { + return getObjectFormat() == Triple::XCOFF; + } + /// Tests whether the target is the PS4 CPU bool isPS4CPU() const { return getArch() == Triple::x86_64 && @@ -656,6 +680,11 @@ public: getEnvironment() == Triple::MuslEABIHF; } + /// Tests whether the target is SPIR (32- or 64-bit). + bool isSPIR() const { + return getArch() == Triple::spir || getArch() == Triple::spir64; + } + /// Tests whether the target is NVPTX (32- or 64-bit). bool isNVPTX() const { return getArch() == Triple::nvptx || getArch() == Triple::nvptx64; @@ -691,6 +720,16 @@ public: return isMIPS32() || isMIPS64(); } + /// Tests whether the target is 64-bit PowerPC (little and big endian). + bool isPPC64() const { + return getArch() == Triple::ppc64 || getArch() == Triple::ppc64le; + } + + /// Tests whether the target is RISC-V (32- and 64-bit). + bool isRISCV() const { + return getArch() == Triple::riscv32 || getArch() == Triple::riscv64; + } + /// Tests whether the target supports comdat bool supportsCOMDAT() const { return !isOSBinFormatMachO(); diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index b60fd0981398..4140c22aad3d 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -1,9 +1,8 @@ //===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -274,6 +273,9 @@ namespace llvm { assert(isValid() && "Invalid twine!"); } + /// Delete the implicit conversion from nullptr as Twine(const char *) + /// cannot take nullptr. + /*implicit*/ Twine(std::nullptr_t) = delete; /// Construct from an std::string. /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) { diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h index c86bedd07687..bfea988f1702 100644 --- a/include/llvm/ADT/UniqueVector.h +++ b/include/llvm/ADT/UniqueVector.h @@ -1,9 +1,8 @@ //===- llvm/ADT/UniqueVector.h ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h index 9028abe4c72c..5aefb05ecdda 100644 --- a/include/llvm/ADT/VariadicFunction.h +++ b/include/llvm/ADT/VariadicFunction.h @@ -1,9 +1,8 @@ -//===--- VariadicFunctions.h - Variadic Functions ---------------*- C++ -*-===// +//===- VariadicFunction.h - Variadic Functions ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/bit.h b/include/llvm/ADT/bit.h index a4aba7b6a9ee..a790d5ed2d21 100644 --- a/include/llvm/ADT/bit.h +++ b/include/llvm/ADT/bit.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/bit.h - C++20 <bit> ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -41,11 +40,11 @@ template <typename To, typename From , typename = typename std::enable_if<__is_trivially_copyable(To)>::type , typename = typename std::enable_if<__is_trivially_copyable(From)>::type #else - // This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike - // llvm/Support/type_traits.h's isPodLike we don't want to provide a - // good-enough answer here: developers in that configuration will hit - // compilation failures on the bots instead of locally. That's acceptable - // because it's very few developers, and only until we move past C++11. +// This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike +// llvm/Support/type_traits.h's is_trivially_copyable we don't want to +// provide a good-enough answer here: developers in that configuration will hit +// compilation failures on the bots instead of locally. That's acceptable +// because it's very few developers, and only until we move past C++11. #endif > inline To bit_cast(const From &from) noexcept { diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h index b2e8ec5c3f6d..4f5134008692 100644 --- a/include/llvm/ADT/edit_distance.h +++ b/include/llvm/ADT/edit_distance.h @@ -1,9 +1,8 @@ //===-- llvm/ADT/edit_distance.h - Array edit distance function --- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/fallible_iterator.h b/include/llvm/ADT/fallible_iterator.h new file mode 100644 index 000000000000..6501ad2233cd --- /dev/null +++ b/include/llvm/ADT/fallible_iterator.h @@ -0,0 +1,243 @@ +//===--- fallible_iterator.h - Wrapper for fallible iterators ---*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_FALLIBLE_ITERATOR_H +#define LLVM_ADT_FALLIBLE_ITERATOR_H + +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Error.h" + +#include <type_traits> + +namespace llvm { + +/// A wrapper class for fallible iterators. +/// +/// The fallible_iterator template wraps an underlying iterator-like class +/// whose increment and decrement operations are replaced with fallible versions +/// like: +/// +/// @code{.cpp} +/// Error inc(); +/// Error dec(); +/// @endcode +/// +/// It produces an interface that is (mostly) compatible with a traditional +/// c++ iterator, including ++ and -- operators that do not fail. +/// +/// Instances of the wrapper are constructed with an instance of the +/// underlying iterator and (for non-end iterators) a reference to an Error +/// instance. If the underlying increment/decrement operations fail, the Error +/// is returned via this reference, and the resulting iterator value set to an +/// end-of-range sentinel value. This enables the following loop idiom: +/// +/// @code{.cpp} +/// class Archive { // E.g. Potentially malformed on-disk archive +/// public: +/// fallible_iterator<ArchiveChildItr> children_begin(Error &Err); +/// fallible_iterator<ArchiveChildItr> children_end(); +/// iterator_range<fallible_iterator<ArchiveChildItr>> +/// children(Error &Err) { +/// return make_range(children_begin(Err), children_end()); +/// //... +/// }; +/// +/// void walk(Archive &A) { +/// Error Err = Error::success(); +/// for (auto &C : A.children(Err)) { +/// // Loop body only entered when increment succeeds. +/// } +/// if (Err) { +/// // handle error. +/// } +/// } +/// @endcode +/// +/// The wrapper marks the referenced Error as unchecked after each increment +/// and/or decrement operation, and clears the unchecked flag when a non-end +/// value is compared against end (since, by the increment invariant, not being +/// an end value proves that there was no error, and is equivalent to checking +/// that the Error is success). This allows early exits from the loop body +/// without requiring redundant error checks. +template <typename Underlying> class fallible_iterator { +private: + template <typename T> + using enable_if_struct_deref_supported = std::enable_if< + !std::is_void<decltype(std::declval<T>().operator->())>::value, + decltype(std::declval<T>().operator->())>; + +public: + /// Construct a fallible iterator that *cannot* be used as an end-of-range + /// value. + /// + /// A value created by this method can be dereferenced, incremented, + /// decremented and compared, providing the underlying type supports it. + /// + /// The error that is passed in will be initially marked as checked, so if the + /// iterator is not used at all the Error need not be checked. + static fallible_iterator itr(Underlying I, Error &Err) { + (void)!!Err; + return fallible_iterator(std::move(I), &Err); + } + + /// Construct a fallible iteratro that can be used as an end-of-range value. + /// + /// A value created by this method can be dereferenced (if the underlying + /// value points at a valid value) and compared, but not incremented or + /// decremented. + static fallible_iterator end(Underlying I) { + return fallible_iterator(std::move(I), nullptr); + } + + /// Forward dereference to the underlying iterator. + auto operator*() -> decltype(*std::declval<Underlying>()) { return *I; } + + /// Forward const dereference to the underlying iterator. + auto operator*() const -> decltype(*std::declval<const Underlying>()) { + return *I; + } + + /// Forward structure dereference to the underlying iterator (if the + /// underlying iterator supports it). + template <typename T = Underlying> + typename enable_if_struct_deref_supported<T>::type operator->() { + return I.operator->(); + } + + /// Forward const structure dereference to the underlying iterator (if the + /// underlying iterator supports it). + template <typename T = Underlying> + typename enable_if_struct_deref_supported<const T>::type operator->() const { + return I.operator->(); + } + + /// Increment the fallible iterator. + /// + /// If the underlying 'inc' operation fails, this will set the Error value + /// and update this iterator value to point to end-of-range. + /// + /// The Error value is marked as needing checking, regardless of whether the + /// 'inc' operation succeeds or fails. + fallible_iterator &operator++() { + assert(getErrPtr() && "Cannot increment end iterator"); + if (auto Err = I.inc()) + handleError(std::move(Err)); + else + resetCheckedFlag(); + return *this; + } + + /// Decrement the fallible iterator. + /// + /// If the underlying 'dec' operation fails, this will set the Error value + /// and update this iterator value to point to end-of-range. + /// + /// The Error value is marked as needing checking, regardless of whether the + /// 'dec' operation succeeds or fails. + fallible_iterator &operator--() { + assert(getErrPtr() && "Cannot decrement end iterator"); + if (auto Err = I.dec()) + handleError(std::move(Err)); + else + resetCheckedFlag(); + return *this; + } + + /// Compare fallible iterators for equality. + /// + /// Returns true if both LHS and RHS are end-of-range values, or if both are + /// non-end-of-range values whose underlying iterator values compare equal. + /// + /// If this is a comparison between an end-of-range iterator and a + /// non-end-of-range iterator, then the Error (referenced by the + /// non-end-of-range value) is marked as checked: Since all + /// increment/decrement operations result in an end-of-range value, comparing + /// false against end-of-range is equivalent to checking that the Error value + /// is success. This flag management enables early returns from loop bodies + /// without redundant Error checks. + friend bool operator==(const fallible_iterator &LHS, + const fallible_iterator &RHS) { + // If both iterators are in the end state they compare + // equal, regardless of whether either is valid. + if (LHS.isEnd() && RHS.isEnd()) + return true; + + assert(LHS.isValid() && RHS.isValid() && + "Invalid iterators can only be compared against end"); + + bool Equal = LHS.I == RHS.I; + + // If the iterators differ and this is a comparison against end then mark + // the Error as checked. + if (!Equal) { + if (LHS.isEnd()) + (void)!!*RHS.getErrPtr(); + else + (void)!!*LHS.getErrPtr(); + } + + return Equal; + } + + /// Compare fallible iterators for inequality. + /// + /// See notes for operator==. + friend bool operator!=(const fallible_iterator &LHS, + const fallible_iterator &RHS) { + return !(LHS == RHS); + } + +private: + fallible_iterator(Underlying I, Error *Err) + : I(std::move(I)), ErrState(Err, false) {} + + Error *getErrPtr() const { return ErrState.getPointer(); } + + bool isEnd() const { return getErrPtr() == nullptr; } + + bool isValid() const { return !ErrState.getInt(); } + + void handleError(Error Err) { + *getErrPtr() = std::move(Err); + ErrState.setPointer(nullptr); + ErrState.setInt(true); + } + + void resetCheckedFlag() { + *getErrPtr() = Error::success(); + } + + Underlying I; + mutable PointerIntPair<Error *, 1> ErrState; +}; + +/// Convenience wrapper to make a fallible_iterator value from an instance +/// of an underlying iterator and an Error reference. +template <typename Underlying> +fallible_iterator<Underlying> make_fallible_itr(Underlying I, Error &Err) { + return fallible_iterator<Underlying>::itr(std::move(I), Err); +} + +/// Convenience wrapper to make a fallible_iterator end value from an instance +/// of an underlying iterator. +template <typename Underlying> +fallible_iterator<Underlying> make_fallible_end(Underlying E) { + return fallible_iterator<Underlying>::end(std::move(E)); +} + +template <typename Underlying> +iterator_range<fallible_iterator<Underlying>> +make_fallible_range(Underlying I, Underlying E, Error &Err) { + return make_range(make_fallible_itr(std::move(I), Err), + make_fallible_end(std::move(E))); +} + +} // end namespace llvm + +#endif // LLVM_ADT_FALLIBLE_ITERATOR_H diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 00bb6d528175..06c7abff965f 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -1,9 +1,8 @@ //==-- llvm/ADT/ilist.h - Intrusive Linked List Template ---------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -66,9 +65,8 @@ template <typename NodeTy> struct ilist_callback_traits { void addNodeToList(NodeTy *) {} void removeNodeFromList(NodeTy *) {} - /// Callback before transferring nodes to this list. - /// - /// \pre \c this!=&OldList + /// Callback before transferring nodes to this list. The nodes may already be + /// in this same list. template <class Iterator> void transferNodesFromList(ilist_callback_traits &OldList, Iterator /*first*/, Iterator /*last*/) { @@ -287,8 +285,8 @@ private: if (position == last) return; - if (this != &L2) // Notify traits we moved the nodes... - this->transferNodesFromList(L2, first, last); + // Notify traits we moved the nodes... + this->transferNodesFromList(L2, first, last); base_list_type::splice(position, L2, first, last); } diff --git a/include/llvm/ADT/ilist_base.h b/include/llvm/ADT/ilist_base.h index 3d818a48d41d..b8c098b951ad 100644 --- a/include/llvm/ADT/ilist_base.h +++ b/include/llvm/ADT/ilist_base.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ilist_base.h - Intrusive List Base --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/ilist_iterator.h b/include/llvm/ADT/ilist_iterator.h index 671e644e0154..cbe5cefa96d1 100644 --- a/include/llvm/ADT/ilist_iterator.h +++ b/include/llvm/ADT/ilist_iterator.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h index dd0e6b4ec2b9..e040d9630a1e 100644 --- a/include/llvm/ADT/ilist_node.h +++ b/include/llvm/ADT/ilist_node.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ilist_node.h - Intrusive Linked List Helper -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include/llvm/ADT/ilist_node_base.h b/include/llvm/ADT/ilist_node_base.h index e5062ac4eaad..f6c518e6eed7 100644 --- a/include/llvm/ADT/ilist_node_base.h +++ b/include/llvm/ADT/ilist_node_base.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ilist_node_base.h - Intrusive List Node Base -----*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/ilist_node_options.h b/include/llvm/ADT/ilist_node_options.h index 7ff4005f6757..9b95cdbe08c4 100644 --- a/include/llvm/ADT/ilist_node_options.h +++ b/include/llvm/ADT/ilist_node_options.h @@ -1,9 +1,8 @@ //===- llvm/ADT/ilist_node_options.h - ilist_node Options -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h index 40e490cf7864..467fd4c00ec5 100644 --- a/include/llvm/ADT/iterator.h +++ b/include/llvm/ADT/iterator.h @@ -1,9 +1,8 @@ //===- iterator.h - Utilities for using and defining iterators --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h index 2ba12866ecf3..774c7c4e3366 100644 --- a/include/llvm/ADT/iterator_range.h +++ b/include/llvm/ADT/iterator_range.h @@ -1,9 +1,8 @@ //===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// \file diff --git a/include/llvm/ADT/simple_ilist.h b/include/llvm/ADT/simple_ilist.h index 4c7598a1acb4..9257b47b9cf8 100644 --- a/include/llvm/ADT/simple_ilist.h +++ b/include/llvm/ADT/simple_ilist.h @@ -1,9 +1,8 @@ //===- llvm/ADT/simple_ilist.h - Simple Intrusive List ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// |
