blob: 9324c3d3062c6c3c41ce628a6d09b099471d620b [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_rs_export_type.h"
2
3#include <vector>
Shih-wei Liao462aefd2010-06-04 15:32:04 -07004
5#include "llvm/Type.h"
6#include "llvm/DerivedTypes.h"
7
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07008#include "llvm/ADT/StringExtras.h"
9#include "llvm/Target/TargetData.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070010
Shih-wei Liao0a3f20e2010-08-10 13:09:49 -070011#include "clang/AST/RecordLayout.h"
12
zonr6315f762010-10-05 15:35:14 +080013#include "slang_rs_context.h"
14#include "slang_rs_export_element.h"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070015
16using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070017
18/****************************** RSExportType ******************************/
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019bool RSExportType::NormalizeType(const clang::Type *&T,
20 llvm::StringRef &TypeName) {
21 llvm::SmallPtrSet<const clang::Type*, 8> SPS =
22 llvm::SmallPtrSet<const clang::Type*, 8>();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070023
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070024 if ((T = RSExportType::TypeExportable(T, SPS)) == NULL)
zonr6315f762010-10-05 15:35:14 +080025 // TODO(zonr): warn that type not exportable.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070026 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070027
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070028 // Get type name
29 TypeName = RSExportType::GetTypeName(T);
30 if (TypeName.empty())
zonr6315f762010-10-05 15:35:14 +080031 // TODO(zonr): warning that the type is unnamed.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070032 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070033
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070034 return true;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070035}
36
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070037const clang::Type
38*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) {
Zonr Chang0da0a7d2010-10-05 21:26:37 +080039 if (DD) {
40 clang::QualType T;
41 if (DD->getTypeSourceInfo())
42 T = DD->getTypeSourceInfo()->getType();
43 else
44 T = DD->getType();
45
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070046 if (T.isNull())
47 return NULL;
48 else
49 return T.getTypePtr();
50 }
51 return NULL;
52}
53
54llvm::StringRef RSExportType::GetTypeName(const clang::Type* T) {
55 T = GET_CANONICAL_TYPE(T);
56 if (T == NULL)
57 return llvm::StringRef();
58
59 switch (T->getTypeClass()) {
60 case clang::Type::Builtin: {
61 const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T);
62
63 switch (BT->getKind()) {
64 // Compiler is smart enough to optimize following *big if branches*
65 // since they all become "constant comparison" after macro expansion
66#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
67 case builtin_type: { \
68 if (type == RSExportPrimitiveType::DataTypeFloat32) \
69 return "float"; \
70 else if (type == RSExportPrimitiveType::DataTypeFloat64) \
71 return "double"; \
72 else if (type == RSExportPrimitiveType::DataTypeUnsigned8) \
73 return "uchar"; \
74 else if (type == RSExportPrimitiveType::DataTypeUnsigned16) \
75 return "ushort"; \
76 else if (type == RSExportPrimitiveType::DataTypeUnsigned32) \
77 return "uint"; \
78 else if (type == RSExportPrimitiveType::DataTypeSigned8) \
79 return "char"; \
80 else if (type == RSExportPrimitiveType::DataTypeSigned16) \
81 return "short"; \
82 else if (type == RSExportPrimitiveType::DataTypeSigned32) \
83 return "int"; \
zonr6315f762010-10-05 15:35:14 +080084 else if (type == RSExportPrimitiveType::DataTypeSigned64) \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070085 return "long"; \
Shih-wei Liao91a37832010-10-03 19:11:51 -070086 else if (type == RSExportPrimitiveType::DataTypeBoolean) \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070087 return "bool"; \
88 else \
89 assert(false && "Unknow data type of supported builtin"); \
90 break; \
91 }
92#include "slang_rs_export_type_support.inc"
93
94 default: {
95 assert(false && "Unknown data type of the builtin");
96 break;
97 }
98 }
99 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700100 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700101 case clang::Type::Record: {
102 const clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
103 llvm::StringRef Name = RD->getName();
104 if (Name.empty()) {
105 if (RD->getTypedefForAnonDecl() != NULL)
106 Name = RD->getTypedefForAnonDecl()->getName();
107
zonr6315f762010-10-05 15:35:14 +0800108 if (Name.empty())
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700109 // Try to find a name from redeclaration (i.e. typedef)
110 for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(),
111 RE = RD->redecls_end();
112 RI != RE;
113 RI++) {
114 assert(*RI != NULL && "cannot be NULL object");
115
116 Name = (*RI)->getName();
117 if (!Name.empty())
118 break;
119 }
120 }
121 return Name;
122 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700123 case clang::Type::Pointer: {
124 // "*" plus pointee name
zonr6315f762010-10-05 15:35:14 +0800125 const clang::Type *PT = GET_POINTEE_TYPE(T);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700126 llvm::StringRef PointeeName;
127 if (NormalizeType(PT, PointeeName)) {
128 char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ];
129 Name[0] = '*';
130 memcpy(Name + 1, PointeeName.data(), PointeeName.size());
131 Name[PointeeName.size() + 1] = '\0';
132 return Name;
133 }
134 break;
135 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700136 case clang::Type::ExtVector: {
137 const clang::ExtVectorType *EVT =
138 UNSAFE_CAST_TYPE(clang::ExtVectorType, T);
139 return RSExportVectorType::GetTypeName(EVT);
140 break;
141 }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800142 case clang::Type::ConstantArray : {
143 // Construct name for a constant array is too complicated.
144 return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE;
145 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700146 default: {
147 break;
148 }
149 }
150
151 return llvm::StringRef();
152}
153
154const clang::Type *RSExportType::TypeExportable(
155 const clang::Type *T,
156 llvm::SmallPtrSet<const clang::Type*, 8>& SPS) {
157 // Normalize first
158 if ((T = GET_CANONICAL_TYPE(T)) == NULL)
159 return NULL;
160
161 if (SPS.count(T))
162 return T;
163
164 switch (T->getTypeClass()) {
165 case clang::Type::Builtin: {
166 const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T);
167
168 switch (BT->getKind()) {
169#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
170 case builtin_type:
171#include "slang_rs_export_type_support.inc"
172 {
173 return T;
174 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700175 default: {
176 return NULL;
177 }
178 }
179 // Never be here
180 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700181 case clang::Type::Record: {
182 if (RSExportPrimitiveType::GetRSObjectType(T) !=
183 RSExportPrimitiveType::DataTypeUnknown)
zonr6315f762010-10-05 15:35:14 +0800184 return T; // RS object type, no further checks are needed
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700185
186 // Check internal struct
187 const clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
188 if (RD != NULL)
189 RD = RD->getDefinition();
190
191 // Fast check
192 if (RD->hasFlexibleArrayMember() || RD->hasObjectMember())
193 return NULL;
194
195 // Insert myself into checking set
196 SPS.insert(T);
197
198 // Check all element
199 for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
200 FE = RD->field_end();
201 FI != FE;
202 FI++) {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800203 const clang::FieldDecl *FD = *FI;
204 const clang::Type *FT = GetTypeOfDecl(FD);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700205 FT = GET_CANONICAL_TYPE(FT);
206
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800207 if (!TypeExportable(FT, SPS)) {
208 fprintf(stderr, "Field `%s' in Record `%s' contains unsupported "
209 "type\n", FD->getNameAsString().c_str(),
210 RD->getNameAsString().c_str());
211 FT->dump();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700212 return NULL;
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800213 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700214 }
215
216 return T;
217 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700218 case clang::Type::Pointer: {
219 const clang::PointerType *PT = UNSAFE_CAST_TYPE(clang::PointerType, T);
220 const clang::Type *PointeeType = GET_POINTEE_TYPE(PT);
221
Zonr Chang2e1dba62010-10-05 22:20:11 +0800222 if (PointeeType->getTypeClass() == clang::Type::Pointer)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700223 return T;
Zonr Chang2e1dba62010-10-05 22:20:11 +0800224 // We don't support pointer with array-type pointee or unsupported pointee
225 // type
226 if (PointeeType->isArrayType() ||
227 (TypeExportable(PointeeType, SPS) == NULL) )
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700228 return NULL;
229 else
230 return T;
231 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700232 case clang::Type::ExtVector: {
233 const clang::ExtVectorType *EVT =
234 UNSAFE_CAST_TYPE(clang::ExtVectorType, T);
235 // Only vector with size 2, 3 and 4 are supported.
236 if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4)
237 return NULL;
238
239 // Check base element type
240 const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
241
242 if ((ElementType->getTypeClass() != clang::Type::Builtin) ||
243 (TypeExportable(ElementType, SPS) == NULL))
244 return NULL;
245 else
246 return T;
247 }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800248 case clang::Type::ConstantArray: {
249 const clang::ConstantArrayType *CAT =
250 UNSAFE_CAST_TYPE(clang::ConstantArrayType, T);
251
252 // Check size
253 if (CAT->getSize().getActiveBits() > 32) {
254 fprintf(stderr, "RSExportConstantArrayType::Create : array with too "
255 "large size (> 2^32).\n");
256 return NULL;
257 }
258 // Check element type
259 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
260 if (ElementType->isArrayType()) {
261 fprintf(stderr, "RSExportType::TypeExportable : constant array with 2 "
262 "or higher dimension of constant is not supported.\n");
263 return NULL;
264 }
265 if (TypeExportable(ElementType, SPS) == NULL)
266 return NULL;
267 else
268 return T;
269 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700270 default: {
271 return NULL;
272 }
273 }
274}
275
276RSExportType *RSExportType::Create(RSContext *Context,
277 const clang::Type *T,
278 const llvm::StringRef &TypeName) {
279 // Lookup the context to see whether the type was processed before.
280 // Newly created RSExportType will insert into context
281 // in RSExportType::RSExportType()
282 RSContext::export_type_iterator ETI = Context->findExportType(TypeName);
283
284 if (ETI != Context->export_types_end())
285 return ETI->second;
286
287 RSExportType *ET = NULL;
288 switch (T->getTypeClass()) {
289 case clang::Type::Record: {
290 RSExportPrimitiveType::DataType dt =
291 RSExportPrimitiveType::GetRSObjectType(TypeName);
292 switch (dt) {
Zonr Chang92b344a2010-10-05 20:39:03 +0800293 case RSExportPrimitiveType::DataTypeUnknown: {
294 // User-defined types
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700295 ET = RSExportRecordType::Create(Context,
296 T->getAsStructureType(),
297 TypeName);
298 break;
299 }
Zonr Chang92b344a2010-10-05 20:39:03 +0800300 case RSExportPrimitiveType::DataTypeRSMatrix2x2: {
301 // 2 x 2 Matrix type
302 ET = RSExportMatrixType::Create(Context,
303 T->getAsStructureType(),
304 TypeName,
305 2);
306 break;
307 }
308 case RSExportPrimitiveType::DataTypeRSMatrix3x3: {
309 // 3 x 3 Matrix type
310 ET = RSExportMatrixType::Create(Context,
311 T->getAsStructureType(),
312 TypeName,
313 3);
314 break;
315 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700316 case RSExportPrimitiveType::DataTypeRSMatrix4x4: {
Zonr Chang92b344a2010-10-05 20:39:03 +0800317 // 4 x 4 Matrix type
318 ET = RSExportMatrixType::Create(Context,
319 T->getAsStructureType(),
320 TypeName,
321 4);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700322 break;
323 }
324 default: {
Zonr Chang92b344a2010-10-05 20:39:03 +0800325 // Others are primitive types
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700326 ET = RSExportPrimitiveType::Create(Context, T, TypeName);
327 break;
328 }
329 }
330 break;
331 }
332 case clang::Type::Builtin: {
333 ET = RSExportPrimitiveType::Create(Context, T, TypeName);
334 break;
335 }
336 case clang::Type::Pointer: {
337 ET = RSExportPointerType::Create(Context,
338 UNSAFE_CAST_TYPE(clang::PointerType, T),
339 TypeName);
Zonr Chang92b344a2010-10-05 20:39:03 +0800340 // FIXME: free the name (allocated in RSExportType::GetTypeName)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700341 delete [] TypeName.data();
342 break;
343 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700344 case clang::Type::ExtVector: {
345 ET = RSExportVectorType::Create(Context,
346 UNSAFE_CAST_TYPE(clang::ExtVectorType, T),
347 TypeName);
348 break;
349 }
Zonr Chang2e1dba62010-10-05 22:20:11 +0800350 case clang::Type::ConstantArray: {
351 ET = RSExportConstantArrayType::Create(
352 Context,
353 UNSAFE_CAST_TYPE(clang::ConstantArrayType, T));
354 break;
355 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700356 default: {
zonr6315f762010-10-05 15:35:14 +0800357 // TODO(zonr): warn that type is not exportable.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700358 fprintf(stderr,
359 "RSExportType::Create : type '%s' is not exportable\n",
360 T->getTypeClassName());
361 break;
362 }
363 }
364
365 return ET;
366}
367
zonr6315f762010-10-05 15:35:14 +0800368RSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700369 llvm::StringRef TypeName;
370 if (NormalizeType(T, TypeName))
371 return Create(Context, T, TypeName);
372 else
Shih-wei Liaocecd11d2010-09-21 08:07:58 -0700373 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700374}
375
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700376RSExportType *RSExportType::CreateFromDecl(RSContext *Context,
377 const clang::VarDecl *VD) {
378 return RSExportType::Create(Context, GetTypeOfDecl(VD));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700379}
380
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700381size_t RSExportType::GetTypeStoreSize(const RSExportType *ET) {
382 return ET->getRSContext()->getTargetData()->getTypeStoreSize(
zonr6315f762010-10-05 15:35:14 +0800383 ET->getLLVMType());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700384}
385
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700386size_t RSExportType::GetTypeAllocSize(const RSExportType *ET) {
387 if (ET->getClass() == RSExportType::ExportClassRecord)
388 return static_cast<const RSExportRecordType*>(ET)->getAllocSize();
389 else
390 return ET->getRSContext()->getTargetData()->getTypeAllocSize(
zonr6315f762010-10-05 15:35:14 +0800391 ET->getLLVMType());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700392}
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700393
Zonr Chang6b6320a2010-10-05 22:42:01 +0800394RSExportType::RSExportType(RSContext *Context,
395 ExportClass Class,
396 const llvm::StringRef &Name)
zonr6315f762010-10-05 15:35:14 +0800397 : mContext(Context),
Zonr Chang6b6320a2010-10-05 22:42:01 +0800398 mClass(Class),
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800399 // Make a copy on Name since memory stored @Name is either allocated in
400 // ASTContext or allocated in GetTypeName which will be destroyed later.
zonr6315f762010-10-05 15:35:14 +0800401 mName(Name.data(), Name.size()),
402 mLLVMType(NULL) {
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800403 // Don't cache the type whose name start with '<'. Those type failed to
404 // get their name since constructing their name in GetTypeName() requiring
405 // complicated work.
406 if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX))
407 // TODO(zonr): Need to check whether the insertion is successful or not.
408 Context->insertExportType(llvm::StringRef(Name), this);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700409 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700410}
411
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700412/************************** RSExportPrimitiveType **************************/
413RSExportPrimitiveType::RSObjectTypeMapTy
414*RSExportPrimitiveType::RSObjectTypeMap = NULL;
415
zonr6315f762010-10-05 15:35:14 +0800416llvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700417
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700418bool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) {
419 if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin))
420 return true;
421 else
422 return false;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700423}
424
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700425RSExportPrimitiveType::DataType
426RSExportPrimitiveType::GetRSObjectType(const llvm::StringRef &TypeName) {
427 if (TypeName.empty())
428 return DataTypeUnknown;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700429
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700430 if (RSObjectTypeMap == NULL) {
431 RSObjectTypeMap = new RSObjectTypeMapTy(16);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700432
433#define USE_ELEMENT_DATA_TYPE
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700434#define DEF_RS_OBJECT_TYPE(type, name) \
435 RSObjectTypeMap->GetOrCreateValue(name, GET_ELEMENT_DATA_TYPE(type));
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700436#include "slang_rs_export_element_support.inc"
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700437 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700438
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700439 RSObjectTypeMapTy::const_iterator I = RSObjectTypeMap->find(TypeName);
440 if (I == RSObjectTypeMap->end())
441 return DataTypeUnknown;
442 else
443 return I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700444}
445
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700446RSExportPrimitiveType::DataType
447RSExportPrimitiveType::GetRSObjectType(const clang::Type *T) {
448 T = GET_CANONICAL_TYPE(T);
449 if ((T == NULL) || (T->getTypeClass() != clang::Type::Record))
450 return DataTypeUnknown;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700451
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700452 return GetRSObjectType( RSExportType::GetTypeName(T) );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700453}
454
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700455const size_t
456RSExportPrimitiveType::SizeOfDataTypeInBits[
457 RSExportPrimitiveType::DataTypeMax + 1] = {
zonr6315f762010-10-05 15:35:14 +0800458 16, // DataTypeFloat16
459 32, // DataTypeFloat32
460 64, // DataTypeFloat64
461 8, // DataTypeSigned8
462 16, // DataTypeSigned16
463 32, // DataTypeSigned32
464 64, // DataTypeSigned64
465 8, // DataTypeUnsigned8
466 16, // DataTypeUnsigned16
467 32, // DataTypeUnsigned32
468 64, // DataTypeUnSigned64
469 1, // DataTypeBoolean
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700470
zonr6315f762010-10-05 15:35:14 +0800471 16, // DataTypeUnsigned565
472 16, // DataTypeUnsigned5551
473 16, // DataTypeUnsigned4444
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700474
zonr6315f762010-10-05 15:35:14 +0800475 128, // DataTypeRSMatrix2x2
476 288, // DataTypeRSMatrix3x3
477 512, // DataTypeRSMatrix4x4
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700478
zonr6315f762010-10-05 15:35:14 +0800479 32, // DataTypeRSElement
480 32, // DataTypeRSType
481 32, // DataTypeRSAllocation
482 32, // DataTypeRSSampler
483 32, // DataTypeRSScript
484 32, // DataTypeRSMesh
485 32, // DataTypeRSProgramFragment
486 32, // DataTypeRSProgramVertex
487 32, // DataTypeRSProgramRaster
488 32, // DataTypeRSProgramStore
489 32, // DataTypeRSFont
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700490 0
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700491};
492
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700493size_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) {
494 assert(((EPT->getType() >= DataTypeFloat32) &&
495 (EPT->getType() < DataTypeMax)) &&
496 "RSExportPrimitiveType::GetSizeInBits : unknown data type");
497 return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ];
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700498}
499
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700500RSExportPrimitiveType::DataType
zonr6315f762010-10-05 15:35:14 +0800501RSExportPrimitiveType::GetDataType(const clang::Type *T) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700502 if (T == NULL)
503 return DataTypeUnknown;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700504
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700505 switch (T->getTypeClass()) {
506 case clang::Type::Builtin: {
507 const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T);
508 switch (BT->getKind()) {
509#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
510 case builtin_type: { \
511 return type; \
512 break; \
513 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700514#include "slang_rs_export_type_support.inc"
515
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700516 // The size of types Long, ULong and WChar depend on platform so we
517 // abandon the support to them. Type of its size exceeds 32 bits (e.g.
518 // int64_t, double, etc.): no support
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700519
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700520 default: {
zonr6315f762010-10-05 15:35:14 +0800521 // TODO(zonr): warn that the type is unsupported
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700522 fprintf(stderr, "RSExportPrimitiveType::GetDataType : built-in type "
523 "has no corresponding data type for built-in type");
524 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700525 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700526 }
527 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700528 }
529
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700530 case clang::Type::Record: {
531 // must be RS object type
532 return RSExportPrimitiveType::GetRSObjectType(T);
533 break;
534 }
535
536 default: {
537 fprintf(stderr, "RSExportPrimitiveType::GetDataType : type '%s' is not "
538 "supported primitive type", T->getTypeClassName());
539 break;
540 }
541 }
542
543 return DataTypeUnknown;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700544}
545
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700546RSExportPrimitiveType
547*RSExportPrimitiveType::Create(RSContext *Context,
548 const clang::Type *T,
549 const llvm::StringRef &TypeName,
550 DataKind DK,
551 bool Normalized) {
552 DataType DT = GetDataType(T);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700553
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700554 if ((DT == DataTypeUnknown) || TypeName.empty())
555 return NULL;
556 else
Zonr Chang6b6320a2010-10-05 22:42:01 +0800557 return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName,
558 DT, DK, Normalized);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700559}
560
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700561RSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context,
562 const clang::Type *T,
563 DataKind DK) {
564 llvm::StringRef TypeName;
565 if (RSExportType::NormalizeType(T, TypeName) && IsPrimitiveType(T))
566 return Create(Context, T, TypeName, DK);
567 else
568 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700569}
570
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700571const llvm::Type *RSExportPrimitiveType::convertToLLVMType() const {
572 llvm::LLVMContext &C = getRSContext()->getLLVMContext();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700573
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700574 if (isRSObjectType()) {
575 // struct {
576 // int *p;
577 // } __attribute__((packed, aligned(pointer_size)))
578 //
579 // which is
580 //
581 // <{ [1 x i32] }> in LLVM
582 //
583 if (RSObjectLLVMType == NULL) {
584 std::vector<const llvm::Type *> Elements;
zonr6315f762010-10-05 15:35:14 +0800585 Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700586 RSObjectLLVMType = llvm::StructType::get(C, Elements, true);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700587 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700588 return RSObjectLLVMType;
589 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700590
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700591 switch (mType) {
592 case DataTypeFloat32: {
593 return llvm::Type::getFloatTy(C);
594 break;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700595 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700596 case DataTypeFloat64: {
597 return llvm::Type::getDoubleTy(C);
598 break;
599 }
Shih-wei Liao91a37832010-10-03 19:11:51 -0700600 case DataTypeBoolean: {
601 return llvm::Type::getInt1Ty(C);
602 break;
603 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700604 case DataTypeSigned8:
605 case DataTypeUnsigned8: {
606 return llvm::Type::getInt8Ty(C);
607 break;
608 }
609 case DataTypeSigned16:
610 case DataTypeUnsigned16:
611 case DataTypeUnsigned565:
612 case DataTypeUnsigned5551:
613 case DataTypeUnsigned4444: {
614 return llvm::Type::getInt16Ty(C);
615 break;
616 }
617 case DataTypeSigned32:
618 case DataTypeUnsigned32: {
619 return llvm::Type::getInt32Ty(C);
620 break;
621 }
622 case DataTypeSigned64: {
623 // case DataTypeUnsigned64:
624 return llvm::Type::getInt64Ty(C);
625 break;
626 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700627 default: {
628 assert(false && "Unknown data type");
629 }
630 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700631
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700632 return NULL;
633}
634
635/**************************** RSExportPointerType ****************************/
636
637const clang::Type *RSExportPointerType::IntegerType = NULL;
638
639RSExportPointerType
640*RSExportPointerType::Create(RSContext *Context,
641 const clang::PointerType *PT,
642 const llvm::StringRef &TypeName) {
643 const clang::Type *PointeeType = GET_POINTEE_TYPE(PT);
644 const RSExportType *PointeeET;
645
646 if (PointeeType->getTypeClass() != clang::Type::Pointer) {
647 PointeeET = RSExportType::Create(Context, PointeeType);
648 } else {
649 // Double or higher dimension of pointer, export as int*
650 assert(IntegerType != NULL && "Built-in integer type is not set");
651 PointeeET = RSExportPrimitiveType::Create(Context, IntegerType);
652 }
653
654 if (PointeeET == NULL) {
655 fprintf(stderr, "Failed to create type for pointee");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700656 return NULL;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700657 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700658
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700659 return new RSExportPointerType(Context, TypeName, PointeeET);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700660}
661
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700662const llvm::Type *RSExportPointerType::convertToLLVMType() const {
663 const llvm::Type *PointeeType = mPointeeType->getLLVMType();
664 return llvm::PointerType::getUnqual(PointeeType);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700665}
666
zonr6315f762010-10-05 15:35:14 +0800667/***************************** RSExportVectorType *****************************/
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700668const char* RSExportVectorType::VectorTypeNameStore[][3] = {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700669 /* 0 */ { "char2", "char3", "char4" },
670 /* 1 */ { "uchar2", "uchar3", "uchar4" },
671 /* 2 */ { "short2", "short3", "short4" },
672 /* 3 */ { "ushort2", "ushort3", "ushort4" },
673 /* 4 */ { "int2", "int3", "int4" },
674 /* 5 */ { "uint2", "uint3", "uint4" },
675 /* 6 */ { "float2", "float3", "float4" },
676 /* 7 */ { "double2", "double3", "double4" },
677 /* 8 */ { "long2", "long3", "long4" },
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700678};
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700679
zonr6315f762010-10-05 15:35:14 +0800680llvm::StringRef
681RSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700682 const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700683
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700684 if ((ElementType->getTypeClass() != clang::Type::Builtin))
685 return llvm::StringRef();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700686
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700687 const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType,
688 ElementType);
689 const char **BaseElement = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700690
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700691 switch (BT->getKind()) {
692 // Compiler is smart enough to optimize following *big if branches* since
693 // they all become "constant comparison" after macro expansion
694#define SLANG_RS_SUPPORT_BUILTIN_TYPE(builtin_type, type) \
695 case builtin_type: { \
696 if (type == RSExportPrimitiveType::DataTypeSigned8) \
697 BaseElement = VectorTypeNameStore[0]; \
698 else if (type == RSExportPrimitiveType::DataTypeUnsigned8) \
699 BaseElement = VectorTypeNameStore[1]; \
700 else if (type == RSExportPrimitiveType::DataTypeSigned16) \
701 BaseElement = VectorTypeNameStore[2]; \
702 else if (type == RSExportPrimitiveType::DataTypeUnsigned16) \
703 BaseElement = VectorTypeNameStore[3]; \
704 else if (type == RSExportPrimitiveType::DataTypeSigned32) \
705 BaseElement = VectorTypeNameStore[4]; \
706 else if (type == RSExportPrimitiveType::DataTypeUnsigned32) \
707 BaseElement = VectorTypeNameStore[5]; \
708 else if (type == RSExportPrimitiveType::DataTypeFloat32) \
709 BaseElement = VectorTypeNameStore[6]; \
710 else if (type == RSExportPrimitiveType::DataTypeFloat64) \
711 BaseElement = VectorTypeNameStore[7]; \
712 else if (type == RSExportPrimitiveType::DataTypeSigned64) \
713 BaseElement = VectorTypeNameStore[8]; \
Shih-wei Liao91a37832010-10-03 19:11:51 -0700714 else if (type == RSExportPrimitiveType::DataTypeBoolean) \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700715 BaseElement = VectorTypeNameStore[0]; \
716 break; \
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700717 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700718#include "slang_rs_export_type_support.inc"
719 default: {
720 return llvm::StringRef();
721 }
722 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700723
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700724 if ((BaseElement != NULL) &&
725 (EVT->getNumElements() > 1) &&
726 (EVT->getNumElements() <= 4))
727 return BaseElement[EVT->getNumElements() - 2];
728 else
729 return llvm::StringRef();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700730}
731
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700732RSExportVectorType *RSExportVectorType::Create(RSContext *Context,
733 const clang::ExtVectorType *EVT,
734 const llvm::StringRef &TypeName,
735 DataKind DK,
736 bool Normalized) {
Zonr Chang92b344a2010-10-05 20:39:03 +0800737 assert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700738
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700739 const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT);
740 RSExportPrimitiveType::DataType DT =
741 RSExportPrimitiveType::GetDataType(ElementType);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700742
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700743 if (DT != RSExportPrimitiveType::DataTypeUnknown)
744 return new RSExportVectorType(Context,
745 TypeName,
746 DT,
747 DK,
748 Normalized,
749 EVT->getNumElements());
750 else
751 fprintf(stderr, "RSExportVectorType::Create : unsupported base element "
752 "type\n");
753 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700754}
755
zonr6315f762010-10-05 15:35:14 +0800756const llvm::Type *RSExportVectorType::convertToLLVMType() const {
757 const llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700758 return llvm::VectorType::get(ElementType, getNumElement());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700759}
760
Zonr Chang92b344a2010-10-05 20:39:03 +0800761/***************************** RSExportMatrixType *****************************/
762RSExportMatrixType *RSExportMatrixType::Create(RSContext *Context,
763 const clang::RecordType *RT,
764 const llvm::StringRef &TypeName,
765 unsigned Dim) {
766 assert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record));
767 assert((Dim > 1) && "Invalid dimension of matrix");
768
769 // Check whether the struct rs_matrix is in our expected form (but assume it's
770 // correct if we're not sure whether it's correct or not)
771 const clang::RecordDecl* RD = RT->getDecl();
772 RD = RD->getDefinition();
773 if (RD != NULL) {
774 // Find definition, perform further examination
775 if (RD->field_empty()) {
776 fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: "
777 "must have 1 field for saving values", TypeName.data());
778 return NULL;
779 }
780
781 clang::RecordDecl::field_iterator FIT = RD->field_begin();
782 const clang::FieldDecl *FD = *FIT;
783 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
784 if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) {
785 fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: "
786 "first field should be an array with constant size",
787 TypeName.data());
788 return NULL;
789 }
790 const clang::ConstantArrayType *CAT =
791 static_cast<const clang::ConstantArrayType *>(FT);
Zonr Chang2e1dba62010-10-05 22:20:11 +0800792 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
Zonr Chang92b344a2010-10-05 20:39:03 +0800793 if ((ElementType == NULL) ||
794 (ElementType->getTypeClass() != clang::Type::Builtin) ||
795 (static_cast<const clang::BuiltinType *>(ElementType)->getKind()
796 != clang::BuiltinType::Float)) {
797 fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: "
798 "first field should be a float array", TypeName.data());
799 return NULL;
800 }
801
802 if (CAT->getSize() != Dim * Dim) {
803 fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: "
804 "first field should be an array with size %d",
805 TypeName.data(), Dim * Dim);
806 return NULL;
807 }
808
809 FIT++;
810 if (FIT != RD->field_end()) {
811 fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: "
812 "must have exactly 1 field", TypeName.data());
813 return NULL;
814 }
815 }
816
817 return new RSExportMatrixType(Context, TypeName, Dim);
818}
819
Zonr Chang92b344a2010-10-05 20:39:03 +0800820const llvm::Type *RSExportMatrixType::convertToLLVMType() const {
821 // Construct LLVM type:
822 // struct {
823 // float X[mDim * mDim];
824 // }
825
826 llvm::LLVMContext &C = getRSContext()->getLLVMContext();
827 llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C),
828 mDim * mDim);
829 return llvm::StructType::get(C, X, NULL);
830}
831
Zonr Chang2e1dba62010-10-05 22:20:11 +0800832/************************* RSExportConstantArrayType *************************/
833RSExportConstantArrayType
834*RSExportConstantArrayType::Create(RSContext *Context,
835 const clang::ConstantArrayType *CAT) {
836 assert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray);
837
838 assert((CAT->getSize().getActiveBits() < 32) && "array too large");
839
840 unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue());
841 assert((Size > 0) && "Constant array should have size greater than 0");
842
843 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
844 RSExportType *ElementET = RSExportType::Create(Context, ElementType);
845
846 if (ElementET == NULL) {
847 fprintf(stderr, "RSExportConstantArrayType::Create : failed to create "
848 "RSExportType for array element.\n");
849 return NULL;
850 }
851
852 return new RSExportConstantArrayType(Context,
853 ElementET,
854 Size);
855}
856
Zonr Chang2e1dba62010-10-05 22:20:11 +0800857const llvm::Type *RSExportConstantArrayType::convertToLLVMType() const {
858 return llvm::ArrayType::get(mElementType->getLLVMType(), getSize());
859}
860
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700861/**************************** RSExportRecordType ****************************/
862RSExportRecordType *RSExportRecordType::Create(RSContext *Context,
863 const clang::RecordType *RT,
864 const llvm::StringRef &TypeName,
865 bool mIsArtificial) {
Zonr Chang92b344a2010-10-05 20:39:03 +0800866 assert(RT != NULL && RT->getTypeClass() == clang::Type::Record);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700867
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700868 const clang::RecordDecl *RD = RT->getDecl();
869 assert(RD->isStruct());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700870
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700871 RD = RD->getDefinition();
872 if (RD == NULL) {
zonr6315f762010-10-05 15:35:14 +0800873 // TODO(zonr): warn that actual struct definition isn't declared in this
874 // moudle.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700875 fprintf(stderr, "RSExportRecordType::Create : this struct is not defined "
876 "in this module.");
877 return NULL;
878 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700879
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800880 // Struct layout construct by clang. We rely on this for obtaining the
881 // alloc size of a struct and offset of every field in that struct.
882 const clang::ASTRecordLayout *RL =
883 &Context->getASTContext()->getASTRecordLayout(RD);
884 assert((RL != NULL) && "Failed to retrieve the struct layout from Clang.");
885
886 RSExportRecordType *ERT =
887 new RSExportRecordType(Context,
888 TypeName,
889 RD->hasAttr<clang::PackedAttr>(),
890 mIsArtificial,
891 (RL->getSize() >> 3));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700892 unsigned int Index = 0;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700893
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700894 for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
895 FE = RD->field_end();
896 FI != FE;
Shih-wei Liao91a37832010-10-03 19:11:51 -0700897 FI++, Index++) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700898#define FAILED_CREATE_FIELD(err) do { \
899 if (*err) \
900 fprintf(stderr, \
901 "RSExportRecordType::Create : failed to create field (%s)\n", \
902 err); \
903 delete ERT; \
904 return NULL; \
905 } while (false)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700906
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700907 // FIXME: All fields should be primitive type
908 assert((*FI)->getKind() == clang::Decl::Field);
909 clang::FieldDecl *FD = *FI;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700910
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700911 // We don't support bit field
912 //
zonr6315f762010-10-05 15:35:14 +0800913 // TODO(zonr): allow bitfield with size 8, 16, 32
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700914 if (FD->isBitField())
915 FAILED_CREATE_FIELD("bit field is not supported");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700916
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700917 // Type
zonr6315f762010-10-05 15:35:14 +0800918 RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700919
zonr6315f762010-10-05 15:35:14 +0800920 if (ET != NULL)
Zonr Chang0da0a7d2010-10-05 21:26:37 +0800921 ERT->mFields.push_back(
922 new Field(ET, FD->getName(), ERT,
923 static_cast<size_t>(RL->getFieldOffset(Index) >> 3)));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700924 else
925 FAILED_CREATE_FIELD(FD->getName().str().c_str());
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700926#undef FAILED_CREATE_FIELD
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700927 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700928
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700929 return ERT;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700930}
931
zonr6315f762010-10-05 15:35:14 +0800932const llvm::Type *RSExportRecordType::convertToLLVMType() const {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700933 std::vector<const llvm::Type*> FieldTypes;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700934
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700935 for (const_field_iterator FI = fields_begin(),
936 FE = fields_end();
937 FI != FE;
938 FI++) {
939 const Field *F = *FI;
940 const RSExportType *FET = F->getType();
Shih-wei Liao1f0d88f2010-06-25 00:15:24 -0700941
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700942 FieldTypes.push_back(FET->getLLVMType());
943 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700944
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700945 return llvm::StructType::get(getRSContext()->getLLVMContext(),
946 FieldTypes,
947 mIsPacked);
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700948}