slang_rs_export_type.cpp revision ee4016d1247d3fbe50822de279d3da273d8aef4c
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <vector> 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2243730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao#include "clang/AST/ASTContext.h" 2323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "clang/AST/Attr.h" 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/RecordLayout.h" 25462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 2723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DataLayout.h" 2823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/DerivedTypes.h" 2923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Type.h" 300a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 34a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 35d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines#include "slang_version.h" 36462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 37641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 40641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 43e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 45fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hinesstatic RSReflectionType gReflectionTypes[] = { 46fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 47fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 48fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 49fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 50fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 51fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 52fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 5347aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 5447aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 5547aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 5647aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 57fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 5847aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines {"BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 59fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 60fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 61fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 62fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 63fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 64fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 65fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 66fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 67fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 68fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 69fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 70fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 71fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 72fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 73fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 74fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 75fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 76fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 77fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 78fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 79fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines {"RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 80fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines}; 81fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 8224e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 8324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 8424e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 8548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 8624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 875bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord); 8824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 89ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murraytemplate <unsigned N> 90d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic void ReportTypeError(slang::RSContext *Context, 9111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::NamedDecl *ND, 9224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 93ee4016d1247d3fbe50822de279d3da273d8aef4cTim Murray const char (&Message)[N], 94d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI = 0) { 9524e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 9624e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 99d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(TopLevelRecord->getLocation(), Message) 100d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TopLevelRecord->getName() << TargetAPI; 10111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else if (ND) { 102d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(ND->getLocation(), Message) << ND->getName() 103d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << TargetAPI; 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 1056e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 10624e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 10724e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 10824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 10924e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 11024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 11124e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 11248d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 11324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 1145bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::RecordDecl *TopLevelRecord) { 11524e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 11624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 118d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 1199207a2e495c8363606861e4f034504ec5c153dabLogan Chien "multidimensional arrays cannot be exported: '%0'"); 12024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 12124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 12224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 12324e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 12424e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 12524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 12624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 12724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 128d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 1299207a2e495c8363606861e4f034504ec5c153dabLogan Chien "vectors of non-primitive types cannot be exported: '%0'"); 13024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 13124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 13224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 13324e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 134d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 1359207a2e495c8363606861e4f034504ec5c153dabLogan Chien "arrays of width 3 vector types cannot be exported: '%0'"); 13624e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 13724e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 13824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 13924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 14048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (TypeExportableHelper(ElementType, SPS, Context, VD, 141d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines TopLevelRecord) == NULL) { 14224e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 143d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 14424e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 145d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 14624e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 14724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 14824e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 149e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::Type const *T, 150e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 15148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 152e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines clang::VarDecl const *VD, 1535bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines clang::RecordDecl const *TopLevelRecord) { 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1601f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 163be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 164be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 167a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 169a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 173462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 177b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 178d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines RSExportPrimitiveType::DataTypeUnknown) { 1796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 180d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 183cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 184d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, T->getAsUnionType()->getDecl(), 1859207a2e495c8363606861e4f034504ec5c153dabLogan Chien "unions cannot be exported: '%0'"); 186cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 187cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 1886e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 189cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 190cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 191cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 19224e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 1932ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 1952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 196d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, T->getAsStructureType()->getDecl(), 1979207a2e495c8363606861e4f034504ec5c153dabLogan Chien "struct is not defined in this module"); 1982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 201f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 202e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 203e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 204e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 205e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 206d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, RD, 2079207a2e495c8363606861e4f034504ec5c153dabLogan Chien "anonymous structures cannot be exported"); 208e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 209e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 210e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 2119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 2129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 2139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 214f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 217f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 2230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 224e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 226462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 22748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (!TypeExportableHelper(FT, SPS, Context, VD, TopLevelRecord)) { 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 2302ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 2312ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 2322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 2332ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 2342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 235d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 236d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet FD->getLocation(), 237d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "bit fields are not able to be exported: '%0.%1'") 238d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 2392ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2402ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 242462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 246e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 247d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 248aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "structures containing pointers cannot be exported: '%0'"); 249c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 250c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 25124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 252be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 253be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 255462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 256aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines if (PointeeType->getTypeClass() == clang::Type::Pointer) { 257d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, TopLevelRecord, 258aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines "multiple levels of pointers cannot be exported: '%0'"); 259aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines return NULL; 260aa82e74b08fcdc2e4e6c1f6796699566b331b656Stephen Hines } 2612e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2622e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2632e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 26448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(PointeeType, SPS, Context, VD, 2655bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 272be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 276f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 279462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 28148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines (TypeExportableHelper(ElementType, SPS, Context, VD, 2825bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord) == NULL)) 2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 2882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 289be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 2902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 29148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Context, VD, 2925bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines TopLevelRecord); 2932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 29448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines case clang::Type::Enum: { 29548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // FIXME: We currently convert enums to integers, rather than reflecting 29648d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines // a more complete (and nicer type-safe Java version). 29748d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return Context->getASTContext().IntTy.getTypePtr(); 29848d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } 2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 30048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slangAssert(false && "Unknown type cannot be validated"); 3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 302462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 3039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 3049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 306e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 307e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 3089207a2e495c8363606861e4f034504ec5c153dabLogan Chien// If the Type T is not exportable, this function returns NULL. DiagEngine is 30978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// used to generate proper Clang diagnostic messages when a 310e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 311e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 312e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 313e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 31448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines slang::RSContext *Context, 3155bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 316e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 317e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 318e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 31948d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines return TypeExportableHelper(T, SPS, Context, VD, NULL); 32078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 32178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 322d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletstatic bool ValidateRSObjectInVarDecl(slang::RSContext *Context, 323d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, bool InCompositeType, 324d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines unsigned int TargetAPI) { 325d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (TargetAPI < SLANG_JB_TARGET_API) { 326d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are already in a composite type (like an array or structure). 327d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (InCompositeType) { 328d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are actually exported (i.e. non-static). 32944f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines if (VD->hasLinkage() && 33044f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines (VD->getFormalLinkage() == clang::ExternalLinkage)) { 331d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines // Only if we are not a pointer to an object. 332d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 333d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (T->getTypeClass() != clang::Type::Pointer) { 334d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, VD, NULL, 335d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "arrays/structures containing RS object types " 336d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines "cannot be exported in target API < %1: '%0'", 337d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines SLANG_JB_TARGET_API); 338d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 339d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 340d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 341d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 342d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 343d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 344d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return true; 345d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines} 346d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 34711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// Helper function for ValidateType(). We do a recursive descent on the 348d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// type hierarchy to ensure that we can properly export/handle the 349d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// declaration. 350d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// \return true if the variable declaration is valid, 351d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// false if it is invalid (along with proper diagnostics). 352d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// 35311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// C - ASTContext (for diagnostics + builtin types). 35411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// T - sub-type that we are validating. 35511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// ND - (optional) top-level named declaration that we are validating. 356d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// SPS - set of types we have already seen/validated. 357d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// InCompositeType - true if we are within an outer composite type. 358d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// UnionDecl - set if we are in a sub-type of a union. 359d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines// TargetAPI - target SDK API level. 36011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines// IsFilterscript - whether or not we are compiling for Filterscript 36111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hinesstatic bool ValidateTypeHelper( 362d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet slang::RSContext *Context, 36311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::ASTContext &C, 36478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 36511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::NamedDecl *ND, 36611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::SourceLocation Loc, 36778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 368d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines bool InCompositeType, 369d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines clang::RecordDecl *UnionDecl, 37011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines unsigned int TargetAPI, 37111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 37278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = GET_CANONICAL_TYPE(T)) == NULL) 37378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 37478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 37578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 37678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 37778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 37878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 37978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 380d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(T)) { 38111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL); 382d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (VD && !ValidateRSObjectInVarDecl(Context, VD, InCompositeType, 383d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet TargetAPI)) { 384d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines return false; 385d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 386d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 387d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines 38878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportPrimitiveType::GetRSSpecificType(T) != 38978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RSExportPrimitiveType::DataTypeUnknown) { 39078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 39178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 39278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 393d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, NULL, UnionDecl, 39478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 39578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 39678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 39778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 39878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 39978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *RD = NULL; 40078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 40178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 40278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 40378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 40478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 40578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 40678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 40778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 40878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 40978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 41078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 41278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD != NULL) { 41378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 41478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD == NULL) { 41578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 41678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 41778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 41978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 42178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 42278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 42378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 42578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 42678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 42878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 42978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 43078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 43178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 43278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 43378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 43478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FT = GET_CANONICAL_TYPE(FT); 43578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 436d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet if (!ValidateTypeHelper(Context, C, FT, ND, Loc, SPS, true, UnionDecl, 43711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines TargetAPI, IsFilterscript)) { 43878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 43978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 44378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 44478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 44578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 44611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 44711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines clang::QualType QT = T->getCanonicalTypeInternal(); 44811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (QT == C.DoubleTy || 44911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongDoubleTy || 45011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongTy || 45111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines QT == C.LongLongTy) { 45211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 453d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 454d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 45511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 456d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript: '%0'") 457d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 45811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 459d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 460d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Loc, 46111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines "Builtin types > 32 bits in size are forbidden in " 462d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Filterscript"); 46311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 46411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 46511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 46611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 46778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 46878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 46978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 47078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 47111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (IsFilterscript) { 47211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines if (ND) { 473d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(Loc, 474d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "Pointers are forbidden in Filterscript: '%0'") 475d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << ND->getName(); 47611274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return false; 47711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } else { 47811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // TODO(srhines): Find a better way to handle expressions (i.e. no 47911274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // NamedDecl) involving pointers in FS that should be allowed. 48011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // An example would be calls to library functions like 48111274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines // rsMatrixMultiply() that take rs_matrixNxN * types. 48211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 48311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines } 48411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 48578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::PointerType *PT = 48678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T); 48778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 48878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 489d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, PointeeType, ND, Loc, SPS, 490d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet InCompositeType, UnionDecl, TargetAPI, 491d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet IsFilterscript); 49278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 49378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 49478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 49578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 49678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 49778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 498b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines if (TargetAPI < SLANG_ICS_TARGET_API && 499b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines InCompositeType && 500fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines EVT->getNumElements() == 3 && 501fdae63e8142f56521813f59e0c506ed3a1636021Stephen Hines ND && 50244f10063c2c08dab103a44cded0c3a288d65d43bStephen Hines ND->getFormalLinkage() == clang::ExternalLinkage) { 503d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet ReportTypeError(Context, ND, NULL, 504b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "structs containing vectors of dimension 3 cannot " 505b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines "be exported at this API level: '%0'"); 506b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines return false; 507b13b85e31ac978254cb1ed7653f149f8a3eef460Stephen Hines } 508d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 509d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet UnionDecl, TargetAPI, IsFilterscript); 51078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 51178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 51278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 51378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ConstantArrayType *CAT = 51478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 51578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 516d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, ElementType, ND, Loc, SPS, true, 517d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet UnionDecl, TargetAPI, IsFilterscript); 51878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 51978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 52178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 52278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 52478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 52578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 526e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 527e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 528e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 529e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 530e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 531e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 532e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 53348d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines RSContext *Context, 5345bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines const clang::VarDecl *VD) { 53548d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if ((T = TypeExportable(T, Context, VD)) == NULL) { 536e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 537e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 538e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 539e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 54048d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (Context && TypeName.empty()) { 54148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (VD) { 542d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(VD->getLocation(), 543d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "anonymous types cannot be exported"); 54448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines } else { 545d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("anonymous types cannot be exported"); 546e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 547e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 548e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 549e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 550e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 551e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 552e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 553d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateType(slang::RSContext *Context, clang::ASTContext &C, 554d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::QualType QT, clang::NamedDecl *ND, 555d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::SourceLocation Loc, 556d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet unsigned int TargetAPI, bool IsFilterscript) { 55711274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines const clang::Type *T = QT.getTypePtr(); 55878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 55978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 56078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 561d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateTypeHelper(Context, C, T, ND, Loc, SPS, false, NULL, TargetAPI, 56211274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines IsFilterscript); 56311274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines return true; 56411274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines} 56511274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines 566d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouilletbool RSExportType::ValidateVarDecl(slang::RSContext *Context, 567d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet clang::VarDecl *VD, unsigned int TargetAPI, 56811274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines bool IsFilterscript) { 569d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet return ValidateType(Context, VD->getASTContext(), VD->getType(), VD, 57011274a7324b478ec13e1d10a1b81350b34a65ab1Stephen Hines VD->getLocation(), TargetAPI, IsFilterscript); 57178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 57278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 573e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 574e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 575e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 5768de1922e037612f2521acac2f4c4289a9f71450dStephen Hines clang::QualType T = DD->getType(); 577e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 578e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 579e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 580e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 581e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 582e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 583e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 584e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 585e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 586e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 587e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 588e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 589e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 590e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 591e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 592e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 593be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 594be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 595e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 596e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 597e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 598e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 599e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 600e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 601e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 602e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 6036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type of the builtin"); 604e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 605e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 606e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 607e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 608e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 609e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 610cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 611cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 612cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 613dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 614cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 615cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 616cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 617e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 618e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 61983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (RD->getTypedefNameForAnonDecl() != NULL) { 62083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = RD->getTypedefNameForAnonDecl()->getName(); 62183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 62283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 62383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (Name.empty()) { 62483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao // Try to find a name from redeclaration (i.e. typedef) 62583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 62683f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RE = RD->redecls_end(); 62783f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI != RE; 62883f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao RI++) { 62983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao slangAssert(*RI != NULL && "cannot be NULL object"); 63083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao 63183f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao Name = (*RI)->getName(); 63283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao if (!Name.empty()) 63383f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao break; 63483f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 63583f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao } 636e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 637e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 638e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 639e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 640e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 641e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 642e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 6435bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL)) { 644e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 645e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 646e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 647e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 648e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 649e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 650e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 651e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 652e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 653e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 654be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 655e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 656e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 657e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 658e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 659e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 660e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 661e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 662e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 663e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 664e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 665e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 666e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 667e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 668e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 669e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 670e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 6719ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 6729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 6739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 6749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 6759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 6769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 6779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 6789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 6809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 6819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 6839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 6849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 6859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 686b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 6879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 68892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 68992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 6909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 6929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 6939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 69592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 69692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 69792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 69892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 69992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 70092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 70192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 70292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 70392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 70492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 70592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 70692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 70792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 70892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 70992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 71092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 71292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 71392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 71492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 71592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 71692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 7179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 72092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 7219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 7229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 7289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 7299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 7329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 7335baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 73492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 7359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 7369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 7399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 7405baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 7419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7432e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 7442e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 7452e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 746be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 7472e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 7482e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 7499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 750d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("unknown type cannot be exported: '%0'") 751d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << T->getTypeClassName(); 7529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 757462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 7581f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 7596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 76148d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (NormalizeType(T, TypeName, Context, NULL)) { 7629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 763d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } else { 7649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 765d5a84f6d49d64738e4bb7c9dea7242e48acad959Stephen Hines } 766462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 767462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7689ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 7699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 7709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 771462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 772462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 77423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines return ET->getRSContext()->getDataLayout()->getTypeStoreSize( 7756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 776462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 777462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 7799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 7809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 7819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 78223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines return ET->getRSContext()->getDataLayout()->getTypeAllocSize( 7836315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 785462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7866b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 7876b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 7886b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 789a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 7906b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 7910da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 7920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 7936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 794a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 795a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 7960da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 7970da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 7980da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 7990da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 8000da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 8010da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 8029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 803462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 804462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8053cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 8063cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 8073cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 808641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 809641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 8103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 811641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 812641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 813641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 814641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 815641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 816641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 817641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 818a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 819a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 820a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 821a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 8229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 823b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 824b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 827462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 8309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 8319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 833462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 834462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8359ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 836b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 8379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 8389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 839462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 840b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 841b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 842b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 843b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 844a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 845b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 846a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 848462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 849b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 850b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 857b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 8589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 8609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 862b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 863b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 864b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 865b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 866b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 867b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 868b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 869b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 870b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 8719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 8729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 873feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 874feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 875feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 876feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 877feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 878feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 879feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 880feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 881feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 882feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 883b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 884feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 885b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (RD) { 886b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines RD = RD->getDefinition(); 887b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 888b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (!RD) { 889b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines return false; 890b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 891b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines 892feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 893feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 894feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 895feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 896feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 897feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 898feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 899feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 900feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 901feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 902feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 903feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 904feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 905feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 906feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 907feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 908feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 909feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 910feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 911feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 912feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 913feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 914feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 915feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 916feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 917feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 918feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 919feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 920feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 921feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 922feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 923feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 924feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 925feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 926feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 927feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 928feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 929feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 930feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 931feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 932feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 933feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 934a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 935a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 936a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 937a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 938a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 939462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 940462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 9426e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 9436e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 9446e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 9459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 946462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 947462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9489ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 9492ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 9509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 952462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 9549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 955be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 956be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 9579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 958a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 959a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 960a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 9619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 962a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 963a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 964a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 9659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 966d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("built-in type cannot be exported: '%0'") 967d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << T->getTypeClassName(); 9689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 969462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 9749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 975b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 9769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 978d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError("primitive type cannot be exported: '%0'") 9792ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 9809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 981462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 983462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 985462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 986462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9879ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 9889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 9899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 9909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 9919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 9922ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 993462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 9959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 9969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9976b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 9982b8fb64be3047df940a219872b331eb11de2758dStephen Hines DT, Normalized); 999462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1000462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10019ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 10022b8fb64be3047df940a219872b331eb11de2758dStephen Hines const clang::Type *T) { 10039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 100448d893dc7794b3cfb74f35955ca763ee4170f9adStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context, NULL) 100578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 10062b8fb64be3047df940a219872b331eb11de2758dStephen Hines return Create(Context, T, TypeName); 1007e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 10089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1009e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 1010462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1011462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10127c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 10139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 10149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 10169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 10179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 10189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 10199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 10219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 10239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 10257c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type *> Elements; 10266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1027a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 1028462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 10309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1031462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 10339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 10349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 10359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 10389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 10399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 104191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 104291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 104391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 104491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 10459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 10469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 10489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 10529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 10549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 10559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 10569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 10599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 10609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 10619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1063a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 1064a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 10659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 10669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 10679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 10696e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 1070462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1072462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1074462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1075462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1076a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 1077a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1078a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1079a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1080a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1081a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1082a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1083a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1084a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1085641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 1086641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1087641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1088641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1089641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1090fdd1ba13a69501a1b91fdc9be31413215d467497Stephen HinesRSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1091fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines if (DT > DataTypeUnknown && DT < DataTypeMax) { 1092fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return &gReflectionTypes[DT]; 1093fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } else { 1094fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines return NULL; 1095fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines } 1096fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines} 1097fdd1ba13a69501a1b91fdc9be31413215d467497Stephen Hines 10989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 1099462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11009ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 11019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 11029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 11039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 11049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 11059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 1106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 11089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 11099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 11109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 11112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 11122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 11139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 11162ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 11189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 1121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1122462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11237c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportPointerType::convertToLLVMType() const { 11247c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *PointeeType = mPointeeType->getLLVMType(); 11259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 1126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1128a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 1129a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1130a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1131a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1132a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1133a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1134a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1135a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1136a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1137a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1138a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1139a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 11403cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 11413cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 11423cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1143641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 11443cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1145641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1146641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1147641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1148641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1149641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1150641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1151641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1152641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 11546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 11556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 11569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 11599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 11609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1161be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 11629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1163a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1164a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1165a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 11669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 11689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 11699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1170a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1171a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 1172a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1173a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 1174a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 1175a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 1176a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 11779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 11789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 1179462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 11809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1181462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11839ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 11849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 11859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 11869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 11876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 11909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 11912ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1192462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 11949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 11959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 11969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 11979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 11989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 11999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 12002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1201462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1202462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12037c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportVectorType::convertToLLVMType() const { 12047c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 12059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1207462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1208a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1209a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1210a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1211a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1212a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1213a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1214a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1215a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1216a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1217a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1218641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1219641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1220641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1221641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1222641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1223641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 122492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 122592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 122692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 122792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 122892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 12296e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 12306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 123192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 123292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 123392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 123492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 123592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 123692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 123792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 123892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 1239d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError( 1240d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet RD->getLocation(), 1241d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have 1 field for saving values: '%0'") 1242d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 124392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 124492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 124592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 124692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 124792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 124892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 124992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1250d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1251d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field should" 1252d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet " be an array with constant size: '%0'") 1253d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 125492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 125592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 125692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 125792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 12582e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 125992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 126092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 12619207a2e495c8363606861e4f034504ec5c153dabLogan Chien (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 12629207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::BuiltinType::Float)) { 1263d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1264d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1265d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be a float array: '%0'") 1266d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 126792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 126892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 126992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 127092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 1271d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1272d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: first field " 1273d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "should be an array with size %0: '%1'") 1274d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << (Dim * Dim) << (RD->getName()); 127592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 127692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 127792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 127892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 127992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 1280d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1281d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "invalid matrix struct: must have " 1282d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "exactly 1 field: '%0'") 1283d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName(); 128492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 128592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 128692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 128792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 128892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 128992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 129092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 12917c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportMatrixType::convertToLLVMType() const { 129292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 129392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 129492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 129592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 129692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 129792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 129892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 129992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 1300a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines return llvm::StructType::get(C, X, false); 130192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 130292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1303a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1304a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1305a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1306a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1307a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1308a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1309a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 13106e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1311a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1312a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1313a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1314a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1315641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1316641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1317641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1318641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1319641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13202e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 13212e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 13222e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 13232e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 13246e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 13252e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13266e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 13272e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13282e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 13296e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 13302e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13312e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 13322e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 13332e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13342e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 13352e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 13362e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 13372e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13382e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 13392e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 13402e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 13412e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13422e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 13437c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 13442e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 13452e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 13462e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1347a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1348a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1349a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1350a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1351a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1352a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1353a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1354a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1355a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1356a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1357a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1358a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1359a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1360a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 13613cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 13623cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 13633cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1364641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 13653cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1366641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1367641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1368641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1369641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1370a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1371a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1372a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1373a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1374641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1375641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 13769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 13779ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 13789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 13799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 13809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 13816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1382462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 13846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1385462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 13879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 13886e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 13899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 13909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1391462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 13930da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 13940da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 13959e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1396f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1397f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 13980da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 13990da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 14000da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 14010da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 14020da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 14030da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 140468318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 14059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 14069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 14089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 14099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 141091a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 14119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 141343730fe3c839af391efe6bdf56b0479860121924Shih-wei Liao slangAssert(FI->getKind() == clang::Decl::Field); 14149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 14159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14162ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 14172ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14182ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 14216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 14229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 14240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 14250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 14260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 14272ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 1428d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet Context->ReportError(RD->getLocation(), 1429d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet "field type cannot be exported: '%0.%1'") 1430d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet << RD->getName() << FD->getName(); 14312ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 14322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 14339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 14340a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 14359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1436462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1437462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14387c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liaollvm::Type *RSExportRecordType::convertToLLVMType() const { 14393cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 14403cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 14417c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 14427c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao std::vector<llvm::Type*> FieldTypes; 1443462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14443cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 14459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 14469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 14479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 14489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 14491f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 14509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 14519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1452462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14533cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 14543cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 14553cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 14567c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao if (ST != NULL) { 14577c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao return ST; 14587c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } else { 14593cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 14607c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao } 1461462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1462641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1463a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1464a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1465a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1466a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1467a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1468e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1469a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1470a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1471a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1472a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1473a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1474a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1475a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1476a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1477a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1478a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1479a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1480a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1481a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1482a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1483a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1484a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1485a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1486a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1487a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1488e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1489a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1490a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1491a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1492a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 14933cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 14943cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 14953cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1496641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1497641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1498641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1499641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1500641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1501641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 15023cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1503641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1504641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1505641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1506641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1507641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1508641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1509641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1510641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1511641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1512641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1513641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1514641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1515641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1516641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1517641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1518641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1519641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1520641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1521641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1522641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1523641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1524e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 15251b6a0883cd6984e11e59b0c847fb334df1f41afcJason Samsvoid RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 15261b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams memset(rtd, 0, sizeof(*rtd)); 15271b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = 1; 15281b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15291b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams switch(getClass()) { 15301b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPrimitive: { 15311b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 15321b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 15331b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15341b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15351b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassPointer: { 15361b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 15371b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportType *PointeeType = EPT->getPointeeType(); 15381b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams PointeeType->convertToRTD(rtd); 15391b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->isPointer = true; 15401b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15411b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15421b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassVector: { 15431b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 15441b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = EVT->getRSReflectionType(EVT); 15451b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->vecSize = EVT->getNumElement(); 15461b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15471b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15481b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassMatrix: { 15491b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 15501b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams unsigned Dim = EMT->getDim(); 15511b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert((Dim >= 2) && (Dim <= 4)); 15521b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->type = &gReflectionTypes[15 + Dim-2]; 15531b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15541b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15551b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassConstantArray: { 15561b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams const RSExportConstantArrayType* CAT = 15571b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams static_cast<const RSExportConstantArrayType*>(this); 15581b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams CAT->getElementType()->convertToRTD(rtd); 15591b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams rtd->arraySize = CAT->getSize(); 15601b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return; 15611b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15621b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams case RSExportType::ExportClassRecord: { 15631b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(!"RSExportType::ExportClassRecord not implemented"); 15641b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 15651b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15661b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams default: { 15671b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams slangAssert(false && "Unknown class of type"); 15681b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15691b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams } 15701b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams} 15711b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 15721b6a0883cd6984e11e59b0c847fb334df1f41afcJason Sams 1573e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1574