slang_rs_export_type.cpp revision 5abbe0e9ca2508260b627ffef2bf01e2554e8357
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" 34d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines#include "slang_version.h" 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 36641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 37641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 42e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 44474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet/* For the data types we support, their category, names, and size (in bits). 45474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * 46474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * IMPORTANT: The data types in this table should be at the same index 47474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * as specified by the corresponding DataType enum. 48474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 49fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 50474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 51474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 52474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 53474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 54474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 55474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 56474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 57474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 58474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 59474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 60474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {PrimitiveDataType, "UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 61474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 625abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", nullptr, nullptr, false}, 63474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 645abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {PrimitiveDataType, "UNSIGNED_5_6_5", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false}, 655abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {PrimitiveDataType, "UNSIGNED_5_5_5_1", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false}, 665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {PrimitiveDataType, "UNSIGNED_4_4_4_4", nullptr, 16, nullptr, nullptr, nullptr, nullptr, false}, 67474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 685abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {MatrixDataType, "MATRIX_2X2", nullptr, 4*32, "rsMatrix_2x2", "Matrix2f", nullptr, nullptr, false}, 695abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {MatrixDataType, "MATRIX_3X3", nullptr, 9*32, "rsMatrix_3x3", "Matrix3f", nullptr, nullptr, false}, 705abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {MatrixDataType, "MATRIX_4X4", nullptr, 16*32, "rsMatrix_4x4", "Matrix4f", nullptr, nullptr, false}, 71474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // RS object types are 32 bits in 32-bit RS, but 256 bits in 64-bit RS. 739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // This is handled specially by the GetSizeInBits() method. 745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", nullptr, nullptr, false}, 755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", nullptr, nullptr, false}, 765abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", nullptr, nullptr, false}, 775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", nullptr, nullptr, false}, 785abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", nullptr, nullptr, false}, 795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", nullptr, nullptr, false}, 805abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", nullptr, nullptr, false}, 815abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes 825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", nullptr, nullptr, false}, 835abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", nullptr, nullptr, false}, 845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", nullptr, nullptr, false}, 855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", nullptr, nullptr, false}, 865abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes {ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", nullptr, nullptr, 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; 93cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet 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 100cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet 101474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo BuiltinInfoTable[] = { 102cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Bool, DataTypeBoolean, 103474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"bool", "bool2", "bool3", "bool4"}}, 104cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char_U, DataTypeUnsigned8, 105474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 106cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UChar, DataTypeUnsigned8, 107474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 108cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char16, DataTypeSigned16, 109474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 110cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char32, DataTypeSigned32, 111474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 112cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UShort, DataTypeUnsigned16, 113474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ushort", "ushort2", "ushort3", "ushort4"}}, 114cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UInt, DataTypeUnsigned32, 115474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uint", "uint2", "uint3", "uint4"}}, 116cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::ULong, DataTypeUnsigned32, 117474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uint", "uint2", "uint3", "uint4"}}, 118cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::ULongLong, DataTypeUnsigned64, 119474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ulong", "ulong2", "ulong3", "ulong4"}}, 120474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 121cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char_S, DataTypeSigned8, 122474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 123cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::SChar, DataTypeSigned8, 124474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 125cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Short, DataTypeSigned16, 126474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 127cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Int, DataTypeSigned32, 128474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 129cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Long, DataTypeSigned64, 130474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 131cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::LongLong, DataTypeSigned64, 132474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 133cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Float, DataTypeFloat32, 134474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"float", "float2", "float3", "float4"}}, 135cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Double, DataTypeFloat64, 136474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"double", "double2", "double3", "double4"}}, 137474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 138474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int BuiltinInfoTableCount = sizeof(BuiltinInfoTable) / sizeof(BuiltinInfoTable[0]); 139474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 140474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct NameAndPrimitiveType { 141474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *name; 142cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType dataType; 143474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 144474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 145474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstatic NameAndPrimitiveType MatrixAndObjectDataTypes[] = { 146cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix2x2", DataTypeRSMatrix2x2}, 147cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix3x3", DataTypeRSMatrix3x3}, 148cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix4x4", DataTypeRSMatrix4x4}, 149cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_element", DataTypeRSElement}, 150cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_type", DataTypeRSType}, 151cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_allocation", DataTypeRSAllocation}, 152cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_sampler", DataTypeRSSampler}, 153cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_script", DataTypeRSScript}, 154cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_mesh", DataTypeRSMesh}, 155cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_path", DataTypeRSPath}, 156cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_fragment", DataTypeRSProgramFragment}, 157cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_vertex", DataTypeRSProgramVertex}, 158cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_raster", DataTypeRSProgramRaster}, 159cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_store", DataTypeRSProgramStore}, 160cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_font", DataTypeRSFont}, 161fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 162fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 163474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int MatrixAndObjectDataTypesCount = 164474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet sizeof(MatrixAndObjectDataTypes) / sizeof(MatrixAndObjectDataTypes[0]); 165474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 16624e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 16724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 16824e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 16948d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 17024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1715bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 17224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 173ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murraytemplate <unsigned N> 174d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic void ReportTypeError(slang::RSContext *Context, 17511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::NamedDecl *ND, 17624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 177ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray const char (&Message)[N], 178d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 17924e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 18024e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 18124e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 18224e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 183d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(TopLevelRecord->getLocation(), Message) 184d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TopLevelRecord->getName() << TargetAPI; 18511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (ND) { 186d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(ND->getLocation(), Message) << ND->getName() 187d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TargetAPI; 18824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 1896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 19024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 19124e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 19224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 19324e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 19424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 19524e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 19648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 19724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1985bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 19924e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 200b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 20124e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 202d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2039207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 2045abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 20524e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 20624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 20724e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 20824e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 20924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 210b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *BaseElementType = GetExtVectorElementType(EVT); 21124e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 212d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2139207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 2145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 21524e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 21624e79f69125cf87fcaa78c04510a831037203eebStephen Hines 21724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 218d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2199207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 2205abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 22124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 22224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 22324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 22448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (TypeExportableHelper(ElementType, SPS, Context, VD, 2255abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr) { 2265abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 227d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 22824e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 229d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 23024e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 23124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 232474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo *FindBuiltinType(clang::BuiltinType::Kind builtinTypeKind) { 233474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < BuiltinInfoTableCount; i++) { 234474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (builtinTypeKind == BuiltinInfoTable[i].builtinTypeKind) { 235474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return &BuiltinInfoTable[i]; 236474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 237474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 2385abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 239474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet} 240474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 24124e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 242e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 243e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 24448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 245e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 2465bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 2485abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = GetCanonicalType(T)) == nullptr) 2495abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2531f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 254b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 255b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 258b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI); 2595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return FindBuiltinType(BT->getKind()) == nullptr ? nullptr : T; 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 262cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (RSExportPrimitiveType::GetRSSpecificType(T) != DataTypeUnknown) { 2636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 264d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 267cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 268d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(), 2699207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 2705abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 271cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 2726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 2735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 274cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 275cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 27624e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 2775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 2795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 2805abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, T->getAsStructureType()->getDecl(), 2819207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 2825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 2832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 285f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 286e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 287e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 288e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 289e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 2905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, RD, 2919207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 2925abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 293e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 294e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 2975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 298f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 301f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 3059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 3069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 3070da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 308e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 309b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet FT = GetCanonicalType(FT); 310462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) { 3125abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3130da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 3152ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 3162ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 3172ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 3182ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 319d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 320d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet FD->getLocation(), 321d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "bit fields are not able to be exported: '%0.%1'") 322d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 3235abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3242ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 326462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 330e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 331d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 332aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "structures containing pointers cannot be exported: '%0'"); 3335abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 334c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 33524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 336b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *PT = static_cast<const clang::PointerType*>(CTI); 337b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(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'"); 3425abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 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, 3485abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr)) 3495abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 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 = 355b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 3585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 359f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 361b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 362462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 36448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(ElementType, SPS, Context, VD, 3655abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr)) 3665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3702e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 3712e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 372b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ConstantArrayType*>(CTI); 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"); 3845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 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 3905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// the canonical type. 3915abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// 3925abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// If the Type T is not exportable, this function returns nullptr. DiagEngine is 3935abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// used to generate proper Clang diagnostic messages when a non-exportable type 3945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// is detected. TopLevelRecord is used to capture the highest struct (in the 3955abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// case of a nested hierarchy) for detecting other types that cannot be exported 3965abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// (mostly pointers within a struct). 397e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 39848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 3995bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 400e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 401e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 402e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 4035abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return TypeExportableHelper(T, SPS, Context, VD, nullptr); 40478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 40578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 406d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic bool ValidateRSObjectInVarDecl(slang::RSContext *Context, 407d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, bool InCompositeType, 408d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 409d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 410d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 411d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 412d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 41344f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->hasLinkage() && 41444f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines (VD->getFormalLinkage() == clang::ExternalLinkage)) { 415d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 416b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *T = GetCanonicalType(VD->getType().getTypePtr()); 417d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 4185abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, VD, nullptr, 419d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 420d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 421d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 422d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 423d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 424d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 425d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 426d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 427d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 428d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 429d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 430d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 43111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// Helper function for ValidateType(). We do a recursive descent on the 432d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 433d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 434d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 435d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 436d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 43711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// C - ASTContext (for diagnostics + builtin types). 43811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// T - sub-type that we are validating. 43911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// ND - (optional) top-level named declaration that we are validating. 440d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 441d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 442d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 443d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 44411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// IsFilterscript - whether or not we are compiling for Filterscript 44511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesstatic bool ValidateTypeHelper( 446d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet slang::RSContext *Context, 44711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::ASTContext &C, 44878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 44911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, 45011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::SourceLocation Loc, 45178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 452d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 453d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 45411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines unsigned int TargetAPI, 45511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 4565abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = GetCanonicalType(T)) == nullptr) 45778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 45878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 45978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 46078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 46178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 462b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 463b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 46478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 46578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 466d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 4675abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : nullptr); 468d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType, 469d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet TargetAPI)) { 470d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 471d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 472d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 473d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 474cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (RSExportPrimitiveType::GetRSSpecificType(T) != DataTypeUnknown) { 47578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 47678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 47778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 4785abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, UnionDecl, 47978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 48078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 48178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 48278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 48378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 4845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::RecordDecl *RD = nullptr; 48578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 48678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 48778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 48878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 48978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 49078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 49178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 49278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 49378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 49478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 49578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 49678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 4975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 49878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 4995abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 50078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 50178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 50278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 50678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 50778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 50878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 51078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 51178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 51278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 51378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 51478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 51578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 51678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 51778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 51878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 519b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet FT = GetCanonicalType(FT); 52078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 521d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!ValidateTypeHelper(Context, C, FT, ND, Loc, SPS, true, UnionDecl, 52211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript)) { 52378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 52478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 52878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 53078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 53111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 53211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::QualType QT = T->getCanonicalTypeInternal(); 53311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (QT == C.DoubleTy || 53411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongDoubleTy || 53511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongTy || 53611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongLongTy) { 53711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 538d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 539d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 54011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 541d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript: '%0'") 542d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 54311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 544d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 545d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 54611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 547d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript"); 54811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 54911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 55011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 55111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 55278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 55378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 55478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 55578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 55611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 55711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 558d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(Loc, 559d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Pointers are forbidden in Filterscript: '%0'") 560d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 56111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 56211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 56311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // TODO(srhines): Find a better way to handle expressions (i.e. no 56411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // NamedDecl) involving pointers in FS that should be allowed. 56511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // An example would be calls to library functions like 56611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // rsMatrixMultiply() that take rs_matrixNxN * types. 56711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 570b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *PT = static_cast<const clang::PointerType*>(CTI); 571b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(PT); 57278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 573d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, PointeeType, ND, Loc, SPS, 574d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet InCompositeType, UnionDecl, TargetAPI, 575d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet IsFilterscript); 57678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 57778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 57878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 57978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 580b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 581b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 582b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines if (TargetAPI < SLANG_ICS_TARGET_API && 583b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines InCompositeType && 584fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines EVT->getNumElements() == 3 && 585fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND && 58644f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines ND->getFormalLinkage() == clang::ExternalLinkage) { 5875abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, ND, nullptr, 588b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "structs containing vectors of dimension 3 cannot " 589b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "be exported at this API level: '%0'"); 590b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines return false; 591b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines } 592d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 593d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet UnionDecl, TargetAPI, IsFilterscript); 59478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 59578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 59678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 597b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::ConstantArrayType *CAT = static_cast<const clang::ConstantArrayType*>(CTI); 598b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(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 613eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouilletstd::string CreateDummyName(const char *type, const std::string &name) { 614eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet std::stringstream S; 615eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << "<" << type; 616eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet if (!name.empty()) { 617eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << ":" << name; 618eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet } 619eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << ">"; 620eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet return S.str(); 621eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet} 622eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet 623e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 624e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 625e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 62648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines RSContext *Context, 6275bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 6285abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = TypeExportable(T, Context, VD)) == nullptr) { 629e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 630e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 631e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 632e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 63348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (Context && TypeName.empty()) { 63448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (VD) { 635d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(VD->getLocation(), 636d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "anonymous types cannot be exported"); 63748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } else { 638d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("anonymous types cannot be exported"); 639e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 640e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 641e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 642e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 643e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 644e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 645e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 646d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateType(slang::RSContext *Context, clang::ASTContext &C, 647d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::QualType QT, clang::NamedDecl *ND, 648d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::SourceLocation Loc, 649d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet unsigned int TargetAPI, bool IsFilterscript) { 65011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::Type *T = QT.getTypePtr(); 65178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 65278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 65378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 6545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, nullptr, TargetAPI, 65511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines IsFilterscript); 65611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return true; 65711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 65811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 659d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateVarDecl(slang::RSContext *Context, 660d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, unsigned int TargetAPI, 66111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 662d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateType(Context, VD->getASTContext(), VD->getType(), VD, 66311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VD->getLocation(), TargetAPI, IsFilterscript); 66478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 66578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 666e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 667e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 668e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 6698de1922e037612f2521acac2f4c4289a9f71450dStephen Hines clang::QualType T = DD->getType(); 670e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 671e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 6725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 673e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 674e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 675e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 6765abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 677e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 678e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 679e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 680b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet T = GetCanonicalType(T); 6815abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (T == nullptr) 682e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 683e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 684b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 685b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 686e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 687e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 688b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI); 689474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 6905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 691474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->cname[0]; 692e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 693474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Unknown data type of the builtin"); 694e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 695e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 696e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 697cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 698cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 699cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 700dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 701cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 702cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 703cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 704e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 705e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 7065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD->getTypedefNameForAnonDecl() != nullptr) { 70783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 70883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 70983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 71083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 71183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 71283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 71383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 71483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 71583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 7165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(*RI != nullptr && "cannot be NULL object"); 71783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 71883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 71983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 72083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 72183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 72283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 723e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 724e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 725e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 726e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 727e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 728b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *P = static_cast<const clang::PointerType*>(CTI); 729b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PT = GetPointeeType(P); 730e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 7315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (NormalizeType(PT, PointeeName, nullptr, nullptr)) { 732e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 733e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 734e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 735e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 736e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 737e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 738e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 739e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 740e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 741e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 742b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 743e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 744e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 745e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 746e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 747e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 748eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet return CreateDummyName("ConstantArray", std::string()); 749e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 750e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 751e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 752e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 753e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 754e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 755e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 756e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 757e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 758e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 7599ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 7619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 7629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 7639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 7649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 7659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 7669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 7689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 7699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 770b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 771b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 7725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSExportType *ET = nullptr; 7739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 7749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 775cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType dt = RSExportPrimitiveType::GetRSSpecificType(TypeName); 7769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 777cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnknown: { 77892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 7799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 7809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 7819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 7829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 784cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix2x2: { 78592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 78692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 78792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 78892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 78992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 79092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 79192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 792cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix3x3: { 79392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 79492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 79592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 79692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 79792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 79892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 79992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 800cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix4x4: { 80192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 80292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 80392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 80492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 80592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 80992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 8109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 8119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 8179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 8219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 822b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::PointerType*>(CTI), 823b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet TypeName); 82492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 8269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 830b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI), 831b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet TypeName); 8329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8342e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 8352e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 8362e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 837b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ConstantArrayType*>(CTI)); 8382e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 8392e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 8409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 841d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("unknown type cannot be exported: '%0'") 842d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << T->getTypeClassName(); 8439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 848462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 8491f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 8506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 8525abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (NormalizeType(T, TypeName, Context, nullptr)) { 8539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 854d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 8555abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 856d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 857462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 858462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 8609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 862462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 863462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 864c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouilletsize_t RSExportType::getStoreSize() const { 865c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet return getRSContext()->getDataLayout()->getTypeStoreSize(getLLVMType()); 866462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 867462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 868c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouilletsize_t RSExportType::getAllocSize() const { 869c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet return getRSContext()->getDataLayout()->getTypeAllocSize(getLLVMType()); 870462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 871462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8726b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 8736b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 8746b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 875a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 8766b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 8770da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 8780da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 8796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 8805abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mLLVMType(nullptr) { 8810da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 8820da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 8830da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 884b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet if (!IsDummyName(Name)) { 8850da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 8860da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 887b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet } 888b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 889462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 890462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8913cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 8923cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 8933cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 894641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 8955abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mLLVMType = nullptr; 8963cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 897641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 898641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 899641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 900641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 901641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 902641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 903641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 904a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 905a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 906a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 9079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 908b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 909b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 9109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 9125abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T != nullptr) && (T->getTypeClass() == clang::Type::Builtin)) 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 9149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 916462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 917462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 918cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType 919b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 9209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 9219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 922462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 923b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 924474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < MatrixAndObjectDataTypesCount; i++) { 925474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSSpecificTypeMap->GetOrCreateValue(MatrixAndObjectDataTypes[i].name, 926474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet MatrixAndObjectDataTypes[i].dataType); 927474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 9289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 929462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 930b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 931b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 9329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 9359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 9369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 937cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType RSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 938b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet T = GetCanonicalType(T); 9395abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T == nullptr) || (T->getTypeClass() != clang::Type::Record)) 9409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 942b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 943b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 944b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 945b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 946474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 947474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 948474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 949474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == MatrixDataType; 950b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 951b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 952b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 953474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 954474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 955474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 956474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == ObjectDataType; 9579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 9589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 959feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 960feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 961feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 962feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 963feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 964feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 965feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 966feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 967feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 968feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 969b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 970feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 971b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (RD) { 972b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines RD = RD->getDefinition(); 973b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 974b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (!RD) { 975b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines return false; 976b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 977b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 978feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 979feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 980feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 981feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 982feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 983feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 984feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 985feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 986feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 987feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 988feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 989feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 990cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = GetRSSpecificType(FT); 991feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 992feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 993feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 994feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 995feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 996cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix2x2: 997cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix3x3: 998cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix4x4: 999feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 1000feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 1001feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 1002feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 1003feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 1004feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 1005feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1006feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 1007feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 1008feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1009feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 1010feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 1011feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 1012feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 1013feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1014feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1015feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1016feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 1017feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 1018feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 1019feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 10209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 1021474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int type = EPT->getType(); 1022474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert((type > DataTypeUnknown && type < DataTypeMax) && 10236e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 10249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // All RS object types are 256 bits in 64-bit RS. 10259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (EPT->isRSObjectType() && EPT->getRSContext()->is64Bit()) { 10269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return 256; 10279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1028474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[type].size_in_bits; 1029462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1030462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1031cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType 10322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 10335abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (T == nullptr) 10349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1035462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 1038be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 1039b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::BuiltinType*>(T->getCanonicalTypeInternal().getTypePtr()); 1040474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 10415abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 1042474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->type; 10439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1044474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // The size of type WChar depend on platform so we abandon the support 1045474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // to them. 1046474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet Context->ReportError("built-in type cannot be exported: '%0'") 1047474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet << T->getTypeClassName(); 10489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 1052b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1055d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("primitive type cannot be exported: '%0'") 10562ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 10579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1058462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1060462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1062462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1063462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10649ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 10659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 10669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 10679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 10692ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 1070462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 10725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 10739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 10746b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 10752b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 1076462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1077462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10789ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 10792b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 10815abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RSExportType::NormalizeType(T, TypeName, Context, nullptr) 108278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 10832b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 1084e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 10855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1086e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 1087462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1088462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10897c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 10909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 10919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 10939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 10949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 10959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 10969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 10989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 11009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 1101a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray std::vector<llvm::Type *> Elements; 1102a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray if (getRSContext()->is64Bit()) { 1103a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray // 64-bit path 1104a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt64Ty(C), 4)); 1105a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray return llvm::StructType::get(C, Elements, true); 1106a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray } else { 1107a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray // 32-bit legacy path 1108a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1109a6bce2db689b1ad086860ed3f5845a00489e3a49Tim Murray return llvm::StructType::get(C, Elements, true); 1110462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 11149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 11159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 11169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 11199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 11209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 112291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 112391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 112491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 112591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 11269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 11279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 11289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 11299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 11329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 11339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 11349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 11359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 11369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 11379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 11409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 11419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 11429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1144a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1145a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 11469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 11479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1151462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1157641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1158641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1159641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1160641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1161641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1162fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1163fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1164fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1165fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 11665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1167fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1168fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1169fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 11709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1171462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11729ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 11739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 11749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 11759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 1176b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(PT); 11779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1178462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 11809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 11819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 11829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 11832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 11842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 11859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11875abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (PointeeET == nullptr) { 11882ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 11895abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 11909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1193462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11957c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 11967c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 11979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12003cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 12013cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12023cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1203641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 12043cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1205641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1206641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1207641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1208641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1209641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1210641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1211641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1212641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 12146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 12156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 1216b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 1217474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet llvm::StringRef name; 1218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 1220474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1222b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = 1223b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::BuiltinType*>( 1224b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet ElementType->getCanonicalTypeInternal().getTypePtr()); 1225b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 1226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1227a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1228474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1230474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 12315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 1232474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int I = EVT->getNumElements() - 1; 1233474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (I < kMaxVectorSize) { 1234474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet name = info->cname[I]; 1235474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 1236474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Max vector is 4"); 1237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 12389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1239474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 1240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12429ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 12439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 12449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 12465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(EVT != nullptr && EVT->getTypeClass() == clang::Type::ExtVector); 1247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1248b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 1249cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetDataType(Context, ElementType); 1250462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1251cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT != DataTypeUnknown) 12529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 12539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 12549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 12559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 12569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 12579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 12585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1260462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12617c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 12627c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 12639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1264462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1265462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1266641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1267641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1268641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1269641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1270641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1271641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 127292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 127392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 127492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 127592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 127692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 12775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((RT != nullptr) && (RT->getTypeClass() == clang::Type::Record)); 12786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 127992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 128092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 128192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 128292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 128392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 12845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 128592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 128692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 1287d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 1288d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet RD->getLocation(), 1289d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have 1 field for saving values: '%0'") 1290d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 12915abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 129292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 129392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 129492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 129592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 129692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 12975abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((FT == nullptr) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1298d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1299d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field should" 1300d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet " be an array with constant size: '%0'") 1301d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13025abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 130392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 130492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 130592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 1306b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 13075abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((ElementType == nullptr) || 130892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 13099207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 13109207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 1311d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1312d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1313d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be a float array: '%0'") 1314d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13155abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 131692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 131792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 131892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 1319d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1320d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1321d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be an array with size %0: '%1'") 1322d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << (Dim * Dim) << (RD->getName()); 13235abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 132492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 132592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 132692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 132792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 1328d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1329d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have " 1330d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "exactly 1 field: '%0'") 1331d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 133392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 133492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 133592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 133692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 133792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 133892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 13397c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 134092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 134192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 134292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 134392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 134492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 134592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 134692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 134792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1348a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 134992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 135092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1351641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1352641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1353641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1354641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1355641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13562e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 13572e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 13582e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 13592e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 13605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(CAT != nullptr && CAT->getTypeClass() == clang::Type::ConstantArray); 13612e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 13632e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13642e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 13656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 13662e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1367b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 13682e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 13692e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13705abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ElementET == nullptr) { 13715abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 13722e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 13732e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 13752e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 13762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 13772e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13797c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 13802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 13812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13833cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 13843cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 13853cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1386641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 13873cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1388641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1389641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1390641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1391641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1392a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1393a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1394a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1395a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1396641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1397641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 13999ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 14009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 14019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 14029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 14035abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(RT != nullptr && RT->getTypeClass() == clang::Type::Record); 1404462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 14066e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1407462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 14095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 14106e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 14115abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1413462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 14150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 14160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 14179e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 14185abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((RL != nullptr) && 1419f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 14200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 14210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 14220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 14230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 14240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 14250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 1426c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet RL->getDataSize().getQuantity(), 142768318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 14289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 14299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 14319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 14329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 143391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 14349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 143643730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao slangAssert(FI->getKind() == clang::Decl::Field); 14379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 14389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14392ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 14405abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14412ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 14446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 14459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ET != nullptr) { 14470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 14480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 14490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 14502ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 1451d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1452d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "field type cannot be exported: '%0.%1'") 1453d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 14545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 14570a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 14589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1459462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1460462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14617c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 14623cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 14633cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 14647c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 14657c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1466462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14673cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 14689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 14699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 14709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 14719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 14721f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 14739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 14749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1475462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 14773cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 14783cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 14795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ST != nullptr) { 14807c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 14817c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 14825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14837c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1484462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1485641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 14863cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 14873cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14883cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1489641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1490641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1491641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1492641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1493641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1494641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 14953cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1496641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1497641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1498641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1499641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1500641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1501641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1502641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1503641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1504641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1505641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1506641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1507641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1508641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1509641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1510641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1511641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1512641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1513641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1514641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1515641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1516641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1517e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 15181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 15191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 15201b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 15211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 15291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 15301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 15311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 15321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 15331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 15361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 15371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 15381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 15391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 15421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 15431b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 15441b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 15451b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 15461b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15471b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15481b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 15491b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 15501b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 15511b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 15521b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 15531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15541b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 15561b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 15571b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 15581b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15591b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 15601b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 15611b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15621b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15631b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 15641b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15651b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1566e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1567