slang_rs_export_type.cpp revision 7682b663581dd8f67b422f6f2f31692ab2f870e3
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 447682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// For the data types we support: 457682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// Category - data type category 467682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// RsType - element name in RenderScript 477682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// RsShortType - short element name in RenderScript 487682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// SizeInBits - size in bits 497682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// CName - reflected C name 507682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// JavaName - reflected Java name 517682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// JavaArrayElementName - reflected name in Java arrays 527682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// CVecName - prefix for C vector types 537682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// JavaVecName - prefix for Java vector type 547682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// JavaPromotion - unsigned type undergoing Java promotion 557682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// 567682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// IMPORTANT: The data types in this table should be at the same index as 577682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// specified by the corresponding DataType enum. 587682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// 597682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// TODO: Pull this information out into a separate file. 60fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 617682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#define _ nullptr 627682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "FLOAT_16", "F16", 16, "half", "short", _, "Half", "Half", false}, 637682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "FLOAT_32", "F32", 32, "float", "float", "float", "Float", "Float", false}, 647682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "FLOAT_64", "F64", 64, "double", "double", "double", "Double", "Double", false}, 657682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "SIGNED_8", "I8", 8, "int8_t", "byte", "byte", "Byte", "Byte", false}, 667682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "SIGNED_16", "I16", 16, "int16_t", "short", "short", "Short", "Short", false}, 677682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "SIGNED_32", "I32", 32, "int32_t", "int", "int", "Int", "Int", false}, 687682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "SIGNED_64", "I64", 64, "int64_t", "long", "long", "Long", "Long", false}, 697682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_8", "U8", 8, "uint8_t", "short", "byte", "UByte", "Short", true}, 707682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_16", "U16", 16, "uint16_t", "int", "short", "UShort", "Int", true}, 717682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_32", "U32", 32, "uint32_t", "long", "int", "UInt", "Long", true}, 727682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_64", "U64", 64, "uint64_t", "long", "long", "ULong", "Long", false}, 737682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "BOOLEAN", "BOOLEAN", 8, "bool", "boolean", "byte", _, _, false}, 747682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_5_6_5", _, 16, _, _, _, _, _, false}, 757682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_5_5_5_1", _, 16, _, _, _, _, _, false}, 767682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{PrimitiveDataType, "UNSIGNED_4_4_4_4", _, 16, _, _, _, _, _, false}, 777682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala 787682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{MatrixDataType, "MATRIX_2X2", _, 4*32, "rsMatrix_2x2", "Matrix2f", _, _, _, false}, 797682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{MatrixDataType, "MATRIX_3X3", _, 9*32, "rsMatrix_3x3", "Matrix3f", _, _, _, false}, 807682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{MatrixDataType, "MATRIX_4X4", _, 16*32, "rsMatrix_4x4", "Matrix4f", _, _, _, false}, 817682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala 827682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// RS object types are 32 bits in 32-bit RS, but 256 bits in 64-bit RS. 837682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala// This is handled specially by the GetSizeInBits(}, method. 847682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_ELEMENT", "ELEMENT", 32, "Element", "Element", _, _, _, false}, 857682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_TYPE", "TYPE", 32, "Type", "Type", _, _, _, false}, 867682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", _, _, _, false}, 877682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", _, _, _, false}, 887682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_SCRIPT", "SCRIPT", 32, "Script", "Script", _, _, _, false}, 897682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_MESH", "MESH", 32, "Mesh", "Mesh", _, _, _, false}, 907682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_PATH", "PATH", 32, "Path", "Path", _, _, _, false}, 917682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", _, _, _, false}, 927682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", _, _, _, false}, 937682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", _, _, _, false}, 947682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", _, _, _, false}, 957682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala{ObjectDataType, "RS_FONT", "FONT", 32, "Font", "Font", _, _, _, false}, 967682b663581dd8f67b422f6f2f31692ab2f870e3Matt Wala#undef _ 97474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 98474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 99474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int kMaxVectorSize = 4; 100474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 101474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct BuiltinInfo { 102474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet clang::BuiltinType::Kind builtinTypeKind; 103cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType type; 104474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet /* TODO If we return std::string instead of llvm::StringRef, we could build 105474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * the name instead of duplicating the entries. 106474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 107474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *cname[kMaxVectorSize]; 108474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 109474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 110cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet 111474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo BuiltinInfoTable[] = { 112cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Bool, DataTypeBoolean, 113474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"bool", "bool2", "bool3", "bool4"}}, 114cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char_U, DataTypeUnsigned8, 115474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 116cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UChar, DataTypeUnsigned8, 117474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uchar", "uchar2", "uchar3", "uchar4"}}, 118cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char16, DataTypeSigned16, 119474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 120cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char32, DataTypeSigned32, 121474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 122cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UShort, DataTypeUnsigned16, 123474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ushort", "ushort2", "ushort3", "ushort4"}}, 124cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::UInt, DataTypeUnsigned32, 125474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"uint", "uint2", "uint3", "uint4"}}, 126e46265d27df092fbd911075403ec04d9c7ef8de1Tim Murray {clang::BuiltinType::ULong, DataTypeUnsigned64, 127e46265d27df092fbd911075403ec04d9c7ef8de1Tim Murray {"ulong", "ulong2", "ulong3", "ulong4"}}, 128cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::ULongLong, DataTypeUnsigned64, 129474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"ulong", "ulong2", "ulong3", "ulong4"}}, 130474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 131cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Char_S, DataTypeSigned8, 132474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 133cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::SChar, DataTypeSigned8, 134474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"char", "char2", "char3", "char4"}}, 135cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Short, DataTypeSigned16, 136474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"short", "short2", "short3", "short4"}}, 137cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Int, DataTypeSigned32, 138474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"int", "int2", "int3", "int4"}}, 139cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Long, DataTypeSigned64, 140474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 141cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::LongLong, DataTypeSigned64, 142474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"long", "long2", "long3", "long4"}}, 143e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar {clang::BuiltinType::Half, DataTypeFloat16, 144e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar {"half", "half2", "half3", "half4"}}, 145cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Float, DataTypeFloat32, 146474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"float", "float2", "float3", "float4"}}, 147cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {clang::BuiltinType::Double, DataTypeFloat64, 148474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet {"double", "double2", "double3", "double4"}}, 149474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 150474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int BuiltinInfoTableCount = sizeof(BuiltinInfoTable) / sizeof(BuiltinInfoTable[0]); 151474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 152474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct NameAndPrimitiveType { 153474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *name; 154cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType dataType; 155474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 156474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 157474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstatic NameAndPrimitiveType MatrixAndObjectDataTypes[] = { 158cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix2x2", DataTypeRSMatrix2x2}, 159cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix3x3", DataTypeRSMatrix3x3}, 160cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_matrix4x4", DataTypeRSMatrix4x4}, 161cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_element", DataTypeRSElement}, 162cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_type", DataTypeRSType}, 163cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_allocation", DataTypeRSAllocation}, 164cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_sampler", DataTypeRSSampler}, 165cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_script", DataTypeRSScript}, 166cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_mesh", DataTypeRSMesh}, 167cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_path", DataTypeRSPath}, 168cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_fragment", DataTypeRSProgramFragment}, 169cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_vertex", DataTypeRSProgramVertex}, 170cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_raster", DataTypeRSProgramRaster}, 171cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_program_store", DataTypeRSProgramStore}, 172cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_font", DataTypeRSFont}, 173fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 174fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 175474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int MatrixAndObjectDataTypesCount = 176474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet sizeof(MatrixAndObjectDataTypes) / sizeof(MatrixAndObjectDataTypes[0]); 177474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 17824e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 17924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 18024e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 18148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 18224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1835bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 18424e79f69125cf87fcaa78c04510a831037203eebStephen Hines 185ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murraytemplate <unsigned N> 186d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic void ReportTypeError(slang::RSContext *Context, 18711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::NamedDecl *ND, 18824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 189ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray const char (&Message)[N], 190d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 19124e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 19224e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 19324e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 19424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 195d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(TopLevelRecord->getLocation(), Message) 196d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TopLevelRecord->getName() << TargetAPI; 19711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (ND) { 198d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(ND->getLocation(), Message) << ND->getName() 199d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TargetAPI; 20024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 2016e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 20224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 20324e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 20424e79f69125cf87fcaa78c04510a831037203eebStephen Hines 20524e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 20624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 20724e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 20848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 20924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 2105bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 21124e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 212b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 21324e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 214d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2159207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 2165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 21724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 21824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 21924e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 22024e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 22124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 222b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *BaseElementType = GetExtVectorElementType(EVT); 22324e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 224d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2259207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 2265abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 22724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 22824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 22924e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 230d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 2319207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 2325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 23324e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 23424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 23524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 23648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (TypeExportableHelper(ElementType, SPS, Context, VD, 2375abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr) { 2385abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 239d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 24024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 241d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 24224e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 24324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 244474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc BrouilletBuiltinInfo *FindBuiltinType(clang::BuiltinType::Kind builtinTypeKind) { 245474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < BuiltinInfoTableCount; i++) { 246474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (builtinTypeKind == BuiltinInfoTable[i].builtinTypeKind) { 247474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return &BuiltinInfoTable[i]; 248474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 249474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 2505abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 251474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet} 252474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 25324e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 254e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 255e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 25648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 257e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 2585bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 2605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = GetCanonicalType(T)) == nullptr) 2615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 262462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2651f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 266b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 267b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 270b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI); 2715abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return FindBuiltinType(BT->getKind()) == nullptr ? nullptr : T; 2729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 274cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (RSExportPrimitiveType::GetRSSpecificType(T) != DataTypeUnknown) { 2756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 276d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 277462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 279cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 280d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(), 2819207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 2825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 283cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 2846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 2855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 286cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 287cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 28824e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 2895abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 2915abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 2925abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, T->getAsStructureType()->getDecl(), 2939207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 2945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 2952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2962ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 297f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 298e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 299e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 300e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 301e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 3025abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, RD, 3039207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 3045abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 305e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 306e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 3095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 310f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 313f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 3169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 3179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 3189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 320e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 321b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet FT = GetCanonicalType(FT); 322462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 32348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) { 3245abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 3262ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 3272ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 3282ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 3292ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 3302ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 331d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 332d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet FD->getLocation(), 333d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "bit fields are not able to be exported: '%0.%1'") 334d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 3355abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 3379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 338462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 342e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 343d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 344ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "structures containing pointers cannot be used as the type of " 345ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "an exported global variable or the parameter to an exported " 346ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "function: '%0'"); 3475abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 348c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 34924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 350b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *PT = static_cast<const clang::PointerType*>(CTI); 351b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(PT); 352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 353aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines if (PointeeType->getTypeClass() == clang::Type::Pointer) { 354d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 355aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "multiple levels of pointers cannot be exported: '%0'"); 3565abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 357aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines } 3582e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 3592e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 3602e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 36148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(PointeeType, SPS, Context, VD, 3625abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr)) 3635abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 3689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 369b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 3709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 3719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 3725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 373f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 3749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 375b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 376462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 37848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(ElementType, SPS, Context, VD, 3795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes TopLevelRecord) == nullptr)) 3805abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 3819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 3852e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 386b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ConstantArrayType*>(CTI); 3872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 38848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Context, VD, 3895bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord); 3902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 39148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines case clang::Type::Enum: { 39248d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // FIXME: We currently convert enums to integers, rather than reflecting 39348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // a more complete (and nicer type-safe Java version). 39448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return Context->getASTContext().IntTy.getTypePtr(); 39548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } 3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 39748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slangAssert(false && "Unknown type cannot be validated"); 3985abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 399462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 402462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 403e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 4045abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// the canonical type. 4055abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// 4065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// If the Type T is not exportable, this function returns nullptr. DiagEngine is 4075abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// used to generate proper Clang diagnostic messages when a non-exportable type 4085abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// is detected. TopLevelRecord is used to capture the highest struct (in the 4095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// case of a nested hierarchy) for detecting other types that cannot be exported 4105abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes// (mostly pointers within a struct). 411e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 41248d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 4135bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 414e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 415e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 416e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 4175abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return TypeExportableHelper(T, SPS, Context, VD, nullptr); 41878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 41978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 420d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic bool ValidateRSObjectInVarDecl(slang::RSContext *Context, 421d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, bool InCompositeType, 422d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 423d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 424d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 425d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 426d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 42744f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->hasLinkage() && 42844f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines (VD->getFormalLinkage() == clang::ExternalLinkage)) { 429d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 430b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *T = GetCanonicalType(VD->getType().getTypePtr()); 431d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 4325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, VD, nullptr, 433d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 434d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 435d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 436d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 437d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 438d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 439d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 440d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 441d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 442d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 443d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 444d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 44511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// Helper function for ValidateType(). We do a recursive descent on the 446d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 447d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 448d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 449d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 450d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 45111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// C - ASTContext (for diagnostics + builtin types). 45211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// T - sub-type that we are validating. 45311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// ND - (optional) top-level named declaration that we are validating. 454d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 455d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 456d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 457d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 45811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// IsFilterscript - whether or not we are compiling for Filterscript 459ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines// IsExtern - is this type externally visible (i.e. extern global or parameter 460ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines// to an extern function) 46111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesstatic bool ValidateTypeHelper( 462d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet slang::RSContext *Context, 46311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::ASTContext &C, 46478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 46511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, 46611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::SourceLocation Loc, 46778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 468d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 469d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 47011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines unsigned int TargetAPI, 471ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines bool IsFilterscript, 472ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines bool IsExtern) { 4735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = GetCanonicalType(T)) == nullptr) 47478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 47578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 47678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 47778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 47878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 479b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 480b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 48178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 48278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 483d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 4845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : nullptr); 485d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType, 486d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet TargetAPI)) { 487d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 488d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 489d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 490d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 491cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (RSExportPrimitiveType::GetRSSpecificType(T) != DataTypeUnknown) { 49278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 49378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 49478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 4955abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, nullptr, UnionDecl, 49678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 49778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 49878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 49978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 5015abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::RecordDecl *RD = nullptr; 50278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 50478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 50578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 50678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 50778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 50878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 50978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 51078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 51178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 51278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 51378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 5145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 51578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 5165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 51778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 51878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 51978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 52378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 52478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 52578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 52778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 52878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 53078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 53178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 53278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 53378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 53478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 53578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 536b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet FT = GetCanonicalType(FT); 53778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 538d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!ValidateTypeHelper(Context, C, FT, ND, Loc, SPS, true, UnionDecl, 539ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines TargetAPI, IsFilterscript, IsExtern)) { 54078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 54178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 54278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 54378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 54478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 54578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 54678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 54778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 54811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 54911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::QualType QT = T->getCanonicalTypeInternal(); 55011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (QT == C.DoubleTy || 55111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongDoubleTy || 55211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongTy || 55311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongLongTy) { 55411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 555d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 556d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 55711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 558d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript: '%0'") 559d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 56011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 561d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 562d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 56311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 564d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript"); 56511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 56711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 56978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 57078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 57178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 57278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 57311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 57411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 575d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(Loc, 576d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Pointers are forbidden in Filterscript: '%0'") 577d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 57811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 57911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 58011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // TODO(srhines): Find a better way to handle expressions (i.e. no 58111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // NamedDecl) involving pointers in FS that should be allowed. 58211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // An example would be calls to library functions like 58311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // rsMatrixMultiply() that take rs_matrixNxN * types. 58411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 58511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 58611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 587ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines // Forbid pointers in structures that are externally visible. 588ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines if (InCompositeType && IsExtern) { 589ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines if (ND) { 590ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines Context->ReportError(Loc, 591ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "structures containing pointers cannot be used as the type of " 592ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "an exported global variable or the parameter to an exported " 593ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "function: '%0'") 594ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines << ND->getName(); 595ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } else { 596ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines Context->ReportError(Loc, 597ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "structures containing pointers cannot be used as the type of " 598ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "an exported global variable or the parameter to an exported " 599ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines "function"); 600ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } 601ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines return false; 602ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } 603ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines 604b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *PT = static_cast<const clang::PointerType*>(CTI); 605b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(PT); 60678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 607d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, PointeeType, ND, Loc, SPS, 608d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet InCompositeType, UnionDecl, TargetAPI, 609ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines IsFilterscript, IsExtern); 61078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 61178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 61278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 61378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 614b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 615b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 616b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines if (TargetAPI < SLANG_ICS_TARGET_API && 617b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines InCompositeType && 618fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines EVT->getNumElements() == 3 && 619fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND && 62044f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines ND->getFormalLinkage() == clang::ExternalLinkage) { 6215abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes ReportTypeError(Context, ND, nullptr, 622b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "structs containing vectors of dimension 3 cannot " 623b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "be exported at this API level: '%0'"); 624b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines return false; 625b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines } 626d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 627ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines UnionDecl, TargetAPI, IsFilterscript, IsExtern); 62878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 62978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 63078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 631b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::ConstantArrayType *CAT = static_cast<const clang::ConstantArrayType*>(CTI); 632b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 633d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 634ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines UnionDecl, TargetAPI, IsFilterscript, IsExtern); 63578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 63678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 63778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 63878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 63978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 64078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 64178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 64278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 643e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 644e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 645e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 646e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 647eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouilletstd::string CreateDummyName(const char *type, const std::string &name) { 648eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet std::stringstream S; 649eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << "<" << type; 650eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet if (!name.empty()) { 651eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << ":" << name; 652eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet } 653eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet S << ">"; 654eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet return S.str(); 655eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet} 656eca0534a31b6185d6ab758f5e97acd7a4cb21e8eJean-Luc Brouillet 657e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 658e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 659e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 66048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines RSContext *Context, 6615bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 6625abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T = TypeExportable(T, Context, VD)) == nullptr) { 663e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 664e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 665e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 666e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 66748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (Context && TypeName.empty()) { 66848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (VD) { 669d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(VD->getLocation(), 670d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "anonymous types cannot be exported"); 67148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } else { 672d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("anonymous types cannot be exported"); 673e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 674e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 675e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 676e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 677e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 678e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 679e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 680d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateType(slang::RSContext *Context, clang::ASTContext &C, 681d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::QualType QT, clang::NamedDecl *ND, 682d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::SourceLocation Loc, 683ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines unsigned int TargetAPI, bool IsFilterscript, 684ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines bool IsExtern) { 68511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::Type *T = QT.getTypePtr(); 68678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 68778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 68878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 689ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines // If this is an externally visible variable declaration, we check if the 690ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines // type is able to be exported first. 69133ea573b6df7b7fe48d2b68d4c479f33082e3c0dStephen Hines if (auto VD = llvm::dyn_cast_or_null<clang::VarDecl>(ND)) { 692ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines if (VD->getFormalLinkage() == clang::ExternalLinkage) { 693ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines if (!TypeExportable(T, Context, VD)) { 694ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines return false; 695ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } 696ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } 697ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines } 6985abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, nullptr, TargetAPI, 699ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines IsFilterscript, IsExtern); 70011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 70111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 702d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateVarDecl(slang::RSContext *Context, 703d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, unsigned int TargetAPI, 70411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 705d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateType(Context, VD->getASTContext(), VD->getType(), VD, 706ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines VD->getLocation(), TargetAPI, IsFilterscript, 707ab94bccca64c9b126cbd1b732aa5e681d8639b99Stephen Hines (VD->getFormalLinkage() == clang::ExternalLinkage)); 70878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 70978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 710e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 711e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 712e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 7138de1922e037612f2521acac2f4c4289a9f71450dStephen Hines clang::QualType T = DD->getType(); 714e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 715e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 7165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 717e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 718e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 719e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 7205abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 721e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 722e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 723e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 724b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet T = GetCanonicalType(T); 7255abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (T == nullptr) 726e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 727e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 728b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 729b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 730e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 731e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 732b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = static_cast<const clang::BuiltinType*>(CTI); 733474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 7345abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 735474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->cname[0]; 736e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 737474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Unknown data type of the builtin"); 738e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 739e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 740e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 741cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 742cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 743cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 744dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 745cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 746cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 747cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 748e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 749e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 7505abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD->getTypedefNameForAnonDecl() != nullptr) { 75183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 75283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 75383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 75483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 75583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 75683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 75783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 75883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 75983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 7605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(*RI != nullptr && "cannot be NULL object"); 76183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 76283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 76383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 76483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 76583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 76683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 767e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 768e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 769e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 770e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 771e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 772b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::PointerType *P = static_cast<const clang::PointerType*>(CTI); 773b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PT = GetPointeeType(P); 774e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 7755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (NormalizeType(PT, PointeeName, nullptr, nullptr)) { 776e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 777e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 778e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 779e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 780e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 781e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 782e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 783e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 784e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 785e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 786b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI); 787e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 788e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 789e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 790e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 791e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 792340b5550cf63b6beae3b12c2e91377bce7704c34Stephen Hines return "<ConstantArray>"; 793e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 794e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 795e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 796e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 797e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 798e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 799e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 800e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 801e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 802e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 8059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 8099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 8109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 8129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 8139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 814b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *CTI = T->getCanonicalTypeInternal().getTypePtr(); 815b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 8165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSExportType *ET = nullptr; 8179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 819cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType dt = RSExportPrimitiveType::GetRSSpecificType(TypeName); 8209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 821cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnknown: { 82292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 8239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 8249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 8269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 828cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix2x2: { 82992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 83092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 83192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 83292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 83392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 83492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 83592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 836cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix3x3: { 83792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 83892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 83992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 84092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 84192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 84292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 84392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 844cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix4x4: { 84592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 84692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 84792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 84892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 84992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 8509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 85392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 8559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 8659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 866b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::PointerType*>(CTI), 867b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet TypeName); 86892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 8699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 8709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 8739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 874b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ExtVectorType*>(CTI), 875b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet TypeName); 8769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 8792e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 8802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 881b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::ConstantArrayType*>(CTI)); 8822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 8832e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 8849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 885d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("unknown type cannot be exported: '%0'") 886d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << T->getTypeClassName(); 8879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 892462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 8931f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 8946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 8959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 8965abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (NormalizeType(T, TypeName, Context, nullptr)) { 8979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 898d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 8995abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 900d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 901462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 902462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9039ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 9049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 9059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 906462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 907462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 908c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouilletsize_t RSExportType::getStoreSize() const { 909c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet return getRSContext()->getDataLayout()->getTypeStoreSize(getLLVMType()); 910462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 911462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 912c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouilletsize_t RSExportType::getAllocSize() const { 913c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet return getRSContext()->getDataLayout()->getTypeAllocSize(getLLVMType()); 914462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 915462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9166b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 9176b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 9186b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 919a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 9206b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 9210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 9220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 9236315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 9245abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mLLVMType(nullptr) { 9250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 9260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 9270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 928b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet if (!IsDummyName(Name)) { 9290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 9300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 931b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet } 932b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 933462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 934462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9353cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 9363cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 9373cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 938641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 9395abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes mLLVMType = nullptr; 9403cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 941641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 942641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 943641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 944641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 945641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 946641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 947641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 948a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 949a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 950a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 952b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 953b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 9549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 9565abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T != nullptr) && (T->getTypeClass() == clang::Type::Builtin)) 9579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 9589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 960462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 961462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 962cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType 963b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 9649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 9659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 966462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 967b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 968474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < MatrixAndObjectDataTypesCount; i++) { 9693eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines (*RSSpecificTypeMap)[MatrixAndObjectDataTypes[i].name] = 9703eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines MatrixAndObjectDataTypes[i].dataType; 971474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 9729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 973462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 974b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 975b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 9769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 9799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 9809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 981cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType RSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 982b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet T = GetCanonicalType(T); 9835abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((T == nullptr) || (T->getTypeClass() != clang::Type::Record)) 9849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 9859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 986b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 987b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 988b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 989b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 990474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 991474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 992474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 993474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == MatrixDataType; 994b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 995b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 996b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 997474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (DT < 0 || DT >= DataTypeMax) { 998474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return false; 999474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 1000474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[DT].category == ObjectDataType; 10019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 10029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1003feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 1004feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 1005feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 1006feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 1007feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1008feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 1009feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 1010feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 1011feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1012feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1013b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 1014feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 1015b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (RD) { 1016b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines RD = RD->getDefinition(); 1017b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1018b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (!RD) { 1019b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines return false; 1020b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1021b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 1022feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1023feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 1024feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 1025feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 1026feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 1027feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 1028feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 1029feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1030feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 1031feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 1032feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1033feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 1034cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = GetRSSpecificType(FT); 1035feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 1036feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 1037feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 1038feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1039feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 1040cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix2x2: 1041cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix3x3: 1042cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix4x4: 1043feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 1044feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 1045feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 1046feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 1047feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 1048feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 1049feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1050feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 1051feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 1052feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1053feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 1054feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 1055feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 1056feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 1057feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1058feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1059feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 1060feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 1061feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 1062feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 1063feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 10649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 1065474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int type = EPT->getType(); 1066474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert((type > DataTypeUnknown && type < DataTypeMax) && 10676e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 10689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines // All RS object types are 256 bits in 64-bit RS. 10699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (EPT->isRSObjectType() && EPT->getRSContext()->is64Bit()) { 10709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return 256; 10719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1072474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return gReflectionTypes[type].size_in_bits; 1073462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1074462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1075cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletDataType 10762ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 10775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (T == nullptr) 10789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1079462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 10819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 1082be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 1083b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::BuiltinType*>(T->getCanonicalTypeInternal().getTypePtr()); 1084474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 10855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 1086474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return info->type; 10879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1088474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // The size of type WChar depend on platform so we abandon the support 1089474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet // to them. 1090474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet Context->ReportError("built-in type cannot be exported: '%0'") 1091474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet << T->getTypeClassName(); 10929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 10959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 1096b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 10979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1099d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("primitive type cannot be exported: '%0'") 11002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 11019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1102462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1107462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11089ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 11099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 11109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 11119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 11129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 11132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 1114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 11165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 11186b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 11192b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 1120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11229ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 11232b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 11249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 11255abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RSExportType::NormalizeType(T, TypeName, Context, nullptr) 112678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 11272b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 1128e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 11295abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1130e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 1131462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1132462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11337c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 11349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 11359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 11379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 11389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 11399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 11409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 11419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 11429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 11439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 11449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 1145d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray std::vector<llvm::Type *> Elements; 1146d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray if (getRSContext()->is64Bit()) { 1147d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray // 64-bit path 1148d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt64Ty(C), 4)); 1149d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray return llvm::StructType::get(C, Elements, true); 1150d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray } else { 1151d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray // 32-bit legacy path 1152d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1153d56a92fc2b1d417ce53d9550548fe1661fa37d40Tim Murray return llvm::StructType::get(C, Elements, true); 1154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 1158e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar case DataTypeFloat16: { 1159e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar return llvm::Type::getHalfTy(C); 1160e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar break; 1161e4dd17d7b2a292a600756da7680beecd78f74033Pirama Arumuga Nainar } 11629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 11639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 11649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 11679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 11689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 117091a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 117191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 117291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 117391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 11749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 11759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 11769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 11779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 11809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 11819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 11829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 11839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 11849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 11859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 11889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 11899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 11909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1192a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1193a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 11949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 11959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1199462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 12009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12025abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1203462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1204462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1205641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1206641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1207641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1208641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1209641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1210fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1211fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1212fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1213fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 12145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1215fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1216fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1217fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 12189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1219462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12209ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 12219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 12229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 12239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 1224b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *PointeeType = GetPointeeType(PT); 12259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 12289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 12299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 12309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 12312ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 12322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 12339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1234462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12355abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (PointeeET == nullptr) { 12362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 12375abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 12389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1239462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12437c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 12447c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 12459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12483cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 12493cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12503cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1251641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 12523cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1253641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1254641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1255641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1256641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1257641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1258641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1259641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1260641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 12626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 12636315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 1264b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 1265474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet llvm::StringRef name; 1266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 1268474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1270b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::BuiltinType *BT = 1271b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet static_cast<const clang::BuiltinType*>( 1272b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet ElementType->getCanonicalTypeInternal().getTypePtr()); 1273b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet 1274a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1275a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1276474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 12779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1278474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet BuiltinInfo *info = FindBuiltinType(BT->getKind()); 12795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (info != nullptr) { 1280474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int I = EVT->getNumElements() - 1; 1281474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet if (I < kMaxVectorSize) { 1282474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet name = info->cname[I]; 1283474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 1284474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "Max vector is 4"); 1285462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 12869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1287474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return name; 1288462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1289462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12909ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 12919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 12929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 12945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(EVT != nullptr && EVT->getTypeClass() == clang::Type::ExtVector); 1295462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1296b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetExtVectorElementType(EVT); 1297cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetDataType(Context, ElementType); 1298462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1299cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT != DataTypeUnknown) 13009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 13019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 13029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 13039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 13049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 13059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 13065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1307462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1308462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13097c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 13107c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 13119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1314641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1315641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1316641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1317641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1318641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1319641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 132092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 132192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 132292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 132392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 132492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 13255abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((RT != nullptr) && (RT->getTypeClass() == clang::Type::Record)); 13266e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 132792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 132892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 132992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 133092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 133192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 13325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD != nullptr) { 133392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 133492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 1335d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 1336d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet RD->getLocation(), 1337d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have 1 field for saving values: '%0'") 1338d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13395abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 134092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 134192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 134292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 134392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 134492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 13455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((FT == nullptr) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1346d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1347d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field should" 1348d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet " be an array with constant size: '%0'") 1349d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13505abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 135192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 135292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 135392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 1354b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 13555abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if ((ElementType == nullptr) || 135692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 13579207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 13589207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 1359d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1360d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1361d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be a float array: '%0'") 1362d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13635abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 136492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 136592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 136692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 1367d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1368d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1369d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be an array with size %0: '%1'") 1370d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << (Dim * Dim) << (RD->getName()); 13715abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 137292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 137392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 137492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 137592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 1376d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1377d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have " 1378d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "exactly 1 field: '%0'") 1379d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 13805abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 138192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 138292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 138392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 138492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 138592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 138692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 13877c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 138892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 138992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 139092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 139192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 139292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 139392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 139492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 139592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1396a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 139792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 139892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1399641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1400641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1401641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1402641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1403641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 14042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 14052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 14062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 14072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 14085abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(CAT != nullptr && CAT->getTypeClass() == clang::Type::ConstantArray); 14092e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14106e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 14112e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14122e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 14136e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 14142e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1415b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type *ElementType = GetConstantArrayElementType(CAT); 14162e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 14172e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14185abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ElementET == nullptr) { 14195abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14202e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 14212e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14222e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 14232e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 14242e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 14252e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 14262e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14277c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 14282e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 14292e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 14302e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 14313cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 14323cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14333cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1434641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 14353cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1436641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1437641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1438641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1439641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1440a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1441a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1442a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1443a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1444641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1445641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 14469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 14479ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 14489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 14499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 14509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 14515abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(RT != nullptr && RT->getTypeClass() == clang::Type::Record); 1452462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 14546e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1455462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 14575abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (RD == nullptr) { 14586e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 14595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1461462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 14630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 14640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 14659e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 14665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((RL != nullptr) && 1467f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 14680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 14690da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 14700da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 14710da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 14720da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 14730da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 1474c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet RL->getDataSize().getQuantity(), 147568318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 14769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 14779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 14799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 14809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 148191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 14829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 148443730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao slangAssert(FI->getKind() == clang::Decl::Field); 14859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 14869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14872ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 14885abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 14892ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 14926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 14939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ET != nullptr) { 14950da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 14960da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 14970da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 14982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 1499d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1500d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "field type cannot be exported: '%0.%1'") 1501d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 15025abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 15032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 15049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 15050a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 15069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1507462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1508462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15097c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 15103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 15113cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 15127c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 15137c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1514462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15153cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 15169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 15179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 15189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 15199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 15201f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 15219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 15229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1523462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 15253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 15263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 15275abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (ST != nullptr) { 15287c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 15297c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 15305abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 15317c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1532462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1533641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 15343cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 15353cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 15363cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1537641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1538641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1539641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1540641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1541641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1542641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 15433cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1544641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1545641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1546641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1547641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1548641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1549641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1550641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1551641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1552641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1553641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1554641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1555641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1556641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1557641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1558641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1559641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1560641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1561641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1562641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1563641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1564641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1565e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 15661b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 15671b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 15681b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 15691b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15701b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15711b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15721b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15731b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15741b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15751b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15761b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 15771b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 15781b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 15791b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 15801b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 15811b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15821b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15831b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 15841b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 15851b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 15861b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 15871b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15881b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15891b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 15901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 15911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 15921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 15931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 15941b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15951b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15961b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 15971b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 15981b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 15991b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 16001b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 16011b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16021b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 16041b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 16051b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 16061b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16071b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 16081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 16091b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 16121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 16131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1614e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1615