File: type.cpp

package info (click to toggle)
llvmlite 0.44.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,736 kB
  • sloc: python: 12,771; cpp: 3,146; sh: 185; makefile: 183
file content (170 lines) | stat: -rw-r--r-- 4,670 bytes parent folder | download
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"