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(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(p); 100 } 101 static constexpr int NumLowBitsAvailable = T::NumLowBitsAvailable; 102 }; 103 104 } // end namespace llvm 105 106 #endif 107