slang_rs_export_type.cpp revision 474655a402e70cb329e1bcd4ebbe00bdc5be4206
1a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* 2a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Copyright 2010-2012, The Android Open Source Project 3a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 4a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 5a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * you may not use this file except in compliance with the License. 6a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * You may obtain a copy of the License at 7a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 8a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * http://www.apache.org/licenses/LICENSE-2.0 9a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 10a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * Unless required by applicable law or agreed to in writing, software 11a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * distributed under the License is distributed on an "AS IS" BASIS, 12a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * See the License for the specific language governing permissions and 14a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * limitations under the License. 15a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville */ 16a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 17a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "slang_rs_export_type.h" 18a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 19a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include <list> 20d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn#include <vector> 21a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 2208e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh#include "clang/AST/ASTContext.h" 23a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "clang/AST/Attr.h" 24a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "clang/AST/RecordLayout.h" 25a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 266bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius#include "llvm/ADT/StringExtras.h" 27a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "llvm/IR/DataLayout.h" 28a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "llvm/IR/DerivedTypes.h" 29a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "llvm/IR/Type.h" 30db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 316bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius#include "slang_assert.h" 32a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "slang_rs_context.h" 33a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "slang_rs_export_element.h" 34a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#include "slang_rs_type_spec.h" 352e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn#include "slang_version.h" 36eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh 37a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 38286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if (!ParentClass::equals(E)) \ 39286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn return false; 402999afbcfeab69bf7473e1b9bcabb1c9c6935b19Tyler Gunn 417fa8ac39602ee9841dfcb0fb5c5f4d401925f8b5Tyler Gunnnamespace slang { 42db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 43a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillenamespace { 44a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 45a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville/* For the data types we support, their category, names, and size (in bits). 46a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * 47a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * IMPORTANT: The data types in this table should be at the same index 48a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville * as specified by the corresponding DataType enum. 4921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar */ 5021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkarstatic RSReflectionType gReflectionTypes[] = { 51a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 52a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 53a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 54db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn {PrimitiveDataType, "SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 55db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn {PrimitiveDataType, "SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 56db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn {PrimitiveDataType, "SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 57a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 58a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 59a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 60a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 61a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 62a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 63a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 64a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 6521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar {PrimitiveDataType, "UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 66a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 67a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {PrimitiveDataType, "UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 68a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 69a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {MatrixDataType, "MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 70a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {MatrixDataType, "MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 71a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {MatrixDataType, "MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 72a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 73a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // TODO: For 64 bit, what will be the size of the objects?? 74a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 75a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 76a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 77a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 78a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 79a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 80a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 81a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 82a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 83a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 84a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 85fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn {ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 86fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn {ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 87fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn}; 886bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 896bb557b243f3fc9984b82319026519608ada2c9cRoshan Piusconst int kMaxVectorSize = 4; 906bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius 918bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajanstruct BuiltinInfo { 928bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan clang::BuiltinType::Kind builtinTypeKind; 932e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn RSExportPrimitiveType::DataType type; 94db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn /* TODO If we return std::string instead of llvm::StringRef, we could build 95db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn * the name instead of duplicating the entries. 96db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn */ 97db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn const char *cname[kMaxVectorSize]; 98db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn}; 99db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 100db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler GunnBuiltinInfo BuiltinInfoTable[] = { 101db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn {clang::BuiltinType::Bool, RSExportPrimitiveType::DataTypeBoolean, 102359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn {"bool", "bool2", "bool3", "bool4"}}, 103359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn {clang::BuiltinType::Char_U, RSExportPrimitiveType::DataTypeUnsigned8, 104222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C {"uchar", "uchar2", "uchar3", "uchar4"}}, 105222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C {clang::BuiltinType::UChar, RSExportPrimitiveType::DataTypeUnsigned8, 106fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu {"uchar", "uchar2", "uchar3", "uchar4"}}, 107fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu {clang::BuiltinType::Char16, RSExportPrimitiveType::DataTypeSigned16, 108fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu {"short", "short2", "short3", "short4"}}, 109286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn {clang::BuiltinType::Char32, RSExportPrimitiveType::DataTypeSigned32, 110286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn {"int", "int2", "int3", "int4"}}, 111286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn {clang::BuiltinType::UShort, RSExportPrimitiveType::DataTypeUnsigned16, 112286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn {"ushort", "ushort2", "ushort3", "ushort4"}}, 113286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn {clang::BuiltinType::UInt, RSExportPrimitiveType::DataTypeUnsigned32, 11463fa599fef0383b41f85e1fc3a38d33c4434e24aTyler Gunn {"uint", "uint2", "uint3", "uint4"}}, 1157a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {clang::BuiltinType::ULong, RSExportPrimitiveType::DataTypeUnsigned32, 1167a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {"uint", "uint2", "uint3", "uint4"}}, 1177a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {clang::BuiltinType::ULongLong, RSExportPrimitiveType::DataTypeUnsigned64, 1187a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {"ulong", "ulong2", "ulong3", "ulong4"}}, 1197a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn 1207a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {clang::BuiltinType::Char_S, RSExportPrimitiveType::DataTypeSigned8, 1217a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn {"char", "char2", "char3", "char4"}}, 122a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::SChar, RSExportPrimitiveType::DataTypeSigned8, 123a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"char", "char2", "char3", "char4"}}, 124a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::Short, RSExportPrimitiveType::DataTypeSigned16, 125a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"short", "short2", "short3", "short4"}}, 126a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::Int, RSExportPrimitiveType::DataTypeSigned32, 1276bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"int", "int2", "int3", "int4"}}, 128a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::Long, RSExportPrimitiveType::DataTypeSigned64, 129a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"long", "long2", "long3", "long4"}}, 130a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::LongLong, RSExportPrimitiveType::DataTypeSigned64, 131a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"long", "long2", "long3", "long4"}}, 132a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::Float, RSExportPrimitiveType::DataTypeFloat32, 133a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"float", "float2", "float3", "float4"}}, 134a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {clang::BuiltinType::Double, RSExportPrimitiveType::DataTypeFloat64, 135a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"double", "double2", "double3", "double4"}}, 136a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}; 137a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleconst int BuiltinInfoTableCount = sizeof(BuiltinInfoTable) / sizeof(BuiltinInfoTable[0]); 138a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 139a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillestruct NameAndPrimitiveType { 140a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const char *name; 141a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RSExportPrimitiveType::DataType dataType; 142a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}; 143a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 1446bb557b243f3fc9984b82319026519608ada2c9cRoshan Piusstatic NameAndPrimitiveType MatrixAndObjectDataTypes[] = { 145a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_matrix2x2", RSExportPrimitiveType::DataTypeRSMatrix2x2}, 146a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_matrix3x3", RSExportPrimitiveType::DataTypeRSMatrix3x3}, 147a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_matrix4x4", RSExportPrimitiveType::DataTypeRSMatrix4x4}, 148a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_element", RSExportPrimitiveType::DataTypeRSElement}, 149a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_type", RSExportPrimitiveType::DataTypeRSType}, 150a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_allocation", RSExportPrimitiveType::DataTypeRSAllocation}, 1516bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_sampler", RSExportPrimitiveType::DataTypeRSSampler}, 1526bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_script", RSExportPrimitiveType::DataTypeRSScript}, 1536bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_mesh", RSExportPrimitiveType::DataTypeRSMesh}, 1546bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_path", RSExportPrimitiveType::DataTypeRSPath}, 1556bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_program_fragment", RSExportPrimitiveType::DataTypeRSProgramFragment}, 1566bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius {"rs_program_vertex", RSExportPrimitiveType::DataTypeRSProgramVertex}, 157a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_program_raster", RSExportPrimitiveType::DataTypeRSProgramRaster}, 158a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_program_store", RSExportPrimitiveType::DataTypeRSProgramStore}, 159a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville {"rs_font", RSExportPrimitiveType::DataTypeRSFont}, 160a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville}; 161a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 162a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilleconst int MatrixAndObjectDataTypesCount = 163a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville sizeof(MatrixAndObjectDataTypes) / sizeof(MatrixAndObjectDataTypes[0]); 164f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu 16508e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganeshstatic const clang::Type *TypeExportableHelper( 166c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan const clang::Type *T, 1676bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 168a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slang::RSContext *Context, 169a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::VarDecl *VD, 170a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::RecordDecl *TopLevelRecord); 171a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 172a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savilletemplate <unsigned N> 173a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillestatic void ReportTypeError(slang::RSContext *Context, 174a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::NamedDecl *ND, 175a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::RecordDecl *TopLevelRecord, 176a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const char (&Message)[N], 177d325833e9248c05305b1edabb1d8efc827803f75Jing Zhao unsigned int TargetAPI = 0) { 178a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Attempt to use the type declaration first (if we have one). 179d325833e9248c05305b1edabb1d8efc827803f75Jing Zhao // Fall back to the variable definition, if we are looking at something 180a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // like an array declaration that can't be exported. 1816a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (TopLevelRecord) { 182a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError(TopLevelRecord->getLocation(), Message) 183a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville << TopLevelRecord->getName() << TargetAPI; 184a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (ND) { 185a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError(ND->getLocation(), Message) << ND->getName() 186a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville << TargetAPI; 18708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh } else { 188a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slangAssert(false && "Variables should be validated before exporting"); 189a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 190a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 191553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn 192553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunnstatic const clang::Type *ConstantArrayTypeExportableHelper( 193553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn const clang::ConstantArrayType *CAT, 194553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 195553db651cd5a51eedde0259d5a25e91700ef96c5Tyler Gunn slang::RSContext *Context, 196a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::VarDecl *VD, 19708e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh const clang::RecordDecl *TopLevelRecord) { 19808e9c4b483dac2cbf1b7fe4cbad22f003ff92bcbShriram Ganesh // Check element type 1996bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 2006bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius if (ElementType->isArrayType()) { 201c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu ReportTypeError(Context, VD, TopLevelRecord, 202c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu "multidimensional arrays cannot be exported: '%0'"); 203c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu return NULL; 204c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu } else if (ElementType->isExtVectorType()) { 205c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu const clang::ExtVectorType *EVT = 206a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville static_cast<const clang::ExtVectorType*>(ElementType); 207a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville unsigned numElements = EVT->getNumElements(); 208a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 209f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 2108bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 211c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan ReportTypeError(Context, VD, TopLevelRecord, 2126bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius "vectors of non-primitive types cannot be exported: '%0'"); 213a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 214a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 215a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 216a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (numElements == 3 && CAT->getSize() != 1) { 217a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ReportTypeError(Context, VD, TopLevelRecord, 218a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "arrays of width 3 vector types cannot be exported: '%0'"); 219a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 220a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 221a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 222a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 223a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (TypeExportableHelper(ElementType, SPS, Context, VD, 224a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TopLevelRecord) == NULL) { 225a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 226a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 227a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return CAT; 228a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 229a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 230a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 231a8467dd0c524787104b1ccdddc5e8af10ba729edWink SavilleBuiltinInfo *FindBuiltinType(clang::BuiltinType::Kind builtinTypeKind) { 232a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (int i = 0; i < BuiltinInfoTableCount; i++) { 2336bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius if (builtinTypeKind == BuiltinInfoTable[i].builtinTypeKind) { 2348bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan return &BuiltinInfoTable[i]; 2358bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan } 2366bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius } 237c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu return NULL; 238c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu} 239c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu 240c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wustatic const clang::Type *TypeExportableHelper( 241c6e763fa8aa1121f9c5aef16368115b06e31c6a2Jimmy Wu clang::Type const *T, 242a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 243a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slang::RSContext *Context, 244a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::VarDecl const *VD, 245a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::RecordDecl const *TopLevelRecord) { 246a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Normalize first 247a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if ((T = GET_CANONICAL_TYPE(T)) == NULL) 248a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 249a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 250a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (SPS.count(T)) 251a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return T; 25274c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi 25374c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi switch (T->getTypeClass()) { 25474c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi case clang::Type::Builtin: { 25574c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi const clang::BuiltinType *BT = 25674c8509aede6fe748904e75c156049b4f1ba5e28Hanada Masafumi UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 2577a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn return FindBuiltinType(BT->getKind()) == NULL ? NULL : T; 2587a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 259f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn case clang::Type::Record: { 2602e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn if (RSExportPrimitiveType::GetRSSpecificType(T) != 261f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn RSExportPrimitiveType::DataTypeUnknown) { 2627a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn return T; // RS object type, no further checks are needed 2637a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 2647a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn 2657a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn // Check internal struct 266f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if (T->isUnionType()) { 267f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(), 2682e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn "unions cannot be exported: '%0'"); 269f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return NULL; 270f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } else if (!T->isStructureType()) { 2712e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn slangAssert(false && "Unknown type cannot be exported"); 272f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return NULL; 273f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 274f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 275f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 276f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if (RD != NULL) { 277f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn RD = RD->getDefinition(); 2782e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn if (RD == NULL) { 279f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn ReportTypeError(Context, NULL, T->getAsStructureType()->getDecl(), 2802e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn "struct is not defined in this module"); 281f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return NULL; 282f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 283f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 2842e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn 285f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if (!TopLevelRecord) { 286f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn TopLevelRecord = RD; 2872e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn } 288f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if (RD->getName().empty()) { 289f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn ReportTypeError(Context, NULL, RD, 290f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn "anonymous structures cannot be exported"); 291f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return NULL; 292f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn } 293a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 294a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Fast check 295a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 296a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 297a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 298a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Insert myself into checking set 299a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville SPS.insert(T); 300a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 301a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Check all element 302a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 303a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FE = RD->field_end(); 304a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FI != FE; 305a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FI++) { 306a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::FieldDecl *FD = *FI; 307a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 308a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FT = GET_CANONICAL_TYPE(FT); 309a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 310a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) { 311a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 312a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 313a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 314a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // We don't support bit fields yet 315a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // 316a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 317a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (FD->isBitField()) { 318a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError( 319a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FD->getLocation(), 320a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "bit fields are not able to be exported: '%0.%1'") 321a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville << RD->getName() << FD->getName(); 322a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 323a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 324a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 325a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 326a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return T; 32733cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu } 32833cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu case clang::Type::Pointer: { 32933cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu if (TopLevelRecord) { 33033cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu ReportTypeError(Context, VD, TopLevelRecord, 33133cfb500a7cf192adfc5ca06792fe3847073b6c1Chao Liu "structures containing pointers cannot be exported: '%0'"); 332a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 333a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 334a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 335a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::PointerType *PT = 336a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::PointerType, T); 337a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 338a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 339a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (PointeeType->getTypeClass() == clang::Type::Pointer) { 340a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ReportTypeError(Context, VD, TopLevelRecord, 341a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "multiple levels of pointers cannot be exported: '%0'"); 342a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 343a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 344a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // We don't support pointer with array-type pointee or unsupported pointee 345a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // type 346a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (PointeeType->isArrayType() || 347a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville (TypeExportableHelper(PointeeType, SPS, Context, VD, 348a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TopLevelRecord) == NULL)) 349a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 350a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville else 351a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return T; 352a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 353a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::ExtVector: { 354a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::ExtVectorType *EVT = 355a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 356a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Only vector with size 2, 3 and 4 are supported. 357a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 358a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 359a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 360a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Check base element type 361a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 362a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 363a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if ((ElementType->getTypeClass() != clang::Type::Builtin) || 364a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville (TypeExportableHelper(ElementType, SPS, Context, VD, 365a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TopLevelRecord) == NULL)) 366a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 367a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville else 368a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return T; 369a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 370a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::ConstantArray: { 371a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::ConstantArrayType *CAT = 372a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 373a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 374a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ConstantArrayTypeExportableHelper(CAT, SPS, Context, VD, 375a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TopLevelRecord); 376a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 377a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::Enum: { 378a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // FIXME: We currently convert enums to integers, rather than reflecting 379a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // a more complete (and nicer type-safe Java version). 380a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return Context->getASTContext().IntTy.getTypePtr(); 381a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 382a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville default: { 383a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slangAssert(false && "Unknown type cannot be validated"); 384a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 385a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 386a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 387a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 388a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 389a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// Return the type that can be used to create RSExportType, will always return 390a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// the canonical type 391a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// If the Type T is not exportable, this function returns NULL. DiagEngine is 392a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// used to generate proper Clang diagnostic messages when a 393a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// non-exportable type is detected. TopLevelRecord is used to capture the 394a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// highest struct (in the case of a nested hierarchy) for detecting other 395a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// types that cannot be exported (mostly pointers within a struct). 396a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillestatic const clang::Type *TypeExportable(const clang::Type *T, 397a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slang::RSContext *Context, 398a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::VarDecl *VD) { 399a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::SmallPtrSet<const clang::Type*, 8> SPS = 400a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::SmallPtrSet<const clang::Type*, 8>(); 401a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 402a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return TypeExportableHelper(T, SPS, Context, VD, NULL); 403a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 404a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 405a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillestatic bool ValidateRSObjectInVarDecl(slang::RSContext *Context, 406a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::VarDecl *VD, bool InCompositeType, 407a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville unsigned int TargetAPI) { 408a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (TargetAPI < SLANG_JB_TARGET_API) { 409a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Only if we are already in a composite type (like an array or structure). 410a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (InCompositeType) { 411c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan // Only if we are actually exported (i.e. non-static). 412c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan if (VD->hasLinkage() && 413a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville (VD->getFormalLinkage() == clang::ExternalLinkage)) { 4141999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn // Only if we are not a pointer to an object. 4151999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 4161999b9772eb9b3a230bd2520ffebb152544eaba9Tyler Gunn if (T->getTypeClass() != clang::Type::Pointer) { 417a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ReportTypeError(Context, VD, NULL, 418a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "arrays/structures containing RS object types " 419a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "cannot be exported in target API < %1: '%0'", 420f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu SLANG_JB_TARGET_API); 421a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 422a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 423a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 424a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 425a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 426a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 427a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 428a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 429a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 430a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// Helper function for ValidateType(). We do a recursive descent on the 431a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// type hierarchy to ensure that we can properly export/handle the 432a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// declaration. 433a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// \return true if the variable declaration is valid, 434a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// false if it is invalid (along with proper diagnostics). 435a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// 436a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// C - ASTContext (for diagnostics + builtin types). 43734310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu// T - sub-type that we are validating. 43834310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu// ND - (optional) top-level named declaration that we are validating. 43934310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu// SPS - set of types we have already seen/validated. 44034310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu// InCompositeType - true if we are within an outer composite type. 441a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// UnionDecl - set if we are in a sub-type of a union. 442a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// TargetAPI - target SDK API level. 443a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville// IsFilterscript - whether or not we are compiling for Filterscript 444a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillestatic bool ValidateTypeHelper( 445a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slang::RSContext *Context, 446a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::ASTContext &C, 447a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *&T, 448a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::NamedDecl *ND, 449a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::SourceLocation Loc, 450a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 451a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville bool InCompositeType, 452a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::RecordDecl *UnionDecl, 453a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville unsigned int TargetAPI, 454a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville bool IsFilterscript) { 455a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if ((T = GET_CANONICAL_TYPE(T)) == NULL) 456a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 457a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 458a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (SPS.count(T)) 459a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 460a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 461a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville switch (T->getTypeClass()) { 462a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::Record: { 463a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RSExportPrimitiveType::IsRSObjectType(T)) { 464a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL); 465a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType, 466a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TargetAPI)) { 467a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 468a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 469a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 470a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 471a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RSExportPrimitiveType::GetRSSpecificType(T) != 472a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RSExportPrimitiveType::DataTypeUnknown) { 473a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!UnionDecl) { 474a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 475a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 476a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ReportTypeError(Context, NULL, UnionDecl, 477a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "unions containing RS object types are not allowed"); 478d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee return false; 479a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 480a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 481a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 482a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::RecordDecl *RD = NULL; 483a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 484a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Check internal struct 485a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (T->isUnionType()) { 486a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RD = T->getAsUnionType()->getDecl(); 487a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UnionDecl = RD; 488a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else if (T->isStructureType()) { 489a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RD = T->getAsStructureType()->getDecl(); 490a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 491a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville slangAssert(false && "Unknown type cannot be exported"); 492a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 493a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 494a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 495a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RD != NULL) { 496a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RD = RD->getDefinition(); 497a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RD == NULL) { 498a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // FIXME 499a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 500a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 501a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 502a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 503a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Fast check 504a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 505a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 506032d73c15281387a97cdb91c6f0c7c3a1b1b230eAmit Mahajan 507a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Insert myself into checking set 508a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville SPS.insert(T); 509a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 510a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Check all elements 511a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 512a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FE = RD->field_end(); 513a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FI != FE; 514a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FI++) { 515a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::FieldDecl *FD = *FI; 516a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 517a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville FT = GET_CANONICAL_TYPE(FT); 518a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 519a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (!ValidateTypeHelper(Context, C, FT, ND, Loc, SPS, true, UnionDecl, 520d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee TargetAPI, IsFilterscript)) { 521a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 522a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 523a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 524a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 525a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 526a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 527a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 528a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::Builtin: { 529a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (IsFilterscript) { 530a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville clang::QualType QT = T->getCanonicalTypeInternal(); 531a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (QT == C.DoubleTy || 532a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville QT == C.LongDoubleTy || 533a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville QT == C.LongTy || 534a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville QT == C.LongLongTy) { 535a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (ND) { 536a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError( 537a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Loc, 538a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "Builtin types > 32 bits in size are forbidden in " 539a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "Filterscript: '%0'") 540a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville << ND->getName(); 541a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 542a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError( 5434567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen Loc, 5444567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen "Builtin types > 32 bits in size are forbidden in " 5454567a0789e9966929c71af9a2c3866582c85c9e0Nancy Chen "Filterscript"); 54693c62c8a71821f46194e16ca3e84f95e101edb90Amit Mahajan } 547a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 548a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 549a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 550a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville break; 551a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 552a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 553a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::Pointer: { 554a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (IsFilterscript) { 555a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (ND) { 556a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError(Loc, 557a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "Pointers are forbidden in Filterscript: '%0'") 558a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville << ND->getName(); 559a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 560a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 561d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati // TODO(srhines): Find a better way to handle expressions (i.e. no 562d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati // NamedDecl) involving pointers in FS that should be allowed. 563a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // An example would be calls to library functions like 564a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // rsMatrixMultiply() that take rs_matrixNxN * types. 565a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 566a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 567a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 568a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::PointerType *PT = 569a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::PointerType, T); 570a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 571a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 572a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ValidateTypeHelper(Context, C, PointeeType, ND, Loc, SPS, 573a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville InCompositeType, UnionDecl, TargetAPI, 574a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville IsFilterscript); 575a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 576a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 577a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::ExtVector: { 578a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::ExtVectorType *EVT = 579a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 580a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 581a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (TargetAPI < SLANG_ICS_TARGET_API && 582a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville InCompositeType && 583a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville EVT->getNumElements() == 3 && 584a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ND && 585d9aa1a75304b1c04c352198b9269f40a2a059f74Andrew Lee ND->getFormalLinkage() == clang::ExternalLinkage) { 586a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville ReportTypeError(Context, ND, NULL, 587a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "structs containing vectors of dimension 3 cannot " 588a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "be exported at this API level: '%0'"); 589a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 590a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 591a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 592a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UnionDecl, TargetAPI, IsFilterscript); 593a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 594a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 595a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville case clang::Type::ConstantArray: { 596a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::ConstantArrayType *CAT = 597a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 598a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 599a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 60097fba207643a87dd718395010a98ded3e809a3d7Libin.Tang@motorola.com UnionDecl, TargetAPI, IsFilterscript); 601a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 60237800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan 60337800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan default: { 60437800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan break; 60537800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan } 60637800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan } 60737800d3cdb300fca83462d95221a05bbef21a951Amit Mahajan 608a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 609a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 610a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 611a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} // namespace 612c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan 6136bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius/****************************** RSExportType ******************************/ 6146bb557b243f3fc9984b82319026519608ada2c9cRoshan Piusbool RSExportType::NormalizeType(const clang::Type *&T, 6156bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius llvm::StringRef &TypeName, 6166bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius RSContext *Context, 6176bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius const clang::VarDecl *VD) { 6186bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius if ((T = TypeExportable(T, Context, VD)) == NULL) { 6196bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius return false; 6206bb557b243f3fc9984b82319026519608ada2c9cRoshan Pius } 621a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Get type name 622a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville TypeName = RSExportType::GetTypeName(T); 623a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (Context && TypeName.empty()) { 624a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (VD) { 625a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError(VD->getLocation(), 626a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville "anonymous types cannot be exported"); 627a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 628a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Context->ReportError("anonymous types cannot be exported"); 629a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 630a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return false; 631a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 632a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 633a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return true; 634a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville} 635a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 636a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillebool RSExportType::ValidateType(slang::RSContext *Context, clang::ASTContext &C, 63734310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu clang::QualType QT, clang::NamedDecl *ND, 638541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn clang::SourceLocation Loc, 639a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville unsigned int TargetAPI, bool IsFilterscript) { 640a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *T = QT.getTypePtr(); 641ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn llvm::SmallPtrSet<const clang::Type*, 8> SPS = 642ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn llvm::SmallPtrSet<const clang::Type*, 8>(); 643ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn 644ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, NULL, TargetAPI, 645ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn IsFilterscript); 646ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn return true; 647ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn} 648ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn 649c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajanbool RSExportType::ValidateVarDecl(slang::RSContext *Context, 65034310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu clang::VarDecl *VD, unsigned int TargetAPI, 65134310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu bool IsFilterscript) { 652ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn return ValidateType(Context, VD->getASTContext(), VD->getType(), VD, 653ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn VD->getLocation(), TargetAPI, IsFilterscript); 654c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan} 655c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan 656c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajanconst clang::Type 657c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 658c2b66d57e16623dffc2fe6d02ded4f24c014b6c8Amit Mahajan if (DD) { 65934310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu clang::QualType T = DD->getType(); 660a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 661a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (T.isNull()) 662a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 66334310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu else 664a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return T.getTypePtr(); 665a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 666a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville return NULL; 667f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu} 668a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 669a8467dd0c524787104b1ccdddc5e8af10ba729edWink Savillellvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 670a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville T = GET_CANONICAL_TYPE(T); 6716a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (T == NULL) 6726a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return llvm::StringRef(); 6736a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 6746a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee switch (T->getTypeClass()) { 675f9b150b221db15e88b97a0b9c0971ca3c71c0313fionaxu case clang::Type::Builtin: { 676a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::BuiltinType *BT = 677707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 678707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn BuiltinInfo *info = FindBuiltinType(BT->getKind()); 679707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn if (info != NULL) { 680707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn return info->cname[0]; 681707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn } 682707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn slangAssert(false && "Unknown data type of the builtin"); 683707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn break; 684707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn } 685707644d8250cc5c3c2287068a9df210d7eb3e863Tyler Gunn case clang::Type::Record: { 6866a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee clang::RecordDecl *RD; 687a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (T->isStructureType()) { 688a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RD = T->getAsStructureType()->getDecl(); 689a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } else { 6906a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee break; 691a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 692a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 693a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::StringRef Name = RD->getName(); 694a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (Name.empty()) { 695a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (RD->getTypedefNameForAnonDecl() != NULL) { 696a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville Name = RD->getTypedefNameForAnonDecl()->getName(); 697a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 698a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville 699a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville if (Name.empty()) { 700a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville // Try to find a name from redeclaration (i.e. typedef) 701a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 702a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville RE = RD->redecls_end(); 703549148fb25d8b38c2bd1207c1a21027c6621932bEtan Cohen RI != RE; 704eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh RI++) { 70521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar slangAssert(*RI != NULL && "cannot be NULL object"); 70621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 707ce67e30bf7a91a3ff63f86020c2d91c248c3a71bTyler Gunn Name = (*RI)->getName(); 70875f96a40e73bbf262287b64f7ba79f058adac472Brad Ebinger if (!Name.empty()) 709a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville break; 710a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 711a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 712a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville } 713222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C return Name; 714222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C } 715222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C case clang::Type::Pointer: { 716222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C // "*" plus pointee name 717222bd9d64068a23f5470561655ca4dbd2359eeceJayachandran C const clang::Type *PT = GET_POINTEE_TYPE(T); 718a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville llvm::StringRef PointeeName; 719d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn if (NormalizeType(PT, PointeeName, NULL, NULL)) { 720d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 721d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn Name[0] = '*'; 722d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 723d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn Name[PointeeName.size() + 1] = '\0'; 724d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn return Name; 725d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 726d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn break; 727d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 728d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn case clang::Type::ExtVector: { 729d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn const clang::ExtVectorType *EVT = 730d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 731d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn return RSExportVectorType::GetTypeName(EVT); 732d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn break; 733d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 734d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn case clang::Type::ConstantArray : { 735d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn // Construct name for a constant array is too complicated. 736d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 737d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn } 738d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn default: { 739d7f4ed8ac190763dce7e57b737caa44654b4592aTyler Gunn break; 740541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn } 741541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn } 742fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 743fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn return llvm::StringRef(); 744fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn} 745fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 746fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 747fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler GunnRSExportType *RSExportType::Create(RSContext *Context, 748fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn const clang::Type *T, 749fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn const llvm::StringRef &TypeName) { 750fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn // Lookup the context to see whether the type was processed before. 751fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn // Newly created RSExportType will insert into context 752fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn // in RSExportType::RSExportType() 753fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 754fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 755fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn if (ETI != Context->export_types_end()) 756fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn return ETI->second; 757fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn 758fd2305639e3761c2bf3213463c4f17cc8310f4d0Tyler Gunn RSExportType *ET = NULL; 759eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh switch (T->getTypeClass()) { 760eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh case clang::Type::Record: { 761eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh RSExportPrimitiveType::DataType dt = 762eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh RSExportPrimitiveType::GetRSSpecificType(TypeName); 763eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh switch (dt) { 764eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh case RSExportPrimitiveType::DataTypeUnknown: { 76527e0378194d55fdcb23f4a3a85dc620a234b5855Anju Mathapati // User-defined types 766eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh ET = RSExportRecordType::Create(Context, 767eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh T->getAsStructureType(), 768eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh TypeName); 769eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh break; 770eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 771eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 772eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn // 2 x 2 Matrix type 773eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn ET = RSExportMatrixType::Create(Context, 774eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn T->getAsStructureType(), 775eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn TypeName, 776eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh 2); 777eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh break; 778eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 779eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 780eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh // 3 x 3 Matrix type 781eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh ET = RSExportMatrixType::Create(Context, 782eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh T->getAsStructureType(), 783eb7465409290618ca5d7b5f8ba2ffabba2d936d9Tyler Gunn TypeName, 784c58281f18e760c39c2fedba61453eae7bfdda349Xinying.Deng 3); 785c58281f18e760c39c2fedba61453eae7bfdda349Xinying.Deng break; 786eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 787286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 788286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // 4 x 4 Matrix type 789286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn ET = RSExportMatrixType::Create(Context, 790286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn T->getAsStructureType(), 791286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn TypeName, 792286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 4); 793286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn break; 794286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 795286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn default: { 796286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // Others are primitive types 797286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn ET = RSExportPrimitiveType::Create(Context, T, TypeName); 798286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn break; 799286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 800286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 801286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn break; 802286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 803286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn case clang::Type::Builtin: { 804286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn ET = RSExportPrimitiveType::Create(Context, T, TypeName); 805286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn break; 806286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 807286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn case clang::Type::Pointer: { 808286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn ET = RSExportPointerType::Create(Context, 809286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 810286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn // FIXME: free the name (allocated in RSExportType::GetTypeName) 811286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn delete [] TypeName.data(); 812286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn break; 813286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn } 814286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn case clang::Type::ExtVector: { 815eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh ET = RSExportVectorType::Create(Context, 816eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 817eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh break; 818eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh } 819eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh case clang::Type::ConstantArray: { 820eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh ET = RSExportConstantArrayType::Create( 821eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh Context, 822eeeb1cb65e41778fa78abcaba93a9e4ebe351ec6Shriram Ganesh UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 8236a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee break; 8246a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 8256a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee default: { 8266a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee Context->ReportError("unknown type cannot be exported: '%0'") 8276a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee << T->getTypeClassName(); 8286a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee break; 829d9c3a08d5958e5ced0c0c9f7aabf376a5fe59bb2Anju Mathapati } 8306a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 8316a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 8326a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return ET; 8336a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee} 8346a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 8356a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew LeeRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 8366a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee llvm::StringRef TypeName; 837e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn if (NormalizeType(T, TypeName, Context, NULL)) { 838e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn return Create(Context, T, TypeName); 8396a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } else { 840e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn return NULL; 841288268d5528e0df03f348e303954813cb188c55bRekha Kumar } 842288268d5528e0df03f348e303954813cb188c55bRekha Kumar} 843288268d5528e0df03f348e303954813cb188c55bRekha Kumar 844e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler GunnRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 845288268d5528e0df03f348e303954813cb188c55bRekha Kumar const clang::VarDecl *VD) { 846db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return RSExportType::Create(Context, GetTypeOfDecl(VD)); 847db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 848db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 849db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnsize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 850db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return ET->getRSContext()->getDataLayout()->getTypeStoreSize( 851db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn ET->getLLVMType()); 852db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 853db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 854db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnsize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 855db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (ET->getClass() == RSExportType::ExportClassRecord) 856db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 857db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn else 858db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return ET->getRSContext()->getDataLayout()->getTypeAllocSize( 859db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn ET->getLLVMType()); 860db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 86144b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 862db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler GunnRSExportType::RSExportType(RSContext *Context, 863db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn ExportClass Class, 864db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn const llvm::StringRef &Name) 865db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn : RSExportable(Context, RSExportable::EX_TYPE), 866db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mClass(Class), 867db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Make a copy on Name since memory stored @Name is either allocated in 868db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // ASTContext or allocated in GetTypeName which will be destroyed later. 869db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mName(Name.data(), Name.size()), 870db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mLLVMType(NULL), 871db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn mSpecType(NULL) { 872db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // Don't cache the type whose name start with '<'. Those type failed to 873db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // get their name since constructing their name in GetTypeName() requiring 874db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // complicated work. 875e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 876e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn // TODO(zonr): Need to check whether the insertion is successful or not. 877e70972cf6a3b48df1f7d036877eb28529e606ca9Tyler Gunn Context->insertExportType(llvm::StringRef(Name), this); 878f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return; 879f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn} 880f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 8812e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunnbool RSExportType::keep() { 8822e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn if (!RSExportable::keep()) 8832e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn return false; 8842e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn // Invalidate converted LLVM type. 8852e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn mLLVMType = NULL; 8862e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn return true; 8872e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn} 8882e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn 8892e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunnbool RSExportType::equals(const RSExportable *E) const { 8902e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn CHECK_PARENT_EQUALITY(RSExportable, E); 8912e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 8922e7e09e79c04f34034bebea8f5d86606bb584577Tyler Gunn} 893f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 894f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler GunnRSExportType::~RSExportType() { 895f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn delete mSpecType; 8966a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee} 897f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 8986a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee/************************** RSExportPrimitiveType **************************/ 8996a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Leellvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 900f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler GunnRSExportPrimitiveType::RSSpecificTypeMap; 901f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn 902f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunnllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 903288268d5528e0df03f348e303954813cb188c55bRekha Kumar 904f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunnbool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 905f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 906f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return true; 907f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn else 908f83df11772fcf7f2aae0d9179b4d36eba92ad74eTyler Gunn return false; 909288268d5528e0df03f348e303954813cb188c55bRekha Kumar} 910288268d5528e0df03f348e303954813cb188c55bRekha Kumar 9116a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew LeeRSExportPrimitiveType::DataType 9126a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew LeeRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 9136a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (TypeName.empty()) 9146a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return DataTypeUnknown; 9156a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 9166a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (RSSpecificTypeMap->empty()) { 9176a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee for (int i = 0; i < MatrixAndObjectDataTypesCount; i++) { 9186a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee RSSpecificTypeMap->GetOrCreateValue(MatrixAndObjectDataTypes[i].name, 9196a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee MatrixAndObjectDataTypes[i].dataType); 9206a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9216a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 9226a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 9236a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 92444b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn if (I == RSSpecificTypeMap->end()) 92544b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn return DataTypeUnknown; 92644b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn else 92744b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn return I->getValue(); 92844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn} 92944b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 93044b58c8044c5fc0b271432429fc97707c4c773e1Tyler GunnRSExportPrimitiveType::DataType 931fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall LiuRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 932fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu T = GET_CANONICAL_TYPE(T); 933fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 934fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return DataTypeUnknown; 935fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 936fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return GetRSSpecificType( RSExportType::GetTypeName(T) ); 937fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu} 938fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 939fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liubool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 940fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (DT < 0 || DT >= DataTypeMax) { 941fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return false; 942fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 943fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return gReflectionTypes[DT].category == MatrixDataType; 944fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu} 945fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 946fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liubool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 947fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (DT < 0 || DT >= DataTypeMax) { 948fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return false; 949fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 950fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return gReflectionTypes[DT].category == ObjectDataType; 951fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu} 952fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 953fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liubool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 954fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu bool RSObjectTypeSeen = false; 955fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu while (T && T->isArrayType()) { 956fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu T = T->getArrayElementTypeNoTypeQual(); 957fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 958fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 959fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu const clang::RecordType *RT = T->getAsStructureType(); 960fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (!RT) { 961fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return false; 962fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 963fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 964fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu const clang::RecordDecl *RD = RT->getDecl(); 965fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (RD) { 966fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu RD = RD->getDefinition(); 967fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 968fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu if (!RD) { 969fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu return false; 970fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu } 971fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu 972fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 973fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu FE = RD->field_end(); 974fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu FI != FE; 975fa88fc1de20ddb819975d78c98e4c0d6b27e225aHall Liu FI++) { 9766a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee // We just look through all field declarations to see if we find a 9772e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn // declaration for an RS object type (or an array of one). 9782e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn const clang::FieldDecl *FD = *FI; 9792e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 9802e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn while (FT && FT->isArrayType()) { 9812e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn FT = FT->getArrayElementTypeNoTypeQual(); 9822e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn } 9832e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 984d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 985d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger if (IsRSObjectType(DT)) { 9862e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn // RS object types definitely need to be zero-initialized 987d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger RSObjectTypeSeen = true; 988d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger } else { 989d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger switch (DT) { 990d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger case RSExportPrimitiveType::DataTypeRSMatrix2x2: 991d0a85e9d7e52ecd5de9f7063361d9b01d2493627Brad Ebinger case RSExportPrimitiveType::DataTypeRSMatrix3x3: 9922e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn case RSExportPrimitiveType::DataTypeRSMatrix4x4: 9932e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn // Matrix types should get zero-initialized as well 9942e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn RSObjectTypeSeen = true; 9952e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn break; 9962e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn default: 9972e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn // Ignore all other primitive types 9982e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn break; 9992e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn } 10002e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn while (FT && FT->isArrayType()) { 100121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar FT = FT->getArrayElementTypeNoTypeQual(); 100221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 100321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (FT->isStructureType()) { 100421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar // Recursively handle structs of structs (even though these can't 100521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar // be exported, it is possible for a user to have them internally). 100621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 100721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 100821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 100921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 101021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 101121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return RSObjectTypeSeen; 101221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar} 101321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 101421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkarsize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 101521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar int type = EPT->getType(); 101621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar slangAssert((type > DataTypeUnknown && type < DataTypeMax) && 101721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 101821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return gReflectionTypes[type].size_in_bits; 101921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar} 10202e66c6325d321e41b8851da9a4596f7a745c7b1eTyler Gunn 10212e66c6325d321e41b8851da9a4596f7a745c7b1eTyler GunnRSExportPrimitiveType::DataType 102221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita SarkarRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 102321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (T == NULL) 102421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return DataTypeUnknown; 102521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 102621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar switch (T->getTypeClass()) { 102721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar case clang::Type::Builtin: { 102821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar const clang::BuiltinType *BT = 102921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 103021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar BuiltinInfo *info = FindBuiltinType(BT->getKind()); 103121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar if (info != NULL) { 103221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return info->type; 103321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 103421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar // The size of type WChar depend on platform so we abandon the support 103521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar // to them. 103621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar Context->ReportError("built-in type cannot be exported: '%0'") 103721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar << T->getTypeClassName(); 103821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar break; 103921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 104021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar case clang::Type::Record: { 104121048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar // must be RS object type 104221048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar return RSExportPrimitiveType::GetRSSpecificType(T); 104321048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 104421048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar default: { 104521048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar Context->ReportError("primitive type cannot be exported: '%0'") 104621048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar << T->getTypeClassName(); 104721048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar break; 104821048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 104921048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar } 105021048a2bc97d932a3ddecdfd79003a03f34263ecNivedita Sarkar 10516a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return DataTypeUnknown; 1052363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty} 1053363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty 1054363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj ShettyRSExportPrimitiveType 10556a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee*RSExportPrimitiveType::Create(RSContext *Context, 10566a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee const clang::Type *T, 10576a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee const llvm::StringRef &TypeName, 10586a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee bool Normalized) { 10596a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee DataType DT = GetDataType(Context, T); 10606a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 10616a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if ((DT == DataTypeUnknown) || TypeName.empty()) 10626a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return NULL; 10636a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee else 10646a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 10656a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee DT, Normalized); 10666a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee} 1067363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty 1068363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj ShettyRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 1069363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty const clang::Type *T) { 1070363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty llvm::StringRef TypeName; 1071363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty if (RSExportType::NormalizeType(T, TypeName, Context, NULL) 1072363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty && IsPrimitiveType(T)) { 1073363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty return Create(Context, T, TypeName); 1074363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty } else { 10756a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee return NULL; 10766a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee } 1077363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty} 1078363911ade99b8c798fd1c6ef545d253b8c35a001Dheeraj Shetty 10796a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Leellvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 10806a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 10816a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee 10826a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee if (isRSObjectType()) { 10836a0fa4105fa8104a09b33a3403df5ae2711e0083Andrew Lee // struct { 1084541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // int *p; 1085541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // } __attribute__((packed, aligned(pointer_size))) 1086541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // 1087541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // which is 1088541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // 1089541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // <{ [1 x i32] }> in LLVM 1090541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn // 1091541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn if (RSObjectLLVMType == NULL) { 1092541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn std::vector<llvm::Type *> Elements; 1093541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 10941a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 10951a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu } 10961a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu return RSObjectLLVMType; 109777a1f167b962ceaf7972d246f4c23e17772d1c69fionaxu } 10981a87ab3d7170d618f048c4f5af8c7504a587aaa5Jack Yu 109934310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu switch (mType) { 110034310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu case DataTypeFloat32: { 110134310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu return llvm::Type::getFloatTy(C); 110234310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu break; 110334310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu } 110434310e958f52099ce3a2e74a8e3c4f631a241529Hall Liu case DataTypeFloat64: { 1105541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn return llvm::Type::getDoubleTy(C); 1106541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn break; 1107541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn } 1108541accbd8e08fac77faa1c60d14533b1a5a36347Tyler Gunn case DataTypeBoolean: { 11098bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan return llvm::Type::getInt1Ty(C); 1110359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn break; 1111359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1112359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn case DataTypeSigned8: 1113359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn case DataTypeUnsigned8: { 1114359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return llvm::Type::getInt8Ty(C); 1115359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn break; 1116359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1117359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn case DataTypeSigned16: 1118359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn case DataTypeUnsigned16: 11198bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan case DataTypeUnsigned565: 11208bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan case DataTypeUnsigned5551: 11218bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan case DataTypeUnsigned4444: { 11228bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan return llvm::Type::getInt16Ty(C); 11238bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan break; 11248bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan } 11258bfa1b42f0ffebf33239546ceaf5d6f5ca813191Amit Mahajan case DataTypeSigned32: 1126db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn case DataTypeUnsigned32: { 1127db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return llvm::Type::getInt32Ty(C); 1128db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn break; 1129db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1130db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn case DataTypeSigned64: 1131db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn case DataTypeUnsigned64: { 1132db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return llvm::Type::getInt64Ty(C); 1133db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn break; 1134db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1135db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn default: { 1136db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn slangAssert(false && "Unknown data type"); 1137db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1138db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1139db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1140db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return NULL; 1141db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 1142db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1143db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnunion RSType *RSExportPrimitiveType::convertToSpecType() const { 1144db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn llvm::OwningPtr<union RSType> ST(new union RSType); 1145db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1146db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1147db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn // slang_rs_type_spec.h 1148db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1149db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return ST.take(); 1150db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 1151db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1152db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunnbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1153db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn CHECK_PARENT_EQUALITY(RSExportType, E); 1154db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1155db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 1156db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1157db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler GunnRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1158db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn if (DT > DataTypeUnknown && DT < DataTypeMax) { 1159db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return &gReflectionTypes[DT]; 1160db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } else { 1161db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn return NULL; 1162db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn } 1163db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn} 1164db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1165db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn/**************************** RSExportPointerType ****************************/ 1166db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn 1167db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler GunnRSExportPointerType 1168db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn*RSExportPointerType::Create(RSContext *Context, 1169db5b6a50186bc3fc8d42c50f4d23c91b05412ec6Tyler Gunn const clang::PointerType *PT, 1170359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn const llvm::StringRef &TypeName) { 1171359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 1172359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn const RSExportType *PointeeET; 1173359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1174359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (PointeeType->getTypeClass() != clang::Type::Pointer) { 1175359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn PointeeET = RSExportType::Create(Context, PointeeType); 1176359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } else { 1177359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn // Double or higher dimension of pointer, export as int* 1178359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn PointeeET = RSExportPrimitiveType::Create(Context, 1179359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn Context->getASTContext().IntTy.getTypePtr()); 1180359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1181359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1182359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (PointeeET == NULL) { 1183359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn // Error diagnostic is emitted for corresponding pointee type 1184359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return NULL; 1185359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn } 1186359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1187359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return new RSExportPointerType(Context, TypeName, PointeeET); 1188359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn} 1189359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1190359c182111879b821c0b7eba6d5fa52194293212Tyler Gunnllvm::Type *RSExportPointerType::convertToLLVMType() const { 1191359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn llvm::Type *PointeeType = mPointeeType->getLLVMType(); 1192359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return llvm::PointerType::getUnqual(PointeeType); 1193359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn} 1194359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1195359c182111879b821c0b7eba6d5fa52194293212Tyler Gunnunion RSType *RSExportPointerType::convertToSpecType() const { 1196359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn llvm::OwningPtr<union RSType> ST(new union RSType); 1197359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1198359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1199359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1200359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1201359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1202359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return ST.take(); 1203359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn else 1204359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return NULL; 1205359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn} 1206359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn 1207359c182111879b821c0b7eba6d5fa52194293212Tyler Gunnbool RSExportPointerType::keep() { 1208359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn if (!RSExportType::keep()) 1209359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return false; 1210359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn const_cast<RSExportType*>(mPointeeType)->keep(); 1211359c182111879b821c0b7eba6d5fa52194293212Tyler Gunn return true; 1212286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn} 1213286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 1214286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunnbool RSExportPointerType::equals(const RSExportable *E) const { 1215286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn CHECK_PARENT_EQUALITY(RSExportType, E); 1216286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn return (static_cast<const RSExportPointerType*>(E) 1217286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn ->getPointeeType()->equals(getPointeeType())); 1218286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn} 1219286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 1220286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn/***************************** RSExportVectorType *****************************/ 1221286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunnllvm::StringRef 1222286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler GunnRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 1223286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1224286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn llvm::StringRef name; 1225286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn 1226286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn if ((ElementType->getTypeClass() != clang::Type::Builtin)) 1227286e95aa9cd740c6d8e9fd32aeefeceaf0c81695Tyler Gunn return name; 122844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn 122944b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 123044b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn ElementType); 123144b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn if ((EVT->getNumElements() < 1) || 123244b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn (EVT->getNumElements() > 4)) 123344b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn return name; 12346dee0e40c77ac373820e7e266ff372a481e30befTyler Gunn 123544b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn BuiltinInfo *info = FindBuiltinType(BT->getKind()); 123644b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn if (info != NULL) { 123744b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn // Compiler is smart enough to optimize following *big if branches* since 123844b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn // they all become "constant comparison" after macro expansion 123944b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn int I = EVT->getNumElements() - 1; 124044b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn if (I < kMaxVectorSize) { 124144b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn name = info->cname[I]; 12426dee0e40c77ac373820e7e266ff372a481e30befTyler Gunn } else { 124344b58c8044c5fc0b271432429fc97707c4c773e1Tyler Gunn slangAssert(false && "Max vector is 4"); 12447a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 12457a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn } 12467a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn return name; 12477a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn} 12487a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn 12497a411d4797fb60914f5f6230bde24fc25b12f920Tyler GunnRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 12507a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn const clang::ExtVectorType *EVT, 12517a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn const llvm::StringRef &TypeName, 12527a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn bool Normalized) { 12537a411d4797fb60914f5f6230bde24fc25b12f920Tyler Gunn slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 125465cd15597c5e611184a3f4c8ead5f42644fc00d6Tyler Gunn 1255a8467dd0c524787104b1ccdddc5e8af10ba729edWink Saville const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1256 RSExportPrimitiveType::DataType DT = 1257 RSExportPrimitiveType::GetDataType(Context, ElementType); 1258 1259 if (DT != RSExportPrimitiveType::DataTypeUnknown) 1260 return new RSExportVectorType(Context, 1261 TypeName, 1262 DT, 1263 Normalized, 1264 EVT->getNumElements()); 1265 else 1266 return NULL; 1267} 1268 1269llvm::Type *RSExportVectorType::convertToLLVMType() const { 1270 llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 1271 return llvm::VectorType::get(ElementType, getNumElement()); 1272} 1273 1274union RSType *RSExportVectorType::convertToSpecType() const { 1275 llvm::OwningPtr<union RSType> ST(new union RSType); 1276 1277 RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1278 RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1279 RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1280 1281 return ST.take(); 1282} 1283 1284bool RSExportVectorType::equals(const RSExportable *E) const { 1285 CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1286 return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1287 == getNumElement()); 1288} 1289 1290/***************************** RSExportMatrixType *****************************/ 1291RSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 1292 const clang::RecordType *RT, 1293 const llvm::StringRef &TypeName, 1294 unsigned Dim) { 1295 slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 1296 slangAssert((Dim > 1) && "Invalid dimension of matrix"); 1297 1298 // Check whether the struct rs_matrix is in our expected form (but assume it's 1299 // correct if we're not sure whether it's correct or not) 1300 const clang::RecordDecl* RD = RT->getDecl(); 1301 RD = RD->getDefinition(); 1302 if (RD != NULL) { 1303 // Find definition, perform further examination 1304 if (RD->field_empty()) { 1305 Context->ReportError( 1306 RD->getLocation(), 1307 "invalid matrix struct: must have 1 field for saving values: '%0'") 1308 << RD->getName(); 1309 return NULL; 1310 } 1311 1312 clang::RecordDecl::field_iterator FIT = RD->field_begin(); 1313 const clang::FieldDecl *FD = *FIT; 1314 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1315 if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1316 Context->ReportError(RD->getLocation(), 1317 "invalid matrix struct: first field should" 1318 " be an array with constant size: '%0'") 1319 << RD->getName(); 1320 return NULL; 1321 } 1322 const clang::ConstantArrayType *CAT = 1323 static_cast<const clang::ConstantArrayType *>(FT); 1324 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 1325 if ((ElementType == NULL) || 1326 (ElementType->getTypeClass() != clang::Type::Builtin) || 1327 (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 1328 clang::BuiltinType::Float)) { 1329 Context->ReportError(RD->getLocation(), 1330 "invalid matrix struct: first field " 1331 "should be a float array: '%0'") 1332 << RD->getName(); 1333 return NULL; 1334 } 1335 1336 if (CAT->getSize() != Dim * Dim) { 1337 Context->ReportError(RD->getLocation(), 1338 "invalid matrix struct: first field " 1339 "should be an array with size %0: '%1'") 1340 << (Dim * Dim) << (RD->getName()); 1341 return NULL; 1342 } 1343 1344 FIT++; 1345 if (FIT != RD->field_end()) { 1346 Context->ReportError(RD->getLocation(), 1347 "invalid matrix struct: must have " 1348 "exactly 1 field: '%0'") 1349 << RD->getName(); 1350 return NULL; 1351 } 1352 } 1353 1354 return new RSExportMatrixType(Context, TypeName, Dim); 1355} 1356 1357llvm::Type *RSExportMatrixType::convertToLLVMType() const { 1358 // Construct LLVM type: 1359 // struct { 1360 // float X[mDim * mDim]; 1361 // } 1362 1363 llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 1364 llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 1365 mDim * mDim); 1366 return llvm::StructType::get(C, X, false); 1367} 1368 1369union RSType *RSExportMatrixType::convertToSpecType() const { 1370 llvm::OwningPtr<union RSType> ST(new union RSType); 1371 RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1372 switch (getDim()) { 1373 case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1374 case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1375 case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 1376 default: slangAssert(false && "Matrix type with unsupported dimension."); 1377 } 1378 return ST.take(); 1379} 1380 1381bool RSExportMatrixType::equals(const RSExportable *E) const { 1382 CHECK_PARENT_EQUALITY(RSExportType, E); 1383 return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1384} 1385 1386/************************* RSExportConstantArrayType *************************/ 1387RSExportConstantArrayType 1388*RSExportConstantArrayType::Create(RSContext *Context, 1389 const clang::ConstantArrayType *CAT) { 1390 slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 1391 1392 slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 1393 1394 unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 1395 slangAssert((Size > 0) && "Constant array should have size greater than 0"); 1396 1397 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 1398 RSExportType *ElementET = RSExportType::Create(Context, ElementType); 1399 1400 if (ElementET == NULL) { 1401 return NULL; 1402 } 1403 1404 return new RSExportConstantArrayType(Context, 1405 ElementET, 1406 Size); 1407} 1408 1409llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 1410 return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 1411} 1412 1413union RSType *RSExportConstantArrayType::convertToSpecType() const { 1414 llvm::OwningPtr<union RSType> ST(new union RSType); 1415 1416 RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1417 RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1418 ST, getElementType()->getSpecType()); 1419 RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1420 1421 if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1422 return ST.take(); 1423 else 1424 return NULL; 1425} 1426 1427bool RSExportConstantArrayType::keep() { 1428 if (!RSExportType::keep()) 1429 return false; 1430 const_cast<RSExportType*>(mElementType)->keep(); 1431 return true; 1432} 1433 1434bool RSExportConstantArrayType::equals(const RSExportable *E) const { 1435 CHECK_PARENT_EQUALITY(RSExportType, E); 1436 const RSExportConstantArrayType *RHS = 1437 static_cast<const RSExportConstantArrayType*>(E); 1438 return ((getSize() == RHS->getSize()) && 1439 (getElementType()->equals(RHS->getElementType()))); 1440} 1441 1442/**************************** RSExportRecordType ****************************/ 1443RSExportRecordType *RSExportRecordType::Create(RSContext *Context, 1444 const clang::RecordType *RT, 1445 const llvm::StringRef &TypeName, 1446 bool mIsArtificial) { 1447 slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1448 1449 const clang::RecordDecl *RD = RT->getDecl(); 1450 slangAssert(RD->isStruct()); 1451 1452 RD = RD->getDefinition(); 1453 if (RD == NULL) { 1454 slangAssert(false && "struct is not defined in this module"); 1455 return NULL; 1456 } 1457 1458 // Struct layout construct by clang. We rely on this for obtaining the 1459 // alloc size of a struct and offset of every field in that struct. 1460 const clang::ASTRecordLayout *RL = 1461 &Context->getASTContext().getASTRecordLayout(RD); 1462 slangAssert((RL != NULL) && 1463 "Failed to retrieve the struct layout from Clang."); 1464 1465 RSExportRecordType *ERT = 1466 new RSExportRecordType(Context, 1467 TypeName, 1468 RD->hasAttr<clang::PackedAttr>(), 1469 mIsArtificial, 1470 RL->getSize().getQuantity()); 1471 unsigned int Index = 0; 1472 1473 for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1474 FE = RD->field_end(); 1475 FI != FE; 1476 FI++, Index++) { 1477 1478 // FIXME: All fields should be primitive type 1479 slangAssert(FI->getKind() == clang::Decl::Field); 1480 clang::FieldDecl *FD = *FI; 1481 1482 if (FD->isBitField()) { 1483 return NULL; 1484 } 1485 1486 // Type 1487 RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 1488 1489 if (ET != NULL) { 1490 ERT->mFields.push_back( 1491 new Field(ET, FD->getName(), ERT, 1492 static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 1493 } else { 1494 Context->ReportError(RD->getLocation(), 1495 "field type cannot be exported: '%0.%1'") 1496 << RD->getName() << FD->getName(); 1497 return NULL; 1498 } 1499 } 1500 1501 return ERT; 1502} 1503 1504llvm::Type *RSExportRecordType::convertToLLVMType() const { 1505 // Create an opaque type since struct may reference itself recursively. 1506 1507 // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 1508 std::vector<llvm::Type*> FieldTypes; 1509 1510 for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1511 FI != FE; 1512 FI++) { 1513 const Field *F = *FI; 1514 const RSExportType *FET = F->getType(); 1515 1516 FieldTypes.push_back(FET->getLLVMType()); 1517 } 1518 1519 llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 1520 FieldTypes, 1521 mIsPacked); 1522 if (ST != NULL) { 1523 return ST; 1524 } else { 1525 return NULL; 1526 } 1527} 1528 1529union RSType *RSExportRecordType::convertToSpecType() const { 1530 unsigned NumFields = getFields().size(); 1531 unsigned AllocSize = sizeof(union RSType) + 1532 sizeof(struct RSRecordField) * NumFields; 1533 llvm::OwningPtr<union RSType> ST( 1534 reinterpret_cast<union RSType*>(operator new(AllocSize))); 1535 1536 ::memset(ST.get(), 0, AllocSize); 1537 1538 RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1539 RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1540 RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1541 1542 setSpecTypeTemporarily(ST.get()); 1543 1544 unsigned FieldIdx = 0; 1545 for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1546 FI != FE; 1547 FI++, FieldIdx++) { 1548 const Field *F = *FI; 1549 1550 RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1551 RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1552 } 1553 1554 // TODO(slang): Check whether all fields were created normally. 1555 1556 return ST.take(); 1557} 1558 1559bool RSExportRecordType::keep() { 1560 if (!RSExportType::keep()) 1561 return false; 1562 for (std::list<const Field*>::iterator I = mFields.begin(), 1563 E = mFields.end(); 1564 I != E; 1565 I++) { 1566 const_cast<RSExportType*>((*I)->getType())->keep(); 1567 } 1568 return true; 1569} 1570 1571bool RSExportRecordType::equals(const RSExportable *E) const { 1572 CHECK_PARENT_EQUALITY(RSExportType, E); 1573 1574 const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1575 1576 if (ERT->getFields().size() != getFields().size()) 1577 return false; 1578 1579 const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1580 1581 for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1582 if (!(*AI)->getType()->equals((*BI)->getType())) 1583 return false; 1584 AI++; 1585 BI++; 1586 } 1587 1588 return true; 1589} 1590 1591void RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 1592 memset(rtd, 0, sizeof(*rtd)); 1593 rtd->vecSize = 1; 1594 1595 switch(getClass()) { 1596 case RSExportType::ExportClassPrimitive: { 1597 const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 1598 rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 1599 return; 1600 } 1601 case RSExportType::ExportClassPointer: { 1602 const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 1603 const RSExportType *PointeeType = EPT->getPointeeType(); 1604 PointeeType->convertToRTD(rtd); 1605 rtd->isPointer = true; 1606 return; 1607 } 1608 case RSExportType::ExportClassVector: { 1609 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 1610 rtd->type = EVT->getRSReflectionType(EVT); 1611 rtd->vecSize = EVT->getNumElement(); 1612 return; 1613 } 1614 case RSExportType::ExportClassMatrix: { 1615 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 1616 unsigned Dim = EMT->getDim(); 1617 slangAssert((Dim >= 2) && (Dim <= 4)); 1618 rtd->type = &gReflectionTypes[15 + Dim-2]; 1619 return; 1620 } 1621 case RSExportType::ExportClassConstantArray: { 1622 const RSExportConstantArrayType* CAT = 1623 static_cast<const RSExportConstantArrayType*>(this); 1624 CAT->getElementType()->convertToRTD(rtd); 1625 rtd->arraySize = CAT->getSize(); 1626 return; 1627 } 1628 case RSExportType::ExportClassRecord: { 1629 slangAssert(!"RSExportType::ExportClassRecord not implemented"); 1630 return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 1631 } 1632 default: { 1633 slangAssert(false && "Unknown class of type"); 1634 } 1635 } 1636} 1637 1638 1639} // namespace slang 1640