slang_rs_export_type.cpp revision d5a84f6d49d64738e4bb7c9dea7242e48acad959
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 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/RecordLayout.h" 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/DerivedTypes.h" 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Target/TargetData.h" 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Type.h" 310a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 35a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 36d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines#include "slang_version.h" 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 40641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 41641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 44e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 46fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 47fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 48fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 49fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 50fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 51fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 52fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 53fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 5447aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 5547aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 5647aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 5747aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 58fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 5947aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 60fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 61fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 62fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 63fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 64fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 65fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 66fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 67fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 68fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 69fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 70fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 71fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 72fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 73fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 74fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 75fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 76fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 77fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 78fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 79fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 80fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 81fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 82fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 8324e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 8424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 8524e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 869207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 8724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 885bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 8924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 909207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic void ReportTypeError(clang::DiagnosticsEngine *DiagEngine, 9124e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 9224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 93d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const char *Message, 94d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 959207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (!DiagEngine) { 9624e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 999207a2e495c8363606861e4f034504ec5c153dabLogan Chien const clang::SourceManager &SM = DiagEngine->getSourceManager(); 10078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 10124e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 10224e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 10324e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 1059207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 1069207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(TopLevelRecord->getLocation(), SM), 1079207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 108d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines << TopLevelRecord->getName() << TargetAPI; 10924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (VD) { 1109207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 1119207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(VD->getLocation(), SM), 1129207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 113d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines << VD->getName() << TargetAPI; 11424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 1156e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 11624e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 11824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11924e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 12024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 12124e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 1229207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 12324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1245bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 12524e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 12624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 12724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 1289207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1299207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 13024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 13124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 13224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 13324e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 13424e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 13524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 13624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 13724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 1389207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1399207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 14024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 14124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 14224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 14324e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 1449207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1459207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 14624e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 14724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 14824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 14924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 1509207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 151d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TopLevelRecord) == NULL) { 15224e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 153d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 15424e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 155d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 15624e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 15724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 15824e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 159e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 160e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 161e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::DiagnosticsEngine *DiagEngine, 162e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 1635bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 167462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1701f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 173be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 174be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 177a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 179a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 183462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 187b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 188d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines RSExportPrimitiveType::DataTypeUnknown) { 1896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 190d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 193cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 194d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines ReportTypeError(DiagEngine, VD, T->getAsUnionType()->getDecl(), 1959207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 196cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 197cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 1986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 199cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 200cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 201cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 20224e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 2032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 2052ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 2069207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, NULL, T->getAsStructureType()->getDecl(), 2079207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 2082ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 211f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 212e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 213e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 214e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 215e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 2169207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, NULL, RD, 2179207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 218e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 219e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 220e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 224f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 227f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 2330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 234e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 2359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2375bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (!TypeExportableHelper(FT, SPS, DiagEngine, VD, TopLevelRecord)) { 2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 2402ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 2412ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 2422ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 2432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 2442ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 2459207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (DiagEngine) { 2469207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 2479207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(FD->getLocation(), 2489207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getSourceManager()), 2499207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 2509207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 2519207a2e495c8363606861e4f034504ec5c153dabLogan Chien "bit fields are not able to be exported: '%0.%1'")) 2529207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName() 2539207a2e495c8363606861e4f034504ec5c153dabLogan Chien << FD->getName(); 2542ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2562ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 258462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 262e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 2639207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, NULL, TopLevelRecord, 2649207a2e495c8363606861e4f034504ec5c153dabLogan Chien "structures containing pointers cannot be exported: '%0'"); 265c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 266c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 26724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 268be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 269be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2722e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->getTypeClass() == clang::Type::Pointer) 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2752e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 2779207a2e495c8363606861e4f034504ec5c153dabLogan Chien (TypeExportableHelper(PointeeType, SPS, DiagEngine, VD, 2785bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 285be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 289f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 292462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 2949207a2e495c8363606861e4f034504ec5c153dabLogan Chien (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 2955bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 2969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 3012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 302be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 3032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 3049207a2e495c8363606861e4f034504ec5c153dabLogan Chien return ConstantArrayTypeExportableHelper(CAT, SPS, DiagEngine, VD, 3055bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord); 3062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 3079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 3089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 309462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 3109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 313e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 314e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 3159207a2e495c8363606861e4f034504ec5c153dabLogan Chien// If the Type T is not exportable, this function returns NULL. DiagEngine is 31678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// used to generate proper Clang diagnostic messages when a 317e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 318e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 319e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 320e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 3219207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 3225bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 323e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 324e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 325e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 3265bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines return TypeExportableHelper(T, SPS, DiagEngine, VD, NULL); 32778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 32878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 329d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateRSObjectInVarDecl(clang::VarDecl *VD, 330d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 331d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 332d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 333d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 334d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 335d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 336d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (VD->getLinkage() == clang::ExternalLinkage) { 337d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 338d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 339d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 340d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::ASTContext &C = VD->getASTContext(); 341d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines ReportTypeError(&C.getDiagnostics(), VD, NULL, 342d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 343d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 344d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 345d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 346d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 347d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 348d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 349d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 350d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 351d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 352d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 353d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 354d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// Helper function for ValidateVarDecl(). We do a recursive descent on the 355d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 356d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 357d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 358d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 359d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 360d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// VD - top-level variable declaration that we are validating. 361d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// T - sub-type of VD's type that we are validating. 362d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 363d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 364d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 365d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 36678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateVarDeclHelper( 36778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::VarDecl *VD, 36878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 36978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 370d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 371d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 372d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 37378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = GET_CANONICAL_TYPE(T)) == NULL) 37478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 37578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 37678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 37778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 37878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 37978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 38078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 381d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 382d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (!ValidateRSObjectInVarDecl(VD, InCompositeType, TargetAPI)) { 383d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 384d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 385d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 386d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 38778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportPrimitiveType::GetRSSpecificType(T) != 38878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RSExportPrimitiveType::DataTypeUnknown) { 38978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 39078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 39178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 39278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::ASTContext &C = VD->getASTContext(); 39378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(&C.getDiagnostics(), VD, UnionDecl, 39478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 39578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 39678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 39778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 39878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 39978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *RD = NULL; 40078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 40178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 40278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 40378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 40478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 40578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 40678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 40778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 40878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 40978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 41078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 41278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD != NULL) { 41378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 41478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD == NULL) { 41578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 41678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 41778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 42178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 42278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 42378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 42578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 42678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 42878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 42978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 43078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 43178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 43278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 43378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 43478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FT = GET_CANONICAL_TYPE(FT); 43578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 436d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (!ValidateVarDeclHelper(VD, FT, SPS, true, UnionDecl, TargetAPI)) { 43778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 43878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 43978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 44278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 44578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 44678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 44978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::PointerType *PT = 45078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T); 45178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 45278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 453d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return ValidateVarDeclHelper(VD, PointeeType, SPS, InCompositeType, 454d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines UnionDecl, TargetAPI); 45578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 45678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 45778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 45878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 45978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 46078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 461d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return ValidateVarDeclHelper(VD, ElementType, SPS, true, UnionDecl, 462d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TargetAPI); 46378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 46478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 46578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 46678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ConstantArrayType *CAT = 46778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 46878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 469d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return ValidateVarDeclHelper(VD, ElementType, SPS, true, UnionDecl, 470d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TargetAPI); 47178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 47278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 47378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 47478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 47578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 47678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 47778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 47878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 479e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 480e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 481e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 482e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 483e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 484e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 485e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 4869207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 4875bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 4885bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if ((T = TypeExportable(T, DiagEngine, VD)) == NULL) { 489e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 490e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 491e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 492e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 493e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TypeName.empty()) { 4949207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (DiagEngine) { 49524e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (VD) { 4969207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 4979207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(VD->getLocation(), 4989207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getSourceManager()), 4999207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 5009207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous types cannot be exported")); 50124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 5029207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 5039207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 5049207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous types cannot be exported")); 50524e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 506e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 507e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 508e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 509e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 510e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 511e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 512e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 513d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesbool RSExportType::ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI) { 51478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *T = VD->getType().getTypePtr(); 51578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 51678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 51778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 518d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return ValidateVarDeclHelper(VD, T, SPS, false, NULL, TargetAPI); 51978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 52078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 521e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 522e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 523e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 524e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::QualType T; 525e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD->getTypeSourceInfo()) 526e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getTypeSourceInfo()->getType(); 527e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 528e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getType(); 529e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 530e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 531e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 532e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 533e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 534e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 535e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 536e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 537e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 538e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 539e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 540e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 541e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 542e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 543e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 544e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 545be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 546be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 547e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 548e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 549e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 550e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 551e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 552e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 553e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 554e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 5556e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type of the builtin"); 556e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 557e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 558e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 559e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 560e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 561e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 562cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 563cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 564cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 565dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 566cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 567cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 568cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 569e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 570e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 57183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (RD->getTypedefNameForAnonDecl() != NULL) { 57283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 57383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 57483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 57583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 57683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 57783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 57883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 57983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 58083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 58183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao slangAssert(*RI != NULL && "cannot be NULL object"); 58283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 58383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 58483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 58583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 58683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 58783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 588e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 589e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 590e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 591e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 592e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 593e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 594e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 5955bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL)) { 596e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 597e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 598e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 599e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 600e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 601e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 602e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 603e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 604e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 605e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 606be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 607e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 608e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 609e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 610e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 611e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 612e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 613e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 614e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 615e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 616e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 617e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 618e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 619e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 620e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 621e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 622e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 6239ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 6249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 6259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 6269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 6279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 6289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 6299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 6309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 6329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 6339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 6359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 6369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 6379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 638b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 6399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 64092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 64192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 6429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 6439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 6449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 6459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 64792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 64892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 64992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 65092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 65192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 65292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 65392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 65492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 65592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 65692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 65792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 65892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 65992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 66092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 66192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 66292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 6639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 66492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 66592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 66692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 66792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 66892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 6699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 67292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 6739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 6749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 6809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 6819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 6849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 6855baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 68692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 6879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 6889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 6925baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 6939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 6962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 6972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 698be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 6992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 7002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 7019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 7029207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 7039207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 7049207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 7059207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unknown type cannot be exported: '%0'")) 7069207a2e495c8363606861e4f034504ec5c153dabLogan Chien << T->getTypeClassName(); 7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 712462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 7131f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 7146315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 7159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 716d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (NormalizeType(T, TypeName, Context->getDiagnostics(), NULL)) { 7179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 718d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 720d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 721462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 722462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7239ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 7249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 7259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 726462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 727462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 7299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 7306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 731462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 732462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 7349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 7359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 7369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 7379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 7386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 739462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 740462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7416b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 7426b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 7436b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 744a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 7456b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 7460da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 7470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 7486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 749a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 750a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 7510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 7520da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 7530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 7540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 7550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 7560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 7579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 758462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 759462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7603cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 7613cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 7623cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 763641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 764641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 7653cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 766641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 767641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 768641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 769641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 770641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 771641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 772641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 773a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 774a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 775a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 776a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 7779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 778b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 779b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 7809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 782462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 7849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 7859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 7869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 7879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 788462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 789462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7909ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 791b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 7929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 7939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 794462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 795b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 796b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 797b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 798b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 799a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 800b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 801a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 8029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 803462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 804b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 805b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 8099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8119ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 812b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 8139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 8149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 8159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 817b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 818b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 819b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 820b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 821b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 822b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 823b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 824b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 825b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 8269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 828feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 829feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 830feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 831feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 832feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 833feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 834feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 835feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 836feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 837feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 838feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 839feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RD = RD->getDefinition(); 840feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 841feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 842feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 843feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 844feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 845feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 846feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 847feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 848feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 849feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 850feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 851feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 852feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 853feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 854feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 855feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 856feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 857feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 858feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 859feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 860feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 861feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 862feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 863feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 864feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 865feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 866feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 867feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 868feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 869feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 870feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 871feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 872feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 873feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 874feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 875feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 876feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 877feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 878feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 879feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 880feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 881feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 882a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 883a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 884a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 885a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 886a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 887462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 888462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 8906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 8916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 8926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 8939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 894462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 895462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8969ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 8972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 8999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 900462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 9029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 903be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 904be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 9059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 906a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 907a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 908a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 9099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 910a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 911a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 912a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9149207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 9159207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 9169207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 9179207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 9189207a2e495c8363606861e4f034504ec5c153dabLogan Chien "built-in type cannot be exported: '%0'")) 9199207a2e495c8363606861e4f034504ec5c153dabLogan Chien << T->getTypeClassName(); 9209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 921462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 9269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 927b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 9289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9309207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 9319207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 9329207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 9339207a2e495c8363606861e4f034504ec5c153dabLogan Chien "primitive type cannot be exported: '%0'")) 9342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 9359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 936462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 938462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 940462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 941462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9429ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 9439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 9449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 9459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 9469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 9472ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 948462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 9509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9526b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 9532b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 954462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 955462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9569ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 9572b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 9589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 9595bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), NULL) 96078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 9612b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 962e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 9639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 964e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 965462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 966462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9677c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 9689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 9699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 9719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 9729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 9739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 9749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 9759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 9769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 9779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 9789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 9799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 9807c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type *> Elements; 9816315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 982a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 983462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 9859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 986462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 9889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 9899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 9909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 9939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 9949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 99691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 99791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 99891a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 99991a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 10009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 10019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 10029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 10039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 10069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 10079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 10089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 10099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 10109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 10119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 10149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 10159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 10169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1018a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1019a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 10209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 10219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 10246e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1025462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1027462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1029462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1030462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1031a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 1032a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1033a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1034a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1035a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1036a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1037a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1038a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1039a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1040641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1041641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1042641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1043641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1044641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1045fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1046fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1047fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1048fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 1049fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return NULL; 1050fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1051fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1052fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1054462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10559ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 10569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 10579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 10589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 10599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 10609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1061462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 10639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 10649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 10659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 10662ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 10672ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1069462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 10712ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 10729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 10739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1074462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1076462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1077462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10787c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 10797c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1081462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1082462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1083a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 1084a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1085a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1086a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1087a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1088a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1089a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1090a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1091a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1092a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1093a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1094a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 10953cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 10963cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 10973cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1098641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 10993cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1100641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1101641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1102641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1103641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1104641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1105641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1106641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1107641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 11096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 11106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 11119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1112462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 11149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 11159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1116be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1118a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1119a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1120a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 11219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 11239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 11249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1125a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1126a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 1127a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1128a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 1129a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 1130a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 1131a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 11329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 1134462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11389ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 11399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 11409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 11419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 11426e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 11459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 11462ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 11499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 11509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 11519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 11529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 11539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 11549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 11552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11587c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 11597c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 11609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1163a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1164a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1165a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1166a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1167a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1168a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1169a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1170a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1171a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1172a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1173641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1174641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1175641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1176641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1177641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1178641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 117992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 118092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 118192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 118292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 118392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 11846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 11856e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 118692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 118792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 118892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 118992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 119092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 119192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 11929207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 11932ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 119492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 119592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 11969207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 11979207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 11989207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 11999207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 12009207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: must have 1 field for saving values: '%0'")) 12012ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 120292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 120392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 120492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 120592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 120692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 120792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 120892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 12099207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12109207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12119207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 12129207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field should" 12139207a2e495c8363606861e4f034504ec5c153dabLogan Chien " be an array with constant size: '%0'")) 12149207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 121592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 121692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 121792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 121892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 12192e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 122092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 122192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 12229207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 12239207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 12249207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12259207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12269207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 12279207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field " 12289207a2e495c8363606861e4f034504ec5c153dabLogan Chien "should be a float array: '%0'")) 12299207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 123092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 123192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 123292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 123392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 12349207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12359207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12369207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 12379207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field " 12389207a2e495c8363606861e4f034504ec5c153dabLogan Chien "should be an array with size %0: '%1'")) 12399207a2e495c8363606861e4f034504ec5c153dabLogan Chien << (Dim * Dim) << (RD->getName()); 124092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 124192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 124292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 124392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 124492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 12459207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12469207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12479207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 12489207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: must have " 12499207a2e495c8363606861e4f034504ec5c153dabLogan Chien "exactly 1 field: '%0'")) 12509207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 125192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 125292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 125392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 125492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 125592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 125692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 125792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 12587c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 125992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 126092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 126192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 126292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 126392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 126492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 126592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 126692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1267a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 126892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 126992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1270a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1271a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1272a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1273a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1274a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1275a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1276a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 12776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1278a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1279a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1280a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1281a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1282641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1283641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1284641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1285641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1286641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 12882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 12892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 12902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 12916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 12922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12936e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 12942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 12966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 12972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 12992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 13002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 13022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 13032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 13042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 13062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 13072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 13082e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13092e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13107c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 13112e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 13122e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13132e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1314a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1315a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1316a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1317a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1318a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1319a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1320a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1321a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1322a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1323a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1324a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1325a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1326a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1327a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 13283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 13293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 13303cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1331641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 13323cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1333641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1334641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1335641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1336641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1337a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1338a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1339a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1340a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1341641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1342641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 13449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 13459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 13469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 13479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 13486e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1349462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 13516e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1352462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 13549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 13556e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 13569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 13579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1358462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 13600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 13610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 13629e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1363f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1364f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 13650da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 13660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 13670da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 13680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 13690da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 13700da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 137168318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 13729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 13739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 13759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 13769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 137791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 13789207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 13799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 13816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((*FI)->getKind() == clang::Decl::Field); 13829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 13839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 13852ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 13862ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 13879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 13896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 13909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13912ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 13920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 13930da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 13940da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 13952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 13969207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 13979207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), DiagEngine->getSourceManager()), 13989207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 13999207a2e495c8363606861e4f034504ec5c153dabLogan Chien "field type cannot be exported: '%0.%1'")) 14009207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName() << FD->getName(); 14012ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 14040a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 14059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1406462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1407462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14087c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 14093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 14103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 14117c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 14127c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1413462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14143cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 14159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 14169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 14179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 14189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 14191f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 14209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 14219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1422462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14233cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 14243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 14253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 14267c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao if (ST != NULL) { 14277c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 14287c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 14293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 14307c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1432641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1433a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1434a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1435a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1436a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1437a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1438e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1439a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1440a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1441a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1442a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1443a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1444a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1445a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1446a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1447a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1448a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1449a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1450a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1451a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1452a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1453a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1454a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1455a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1456a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1457a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1458e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1459a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1460a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1461a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1462a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 14633cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 14643cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14653cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1466641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1467641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1468641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1469641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1470641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1471641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 14723cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1473641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1474641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1475641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1476641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1477641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1478641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1479641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1480641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1481641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1482641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1483641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1484641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1485641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1486641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1487641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1488641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1489641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1490641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1491641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1492641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1493641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1494e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 14951b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 14961b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 14971b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 14981b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 14991b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15001b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15011b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15021b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15041b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15051b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 15061b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 15071b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 15081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 15091b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 15101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 15131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 15141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 15151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 15161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 15191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 15201b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 15211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 15221b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 15231b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15241b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 15261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 15271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 15281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 15291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 15301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 15331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 15341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 15351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 15371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 15381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 15411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1543e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1544