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