1 //===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
18 #define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
20 #include "llvm/ADT/PointerUnion.h"
21 #include "llvm/IR/Constant.h"
23 // Forward-declare ConstantInitBuilderBase and give it a
24 // PointerLikeTypeTraits specialization so that we can safely use it
25 // in a PointerUnion below.
28 class ConstantInitBuilderBase;
33 struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
34 using T = ::clang::CodeGen::ConstantInitBuilderBase*;
36 static inline void *getAsVoidPointer(T p) { return p; }
37 static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
38 enum { NumLowBitsAvailable = 2 };
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*>;
52 friend class ConstantInitBuilderBase;
53 explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
56 ConstantInitFuture() {}
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");
63 /// Is this future non-null?
64 explicit operator bool() const { return bool(Data); }
66 /// Return the type of the initializer.
67 llvm::Type *getType() const;
69 /// Abandon this initializer.
72 /// Install the initializer into a global variable. This cannot
73 /// be called multiple times.
74 void installInGlobal(llvm::GlobalVariable *global);
76 void *getOpaqueValue() const { return Data.getOpaqueValue(); }
77 static ConstantInitFuture getFromOpaqueValue(void *value) {
78 ConstantInitFuture result;
79 result.Data = PairTy::getFromOpaqueValue(value);
84 llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
88 } // end namespace CodeGen
89 } // end namespace clang
94 struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
95 using T = ::clang::CodeGen::ConstantInitFuture;
97 static inline void *getAsVoidPointer(T future) {
98 return future.getOpaqueValue();
100 static inline T getFromVoidPointer(void *p) {
101 return T::getFromOpaqueValue(p);
103 enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
106 } // end namespace llvm