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