Rewrite the RSExportConstantArrayType to better support reflecting
constant-sized array variable.
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index a0b94e3..e0f678c 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -133,18 +133,16 @@
}
break;
}
- case clang::Type::ConstantArray: {
- const clang::ConstantArrayType *ECT =
- UNSAFE_CAST_TYPE(clang::ConstantArrayType, T);
- return RSExportConstantArrayType::GetTypeName(ECT);
- break;
- }
case clang::Type::ExtVector: {
const clang::ExtVectorType *EVT =
UNSAFE_CAST_TYPE(clang::ExtVectorType, T);
return RSExportVectorType::GetTypeName(EVT);
break;
}
+ case clang::Type::ConstantArray : {
+ // Construct name for a constant array is too complicated.
+ return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE;
+ }
default: {
break;
}
@@ -221,27 +219,12 @@
const clang::PointerType *PT = UNSAFE_CAST_TYPE(clang::PointerType, T);
const clang::Type *PointeeType = GET_POINTEE_TYPE(PT);
- if ((PointeeType->getTypeClass() != clang::Type::Pointer) &&
- (TypeExportable(PointeeType, SPS) == NULL) )
- return NULL;
- else
+ if (PointeeType->getTypeClass() == clang::Type::Pointer)
return T;
- }
-
- case clang::Type::ConstantArray: {
- const clang::ConstantArrayType *ECT =
- UNSAFE_CAST_TYPE(clang::ConstantArrayType, T);
- // No longer only support 2x2, 3x3 and 4x4 arrays
- // if (ECT->getNumElements() != 4 &&
- // ECT->getNumElements() != 9 &&
- // ECT->getNumElements() != 16)
- // return NULL;
-
- // Check base element type
- const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(ECT);
-
- if ((ElementType->getTypeClass() != clang::Type::Builtin) ||
- (TypeExportable(ElementType, SPS) == NULL))
+ // We don't support pointer with array-type pointee or unsupported pointee
+ // type
+ if (PointeeType->isArrayType() ||
+ (TypeExportable(PointeeType, SPS) == NULL) )
return NULL;
else
return T;
@@ -262,6 +245,28 @@
else
return T;
}
+ case clang::Type::ConstantArray: {
+ const clang::ConstantArrayType *CAT =
+ UNSAFE_CAST_TYPE(clang::ConstantArrayType, T);
+
+ // Check size
+ if (CAT->getSize().getActiveBits() > 32) {
+ fprintf(stderr, "RSExportConstantArrayType::Create : array with too "
+ "large size (> 2^32).\n");
+ return NULL;
+ }
+ // Check element type
+ const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
+ if (ElementType->isArrayType()) {
+ fprintf(stderr, "RSExportType::TypeExportable : constant array with 2 "
+ "or higher dimension of constant is not supported.\n");
+ return NULL;
+ }
+ if (TypeExportable(ElementType, SPS) == NULL)
+ return NULL;
+ else
+ return T;
+ }
default: {
return NULL;
}
@@ -336,19 +341,18 @@
delete [] TypeName.data();
break;
}
- case clang::Type::ConstantArray: {
- ET = RSExportConstantArrayType::Create(
- Context,
- UNSAFE_CAST_TYPE(clang::ConstantArrayType, T),
- TypeName);
- break;
- }
case clang::Type::ExtVector: {
ET = RSExportVectorType::Create(Context,
UNSAFE_CAST_TYPE(clang::ExtVectorType, T),
TypeName);
break;
}
+ case clang::Type::ConstantArray: {
+ ET = RSExportConstantArrayType::Create(
+ Context,
+ UNSAFE_CAST_TYPE(clang::ConstantArrayType, T));
+ break;
+ }
default: {
// TODO(zonr): warn that type is not exportable.
fprintf(stderr,
@@ -664,104 +668,6 @@
return llvm::PointerType::getUnqual(PointeeType);
}
-/************************* RSExportConstantArrayType *************************/
-llvm::StringRef
-RSExportConstantArrayType::GetTypeName(const clang::ConstantArrayType *CT) {
- llvm::APInt i = CT->getSize();
- if (i == 4) {
- return llvm::StringRef("rs_matrix2x2");
- } else if (i == 9) {
- return llvm::StringRef("rs_matrix3x3");
- } else if (i == 16) {
- return llvm::StringRef("rs_matrix4x4");
- }
- return llvm::StringRef();
-}
-
-RSExportConstantArrayType
-*RSExportConstantArrayType::Create(RSContext *Context,
- const clang::ConstantArrayType *CT,
- const llvm::StringRef &TypeName,
- DataKind DK,
- bool Normalized) {
- assert(CT != NULL && CT->getTypeClass() == clang::Type::ConstantArray);
-
- int64_t Size = CT->getSize().getSExtValue();
- RSExportPrimitiveType::DataType DT;
- if (Size == 4) {
- DT = RSExportPrimitiveType::DataTypeRSMatrix2x2;
- } else if (Size == 9) {
- DT = RSExportPrimitiveType::DataTypeRSMatrix3x3;
- } else if (Size == 16) {
- DT = RSExportPrimitiveType::DataTypeRSMatrix4x4;
- } else {
- fprintf(stderr, "RSExportConstantArrayType::Create : unsupported base "
- "element type\n");
- return NULL;
- }
-
- return new RSExportConstantArrayType(Context,
- TypeName,
- DT,
- DK,
- Normalized,
- Size);
-}
-
-RSExportType::ExportClass RSExportConstantArrayType::getClass() const {
- return RSExportType::ExportClassConstantArray;
-}
-
-const llvm::Type *RSExportConstantArrayType::convertToLLVMType() const {
- llvm::LLVMContext &C = getRSContext()->getLLVMContext();
- const llvm::Type *typ;
- switch (getType()) {
- case DataTypeFloat32:
- case DataTypeRSMatrix2x2:
- case DataTypeRSMatrix3x3:
- case DataTypeRSMatrix4x4: {
- typ = llvm::Type::getFloatTy(C);
- break;
- }
- case DataTypeFloat64: {
- typ = llvm::Type::getDoubleTy(C);
- break;
- }
- case DataTypeBoolean: {
- typ = llvm::Type::getInt1Ty(C);
- break;
- }
- case DataTypeSigned8:
- case DataTypeUnsigned8: {
- typ = llvm::Type::getInt8Ty(C);
- break;
- }
- case DataTypeSigned16:
- case DataTypeUnsigned16:
- case DataTypeUnsigned565:
- case DataTypeUnsigned5551:
- case DataTypeUnsigned4444: {
- typ = llvm::Type::getInt16Ty(C);
- break;
- }
- case DataTypeSigned32:
- case DataTypeUnsigned32: {
- typ = llvm::Type::getInt32Ty(C);
- break;
- }
- case DataTypeSigned64: {
- //case DataTypeUnsigned64:
- typ = llvm::Type::getInt64Ty(C);
- break;
- }
- default: {
- assert(false && "Unknown data type");
- break;
- }
- }
- return llvm::ArrayType::get(typ, mNumElement);
-}
-
/***************************** RSExportVectorType *****************************/
const char* RSExportVectorType::VectorTypeNameStore[][3] = {
/* 0 */ { "char2", "char3", "char4" },
@@ -891,8 +797,7 @@
}
const clang::ConstantArrayType *CAT =
static_cast<const clang::ConstantArrayType *>(FT);
- const clang::Type *ElementType =
- GET_CANONICAL_TYPE(CAT->getElementType().getTypePtr());
+ const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
if ((ElementType == NULL) ||
(ElementType->getTypeClass() != clang::Type::Builtin) ||
(static_cast<const clang::BuiltinType *>(ElementType)->getKind()
@@ -936,6 +841,39 @@
return llvm::StructType::get(C, X, NULL);
}
+/************************* RSExportConstantArrayType *************************/
+RSExportConstantArrayType
+*RSExportConstantArrayType::Create(RSContext *Context,
+ const clang::ConstantArrayType *CAT) {
+ assert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray);
+
+ assert((CAT->getSize().getActiveBits() < 32) && "array too large");
+
+ unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue());
+ assert((Size > 0) && "Constant array should have size greater than 0");
+
+ const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT);
+ RSExportType *ElementET = RSExportType::Create(Context, ElementType);
+
+ if (ElementET == NULL) {
+ fprintf(stderr, "RSExportConstantArrayType::Create : failed to create "
+ "RSExportType for array element.\n");
+ return NULL;
+ }
+
+ return new RSExportConstantArrayType(Context,
+ ElementET,
+ Size);
+}
+
+RSExportType::ExportClass RSExportConstantArrayType::getClass() const {
+ return RSExportType::ExportClassConstantArray;
+}
+
+const llvm::Type *RSExportConstantArrayType::convertToLLVMType() const {
+ return llvm::ArrayType::get(mElementType->getLLVMType(), getSize());
+}
+
/**************************** RSExportRecordType ****************************/
RSExportRecordType *RSExportRecordType::Create(RSContext *Context,
const clang::RecordType *RT,