slang_rs_export_type.cpp revision 474655a402e70cb329e1bcd4ebbe00bdc5be4206
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <vector> 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h" 2323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/AST/Attr.h" 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/RecordLayout.h" 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 2723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DataLayout.h" 2823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DerivedTypes.h" 2923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Type.h" 300a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 34a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 35d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines#include "slang_version.h" 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 37641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 40641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 43e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 45474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet/* For the data types we support, their category, names, and size (in bits). 46474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * 47474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * IMPORTANT: The data types in this table should be at the same index 48474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * as specified by the corresponding DataType enum. 49474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 50fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 51474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 52474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 53474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 54474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 55474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 56474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 57474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 58474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 59474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 60474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 61474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 62474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 63474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 64474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 65474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 66474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 67474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 68474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 69474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {MatrixDataType, "MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 70474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {MatrixDataType, "MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 71474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {MatrixDataType, "MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 72474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 73474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // TODO: For 64 bit, what will be the size of the objects?? 74474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 75474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 76474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 77474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 78474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 79474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 80474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 81474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 82474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 83474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 84474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 85474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 86474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 87474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 88474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 89474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int kMaxVectorSize = 4; 90474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 91474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct BuiltinInfo { 92474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet clang::BuiltinType::Kind builtinTypeKind; 93474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSExportPrimitiveType::DataType type; 94474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet /* TODO If we return std::string instead of llvm::StringRef, we could build 95474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * the name instead of duplicating the entries. 96474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 97474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *cname[kMaxVectorSize]; 98474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 99474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 100474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo BuiltinInfoTable[] = { 101474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Bool, RSExportPrimitiveType::DataTypeBoolean, 102474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"bool", "bool2", "bool3", "bool4"}}, 103474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Char_U, RSExportPrimitiveType::DataTypeUnsigned8, 104474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 105474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::UChar, RSExportPrimitiveType::DataTypeUnsigned8, 106474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 107474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Char16, RSExportPrimitiveType::DataTypeSigned16, 108474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 109474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Char32, RSExportPrimitiveType::DataTypeSigned32, 110474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 111474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::UShort, RSExportPrimitiveType::DataTypeUnsigned16, 112474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ushort", "ushort2", "ushort3", "ushort4"}}, 113474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::UInt, RSExportPrimitiveType::DataTypeUnsigned32, 114474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uint", "uint2", "uint3", "uint4"}}, 115474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::ULong, RSExportPrimitiveType::DataTypeUnsigned32, 116474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uint", "uint2", "uint3", "uint4"}}, 117474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::ULongLong, RSExportPrimitiveType::DataTypeUnsigned64, 118474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ulong", "ulong2", "ulong3", "ulong4"}}, 119474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 120474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Char_S, RSExportPrimitiveType::DataTypeSigned8, 121474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 122474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::SChar, RSExportPrimitiveType::DataTypeSigned8, 123474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 124474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Short, RSExportPrimitiveType::DataTypeSigned16, 125474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 126474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Int, RSExportPrimitiveType::DataTypeSigned32, 127474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 128474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Long, RSExportPrimitiveType::DataTypeSigned64, 129474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 130474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::LongLong, RSExportPrimitiveType::DataTypeSigned64, 131474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 132474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Float, RSExportPrimitiveType::DataTypeFloat32, 133474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"float", "float2", "float3", "float4"}}, 134474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {clang::BuiltinType::Double, RSExportPrimitiveType::DataTypeFloat64, 135474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"double", "double2", "double3", "double4"}}, 136474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 137474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int BuiltinInfoTableCount = sizeof(BuiltinInfoTable) / sizeof(BuiltinInfoTable[0]); 138474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 139474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct NameAndPrimitiveType { 140474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *name; 141474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSExportPrimitiveType::DataType dataType; 142474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 143474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 144474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstatic NameAndPrimitiveType MatrixAndObjectDataTypes[] = { 145474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_matrix2x2", RSExportPrimitiveType::DataTypeRSMatrix2x2}, 146474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_matrix3x3", RSExportPrimitiveType::DataTypeRSMatrix3x3}, 147474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_matrix4x4", RSExportPrimitiveType::DataTypeRSMatrix4x4}, 148474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_element", RSExportPrimitiveType::DataTypeRSElement}, 149474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_type", RSExportPrimitiveType::DataTypeRSType}, 150474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_allocation", RSExportPrimitiveType::DataTypeRSAllocation}, 151474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_sampler", RSExportPrimitiveType::DataTypeRSSampler}, 152474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_script", RSExportPrimitiveType::DataTypeRSScript}, 153474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_mesh", RSExportPrimitiveType::DataTypeRSMesh}, 154474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_path", RSExportPrimitiveType::DataTypeRSPath}, 155474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_program_fragment", RSExportPrimitiveType::DataTypeRSProgramFragment}, 156474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_program_vertex", RSExportPrimitiveType::DataTypeRSProgramVertex}, 157474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_program_raster", RSExportPrimitiveType::DataTypeRSProgramRaster}, 158474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_program_store", RSExportPrimitiveType::DataTypeRSProgramStore}, 159474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"rs_font", RSExportPrimitiveType::DataTypeRSFont}, 160fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 161fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 162474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int MatrixAndObjectDataTypesCount = 163474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet sizeof(MatrixAndObjectDataTypes) / sizeof(MatrixAndObjectDataTypes[0]); 164474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 16524e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 16624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 16724e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 16848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 16924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1705bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 17124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 172ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murraytemplate <unsigned N> 173d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic void ReportTypeError(slang::RSContext *Context, 17411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::NamedDecl *ND, 17524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 176ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray const char (&Message)[N], 177d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 17824e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 17924e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 18024e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 18124e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 182d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(TopLevelRecord->getLocation(), Message) 183d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TopLevelRecord->getName() << TargetAPI; 18411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (ND) { 185d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(ND->getLocation(), Message) << ND->getName() 186d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TargetAPI; 18724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 1886e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 18924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 19024e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 19124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 19224e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 19324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 19424e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 19548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 19624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1975bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 19824e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 19924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 20024e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 201d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2029207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 20324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 20424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 20524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 20624e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 20724e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 20824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 20924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 21024e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 211d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2129207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 21324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 21424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 21524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 21624e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 217d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2189207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 21924e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 22024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 22124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 22224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 22348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (TypeExportableHelper(ElementType, SPS, Context, VD, 224d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TopLevelRecord) == NULL) { 22524e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 226d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 22724e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 228d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 22924e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 23024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 231474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo *FindBuiltinType(clang::BuiltinType::Kind builtinTypeKind) { 232474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < BuiltinInfoTableCount; i++) { 233474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (builtinTypeKind == BuiltinInfoTable[i].builtinTypeKind) { 234474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return &BuiltinInfoTable[i]; 235474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 236474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 237474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return NULL; 238474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet} 239474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 24024e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 241e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 242e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 24348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 244e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 2455bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2521f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 255be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 256be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 257474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return FindBuiltinType(BT->getKind()) == NULL ? NULL : T; 2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 260b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 261d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines RSExportPrimitiveType::DataTypeUnknown) { 2626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 263d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 266cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 267d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(), 2689207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 269cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 270cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 2716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 272cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 273cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 274cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 27524e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 2762ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 2782ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 279d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, T->getAsStructureType()->getDecl(), 2809207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 2812ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2822ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 284f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 285e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 286e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 287e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 288e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 289d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, RD, 2909207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 291e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 292e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 293e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 297f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 300f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 307e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) { 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 3142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 3152ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 3162ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 3172ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 318d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 319d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet FD->getLocation(), 320d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "bit fields are not able to be exported: '%0.%1'") 321d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 3222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 3232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 325462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 329e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 330d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 331aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "structures containing pointers cannot be exported: '%0'"); 332c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 333c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 33424e79f69125cf87fcaa78c04510a831037203eebStephen Hines 335be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 336be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 339aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines if (PointeeType->getTypeClass() == clang::Type::Pointer) { 340d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 341aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "multiple levels of pointers cannot be exported: '%0'"); 342aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines return NULL; 343aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines } 3442e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 3452e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 3462e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 34748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(PointeeType, SPS, Context, VD, 3485bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 355be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 359f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 36448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(ElementType, SPS, Context, VD, 3655bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3702e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 3712e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 372be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 3732e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 37448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Context, VD, 3755bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord); 3762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 37748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines case clang::Type::Enum: { 37848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // FIXME: We currently convert enums to integers, rather than reflecting 37948d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // a more complete (and nicer type-safe Java version). 38048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return Context->getASTContext().IntTy.getTypePtr(); 38148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } 3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 38348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slangAssert(false && "Unknown type cannot be validated"); 3849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 385462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 3869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 388462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 389e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 390e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 3919207a2e495c8363606861e4f034504ec5c153dabLogan Chien// If the Type T is not exportable, this function returns NULL. DiagEngine is 39278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// used to generate proper Clang diagnostic messages when a 393e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 394e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 395e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 396e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 39748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 3985bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 399e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 400e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 401e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 40248d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return TypeExportableHelper(T, SPS, Context, VD, NULL); 40378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 40478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 405d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic bool ValidateRSObjectInVarDecl(slang::RSContext *Context, 406d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, bool InCompositeType, 407d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 408d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 409d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 410d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 411d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 41244f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->hasLinkage() && 41344f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines (VD->getFormalLinkage() == clang::ExternalLinkage)) { 414d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 415d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 416d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 417d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, NULL, 418d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 419d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 420d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 421d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 422d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 423d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 424d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 425d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 426d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 427d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 428d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 429d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 43011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// Helper function for ValidateType(). We do a recursive descent on the 431d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 432d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 433d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 434d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 435d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 43611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// C - ASTContext (for diagnostics + builtin types). 43711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// T - sub-type that we are validating. 43811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// ND - (optional) top-level named declaration that we are validating. 439d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 440d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 441d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 442d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 44311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// IsFilterscript - whether or not we are compiling for Filterscript 44411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesstatic bool ValidateTypeHelper( 445d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet slang::RSContext *Context, 44611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::ASTContext &C, 44778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 44811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, 44911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::SourceLocation Loc, 45078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 451d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 452d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 45311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines unsigned int TargetAPI, 45411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 45578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = GET_CANONICAL_TYPE(T)) == NULL) 45678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 45778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 45878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 45978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 46078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 46178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 46278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 463d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 46411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL); 465d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType, 466d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet TargetAPI)) { 467d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 468d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 469d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 470d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 47178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportPrimitiveType::GetRSSpecificType(T) != 47278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RSExportPrimitiveType::DataTypeUnknown) { 47378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 47478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 47578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 476d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, UnionDecl, 47778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 47878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 47978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 48078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 48178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 48278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *RD = NULL; 48378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 48478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 48578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 48678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 48778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 48878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 48978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 49078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 49178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 49278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 49378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 49478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 49578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD != NULL) { 49678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 49778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD == NULL) { 49878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 49978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 50078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 50478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 50578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 50678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 50878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 50978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 51078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 51178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 51278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 51378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 51478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 51578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 51678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 51778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FT = GET_CANONICAL_TYPE(FT); 51878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 519d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!ValidateTypeHelper(Context, C, FT, ND, Loc, SPS, true, UnionDecl, 52011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript)) { 52178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 52278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 52678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 52911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 53011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::QualType QT = T->getCanonicalTypeInternal(); 53111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (QT == C.DoubleTy || 53211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongDoubleTy || 53311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongTy || 53411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongLongTy) { 53511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 536d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 537d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 53811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 539d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript: '%0'") 540d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 54111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 542d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 543d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 54411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 545d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript"); 54611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 54711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 54811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 54911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 55078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 55178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 55278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 55378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 55411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 55511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 556d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(Loc, 557d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Pointers are forbidden in Filterscript: '%0'") 558d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 55911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 56011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 56111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // TODO(srhines): Find a better way to handle expressions (i.e. no 56211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // NamedDecl) involving pointers in FS that should be allowed. 56311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // An example would be calls to library functions like 56411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // rsMatrixMultiply() that take rs_matrixNxN * types. 56511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 56878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::PointerType *PT = 56978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T); 57078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 57178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 572d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, PointeeType, ND, Loc, SPS, 573d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet InCompositeType, UnionDecl, TargetAPI, 574d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet IsFilterscript); 57578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 57678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 57778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 57878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 57978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 58078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 581b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines if (TargetAPI < SLANG_ICS_TARGET_API && 582b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines InCompositeType && 583fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines EVT->getNumElements() == 3 && 584fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND && 58544f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines ND->getFormalLinkage() == clang::ExternalLinkage) { 586d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, ND, NULL, 587b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "structs containing vectors of dimension 3 cannot " 588b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "be exported at this API level: '%0'"); 589b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines return false; 590b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines } 591d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 592d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet UnionDecl, TargetAPI, IsFilterscript); 59378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 59478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 59578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 59678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ConstantArrayType *CAT = 59778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 59878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 599d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 600d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet UnionDecl, TargetAPI, IsFilterscript); 60178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 60278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 60378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 60478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 60578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 60678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 60778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 60878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 609e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 610e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 611e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 612e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 613e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 614e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 615e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 61648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines RSContext *Context, 6175bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 61848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if ((T = TypeExportable(T, Context, VD)) == NULL) { 619e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 620e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 621e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 622e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 62348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (Context && TypeName.empty()) { 62448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (VD) { 625d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(VD->getLocation(), 626d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "anonymous types cannot be exported"); 62748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } else { 628d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("anonymous types cannot be exported"); 629e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 630e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 631e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 632e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 633e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 634e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 635e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 636d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateType(slang::RSContext *Context, clang::ASTContext &C, 637d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::QualType QT, clang::NamedDecl *ND, 638d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::SourceLocation Loc, 639d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet unsigned int TargetAPI, bool IsFilterscript) { 64011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::Type *T = QT.getTypePtr(); 64178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 64278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 64378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 644d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, NULL, TargetAPI, 64511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines IsFilterscript); 64611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return true; 64711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 64811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 649d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateVarDecl(slang::RSContext *Context, 650d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, unsigned int TargetAPI, 65111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 652d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateType(Context, VD->getASTContext(), VD->getType(), VD, 65311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VD->getLocation(), TargetAPI, IsFilterscript); 65478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 65578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 656e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 657e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 658e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 6598de1922e037612f2521acac2f4c4289a9f71450dStephen Hines clang::QualType T = DD->getType(); 660e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 661e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 662e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 663e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 664e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 665e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 666e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 667e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 668e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 669e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 670e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 671e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 672e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 673e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 674e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 675e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 676be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 677be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 678474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 679474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (info != NULL) { 680474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->cname[0]; 681e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 682474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Unknown data type of the builtin"); 683e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 684e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 685e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 686cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 687cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 688cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 689dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 690cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 691cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 692cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 693e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 694e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 69583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (RD->getTypedefNameForAnonDecl() != NULL) { 69683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 69783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 69883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 69983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 70083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 70183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 70283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 70383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 70483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 70583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao slangAssert(*RI != NULL && "cannot be NULL object"); 70683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 70783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 70883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 70983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 71083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 71183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 712e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 713e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 714e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 715e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 716e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 717e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 718e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 7195bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL)) { 720e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 721e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 722e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 723e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 724e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 725e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 726e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 727e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 728e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 729e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 730be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 731e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 732e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 733e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 734e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 735e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 736e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 737e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 738e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 739e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 740e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 741e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 742e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 743e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 744e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 745e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 746e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 7479ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 7489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 7499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 7509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 7519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 7529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 7539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 7549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 7569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 7579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 7599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 7619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 762b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 7639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 76492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 76592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 7669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 7679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 7689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 7699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 77192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 77292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 77392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 77492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 77592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 77692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 77792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 77892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 77992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 78092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 78192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 78292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 78392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 78492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 78592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 78692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 7879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 78892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 78992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 79092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 79192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 79292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 7939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 79692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 7979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 7989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 8059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 8095baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 81092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 8119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 8129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 8159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 8165baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 8179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8192e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 8202e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 8212e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 822be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 8232e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 8242e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 826d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("unknown type cannot be exported: '%0'") 827d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << T->getTypeClassName(); 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 833462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 8341f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 8356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 8369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 83748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (NormalizeType(T, TypeName, Context, NULL)) { 8389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 839d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 8409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 841d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 842462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 843462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 847462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 848462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 85023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines return ET->getRSContext()->getDataLayout()->getTypeStoreSize( 8516315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 852462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 853462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 8559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 85823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines return ET->getRSContext()->getDataLayout()->getTypeAllocSize( 8596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 860462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 861462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8626b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 8636b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 8646b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 865a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 8666b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 8670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 8680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 8696315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 870a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 871a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 8720da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 8730da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 8740da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 8750da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 8760da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 8770da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 8789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 879462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 880462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8813cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 8823cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 8833cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 884641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 885641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 8863cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 887641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 888641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 889641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 890641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 891641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 892641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 893641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 894a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 895a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 896a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 897a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 899b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 900b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 9019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 903462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 9059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 9069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 9079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 909462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 910462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9119ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 912b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 9149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 915462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 916b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 917474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < MatrixAndObjectDataTypesCount; i++) { 918474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSSpecificTypeMap->GetOrCreateValue(MatrixAndObjectDataTypes[i].name, 919474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet MatrixAndObjectDataTypes[i].dataType); 920474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 9219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 922462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 923b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 924b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 9259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 9289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 9299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9309ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 931b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 9329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 9339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 9349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 936b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 937b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 938b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 939b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 940474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 941474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 942474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 943474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == MatrixDataType; 944b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 945b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 946b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 947474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 948474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 949474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 950474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == ObjectDataType; 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 9529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 953feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 954feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 955feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 956feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 957feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 958feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 959feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 960feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 961feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 962feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 963b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 964feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 965b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (RD) { 966b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines RD = RD->getDefinition(); 967b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 968b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (!RD) { 969b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines return false; 970b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 971b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 972feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 973feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 974feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 975feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 976feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 977feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 978feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 979feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 980feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 981feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 982feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 983feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 984feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 985feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 986feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 987feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 988feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 989feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 990feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 991feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 992feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 993feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 994feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 995feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 996feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 997feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 998feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 999feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1000feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 1001feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 1002feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1003feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 1004feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 1005feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 1006feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 1007feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1008feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1009feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1010feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 1011feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 1012feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 1013feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 10149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 1015474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int type = EPT->getType(); 1016474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert((type > DataTypeUnknown && type < DataTypeMax) && 10176e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 1018474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[type].size_in_bits; 1019462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1020462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10219ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 10222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 10239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 10249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1025462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 10279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 1028be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 1029be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 1030474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 1031474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (info != NULL) { 1032474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->type; 10339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1034474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // The size of type WChar depend on platform so we abandon the support 1035474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // to them. 1036474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet Context->ReportError("built-in type cannot be exported: '%0'") 1037474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet << T->getTypeClassName(); 10389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 10419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 1042b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 10439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1045d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("primitive type cannot be exported: '%0'") 10462ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1048462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1050462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1052462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1053462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10549ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 10559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 10569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 10579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 10592ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 1060462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 10629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 10639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 10646b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 10652b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 1066462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1067462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 10692b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 10709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 107148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context, NULL) 107278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 10732b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 1074e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 10759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1076e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 1077462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1078462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10797c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 10819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 10839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 10849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 10859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 10869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 10889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 10909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 10927c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type *> Elements; 10936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1094a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 1095462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 10979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1098462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 11009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 11019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 11029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 11059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 11069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 110891a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 110991a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 111091a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 111191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 11129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 11139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 11149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 11159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 11189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 11199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 11209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 11219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 11229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 11239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 11269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 11279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 11289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1130a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1131a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 11329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 11339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1141462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1142462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1143a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 1144a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1145a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1146a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1147a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1148a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1149a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1150a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1151a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1152641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1153641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1154641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1155641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1156641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1157fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1158fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1159fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1160fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 1161fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return NULL; 1162fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1163fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1164fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 11659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11679ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 11689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 11699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 11709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 11719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 11729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 11759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 11769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 11779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 11782ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 11792ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 11809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 11832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 11849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 11859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11907c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 11917c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 11929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1195a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 1196a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1197a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1198a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1199a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1200a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1201a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1202a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1203a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1204a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1205a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1206a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 12073cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 12083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1210641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 12113cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1212641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1213641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1214641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1215641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1216641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1217641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1218641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1219641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 12216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 12226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 12239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1224474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet llvm::StringRef name; 1225462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 1227474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1229be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 12309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1233474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1235474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 1236474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (info != NULL) { 12379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 12389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1239474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int I = EVT->getNumElements() - 1; 1240474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (I < kMaxVectorSize) { 1241474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet name = info->cname[I]; 1242474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 1243474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Max vector is 4"); 1244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 12459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1246474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 1247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12499ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 12509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 12519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 12536e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 12569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 12572ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 12609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 12619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 12629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 12639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 12649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 12659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 12662ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1267462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12697c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 12707c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 12719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1274a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1275a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1276a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1277a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1278a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1279a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1280a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1281a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1282a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1283a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1284641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1285641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1286641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1287641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1288641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1289641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 129092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 129192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 129292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 129392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 129492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 12956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 12966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 129792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 129892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 129992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 130092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 130192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 130292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 130392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 130492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 1305d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 1306d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet RD->getLocation(), 1307d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have 1 field for saving values: '%0'") 1308d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 130992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 131092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 131192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 131292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 131392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 131492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 131592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1316d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1317d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field should" 1318d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet " be an array with constant size: '%0'") 1319d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 132092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 132192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 132292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 132392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 13242e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 132592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 132692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 13279207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 13289207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 1329d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1330d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1331d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be a float array: '%0'") 1332d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 133392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 133492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 133592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 133692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 1337d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1338d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1339d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be an array with size %0: '%1'") 1340d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << (Dim * Dim) << (RD->getName()); 134192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 134292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 134392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 134492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 134592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 1346d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1347d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have " 1348d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "exactly 1 field: '%0'") 1349d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 135092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 135192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 135292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 135392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 135492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 135592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 135692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 13577c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 135892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 135992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 136092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 136192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 136292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 136392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 136492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 136592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1366a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 136792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 136892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1369a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1370a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1371a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1372a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1373a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1374a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1375a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 13766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1377a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1378a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1379a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1380a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1381641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1382641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1383641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1384641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1385641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 13872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 13882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 13892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 13906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 13912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 13932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 13956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 13962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 13982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 13992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 14012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 14022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 14032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 14052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 14062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 14072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 14082e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14097c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 14102e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 14112e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 14122e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1413a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1414a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1415a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1416a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1417a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1418a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1419a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1420a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1421a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1422a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1423a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1424a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1425a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1426a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 14273cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 14283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1430641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 14313cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1432641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1433641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1434641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1435641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1436a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1437a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1438a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1439a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1440641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1441641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 14429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 14439ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 14449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 14459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 14469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 14476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1448462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 14506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1451462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 14539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 14546e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 14559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 14569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1457462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14580da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 14590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 14600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 14619e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1462f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1463f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 14640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 14650da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 14660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 14670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 14680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 14690da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 147068318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 14719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 14729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 14749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 14759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 147691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 14779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 147943730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao slangAssert(FI->getKind() == clang::Decl::Field); 14809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 14819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14822ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 14832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 14876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 14889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14892ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 14900da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 14910da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 14920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 14932ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 1494d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1495d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "field type cannot be exported: '%0.%1'") 1496d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 14972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 15000a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 15019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1502462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1503462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15047c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 15053cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 15063cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 15077c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 15087c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1509462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 15119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 15129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 15139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 15149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 15151f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 15169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 15179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1518462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15193cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 15203cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 15213cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 15227c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao if (ST != NULL) { 15237c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 15247c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 15253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 15267c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1527462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1528641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1529a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1530a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1531a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1532a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1533a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1534e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1535a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1536a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1537a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1538a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1539a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1540a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1541a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1542a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1543a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1544a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1545a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1546a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1547a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1548a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1549a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1550a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1551a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1552a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1553a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1554e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1555a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1556a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1557a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1558a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 15593cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 15603cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 15613cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1562641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1563641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1564641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1565641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1566641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1567641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 15683cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1569641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1570641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1571641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1572641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1573641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1574641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1575641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1576641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1577641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1578641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1579641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1580641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1581641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1582641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1583641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1584641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1585641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1586641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1587641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1588641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1589641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1590e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 15911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 15921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 15931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 15941b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15951b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15961b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15971b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15981b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15991b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16001b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16011b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 16021b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 16031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 16041b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 16051b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 16061b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16071b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 16091b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 16101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 16111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 16121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 16151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 16161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 16171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 16181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 16191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16201b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 16221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 16231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 16241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 16251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 16261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 16291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 16301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 16311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 16331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 16341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 16371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 16381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1639e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1640