Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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 |