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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
#include "core.h"
#include "llvm-c/Core.h"
#include <string>
#include <iostream>
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Type.h"
struct ElementIterator {
typedef llvm::ArrayRef<llvm::Type *>::iterator subtype_iterator;
subtype_iterator cur;
subtype_iterator end;
ElementIterator(subtype_iterator cur, subtype_iterator end)
: cur(cur), end(end) {}
};
struct OpaqueElementIterator;
typedef OpaqueElementIterator *LLVMElementIteratorRef;
namespace llvm {
static LLVMElementIteratorRef wrap(ElementIterator *GI) {
return reinterpret_cast<LLVMElementIteratorRef>(GI);
}
static ElementIterator *unwrap(LLVMElementIteratorRef GI) {
return reinterpret_cast<ElementIterator *>(GI);
}
} // namespace llvm
extern "C" {
API_EXPORT(LLVMElementIteratorRef)
LLVMPY_ElementIter(LLVMTypeRef Val) {
using namespace llvm;
llvm::Type *ty = llvm::unwrap(Val);
auto elements = ty->subtypes();
return wrap(new ElementIterator(elements.begin(), elements.end()));
}
API_EXPORT(LLVMTypeRef)
LLVMPY_ElementIterNext(LLVMElementIteratorRef GI) {
using namespace llvm;
ElementIterator *iter = unwrap(GI);
if (iter->cur != iter->end) {
const Type *ty = *(iter->cur);
iter->cur++;
return wrap(static_cast<const Type *>(ty));
} else {
return NULL;
}
}
API_EXPORT(void)
LLVMPY_DisposeElementIter(LLVMElementIteratorRef GI) {
delete llvm::unwrap(GI);
}
API_EXPORT(int)
LLVMPY_GetTypeKind(LLVMTypeRef Val) { return (int)LLVMGetTypeKind(Val); }
API_EXPORT(LLVMTypeRef)
LLVMPY_TypeOf(LLVMValueRef Val) { return LLVMTypeOf(Val); }
API_EXPORT(const char *)
LLVMPY_PrintType(LLVMTypeRef type) {
char *str = LLVMPrintTypeToString(type);
const char *out = LLVMPY_CreateString(str);
LLVMDisposeMessage(str);
return out;
}
API_EXPORT(const char *)
LLVMPY_GetTypeName(LLVMTypeRef type) {
// try to convert to a struct type, works for other derived
// types too
llvm::Type *unwrapped = llvm::unwrap(type);
llvm::StructType *ty = llvm::dyn_cast<llvm::StructType>(unwrapped);
if (ty && !ty->isLiteral()) {
return LLVMPY_CreateString(ty->getStructName().str().c_str());
}
return LLVMPY_CreateString("");
}
API_EXPORT(bool)
LLVMPY_TypeIsPointer(LLVMTypeRef type) {
return llvm::unwrap(type)->isPointerTy();
}
API_EXPORT(bool)
LLVMPY_TypeIsArray(LLVMTypeRef type) { return llvm::unwrap(type)->isArrayTy(); }
API_EXPORT(bool)
LLVMPY_TypeIsVector(LLVMTypeRef type) {
return llvm::unwrap(type)->isVectorTy();
}
API_EXPORT(bool)
LLVMPY_TypeIsStruct(LLVMTypeRef type) {
return llvm::unwrap(type)->isStructTy();
}
API_EXPORT(bool)
LLVMPY_TypeIsFunction(LLVMTypeRef type) {
return llvm::unwrap(type)->isFunctionTy();
}
API_EXPORT(bool)
LLVMPY_IsFunctionVararg(LLVMTypeRef type) {
llvm::Type *unwrapped = llvm::unwrap(type);
llvm::FunctionType *ty = llvm::dyn_cast<llvm::FunctionType>(unwrapped);
if (ty != nullptr) {
return ty->isVarArg();
}
return false;
}
API_EXPORT(int)
LLVMPY_GetTypeElementCount(LLVMTypeRef type) {
llvm::Type *unwrapped = llvm::unwrap(type);
if (unwrapped->isArrayTy()) {
return unwrapped->getArrayNumElements();
}
if (unwrapped->isVectorTy()) {
// Fixed vector: get exact number of elements
llvm::FixedVectorType *fixedvec =
llvm::dyn_cast<llvm::FixedVectorType>(unwrapped);
if (fixedvec != nullptr) {
return fixedvec->getNumElements();
}
// Scalable vector: get minimum elements
llvm::ScalableVectorType *scalablevec =
llvm::dyn_cast<llvm::ScalableVectorType>(unwrapped);
if (scalablevec != nullptr) {
return scalablevec->getMinNumElements();
}
}
// Not an array nor vector
return -1;
}
API_EXPORT(uint64_t)
LLVMPY_GetTypeBitWidth(LLVMTypeRef type) {
llvm::Type *unwrapped = llvm::unwrap(type);
auto size = unwrapped->getPrimitiveSizeInBits();
return size.getFixedValue();
}
API_EXPORT(LLVMTypeRef)
LLVMPY_GetReturnType(LLVMTypeRef type) { return LLVMGetReturnType(type); }
API_EXPORT(unsigned)
LLVMPY_CountParamTypes(LLVMTypeRef type) { return LLVMCountParamTypes(type); }
API_EXPORT(void)
LLVMPY_GetParamTypes(LLVMTypeRef type, LLVMTypeRef *out_types) {
LLVMGetParamTypes(type, out_types);
}
API_EXPORT(bool)
LLVMPY_IsPackedStruct(LLVMTypeRef type) { return LLVMIsPackedStruct(type); }
API_EXPORT(bool)
LLVMPY_IsOpaqueStruct(LLVMTypeRef type) { return LLVMIsOpaqueStruct(type); }
API_EXPORT(bool)
LLVMPY_IsLiteralStruct(LLVMTypeRef type) { return LLVMIsLiteralStruct(type); }
} // end extern "C"
|