summaryrefslogtreecommitdiff
path: root/include/llvm/Wrap.h
blob: 0dc5c78bd1119fff3806c954886174774cf7d008 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//===- llvm/Wrap.h - C++ Type Wrapping for the C Interface  -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the wrapping functions for the C interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_WRAP_H
#define LLVM_WRAP_H

#include "llvm-c/Core.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/PassRegistry.h"

/* When included into a C++ source file, also declares 'wrap' and 'unwrap'
  helpers to perform opaque reference<-->pointer conversions. These helpers
  are shorter and more tightly typed than writing the casts by hand when
  authoring bindings. In assert builds, they will do runtime type checking.

  Need these includes to support the LLVM 'cast' template for the C++ 'wrap' 
  and 'unwrap' conversion functions. */

namespace llvm {
  class MemoryBuffer;
  class PassManagerBase;
  struct GenericValue;
  class ExecutionEngine;

  #define DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)   \
    inline ty *unwrap(ref P) {                          \
      return reinterpret_cast<ty*>(P);                  \
    }                                                   \
                                                        \
    inline ref wrap(const ty *P) {                      \
      return reinterpret_cast<ref>(const_cast<ty*>(P)); \
    }
  
  #define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref)      \
    DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)         \
                                                        \
    template<typename T>                                \
    inline T *unwrap(ref P) {                           \
      return cast<T>(unwrap(P));                        \
    }
  
  #define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref)   \
    DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref)         \
                                                        \
    template<typename T>                                \
    inline T *unwrap(ref P) {                           \
      T *Q = (T*)unwrap(P);                             \
      assert(Q && "Invalid cast!");                     \
      return Q;                                         \
    }
  
  DEFINE_ISA_CONVERSION_FUNCTIONS   (Type,               LLVMTypeRef          )
  DEFINE_ISA_CONVERSION_FUNCTIONS   (Value,              LLVMValueRef         )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module,             LLVMModuleRef        )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock,         LLVMBasicBlockRef    )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(IRBuilder<>,        LLVMBuilderRef       )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer,       LLVMMemoryBufferRef  )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMContext,        LLVMContextRef       )
  DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use,                LLVMUseRef           )
  DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase,    LLVMPassManagerRef   )
  DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassRegistry,       LLVMPassRegistryRef  )

  /* LLVMModuleProviderRef exists for historical reasons, but now just holds a
   * Module.
   */
  inline Module *unwrap(LLVMModuleProviderRef MP) {
    return reinterpret_cast<Module*>(MP);
  }
  
  /* Specialized opaque context conversions.
   */
  inline LLVMContext **unwrap(LLVMContextRef* Tys) {
    return reinterpret_cast<LLVMContext**>(Tys);
  }
  
  inline LLVMContextRef *wrap(const LLVMContext **Tys) {
    return reinterpret_cast<LLVMContextRef*>(const_cast<LLVMContext**>(Tys));
  }
  
  /* Specialized opaque type conversions.
   */
  inline Type **unwrap(LLVMTypeRef* Tys) {
    return reinterpret_cast<Type**>(Tys);
  }
  
  inline LLVMTypeRef *wrap(Type **Tys) {
    return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
  }
  
  /* Specialized opaque value conversions.
   */ 
  inline Value **unwrap(LLVMValueRef *Vals) {
    return reinterpret_cast<Value**>(Vals);
  }
  
  template<typename T>
  inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
    #ifdef DEBUG
    for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
      cast<T>(*I);
    #endif
    (void)Length;
    return reinterpret_cast<T**>(Vals);
  }
  
  inline LLVMValueRef *wrap(const Value **Vals) {
    return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
  }
}

#endif