Removing the silly CHelpers header by rolling wrap and unwrap into the C
[oota-llvm.git] / include / llvm-c / Core.h
index 47b89aa513e7f8c3481faed9d712473970d732fa..fb01b8373520001891a9c064c75efce317c7457e 100644 (file)
 |* with C++ due to name mangling. So in addition to C, this interface enables *|
 |* tools written in such languages.                                           *|
 |*                                                                            *|
+|* 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.  *|
+|*                                                                            *|
 \*===----------------------------------------------------------------------===*/
 
 #ifndef LLVM_C_CORE_H
 #define LLVM_C_CORE_H
 
 #ifdef __cplusplus
+
+/* Need these includes to support the LLVM 'cast' template for the C++ 'wrap' 
+   and 'unwrap' conversion functions. */
+#include "llvm/Module.h"
+#include "llvm/Support/LLVMBuilder.h"
+
 extern "C" {
 #endif
 
@@ -412,6 +423,94 @@ LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef V1,
 
 #ifdef __cplusplus
 }
-#endif
 
-#endif
+namespace llvm {
+  /* Opaque module conversions
+   */ 
+  inline Module *unwrap(LLVMModuleRef M) {
+    return reinterpret_cast<Module*>(M);
+  }
+  
+  inline LLVMModuleRef wrap(Module *M) {
+    return reinterpret_cast<LLVMModuleRef>(M);
+  }
+  
+  /* Opaque type conversions
+   */ 
+  inline Type *unwrap(LLVMTypeRef Ty) {
+    return reinterpret_cast<Type*>(Ty);
+  }
+  
+  template<typename T>
+  inline T *unwrap(LLVMTypeRef Ty) {
+    return cast<T>(unwrap(Ty));
+  }
+  
+  inline Type **unwrap(LLVMTypeRef* Tys) {
+    return reinterpret_cast<Type**>(Tys);
+  }
+  
+  inline LLVMTypeRef wrap(const Type *Ty) {
+    return reinterpret_cast<LLVMTypeRef>(const_cast<Type*>(Ty));
+  }
+  
+  inline LLVMTypeRef *wrap(const Type **Tys) {
+    return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
+  }
+  
+  /* Opaque value conversions
+   */ 
+  inline Value *unwrap(LLVMValueRef Val) {
+    return reinterpret_cast<Value*>(Val);
+  }
+  
+  template<typename T>
+  inline T *unwrap(LLVMValueRef Val) {
+    return cast<T>(unwrap(Val));
+  }
+
+  inline Value **unwrap(LLVMValueRef *Vals) {
+    return reinterpret_cast<Value**>(Vals);
+  }
+  
+  template<typename T>
+  inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
+    #if DEBUG
+    for (LLVMValueRef *I = Vals, E = Vals + Length; I != E; ++I)
+      cast<T>(*I);
+    #endif
+    return reinterpret_cast<T**>(Vals);
+  }
+  
+  inline LLVMValueRef wrap(const Value *Val) {
+    return reinterpret_cast<LLVMValueRef>(const_cast<Value*>(Val));
+  }
+  
+  inline LLVMValueRef *wrap(const Value **Vals) {
+    return reinterpret_cast<LLVMValueRef*>(const_cast<Value**>(Vals));
+  }
+  
+  /* Basic block conversions
+   */ 
+  inline BasicBlock *unwrap(LLVMBasicBlockRef BBRef) {
+    return reinterpret_cast<BasicBlock*>(BBRef);
+  }
+  
+  inline LLVMBasicBlockRef wrap(const BasicBlock *BB) {
+    return reinterpret_cast<LLVMBasicBlockRef>(const_cast<BasicBlock*>(BB));
+  }
+  
+  /* Opaque builder conversions.
+   */ 
+  inline LLVMBuilder *unwrap(LLVMBuilderRef B) {
+    return reinterpret_cast<LLVMBuilder*>(B);
+  }
+  
+  inline LLVMBuilderRef wrap(LLVMBuilder *B) {
+    return reinterpret_cast<LLVMBuilderRef>(B);
+  }
+}
+
+#endif /* !defined(__cplusplus) */
+
+#endif /* !defined(LLVM_C_CORE_H) */