Home | History | Annotate | Download | only in CodeGen
      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