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 struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> { 35 using T = ::clang::CodeGen::ConstantInitBuilderBase*; 36 37 static inline void *getAsVoidPointer(T p) { return p; } 38 static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);} 39 enum { NumLowBitsAvailable = 2 }; 40 }; 41 } 42 43 namespace clang { 44 namespace CodeGen { 45 46 /// A "future" for a completed constant initializer, which can be passed 47 /// around independently of any sub-builders (but not the original parent). 48 class ConstantInitFuture { 49 using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>; 50 51 PairTy Data; 52 53 friend class ConstantInitBuilderBase; 54 explicit ConstantInitFuture(ConstantInitBuilderBase *builder); 55 56 public: 57 ConstantInitFuture() {} 58 59 /// A future can be explicitly created from a fixed initializer. 60 explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) { 61 assert(initializer && "creating null future"); 62 } 63 64 /// Is this future non-null? 65 explicit operator bool() const { return bool(Data); } 66 67 /// Return the type of the initializer. 68 llvm::Type *getType() const; 69 70 /// Abandon this initializer. 71 void abandon(); 72 73 /// Install the initializer into a global variable. This cannot 74 /// be called multiple times. 75 void installInGlobal(llvm::GlobalVariable *global); 76 77 void *getOpaqueValue() const { return Data.getOpaqueValue(); } 78 static ConstantInitFuture getFromOpaqueValue(void *value) { 79 ConstantInitFuture result; 80 result.Data = PairTy::getFromOpaqueValue(value); 81 return result; 82 } 83 enum { 84 NumLowBitsAvailable = 85 llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable 86 }; 87 }; 88 89 } // end namespace CodeGen 90 } // end namespace clang 91 92 namespace llvm { 93 94 template <> 95 struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> { 96 using T = ::clang::CodeGen::ConstantInitFuture; 97 98 static inline void *getAsVoidPointer(T future) { 99 return future.getOpaqueValue(); 100 } 101 static inline T getFromVoidPointer(void *p) { 102 return T::getFromOpaqueValue(p); 103 } 104 enum { NumLowBitsAvailable = T::NumLowBitsAvailable }; 105 }; 106 107 } // end namespace llvm 108 109 #endif 110