slang_rs_export_type.cpp revision b0fabe574945bfa85e688e77e9dcb5341fe08840
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <vector> 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h" 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/RecordLayout.h" 24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/DerivedTypes.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Target/TargetData.h" 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Type.h" 320a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 36a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 37d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines#include "slang_version.h" 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 40641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 41641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 42641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 45e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 47fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 48fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 49fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 50fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 51fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 52fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 53fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 54fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 5547aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 5647aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 5747aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 5847aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 59fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 6047aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 61fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 62fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 63fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 64fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 65fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 66fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 67fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 68fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 69fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 70fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 71fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 72fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 73fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 74fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 75fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 76fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 77fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 78fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 79fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 80fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 81fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 82fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 83fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 8424e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 8524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 8624e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 879207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 8824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 895bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 9024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 919207a2e495c8363606861e4f034504ec5c153dabLogan Chienstatic void ReportTypeError(clang::DiagnosticsEngine *DiagEngine, 9211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::NamedDecl *ND, 9324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 94d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const char *Message, 95d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 969207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (!DiagEngine) { 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 9924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 1009207a2e495c8363606861e4f034504ec5c153dabLogan Chien const clang::SourceManager &SM = DiagEngine->getSourceManager(); 10178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 10224e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 10324e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 10524e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 1069207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 1079207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(TopLevelRecord->getLocation(), SM), 1089207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 109d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines << TopLevelRecord->getName() << TargetAPI; 11011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (ND) { 1119207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 11211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::FullSourceLoc(ND->getLocation(), SM), 1139207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 11411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines << ND->getName() << TargetAPI; 11524e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 1166e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11824e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 11924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 12024e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 12124e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 12224e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 1239207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 12424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1255bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 12624e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 12724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 12824e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 1299207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1309207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 13124e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 13224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 13324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 13424e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 13524e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 13624e79f69125cf87fcaa78c04510a831037203eebStephen Hines 13724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 13824e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 1399207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1409207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 14124e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 14224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 14324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 14424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 1459207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, VD, TopLevelRecord, 1469207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 14724e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 14824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 14924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 15024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 1519207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 152d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TopLevelRecord) == NULL) { 15324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 154d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 15524e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 156d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 15724e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 15824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 15924e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 160e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 161e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 162e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::DiagnosticsEngine *DiagEngine, 163e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 1645bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1711f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 174be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 175be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 178a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 180a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 184462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 188b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 189d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines RSExportPrimitiveType::DataTypeUnknown) { 1906315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 191d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 194cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 195d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines ReportTypeError(DiagEngine, VD, T->getAsUnionType()->getDecl(), 1969207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 197cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 198cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 1996e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 200cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 201cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 202cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 20324e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 2042ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 2062ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 2079207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, NULL, T->getAsStructureType()->getDecl(), 2089207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 2092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 212f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 213e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 214e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 215e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 216e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 2179207a2e495c8363606861e4f034504ec5c153dabLogan Chien ReportTypeError(DiagEngine, NULL, RD, 2189207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 219e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 220e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 221e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 2249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 225f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 228f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 2340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 235e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 237462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2385bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (!TypeExportableHelper(FT, SPS, DiagEngine, VD, TopLevelRecord)) { 2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 2412ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 2422ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 2432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 2442ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 2452ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 2469207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (DiagEngine) { 2479207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 2489207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(FD->getLocation(), 2499207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getSourceManager()), 2509207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 2519207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 2529207a2e495c8363606861e4f034504ec5c153dabLogan Chien "bit fields are not able to be exported: '%0.%1'")) 2539207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName() 2549207a2e495c8363606861e4f034504ec5c153dabLogan Chien << FD->getName(); 2552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2562ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2572ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 259462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 263e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 264aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines ReportTypeError(DiagEngine, VD, TopLevelRecord, 265aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "structures containing pointers cannot be exported: '%0'"); 266c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 267c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 26824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 269be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 270be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 272462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 273aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines if (PointeeType->getTypeClass() == clang::Type::Pointer) { 274aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines ReportTypeError(DiagEngine, VD, TopLevelRecord, 275aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "multiple levels of pointers cannot be exported: '%0'"); 276aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines return NULL; 277aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines } 2782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2792e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 2819207a2e495c8363606861e4f034504ec5c153dabLogan Chien (TypeExportableHelper(PointeeType, SPS, DiagEngine, VD, 2825bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 289be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 293f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 296462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 2989207a2e495c8363606861e4f034504ec5c153dabLogan Chien (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 2995bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 3009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 3052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 306be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 3072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 3089207a2e495c8363606861e4f034504ec5c153dabLogan Chien return ConstantArrayTypeExportableHelper(CAT, SPS, DiagEngine, VD, 3095bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord); 3102e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 3119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 3129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 313462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 3149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 316462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 317e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 318e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 3199207a2e495c8363606861e4f034504ec5c153dabLogan Chien// If the Type T is not exportable, this function returns NULL. DiagEngine is 32078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// used to generate proper Clang diagnostic messages when a 321e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 322e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 323e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 324e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 3259207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 3265bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 327e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 328e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 329e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 3305bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines return TypeExportableHelper(T, SPS, DiagEngine, VD, NULL); 33178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 33278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 333d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hinesstatic bool ValidateRSObjectInVarDecl(clang::VarDecl *VD, 334d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 335d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 336d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 337d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 338d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 339d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 34011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (VD->hasLinkage() && (VD->getLinkage() == clang::ExternalLinkage)) { 341d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 342d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 343d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 344d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::ASTContext &C = VD->getASTContext(); 345d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines ReportTypeError(&C.getDiagnostics(), VD, NULL, 346d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 347d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 348d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 349d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 350d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 351d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 352d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 353d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 354d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 355d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 356d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 357d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 35811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// Helper function for ValidateType(). We do a recursive descent on the 359d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 360d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 361d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 362d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 363d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 36411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// C - ASTContext (for diagnostics + builtin types). 36511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// T - sub-type that we are validating. 36611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// ND - (optional) top-level named declaration that we are validating. 367d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 368d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 369d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 370d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 37111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// IsFilterscript - whether or not we are compiling for Filterscript 37211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesstatic bool ValidateTypeHelper( 37311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::ASTContext &C, 37478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 37511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, 37611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::SourceLocation Loc, 37778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 378d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 379d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 38011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines unsigned int TargetAPI, 38111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 38278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = GET_CANONICAL_TYPE(T)) == NULL) 38378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 38478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 38578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 38678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 38778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 38878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 38978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 390d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 39111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL); 39211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (VD && !ValidateRSObjectInVarDecl(VD, InCompositeType, TargetAPI)) { 393d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 394d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 395d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 396d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 39778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportPrimitiveType::GetRSSpecificType(T) != 39878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RSExportPrimitiveType::DataTypeUnknown) { 39978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 40078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 40178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 40211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ReportTypeError(&C.getDiagnostics(), NULL, UnionDecl, 40378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 40478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 40578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 40678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 40778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 40878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *RD = NULL; 40978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 41078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 41178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 41278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 41378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 41478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 41578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 41678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 41778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 41878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 41978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 42078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD != NULL) { 42278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 42378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD == NULL) { 42478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 42578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 42678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 42778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 42878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 43078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 43178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 43278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 43378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 43478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 43578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 43678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 43778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 43878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 43978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 44078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 44178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 44278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 44378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FT = GET_CANONICAL_TYPE(FT); 44478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (!ValidateTypeHelper(C, FT, ND, Loc, SPS, true, UnionDecl, 44611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript)) { 44778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 44878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 45078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 45178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 45278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 45378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 45478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 45511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 45611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::QualType QT = T->getCanonicalTypeInternal(); 45711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (QT == C.DoubleTy || 45811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongDoubleTy || 45911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongTy || 46011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongLongTy) { 46111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 46211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 46311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.Report( 46411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::FullSourceLoc(Loc, C.getSourceManager()), 46511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.getCustomDiagID( 46611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::DiagnosticsEngine::Error, 46711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 46811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Filterscript: '%0'")) << ND->getName(); 46911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 47011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.Report( 47111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::FullSourceLoc(Loc, C.getSourceManager()), 47211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.getCustomDiagID( 47311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::DiagnosticsEngine::Error, 47411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 47511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Filterscript")); 47611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 47711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 47811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 47911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 48078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 48178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 48278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 48378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 48411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 48511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 48611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 48711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.Report( 48811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::FullSourceLoc(Loc, C.getSourceManager()), 48911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines DiagEngine.getCustomDiagID( 49011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::DiagnosticsEngine::Error, 49111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Pointers are forbidden in Filterscript: '%0'")) << ND->getName(); 49211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 49311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 49411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // TODO(srhines): Find a better way to handle expressions (i.e. no 49511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // NamedDecl) involving pointers in FS that should be allowed. 49611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // An example would be calls to library functions like 49711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // rsMatrixMultiply() that take rs_matrixNxN * types. 49811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 49911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 50011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 50178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::PointerType *PT = 50278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T); 50378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 50478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return ValidateTypeHelper(C, PointeeType, ND, Loc, SPS, InCompositeType, 50611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines UnionDecl, TargetAPI, IsFilterscript); 50778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 50878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 50978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 51078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 51178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 51278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 513b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines if (TargetAPI < SLANG_ICS_TARGET_API && 514b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines InCompositeType && 515fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines EVT->getNumElements() == 3 && 516fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND && 517fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND->getLinkage() == clang::ExternalLinkage) { 51811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines ReportTypeError(&C.getDiagnostics(), ND, NULL, 519b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "structs containing vectors of dimension 3 cannot " 520b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "be exported at this API level: '%0'"); 521b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines return false; 522b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines } 52311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return ValidateTypeHelper(C, ElementType, ND, Loc, SPS, true, UnionDecl, 52411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript); 52578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 52878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ConstantArrayType *CAT = 52978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 53078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 53111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return ValidateTypeHelper(C, ElementType, ND, Loc, SPS, true, UnionDecl, 53211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript); 53378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 53478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 53578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 53678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 53778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 53878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 53978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 54078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 541e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 542e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 543e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 544e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 545e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 546e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 547e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 5489207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine, 5495bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 5505bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if ((T = TypeExportable(T, DiagEngine, VD)) == NULL) { 551e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 552e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 553e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 554e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 555e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TypeName.empty()) { 5569207a2e495c8363606861e4f034504ec5c153dabLogan Chien if (DiagEngine) { 55724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (VD) { 5589207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 5599207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(VD->getLocation(), 5609207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getSourceManager()), 5619207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 5629207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous types cannot be exported")); 56324e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 5649207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 5659207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 5669207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous types cannot be exported")); 56724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 568e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 569e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 570e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 571e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 572e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 573e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 574e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 57511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesbool RSExportType::ValidateType(clang::ASTContext &C, clang::QualType QT, 57611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, clang::SourceLocation Loc, unsigned int TargetAPI, 57711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 57811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::Type *T = QT.getTypePtr(); 57978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 58078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 58178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 58211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return ValidateTypeHelper(C, T, ND, Loc, SPS, false, NULL, TargetAPI, 58311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines IsFilterscript); 58411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return true; 58511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 58611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 58711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesbool RSExportType::ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI, 58811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 58911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return ValidateType(VD->getASTContext(), VD->getType(), VD, 59011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VD->getLocation(), TargetAPI, IsFilterscript); 59178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 59278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 593e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 594e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 595e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 596e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::QualType T; 597e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD->getTypeSourceInfo()) 598e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getTypeSourceInfo()->getType(); 599e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 600e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getType(); 601e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 602e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 603e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 604e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 605e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 606e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 607e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 608e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 609e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 610e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 611e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 612e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 613e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 614e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 615e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 616e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 617be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 618be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 619e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 620e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 621e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 622e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 623e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 624e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 625e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 626e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 6276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type of the builtin"); 628e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 629e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 630e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 631e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 632e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 633e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 634cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 635cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 636cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 637dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 638cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 639cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 640cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 641e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 642e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 64383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (RD->getTypedefNameForAnonDecl() != NULL) { 64483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 64583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 64683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 64783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 64883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 64983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 65083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 65183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 65283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 65383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao slangAssert(*RI != NULL && "cannot be NULL object"); 65483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 65583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 65683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 65783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 65883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 65983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 660e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 661e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 662e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 663e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 664e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 665e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 666e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 6675bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL)) { 668e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 669e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 670e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 671e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 672e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 673e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 674e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 675e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 676e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 677e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 678be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 679e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 680e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 681e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 682e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 683e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 684e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 685e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 686e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 687e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 688e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 689e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 690e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 691e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 692e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 693e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 694e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 6959ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 6969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 6979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 6989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 6999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 7009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 7019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 7029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 7049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 7059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 7089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 7099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 710b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 71292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 71392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 7149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 7159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 7169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 7179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 71992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 72092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 72192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 72292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 72392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 72492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 72592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 72692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 72792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 72892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 72992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 73092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 73192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 73292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 73392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 73492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 7359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 73692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 73792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 73892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 73992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 74092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 7419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 74492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 7459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 7469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 7529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 7539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 7569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 7575baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 75892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 7599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 7639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 7645baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 7659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7672e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 7682e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 7692e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 770be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 7712e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 7722e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 7739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 7749207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 7759207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 7769207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 7779207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unknown type cannot be exported: '%0'")) 7789207a2e495c8363606861e4f034504ec5c153dabLogan Chien << T->getTypeClassName(); 7799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 7851f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 7866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 7879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 788d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (NormalizeType(T, TypeName, Context->getDiagnostics(), NULL)) { 7899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 790d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 7919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 792d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 793462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 794462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7959ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 7969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 7979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 798462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 799462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 8019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 8026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 803462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 804462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 8106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 811462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 812462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8136b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 8146b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 8156b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 816a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 8176b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 8180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 8190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 8206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 821a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 822a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 8230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 8240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 8250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 8260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 8270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 8280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 830462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 831462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8323cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 8333cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 8343cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 835641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 836641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 8373cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 838641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 839641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 840641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 841641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 842641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 843641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 844641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 845a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 846a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 847a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 848a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 850b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 851b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 854462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 8589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 860462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 861462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 863b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 8649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 8659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 866462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 867b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 868b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 869b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 870b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 871a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 872b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 873a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 8749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 875462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 876b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 877b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 8789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 8819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8839ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 884b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 8859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 8869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 8879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 889b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 890b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 891b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 892b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 893b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 894b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 895b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 896b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 897b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 900feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 901feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 902feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 903feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 904feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 905feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 906feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 907feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 908feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 909feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 910b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 911feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 912b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (RD) { 913b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines RD = RD->getDefinition(); 914b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 915b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (!RD) { 916b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines return false; 917b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 918b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 919feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 920feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 921feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 922feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 923feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 924feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 925feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 926feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 927feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 928feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 929feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 930feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 931feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 932feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 933feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 934feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 935feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 936feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 937feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 938feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 939feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 940feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 941feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 942feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 943feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 944feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 945feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 946feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 947feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 948feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 949feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 950feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 951feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 952feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 953feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 954feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 955feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 956feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 957feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 958feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 959feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 960feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 961a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 962a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 963a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 964a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 965a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 966462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 967462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 9696e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 9706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 9716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 9729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 973462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 974462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9759ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 9762ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 9779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 9789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 979462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 9819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 982be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 983be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 9849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 985a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 986a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 987a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 9889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 989a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 990a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 991a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 9929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9939207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 9949207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 9959207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 9969207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 9979207a2e495c8363606861e4f034504ec5c153dabLogan Chien "built-in type cannot be exported: '%0'")) 9989207a2e495c8363606861e4f034504ec5c153dabLogan Chien << T->getTypeClassName(); 9999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1000462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 10059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 1006b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 10079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 10099207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 10109207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 10119207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 10129207a2e495c8363606861e4f034504ec5c153dabLogan Chien "primitive type cannot be exported: '%0'")) 10132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 10149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1015462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1017462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 1019462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1020462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10219ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 10229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 10239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 10249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 10262ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 1027462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 10299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 10309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 10316b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 10322b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 1033462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1034462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10359ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 10362b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 10385bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), NULL) 103978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 10402b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 1041e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 10429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1043e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 1044462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1045462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10467c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 10489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 10529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 10559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 10579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 10597c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type *> Elements; 10606315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1061a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 1062462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 10649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1065462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 10679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 10699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 10729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 10739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 107591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 107691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 107791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 107891a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 10799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 10819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 10829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 10859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 10869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 10879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 10889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 10899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 10909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 10939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 10949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 10959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1097a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1098a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 10999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 11009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 11019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1104462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1108462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1109462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1110a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 1111a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1112a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1113a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1114a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1115a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1116a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1117a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1118a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1119641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1120641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1121641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1122641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1123641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1124fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1125fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1126fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1127fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 1128fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return NULL; 1129fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1130fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1131fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 11329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11349ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 11359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 11369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 11379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 11389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 11399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 11429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 11439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 11449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 11452ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 11462ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 11479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 11502ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 11519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 11529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11577c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 11587c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 11599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1161462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1162a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 1163a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1164a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1165a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1166a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1167a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1168a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1169a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1170a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1171a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1172a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1173a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 11743cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 11753cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 11763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1177641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 11783cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1179641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1180641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1181641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1182641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1183641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1184641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1185641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1186641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 11886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 11896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 11909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1191462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 11939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 11949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1195be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 11969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1197a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1198a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1199a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 12009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 12029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 12039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1204a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1205a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 1206a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1207a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 1208a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 1209a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 1210a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 12119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 12129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 1213462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 12149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1216462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12179ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 12189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 12199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 12216e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1222462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 12249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 12252ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 12289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 12299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 12309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 12319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 12329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 12339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 12342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1235462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1236462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12377c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 12387c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 12399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1240462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1241462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1242a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1243a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1244a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1245a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1246a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1247a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1248a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1249a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1250a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1251a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1252641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1253641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1254641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1255641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1256641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1257641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 125892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 125992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 126092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 126192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 126292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 12636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 12646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 126592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 126692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 126792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 126892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 126992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 127092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 12719207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 12722ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 127392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 127492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 12759207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12769207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12779207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID( 12789207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 12799207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: must have 1 field for saving values: '%0'")) 12802ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 128192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 128292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 128392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 128492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 128592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 128692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 128792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 12889207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 12899207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 12909207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 12919207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field should" 12929207a2e495c8363606861e4f034504ec5c153dabLogan Chien " be an array with constant size: '%0'")) 12939207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 129492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 129592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 129692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 129792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 12982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 129992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 130092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 13019207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 13029207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 13039207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 13049207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 13059207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 13069207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field " 13079207a2e495c8363606861e4f034504ec5c153dabLogan Chien "should be a float array: '%0'")) 13089207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 130992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 131092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 131192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 131292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 13139207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 13149207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 13159207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 13169207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: first field " 13179207a2e495c8363606861e4f034504ec5c153dabLogan Chien "should be an array with size %0: '%1'")) 13189207a2e495c8363606861e4f034504ec5c153dabLogan Chien << (Dim * Dim) << (RD->getName()); 131992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 132092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 132192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 132292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 132392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 13249207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 13259207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), *SM), 13269207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 13279207a2e495c8363606861e4f034504ec5c153dabLogan Chien "invalid matrix struct: must have " 13289207a2e495c8363606861e4f034504ec5c153dabLogan Chien "exactly 1 field: '%0'")) 13299207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName(); 133092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 133192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 133292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 133392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 133492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 133592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 133692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 13377c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 133892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 133992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 134092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 134192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 134292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 134392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 134492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 134592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1346a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 134792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 134892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1349a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1350a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1351a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1352a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1353a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1354a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1355a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 13566e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1357a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1358a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1359a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1360a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1361641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1362641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1363641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1364641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1365641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13662e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 13672e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 13682e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 13692e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 13706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 13712e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 13732e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 13756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 13762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13772e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 13782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 13792e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 13812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 13822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 13832e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 13852e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 13862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 13872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13897c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 13902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 13912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1393a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1394a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1395a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1396a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1397a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1398a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1399a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1400a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1401a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1402a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1403a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1404a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1405a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1406a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 14073cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 14083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1410641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 14113cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1412641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1413641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1414641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1415641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1416a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1417a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1418a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1419a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1420641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1421641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 14229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 14239ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 14249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 14259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 14269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 14276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1428462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 14306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1431462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 14339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 14346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 14359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 14369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1437462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14380da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 14390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 14400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 14419e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1443f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 14440da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 14450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 14460da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 14470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 14480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 14490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 145068318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 14519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 14529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 14549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 14559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 145691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 14579207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 14589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 146043730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao slangAssert(FI->getKind() == clang::Decl::Field); 14619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 14629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14632ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 14642ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14652ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 14686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 14699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14702ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 14710da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 14720da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 14730da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 14742ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 14759207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->Report( 14769207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(RD->getLocation(), DiagEngine->getSourceManager()), 14779207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 14789207a2e495c8363606861e4f034504ec5c153dabLogan Chien "field type cannot be exported: '%0.%1'")) 14799207a2e495c8363606861e4f034504ec5c153dabLogan Chien << RD->getName() << FD->getName(); 14802ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14812ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 14830a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 14849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1485462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1486462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14877c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 14883cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 14893cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 14907c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 14917c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1492462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14933cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 14949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 14959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 14969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 14979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 14981f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 14999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 15009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1501462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 15023cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 15033cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 15043cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 15057c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao if (ST != NULL) { 15067c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 15077c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 15083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 15097c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1510462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1511641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1512a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1513a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1514a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1515a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1516a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1517e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1518a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1519a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1520a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1521a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1522a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1523a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1524a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1525a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1526a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1527a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1528a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1529a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1530a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1531a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1532a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1533a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1534a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1535a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1536a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1537e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1538a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1539a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1540a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1541a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 15423cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 15433cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 15443cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1545641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1546641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1547641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1548641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1549641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1550641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 15513cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1552641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1553641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1554641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1555641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1556641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1557641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1558641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1559641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1560641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1561641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1562641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1563641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1564641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1565641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1566641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1567641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1568641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1569641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1570641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1571641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1572641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1573e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 15741b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 15751b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 15761b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 15771b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15781b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15791b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15801b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15811b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15821b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15831b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15841b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 15851b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 15861b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 15871b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 15881b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 15891b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15901b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15911b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 15921b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 15931b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 15941b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 15951b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15961b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15971b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 15981b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 15991b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 16001b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 16011b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 16021b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16031b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16041b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 16051b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 16061b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 16071b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 16081b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 16091b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 16101b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16111b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 16121b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 16131b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 16141b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16151b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 16161b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 16171b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16181b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 16191b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 16201b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 16211b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1622e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1623