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. 27namespace clang { 28namespace CodeGen { 29class ConstantInitBuilderBase; 30} 31} 32namespace llvm { 33template <> 34struct 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 43namespace clang { 44namespace 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). 48class ConstantInitFuture { 49 using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>; 50 51 PairTy Data; 52 53 friend class ConstantInitBuilderBase; 54 explicit ConstantInitFuture(ConstantInitBuilderBase *builder); 55 56public: 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 92namespace llvm { 93 94template <> 95struct 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