| 1 | //===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This class defines the ConstantInitFuture class. This is split out |
| 10 | // from ConstantInitBuilder.h in order to allow APIs to work with it |
| 11 | // without having to include that entire header. This is particularly |
| 12 | // important because it is often useful to be able to default-construct |
| 13 | // a future in, say, a default argument. |
| 14 | // |
| 15 | //===----------------------------------------------------------------------===// |
| 16 | |
| 17 | #ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H |
| 18 | #define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H |
| 19 | |
| 20 | #include "llvm/ADT/PointerUnion.h" |
| 21 | #include "llvm/IR/Constant.h" |
| 22 | |
| 23 | // Forward-declare ConstantInitBuilderBase and give it a |
| 24 | // PointerLikeTypeTraits specialization so that we can safely use it |
| 25 | // in a PointerUnion below. |
| 26 | namespace clang { |
| 27 | namespace CodeGen { |
| 28 | class ConstantInitBuilderBase; |
| 29 | } |
| 30 | } |
| 31 | namespace llvm { |
| 32 | template <> |
| 33 | struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> { |
| 34 | using T = ::clang::CodeGen::ConstantInitBuilderBase*; |
| 35 | |
| 36 | static inline void *getAsVoidPointer(T p) { return p; } |
| 37 | static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);} |
| 38 | static constexpr int NumLowBitsAvailable = 2; |
| 39 | }; |
| 40 | } |
| 41 | |
| 42 | namespace clang { |
| 43 | namespace CodeGen { |
| 44 | |
| 45 | /// A "future" for a completed constant initializer, which can be passed |
| 46 | /// around independently of any sub-builders (but not the original parent). |
| 47 | class ConstantInitFuture { |
| 48 | using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>; |
| 49 | |
| 50 | PairTy Data; |
| 51 | |
| 52 | friend class ConstantInitBuilderBase; |
| 53 | explicit ConstantInitFuture(ConstantInitBuilderBase *builder); |
| 54 | |
| 55 | public: |
| 56 | ConstantInitFuture() {} |
| 57 | |
| 58 | /// A future can be explicitly created from a fixed initializer. |
| 59 | explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) { |
| 60 | assert(initializer && "creating null future" ); |
| 61 | } |
| 62 | |
| 63 | /// Is this future non-null? |
| 64 | explicit operator bool() const { return bool(Data); } |
| 65 | |
| 66 | /// Return the type of the initializer. |
| 67 | llvm::Type *getType() const; |
| 68 | |
| 69 | /// Abandon this initializer. |
| 70 | void abandon(); |
| 71 | |
| 72 | /// Install the initializer into a global variable. This cannot |
| 73 | /// be called multiple times. |
| 74 | void installInGlobal(llvm::GlobalVariable *global); |
| 75 | |
| 76 | void *getOpaqueValue() const { return Data.getOpaqueValue(); } |
| 77 | static ConstantInitFuture getFromOpaqueValue(void *value) { |
| 78 | ConstantInitFuture result; |
| 79 | result.Data = PairTy::getFromOpaqueValue(VP: value); |
| 80 | return result; |
| 81 | } |
| 82 | static constexpr int NumLowBitsAvailable = |
| 83 | llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable; |
| 84 | }; |
| 85 | |
| 86 | } // end namespace CodeGen |
| 87 | } // end namespace clang |
| 88 | |
| 89 | namespace llvm { |
| 90 | |
| 91 | template <> |
| 92 | struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> { |
| 93 | using T = ::clang::CodeGen::ConstantInitFuture; |
| 94 | |
| 95 | static inline void *getAsVoidPointer(T future) { |
| 96 | return future.getOpaqueValue(); |
| 97 | } |
| 98 | static inline T getFromVoidPointer(void *p) { |
| 99 | return T::getFromOpaqueValue(value: p); |
| 100 | } |
| 101 | static constexpr int NumLowBitsAvailable = T::NumLowBitsAvailable; |
| 102 | }; |
| 103 | |
| 104 | } // end namespace llvm |
| 105 | |
| 106 | #endif |
| 107 | |