slang_rs_export_type.cpp revision b0fabe574945bfa85e688e77e9dcb5341fe08840
1660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon/* 2660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * Copyright 2010-2012, The Android Open Source Project 3660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * 4660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * Licensed under the Apache License, Version 2.0 (the "License"); 5660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * you may not use this file except in compliance with the License. 6660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * You may obtain a copy of the License at 7660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * 8660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * http://www.apache.org/licenses/LICENSE-2.0 9660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * 10660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * Unless required by applicable law or agreed to in writing, software 11660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * distributed under the License is distributed on an "AS IS" BASIS, 12660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * See the License for the specific language governing permissions and 14660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon * limitations under the License. 15660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon */ 16660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 17660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "slang_rs_export_type.h" 18660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 19660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include <list> 20660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include <vector> 2151b6956bc8e09eb2237a10a401baebb35096e6abWei Jia 22660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "clang/AST/ASTContext.h" 239b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon#include "clang/AST/RecordLayout.h" 24660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 25660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "llvm/ADT/StringExtras.h" 26660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 27660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "llvm/DerivedTypes.h" 289b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 29660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "llvm/Target/TargetData.h" 30660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 31660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "llvm/Type.h" 32660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 33660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "slang_assert.h" 34660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "slang_rs_context.h" 3542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon#include "slang_rs_export_element.h" 3642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon#include "slang_rs_type_spec.h" 37660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#include "slang_version.h" 38660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 39660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 40660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon if (!ParentClass::equals(E)) \ 41660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon return false; 42660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 43660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moonnamespace slang { 449b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 45660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moonnamespace { 46660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 47660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moonstatic RSReflectionType gReflectionTypes[] = { 48660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"FLOAT_16", "F16", 16, "half", "half", "Half", "Half", false}, 49660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"FLOAT_32", "F32", 32, "float", "float", "Float", "Float", false}, 50660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"FLOAT_64", "F64", 64, "double", "double", "Double", "Double",false}, 51660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"SIGNED_8", "I8", 8, "int8_t", "byte", "Byte", "Byte", false}, 52660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"SIGNED_16", "I16", 16, "int16_t", "short", "Short", "Short", false}, 53660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"SIGNED_32", "I32", 32, "int32_t", "int", "Int", "Int", false}, 54660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"SIGNED_64", "I64", 64, "int64_t", "long", "Long", "Long", false}, 55660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"UNSIGNED_8", "U8", 8, "uint8_t", "short", "UByte", "Short", true}, 569b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon {"UNSIGNED_16", "U16", 16, "uint16_t", "int", "UShort", "Int", true}, 579b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon {"UNSIGNED_32", "U32", 32, "uint32_t", "long", "UInt", "Long", true}, 58660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"UNSIGNED_64", "U64", 64, "uint64_t", "long", "ULong", "Long", false}, 59660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 60660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"BOOLEAN", "BOOLEAN", 8, "bool", "boolean", NULL, NULL, false}, 61660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 62660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"UNSIGNED_5_6_5", NULL, 16, NULL, NULL, NULL, NULL, false}, 63660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"UNSIGNED_5_5_5_1", NULL, 16, NULL, NULL, NULL, NULL, false}, 64660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"UNSIGNED_4_4_4_4", NULL, 16, NULL, NULL, NULL, NULL, false}, 65660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 66660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"MATRIX_2X2", NULL, 4*32, "rsMatrix_2x2", "Matrix2f", NULL, NULL, false}, 67660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"MATRIX_3X3", NULL, 9*32, "rsMatrix_3x3", "Matrix3f", NULL, NULL, false}, 68660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"MATRIX_4X4", NULL, 16*32, "rsMatrix_4x4", "Matrix4f", NULL, NULL, false}, 69660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 70660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_ELEMENT", "ELEMENT", 32, "Element", "Element", NULL, NULL, false}, 71660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_TYPE", "TYPE", 32, "Type", "Type", NULL, NULL, false}, 72660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_ALLOCATION", "ALLOCATION", 32, "Allocation", "Allocation", NULL, NULL, false}, 73660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_SAMPLER", "SAMPLER", 32, "Sampler", "Sampler", NULL, NULL, false}, 74660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_SCRIPT", "SCRIPT", 32, "Script", "Script", NULL, NULL, false}, 75660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_MESH", "MESH", 32, "Mesh", "Mesh", NULL, NULL, false}, 76660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_PATH", "PATH", 32, "Path", "Path", NULL, NULL, false}, 77660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_PROGRAM_FRAGMENT", "PROGRAM_FRAGMENT", 32, "ProgramFragment", "ProgramFragment", NULL, NULL, false}, 78660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_PROGRAM_VERTEX", "PROGRAM_VERTEX", 32, "ProgramVertex", "ProgramVertex", NULL, NULL, false}, 79660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_PROGRAM_RASTER", "PROGRAM_RASTER", 32, "ProgramRaster", "ProgramRaster", NULL, NULL, false}, 80660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_PROGRAM_STORE", "PROGRAM_STORE", 32, "ProgramStore", "ProgramStore", NULL, NULL, false}, 81660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon {"RS_FONT", "FONT", 32, "Font", "Font", NULL, NULL, false} 829b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon}; 839b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 84660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moonstatic const clang::Type *TypeExportableHelper( 85660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const clang::Type *T, 86660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 87660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon clang::DiagnosticsEngine *DiagEngine, 88660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const clang::VarDecl *VD, 89660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const clang::RecordDecl *TopLevelRecord); 90660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon 91660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moonstatic void ReportTypeError(clang::DiagnosticsEngine *DiagEngine, 92660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const clang::NamedDecl *ND, 93660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const clang::RecordDecl *TopLevelRecord, 94660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon const char *Message, 9542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon unsigned int TargetAPI = 0) { 9642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (!DiagEngine) { 9742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return; 9842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 9942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 10042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::SourceManager &SM = DiagEngine->getSourceManager(); 10142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 102660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon // Attempt to use the type declaration first (if we have one). 103660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon // Fall back to the variable definition, if we are looking at something 10442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // like an array declaration that can't be exported. 10542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (TopLevelRecord) { 10642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine->Report( 10742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::FullSourceLoc(TopLevelRecord->getLocation(), SM), 10842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 10942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon << TopLevelRecord->getName() << TargetAPI; 11042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } else if (ND) { 11142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine->Report( 11242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::FullSourceLoc(ND->getLocation(), SM), 11342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)) 11442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon << ND->getName() << TargetAPI; 11542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } else { 116660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon slangAssert(false && "Variables should be validated before exporting"); 117660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon } 1189b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon} 1199b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 1209b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moonstatic const clang::Type *ConstantArrayTypeExportableHelper( 1219b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::ConstantArrayType *CAT, 1229b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 1239b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::DiagnosticsEngine *DiagEngine, 1249b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::VarDecl *VD, 1259b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::RecordDecl *TopLevelRecord) { 1269b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon // Check element type 1279b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 1289b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (ElementType->isArrayType()) { 1299b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon ReportTypeError(DiagEngine, VD, TopLevelRecord, 1309b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon "multidimensional arrays cannot be exported: '%0'"); 1319b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 1329b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } else if (ElementType->isExtVectorType()) { 1339b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::ExtVectorType *EVT = 1349b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon static_cast<const clang::ExtVectorType*>(ElementType); 1359b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon unsigned numElements = EVT->getNumElements(); 136904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 137904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 138904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 139904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon ReportTypeError(DiagEngine, VD, TopLevelRecord, 140904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon "vectors of non-primitive types cannot be exported: '%0'"); 1419b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 1429b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 1439b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 1449b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (numElements == 3 && CAT->getSize() != 1) { 1459b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon ReportTypeError(DiagEngine, VD, TopLevelRecord, 1469b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon "arrays of width 3 vector types cannot be exported: '%0'"); 1479b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 1489b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 1499b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 1509b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 1519b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 1529b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon TopLevelRecord) == NULL) { 1539b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 154904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } else { 155fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return CAT; 156fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 157fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 158fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 159fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonstatic const clang::Type *TypeExportableHelper( 160fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::Type const *T, 161fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::SmallPtrSet<clang::Type const *, 8> &SPS, 162fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::DiagnosticsEngine *DiagEngine, 163fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::VarDecl const *VD, 164fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::RecordDecl const *TopLevelRecord) { 165fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Normalize first 166fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if ((T = GET_CANONICAL_TYPE(T)) == NULL) 167fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 168fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 169fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (SPS.count(T)) 170fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return T; 171fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 172fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon switch (T->getTypeClass()) { 173fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case clang::Type::Builtin: { 174fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::BuiltinType *BT = 175fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 176fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 177fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon switch (BT->getKind()) { 178fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 179fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case builtin_type: 180fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon#include "RSClangBuiltinEnums.inc" 181fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return T; 182fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon default: { 183fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 18442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 18542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 18642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 18742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon case clang::Type::Record: { 18842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (RSExportPrimitiveType::GetRSSpecificType(T) != 189fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon RSExportPrimitiveType::DataTypeUnknown) { 190fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return T; // RS object type, no further checks are needed 191fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 192fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 193fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Check internal struct 194fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T->isUnionType()) { 195fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(DiagEngine, VD, T->getAsUnionType()->getDecl(), 196fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "unions cannot be exported: '%0'"); 197fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 198fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else if (!T->isStructureType()) { 199fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon slangAssert(false && "Unknown type cannot be exported"); 200fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 201fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 202fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 203fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 204fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (RD != NULL) { 205fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon RD = RD->getDefinition(); 206fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (RD == NULL) { 207fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(DiagEngine, NULL, T->getAsStructureType()->getDecl(), 208fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "struct is not defined in this module"); 209fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 210fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 211fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 212fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 213fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (!TopLevelRecord) { 214fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon TopLevelRecord = RD; 215fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 216fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (RD->getName().empty()) { 217fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(DiagEngine, NULL, RD, 218fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "anonymous structures cannot be exported"); 219fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 220fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 221fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 222fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Fast check 223fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 224fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 225fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 226fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Insert myself into checking set 227fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon SPS.insert(T); 228fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 229fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Check all element 230fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 231fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon FE = RD->field_end(); 232fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon FI != FE; 233fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon FI++) { 234fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::FieldDecl *FD = *FI; 235fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 236fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon FT = GET_CANONICAL_TYPE(FT); 237fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 238fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (!TypeExportableHelper(FT, SPS, DiagEngine, VD, TopLevelRecord)) { 239fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 240fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 241fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 242fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // We don't support bit fields yet 243fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // 244fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 245fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (FD->isBitField()) { 246fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (DiagEngine) { 247fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->Report( 248fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::FullSourceLoc(FD->getLocation(), 249fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->getSourceManager()), 250fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->getCustomDiagID( 251fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::DiagnosticsEngine::Error, 252fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "bit fields are not able to be exported: '%0.%1'")) 253fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon << RD->getName() 254fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon << FD->getName(); 255fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 256fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 257fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 258fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 259fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 260fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return T; 261fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 262fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case clang::Type::Pointer: { 263fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (TopLevelRecord) { 264fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(DiagEngine, VD, TopLevelRecord, 265fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "structures containing pointers cannot be exported: '%0'"); 266fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 267fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 268fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 269fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::PointerType *PT = 270fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon UNSAFE_CAST_TYPE(const clang::PointerType, T); 271fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 272fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 273fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (PointeeType->getTypeClass() == clang::Type::Pointer) { 274fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(DiagEngine, VD, TopLevelRecord, 275fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "multiple levels of pointers cannot be exported: '%0'"); 276fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 277fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 278fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // We don't support pointer with array-type pointee or unsupported pointee 279fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // type 280fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (PointeeType->isArrayType() || 281fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon (TypeExportableHelper(PointeeType, SPS, DiagEngine, VD, 282fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon TopLevelRecord) == NULL)) 283fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 2849b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon else 2859b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return T; 2869b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 2879b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon case clang::Type::ExtVector: { 2889b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::ExtVectorType *EVT = 2899b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2909b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon // Only vector with size 2, 3 and 4 are supported. 2919b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2929b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 2939b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 2949b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon // Check base element type 2959b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 2969b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 2979b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if ((ElementType->getTypeClass() != clang::Type::Builtin) || 2989b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon (TypeExportableHelper(ElementType, SPS, DiagEngine, VD, 2999b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon TopLevelRecord) == NULL)) 3009b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 3019b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon else 3029b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return T; 3039b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3049b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon case clang::Type::ConstantArray: { 3059b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::ConstantArrayType *CAT = 3069b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 3079b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 3089b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return ConstantArrayTypeExportableHelper(CAT, SPS, DiagEngine, VD, 3099b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon TopLevelRecord); 3109b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3119b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon default: { 3129b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return NULL; 3139b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3149b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3159b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon} 3169b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 3179b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// Return the type that can be used to create RSExportType, will always return 3189b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// the canonical type 3199b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// If the Type T is not exportable, this function returns NULL. DiagEngine is 3209b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// used to generate proper Clang diagnostic messages when a 3219b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// non-exportable type is detected. TopLevelRecord is used to capture the 322fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon// highest struct (in the case of a nested hierarchy) for detecting other 323fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon// types that cannot be exported (mostly pointers within a struct). 324fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonstatic const clang::Type *TypeExportable(const clang::Type *T, 325fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::DiagnosticsEngine *DiagEngine, 326fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::VarDecl *VD) { 327fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::SmallPtrSet<const clang::Type*, 8> SPS = 328fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::SmallPtrSet<const clang::Type*, 8>(); 329fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 330fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return TypeExportableHelper(T, SPS, DiagEngine, VD, NULL); 331fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 332fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 333fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonstatic bool ValidateRSObjectInVarDecl(clang::VarDecl *VD, 334fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon bool InCompositeType, 335fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon unsigned int TargetAPI) { 336fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (TargetAPI < SLANG_JB_TARGET_API) { 337fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Only if we are already in a composite type (like an array or structure). 338fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (InCompositeType) { 339fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Only if we are actually exported (i.e. non-static). 340fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (VD->hasLinkage() && (VD->getLinkage() == clang::ExternalLinkage)) { 341fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Only if we are not a pointer to an object. 342fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::Type *T = GET_CANONICAL_TYPE(VD->getType().getTypePtr()); 343fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T->getTypeClass() != clang::Type::Pointer) { 344fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::ASTContext &C = VD->getASTContext(); 345fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(&C.getDiagnostics(), VD, NULL, 346fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "arrays/structures containing RS object types " 347fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "cannot be exported in target API < %1: '%0'", 348fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon SLANG_JB_TARGET_API); 349fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return false; 350fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 351fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 352fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 353fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 354fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 355660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon return true; 356660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon} 3579b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 358660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon// Helper function for ValidateType(). We do a recursive descent on the 3599b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// type hierarchy to ensure that we can properly export/handle the 3609b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// declaration. 3619b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// \return true if the variable declaration is valid, 3629b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// false if it is invalid (along with proper diagnostics). 3639b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// 3649b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// C - ASTContext (for diagnostics + builtin types). 3659b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// T - sub-type that we are validating. 3669b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// ND - (optional) top-level named declaration that we are validating. 3679b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// SPS - set of types we have already seen/validated. 3689b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// InCompositeType - true if we are within an outer composite type. 3699b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// UnionDecl - set if we are in a sub-type of a union. 3709b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// TargetAPI - target SDK API level. 3719b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon// IsFilterscript - whether or not we are compiling for Filterscript 3729b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moonstatic bool ValidateTypeHelper( 3739b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::ASTContext &C, 3749b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::Type *&T, 3759b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::NamedDecl *ND, 3769b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::SourceLocation Loc, 3779b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 3789b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon bool InCompositeType, 3799b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::RecordDecl *UnionDecl, 3809b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon unsigned int TargetAPI, 3819b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon bool IsFilterscript) { 3829b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if ((T = GET_CANONICAL_TYPE(T)) == NULL) 3839b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return true; 3849b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 3859b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (SPS.count(T)) 3869b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return true; 3879b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 3889b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon switch (T->getTypeClass()) { 3899b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon case clang::Type::Record: { 3909b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (RSExportPrimitiveType::IsRSObjectType(T)) { 3919b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon clang::VarDecl *VD = (ND ? llvm::dyn_cast<clang::VarDecl>(ND) : NULL); 3929b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (VD && !ValidateRSObjectInVarDecl(VD, InCompositeType, TargetAPI)) { 3939b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return false; 3949b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3959b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 3969b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 3979b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (RSExportPrimitiveType::GetRSSpecificType(T) != 3989b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon RSExportPrimitiveType::DataTypeUnknown) { 3999b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (!UnionDecl) { 4009b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return true; 401fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 402fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon ReportTypeError(&C.getDiagnostics(), NULL, UnionDecl, 403fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "unions containing RS object types are not allowed"); 404fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return false; 405fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 406fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 407fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 408fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::RecordDecl *RD = NULL; 409fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 410fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Check internal struct 411fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T->isUnionType()) { 412fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon RD = T->getAsUnionType()->getDecl(); 413fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon UnionDecl = RD; 414fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else if (T->isStructureType()) { 415fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon RD = T->getAsStructureType()->getDecl(); 416fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else { 417fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon slangAssert(false && "Unknown type cannot be exported"); 418fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return false; 4199b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 4209b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon 4219b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (RD != NULL) { 4229b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon RD = RD->getDefinition(); 4239b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (RD == NULL) { 4249b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon // FIXME 4259b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return true; 426904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } 427904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } 428904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 429904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon // Fast check 430904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 431904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon return false; 432904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 433904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon // Insert myself into checking set 434904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon SPS.insert(T); 435904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 436904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon // Check all elements 437904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 438904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon FE = RD->field_end(); 439904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon FI != FE; 440904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon FI++) { 441904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon const clang::FieldDecl *FD = *FI; 442904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 443904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon FT = GET_CANONICAL_TYPE(FT); 444904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 445904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (!ValidateTypeHelper(C, FT, ND, Loc, SPS, true, UnionDecl, 446904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon TargetAPI, IsFilterscript)) { 447904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon return false; 448904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } 449904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } 450904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 451904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon return true; 452904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } 453904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon 454904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon case clang::Type::Builtin: { 455904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (IsFilterscript) { 456904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon clang::QualType QT = T->getCanonicalTypeInternal(); 457904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (QT == C.DoubleTy || 458904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon QT == C.LongDoubleTy || 459904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon QT == C.LongTy || 460904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon QT == C.LongLongTy) { 461904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 462904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon if (ND) { 463904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon DiagEngine.Report( 464904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon clang::FullSourceLoc(Loc, C.getSourceManager()), 465904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon DiagEngine.getCustomDiagID( 466904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon clang::DiagnosticsEngine::Error, 467904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon "Builtin types > 32 bits in size are forbidden in " 468904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon "Filterscript: '%0'")) << ND->getName(); 469904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon } else { 470904183eeeeb8e9f7345c3e5f517719d6b5c93128Hyundo Moon DiagEngine.Report( 47142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::FullSourceLoc(Loc, C.getSourceManager()), 47242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine.getCustomDiagID( 47342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::DiagnosticsEngine::Error, 47442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon "Builtin types > 32 bits in size are forbidden in " 47542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon "Filterscript")); 47642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 47742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return false; 47842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 47942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 48042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon break; 48142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 48242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 48342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon case clang::Type::Pointer: { 48442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (IsFilterscript) { 48542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (ND) { 48642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 48742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine.Report( 48842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::FullSourceLoc(Loc, C.getSourceManager()), 48942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon DiagEngine.getCustomDiagID( 49042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon clang::DiagnosticsEngine::Error, 49142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon "Pointers are forbidden in Filterscript: '%0'")) << ND->getName(); 49242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return false; 49342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } else { 49442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // TODO(srhines): Find a better way to handle expressions (i.e. no 49542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // NamedDecl) involving pointers in FS that should be allowed. 49642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // An example would be calls to library functions like 49742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // rsMatrixMultiply() that take rs_matrixNxN * types. 49842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 49942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 50042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 50142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::PointerType *PT = 50242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon UNSAFE_CAST_TYPE(const clang::PointerType, T); 50342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 50442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 50542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return ValidateTypeHelper(C, PointeeType, ND, Loc, SPS, InCompositeType, 50642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon UnionDecl, TargetAPI, IsFilterscript); 50742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 50842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 50942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon case clang::Type::ExtVector: { 51042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::ExtVectorType *EVT = 51142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 51242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 51342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (TargetAPI < SLANG_ICS_TARGET_API && 51442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon InCompositeType && 51542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon EVT->getNumElements() == 3 && 51642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon ND && 51742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon ND->getLinkage() == clang::ExternalLinkage) { 51842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon ReportTypeError(&C.getDiagnostics(), ND, NULL, 51942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon "structs containing vectors of dimension 3 cannot " 52042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon "be exported at this API level: '%0'"); 52142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return false; 52242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 52342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return ValidateTypeHelper(C, ElementType, ND, Loc, SPS, true, UnionDecl, 52442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon TargetAPI, IsFilterscript); 52542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 52642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 52742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon case clang::Type::ConstantArray: { 52842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::ConstantArrayType *CAT = 52942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 53042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 53142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return ValidateTypeHelper(C, ElementType, ND, Loc, SPS, true, UnionDecl, 53242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon TargetAPI, IsFilterscript); 53342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 53442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 53542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon default: { 53642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon break; 53742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 53842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 53942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 54042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return true; 54142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon} 54242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 54342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon} // namespace 54442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 545fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon/****************************** RSExportType ******************************/ 546fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonbool RSExportType::NormalizeType(const clang::Type *&T, 547fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::StringRef &TypeName, 548fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::DiagnosticsEngine *DiagEngine, 549fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::VarDecl *VD) { 550fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if ((T = TypeExportable(T, DiagEngine, VD)) == NULL) { 551fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return false; 552fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 553fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Get type name 554fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon TypeName = RSExportType::GetTypeName(T); 555fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (TypeName.empty()) { 556fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (DiagEngine) { 557fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (VD) { 558fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->Report( 559fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::FullSourceLoc(VD->getLocation(), 560fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->getSourceManager()), 561fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 562fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "anonymous types cannot be exported")); 563fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else { 564fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->Report( 565fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 566fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon "anonymous types cannot be exported")); 567fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 568fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 569fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return false; 570fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 571fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 572fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return true; 573fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 574fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 575fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonbool RSExportType::ValidateType(clang::ASTContext &C, clang::QualType QT, 576fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::NamedDecl *ND, clang::SourceLocation Loc, unsigned int TargetAPI, 577fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon bool IsFilterscript) { 578fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::Type *T = QT.getTypePtr(); 579fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::SmallPtrSet<const clang::Type*, 8> SPS = 580fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::SmallPtrSet<const clang::Type*, 8>(); 581fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 582fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return ValidateTypeHelper(C, T, ND, Loc, SPS, false, NULL, TargetAPI, 583fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon IsFilterscript); 584fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return true; 585fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 586fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 587fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonbool RSExportType::ValidateVarDecl(clang::VarDecl *VD, unsigned int TargetAPI, 588fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon bool IsFilterscript) { 589fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return ValidateType(VD->getASTContext(), VD->getType(), VD, 590fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon VD->getLocation(), TargetAPI, IsFilterscript); 591fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 592fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 593fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonconst clang::Type 594fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 595fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (DD) { 596fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::QualType T; 597fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (DD->getTypeSourceInfo()) 598fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon T = DD->getTypeSourceInfo()->getType(); 599fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon else 600fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon T = DD->getType(); 601fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 602fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T.isNull()) 603fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 604fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon else 605fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return T.getTypePtr(); 606fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 607fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return NULL; 608fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon} 609fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 610fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moonllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 611fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon T = GET_CANONICAL_TYPE(T); 612fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T == NULL) 613fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return llvm::StringRef(); 614fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 615fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon switch (T->getTypeClass()) { 616fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case clang::Type::Builtin: { 617fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon const clang::BuiltinType *BT = 618fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 619fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 620fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon switch (BT->getKind()) { 621fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 622fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case builtin_type: \ 623fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon return cname; \ 624fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon break; 625fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon#include "RSClangBuiltinEnums.inc" 626fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon default: { 627fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon slangAssert(false && "Unknown data type of the builtin"); 628fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon break; 629fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 630fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 631fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon break; 632fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 633fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon case clang::Type::Record: { 634fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon clang::RecordDecl *RD; 635fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (T->isStructureType()) { 636fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon RD = T->getAsStructureType()->getDecl(); 637fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } else { 638fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon break; 639fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 640fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 641fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon llvm::StringRef Name = RD->getName(); 642fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (Name.empty()) { 643fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (RD->getTypedefNameForAnonDecl() != NULL) { 644fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon Name = RD->getTypedefNameForAnonDecl()->getName(); 645fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon } 646fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon 647fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon if (Name.empty()) { 648fd328170d288e337cb779b2ef14f9e4c5e860c6aHyundo Moon // Try to find a name from redeclaration (i.e. typedef) 64942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 65042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon RE = RD->redecls_end(); 65142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon RI != RE; 65242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon RI++) { 65342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon slangAssert(*RI != NULL && "cannot be NULL object"); 65442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon 65542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon Name = (*RI)->getName(); 65642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon if (!Name.empty()) 65742a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon break; 65842a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 65942a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 66042a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 66142a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon return Name; 66242a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon } 66342a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon case clang::Type::Pointer: { 66442a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon // "*" plus pointee name 66542a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon const clang::Type *PT = GET_POINTEE_TYPE(T); 66642a6decdd6c173a36e51c19d44849e6654eb60f9Hyundo Moon llvm::StringRef PointeeName; 6679b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon if (NormalizeType(PT, PointeeName, NULL, NULL)) { 6689b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 6699b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon Name[0] = '*'; 6709b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 6719b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon Name[PointeeName.size() + 1] = '\0'; 6729b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return Name; 6739b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 6749b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon break; 6759b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 6769b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon case clang::Type::ExtVector: { 6779b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon const clang::ExtVectorType *EVT = 6789b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 6799b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return RSExportVectorType::GetTypeName(EVT); 6809b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon break; 6819b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 6829b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon case clang::Type::ConstantArray : { 6839b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon // Construct name for a constant array is too complicated. 6849b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 6859b26e9467a77e2ee03f1d19e1dbf9671c3770286Hyundo Moon } 686660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon default: { 687660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon break; 688660a74ebf0a8b5b6c79f9a016b202ccfaf815d3bHyundo Moon } 689 } 690 691 return llvm::StringRef(); 692} 693 694 695RSExportType *RSExportType::Create(RSContext *Context, 696 const clang::Type *T, 697 const llvm::StringRef &TypeName) { 698 // Lookup the context to see whether the type was processed before. 699 // Newly created RSExportType will insert into context 700 // in RSExportType::RSExportType() 701 RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 702 703 if (ETI != Context->export_types_end()) 704 return ETI->second; 705 706 RSExportType *ET = NULL; 707 switch (T->getTypeClass()) { 708 case clang::Type::Record: { 709 RSExportPrimitiveType::DataType dt = 710 RSExportPrimitiveType::GetRSSpecificType(TypeName); 711 switch (dt) { 712 case RSExportPrimitiveType::DataTypeUnknown: { 713 // User-defined types 714 ET = RSExportRecordType::Create(Context, 715 T->getAsStructureType(), 716 TypeName); 717 break; 718 } 719 case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 720 // 2 x 2 Matrix type 721 ET = RSExportMatrixType::Create(Context, 722 T->getAsStructureType(), 723 TypeName, 724 2); 725 break; 726 } 727 case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 728 // 3 x 3 Matrix type 729 ET = RSExportMatrixType::Create(Context, 730 T->getAsStructureType(), 731 TypeName, 732 3); 733 break; 734 } 735 case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 736 // 4 x 4 Matrix type 737 ET = RSExportMatrixType::Create(Context, 738 T->getAsStructureType(), 739 TypeName, 740 4); 741 break; 742 } 743 default: { 744 // Others are primitive types 745 ET = RSExportPrimitiveType::Create(Context, T, TypeName); 746 break; 747 } 748 } 749 break; 750 } 751 case clang::Type::Builtin: { 752 ET = RSExportPrimitiveType::Create(Context, T, TypeName); 753 break; 754 } 755 case clang::Type::Pointer: { 756 ET = RSExportPointerType::Create(Context, 757 UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 758 // FIXME: free the name (allocated in RSExportType::GetTypeName) 759 delete [] TypeName.data(); 760 break; 761 } 762 case clang::Type::ExtVector: { 763 ET = RSExportVectorType::Create(Context, 764 UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 765 break; 766 } 767 case clang::Type::ConstantArray: { 768 ET = RSExportConstantArrayType::Create( 769 Context, 770 UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 771 break; 772 } 773 default: { 774 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 775 DiagEngine->Report( 776 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 777 "unknown type cannot be exported: '%0'")) 778 << T->getTypeClassName(); 779 break; 780 } 781 } 782 783 return ET; 784} 785 786RSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 787 llvm::StringRef TypeName; 788 if (NormalizeType(T, TypeName, Context->getDiagnostics(), NULL)) { 789 return Create(Context, T, TypeName); 790 } else { 791 return NULL; 792 } 793} 794 795RSExportType *RSExportType::CreateFromDecl(RSContext *Context, 796 const clang::VarDecl *VD) { 797 return RSExportType::Create(Context, GetTypeOfDecl(VD)); 798} 799 800size_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 801 return ET->getRSContext()->getTargetData()->getTypeStoreSize( 802 ET->getLLVMType()); 803} 804 805size_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 806 if (ET->getClass() == RSExportType::ExportClassRecord) 807 return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 808 else 809 return ET->getRSContext()->getTargetData()->getTypeAllocSize( 810 ET->getLLVMType()); 811} 812 813RSExportType::RSExportType(RSContext *Context, 814 ExportClass Class, 815 const llvm::StringRef &Name) 816 : RSExportable(Context, RSExportable::EX_TYPE), 817 mClass(Class), 818 // Make a copy on Name since memory stored @Name is either allocated in 819 // ASTContext or allocated in GetTypeName which will be destroyed later. 820 mName(Name.data(), Name.size()), 821 mLLVMType(NULL), 822 mSpecType(NULL) { 823 // Don't cache the type whose name start with '<'. Those type failed to 824 // get their name since constructing their name in GetTypeName() requiring 825 // complicated work. 826 if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 827 // TODO(zonr): Need to check whether the insertion is successful or not. 828 Context->insertExportType(llvm::StringRef(Name), this); 829 return; 830} 831 832bool RSExportType::keep() { 833 if (!RSExportable::keep()) 834 return false; 835 // Invalidate converted LLVM type. 836 mLLVMType = NULL; 837 return true; 838} 839 840bool RSExportType::equals(const RSExportable *E) const { 841 CHECK_PARENT_EQUALITY(RSExportable, E); 842 return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 843} 844 845RSExportType::~RSExportType() { 846 delete mSpecType; 847} 848 849/************************** RSExportPrimitiveType **************************/ 850llvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 851RSExportPrimitiveType::RSSpecificTypeMap; 852 853llvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 854 855bool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 856 if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 857 return true; 858 else 859 return false; 860} 861 862RSExportPrimitiveType::DataType 863RSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 864 if (TypeName.empty()) 865 return DataTypeUnknown; 866 867 if (RSSpecificTypeMap->empty()) { 868#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 869 RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 870#include "RSMatrixTypeEnums.inc" 871#define ENUM_RS_OBJECT_TYPE(type, cname) \ 872 RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 873#include "RSObjectTypeEnums.inc" 874 } 875 876 RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 877 if (I == RSSpecificTypeMap->end()) 878 return DataTypeUnknown; 879 else 880 return I->getValue(); 881} 882 883RSExportPrimitiveType::DataType 884RSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 885 T = GET_CANONICAL_TYPE(T); 886 if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 887 return DataTypeUnknown; 888 889 return GetRSSpecificType( RSExportType::GetTypeName(T) ); 890} 891 892bool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 893 return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 894} 895 896bool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 897 return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 898} 899 900bool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 901 bool RSObjectTypeSeen = false; 902 while (T && T->isArrayType()) { 903 T = T->getArrayElementTypeNoTypeQual(); 904 } 905 906 const clang::RecordType *RT = T->getAsStructureType(); 907 if (!RT) { 908 return false; 909 } 910 911 const clang::RecordDecl *RD = RT->getDecl(); 912 if (RD) { 913 RD = RD->getDefinition(); 914 } 915 if (!RD) { 916 return false; 917 } 918 919 for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 920 FE = RD->field_end(); 921 FI != FE; 922 FI++) { 923 // We just look through all field declarations to see if we find a 924 // declaration for an RS object type (or an array of one). 925 const clang::FieldDecl *FD = *FI; 926 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 927 while (FT && FT->isArrayType()) { 928 FT = FT->getArrayElementTypeNoTypeQual(); 929 } 930 931 RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 932 if (IsRSObjectType(DT)) { 933 // RS object types definitely need to be zero-initialized 934 RSObjectTypeSeen = true; 935 } else { 936 switch (DT) { 937 case RSExportPrimitiveType::DataTypeRSMatrix2x2: 938 case RSExportPrimitiveType::DataTypeRSMatrix3x3: 939 case RSExportPrimitiveType::DataTypeRSMatrix4x4: 940 // Matrix types should get zero-initialized as well 941 RSObjectTypeSeen = true; 942 break; 943 default: 944 // Ignore all other primitive types 945 break; 946 } 947 while (FT && FT->isArrayType()) { 948 FT = FT->getArrayElementTypeNoTypeQual(); 949 } 950 if (FT->isStructureType()) { 951 // Recursively handle structs of structs (even though these can't 952 // be exported, it is possible for a user to have them internally). 953 RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 954 } 955 } 956 } 957 958 return RSObjectTypeSeen; 959} 960 961const size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 962#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 963 bits, 964#include "RSDataTypeEnums.inc" 965 0 // DataTypeMax 966}; 967 968size_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 969 slangAssert(((EPT->getType() > DataTypeUnknown) && 970 (EPT->getType() < DataTypeMax)) && 971 "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 972 return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 973} 974 975RSExportPrimitiveType::DataType 976RSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 977 if (T == NULL) 978 return DataTypeUnknown; 979 980 switch (T->getTypeClass()) { 981 case clang::Type::Builtin: { 982 const clang::BuiltinType *BT = 983 UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 984 switch (BT->getKind()) { 985#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 986 case builtin_type: { \ 987 return DataType ## type; \ 988 } 989#include "RSClangBuiltinEnums.inc" 990 // The size of type WChar depend on platform so we abandon the support 991 // to them. 992 default: { 993 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 994 DiagEngine->Report( 995 DiagEngine->getCustomDiagID( 996 clang::DiagnosticsEngine::Error, 997 "built-in type cannot be exported: '%0'")) 998 << T->getTypeClassName(); 999 break; 1000 } 1001 } 1002 break; 1003 } 1004 case clang::Type::Record: { 1005 // must be RS object type 1006 return RSExportPrimitiveType::GetRSSpecificType(T); 1007 } 1008 default: { 1009 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 1010 DiagEngine->Report( 1011 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1012 "primitive type cannot be exported: '%0'")) 1013 << T->getTypeClassName(); 1014 break; 1015 } 1016 } 1017 1018 return DataTypeUnknown; 1019} 1020 1021RSExportPrimitiveType 1022*RSExportPrimitiveType::Create(RSContext *Context, 1023 const clang::Type *T, 1024 const llvm::StringRef &TypeName, 1025 bool Normalized) { 1026 DataType DT = GetDataType(Context, T); 1027 1028 if ((DT == DataTypeUnknown) || TypeName.empty()) 1029 return NULL; 1030 else 1031 return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 1032 DT, Normalized); 1033} 1034 1035RSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 1036 const clang::Type *T) { 1037 llvm::StringRef TypeName; 1038 if (RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), NULL) 1039 && IsPrimitiveType(T)) { 1040 return Create(Context, T, TypeName); 1041 } else { 1042 return NULL; 1043 } 1044} 1045 1046llvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 1047 llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 1048 1049 if (isRSObjectType()) { 1050 // struct { 1051 // int *p; 1052 // } __attribute__((packed, aligned(pointer_size))) 1053 // 1054 // which is 1055 // 1056 // <{ [1 x i32] }> in LLVM 1057 // 1058 if (RSObjectLLVMType == NULL) { 1059 std::vector<llvm::Type *> Elements; 1060 Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 1061 RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 1062 } 1063 return RSObjectLLVMType; 1064 } 1065 1066 switch (mType) { 1067 case DataTypeFloat32: { 1068 return llvm::Type::getFloatTy(C); 1069 break; 1070 } 1071 case DataTypeFloat64: { 1072 return llvm::Type::getDoubleTy(C); 1073 break; 1074 } 1075 case DataTypeBoolean: { 1076 return llvm::Type::getInt1Ty(C); 1077 break; 1078 } 1079 case DataTypeSigned8: 1080 case DataTypeUnsigned8: { 1081 return llvm::Type::getInt8Ty(C); 1082 break; 1083 } 1084 case DataTypeSigned16: 1085 case DataTypeUnsigned16: 1086 case DataTypeUnsigned565: 1087 case DataTypeUnsigned5551: 1088 case DataTypeUnsigned4444: { 1089 return llvm::Type::getInt16Ty(C); 1090 break; 1091 } 1092 case DataTypeSigned32: 1093 case DataTypeUnsigned32: { 1094 return llvm::Type::getInt32Ty(C); 1095 break; 1096 } 1097 case DataTypeSigned64: 1098 case DataTypeUnsigned64: { 1099 return llvm::Type::getInt64Ty(C); 1100 break; 1101 } 1102 default: { 1103 slangAssert(false && "Unknown data type"); 1104 } 1105 } 1106 1107 return NULL; 1108} 1109 1110union RSType *RSExportPrimitiveType::convertToSpecType() const { 1111 llvm::OwningPtr<union RSType> ST(new union RSType); 1112 RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 1113 // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 1114 // slang_rs_type_spec.h 1115 RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 1116 return ST.take(); 1117} 1118 1119bool RSExportPrimitiveType::equals(const RSExportable *E) const { 1120 CHECK_PARENT_EQUALITY(RSExportType, E); 1121 return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 1122} 1123 1124RSReflectionType *RSExportPrimitiveType::getRSReflectionType(DataType DT) { 1125 if (DT > DataTypeUnknown && DT < DataTypeMax) { 1126 return &gReflectionTypes[DT]; 1127 } else { 1128 return NULL; 1129 } 1130} 1131 1132/**************************** RSExportPointerType ****************************/ 1133 1134RSExportPointerType 1135*RSExportPointerType::Create(RSContext *Context, 1136 const clang::PointerType *PT, 1137 const llvm::StringRef &TypeName) { 1138 const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 1139 const RSExportType *PointeeET; 1140 1141 if (PointeeType->getTypeClass() != clang::Type::Pointer) { 1142 PointeeET = RSExportType::Create(Context, PointeeType); 1143 } else { 1144 // Double or higher dimension of pointer, export as int* 1145 PointeeET = RSExportPrimitiveType::Create(Context, 1146 Context->getASTContext().IntTy.getTypePtr()); 1147 } 1148 1149 if (PointeeET == NULL) { 1150 // Error diagnostic is emitted for corresponding pointee type 1151 return NULL; 1152 } 1153 1154 return new RSExportPointerType(Context, TypeName, PointeeET); 1155} 1156 1157llvm::Type *RSExportPointerType::convertToLLVMType() const { 1158 llvm::Type *PointeeType = mPointeeType->getLLVMType(); 1159 return llvm::PointerType::getUnqual(PointeeType); 1160} 1161 1162union RSType *RSExportPointerType::convertToSpecType() const { 1163 llvm::OwningPtr<union RSType> ST(new union RSType); 1164 1165 RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 1166 RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 1167 1168 if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 1169 return ST.take(); 1170 else 1171 return NULL; 1172} 1173 1174bool RSExportPointerType::keep() { 1175 if (!RSExportType::keep()) 1176 return false; 1177 const_cast<RSExportType*>(mPointeeType)->keep(); 1178 return true; 1179} 1180 1181bool RSExportPointerType::equals(const RSExportable *E) const { 1182 CHECK_PARENT_EQUALITY(RSExportType, E); 1183 return (static_cast<const RSExportPointerType*>(E) 1184 ->getPointeeType()->equals(getPointeeType())); 1185} 1186 1187/***************************** RSExportVectorType *****************************/ 1188llvm::StringRef 1189RSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 1190 const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1191 1192 if ((ElementType->getTypeClass() != clang::Type::Builtin)) 1193 return llvm::StringRef(); 1194 1195 const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 1196 ElementType); 1197 if ((EVT->getNumElements() < 1) || 1198 (EVT->getNumElements() > 4)) 1199 return llvm::StringRef(); 1200 1201 switch (BT->getKind()) { 1202 // Compiler is smart enough to optimize following *big if branches* since 1203 // they all become "constant comparison" after macro expansion 1204#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1205 case builtin_type: { \ 1206 const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1207 return Name[EVT->getNumElements() - 2]; \ 1208 break; \ 1209 } 1210#include "RSClangBuiltinEnums.inc" 1211 default: { 1212 return llvm::StringRef(); 1213 } 1214 } 1215} 1216 1217RSExportVectorType *RSExportVectorType::Create(RSContext *Context, 1218 const clang::ExtVectorType *EVT, 1219 const llvm::StringRef &TypeName, 1220 bool Normalized) { 1221 slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1222 1223 const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1224 RSExportPrimitiveType::DataType DT = 1225 RSExportPrimitiveType::GetDataType(Context, ElementType); 1226 1227 if (DT != RSExportPrimitiveType::DataTypeUnknown) 1228 return new RSExportVectorType(Context, 1229 TypeName, 1230 DT, 1231 Normalized, 1232 EVT->getNumElements()); 1233 else 1234 return NULL; 1235} 1236 1237llvm::Type *RSExportVectorType::convertToLLVMType() const { 1238 llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 1239 return llvm::VectorType::get(ElementType, getNumElement()); 1240} 1241 1242union RSType *RSExportVectorType::convertToSpecType() const { 1243 llvm::OwningPtr<union RSType> ST(new union RSType); 1244 1245 RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1246 RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1247 RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1248 1249 return ST.take(); 1250} 1251 1252bool RSExportVectorType::equals(const RSExportable *E) const { 1253 CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1254 return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1255 == getNumElement()); 1256} 1257 1258/***************************** RSExportMatrixType *****************************/ 1259RSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 1260 const clang::RecordType *RT, 1261 const llvm::StringRef &TypeName, 1262 unsigned Dim) { 1263 slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 1264 slangAssert((Dim > 1) && "Invalid dimension of matrix"); 1265 1266 // Check whether the struct rs_matrix is in our expected form (but assume it's 1267 // correct if we're not sure whether it's correct or not) 1268 const clang::RecordDecl* RD = RT->getDecl(); 1269 RD = RD->getDefinition(); 1270 if (RD != NULL) { 1271 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 1272 const clang::SourceManager *SM = Context->getSourceManager(); 1273 // Find definition, perform further examination 1274 if (RD->field_empty()) { 1275 DiagEngine->Report( 1276 clang::FullSourceLoc(RD->getLocation(), *SM), 1277 DiagEngine->getCustomDiagID( 1278 clang::DiagnosticsEngine::Error, 1279 "invalid matrix struct: must have 1 field for saving values: '%0'")) 1280 << RD->getName(); 1281 return NULL; 1282 } 1283 1284 clang::RecordDecl::field_iterator FIT = RD->field_begin(); 1285 const clang::FieldDecl *FD = *FIT; 1286 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1287 if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 1288 DiagEngine->Report( 1289 clang::FullSourceLoc(RD->getLocation(), *SM), 1290 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1291 "invalid matrix struct: first field should" 1292 " be an array with constant size: '%0'")) 1293 << RD->getName(); 1294 return NULL; 1295 } 1296 const clang::ConstantArrayType *CAT = 1297 static_cast<const clang::ConstantArrayType *>(FT); 1298 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 1299 if ((ElementType == NULL) || 1300 (ElementType->getTypeClass() != clang::Type::Builtin) || 1301 (static_cast<const clang::BuiltinType *>(ElementType)->getKind() != 1302 clang::BuiltinType::Float)) { 1303 DiagEngine->Report( 1304 clang::FullSourceLoc(RD->getLocation(), *SM), 1305 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1306 "invalid matrix struct: first field " 1307 "should be a float array: '%0'")) 1308 << RD->getName(); 1309 return NULL; 1310 } 1311 1312 if (CAT->getSize() != Dim * Dim) { 1313 DiagEngine->Report( 1314 clang::FullSourceLoc(RD->getLocation(), *SM), 1315 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1316 "invalid matrix struct: first field " 1317 "should be an array with size %0: '%1'")) 1318 << (Dim * Dim) << (RD->getName()); 1319 return NULL; 1320 } 1321 1322 FIT++; 1323 if (FIT != RD->field_end()) { 1324 DiagEngine->Report( 1325 clang::FullSourceLoc(RD->getLocation(), *SM), 1326 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1327 "invalid matrix struct: must have " 1328 "exactly 1 field: '%0'")) 1329 << RD->getName(); 1330 return NULL; 1331 } 1332 } 1333 1334 return new RSExportMatrixType(Context, TypeName, Dim); 1335} 1336 1337llvm::Type *RSExportMatrixType::convertToLLVMType() const { 1338 // Construct LLVM type: 1339 // struct { 1340 // float X[mDim * mDim]; 1341 // } 1342 1343 llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 1344 llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 1345 mDim * mDim); 1346 return llvm::StructType::get(C, X, false); 1347} 1348 1349union RSType *RSExportMatrixType::convertToSpecType() const { 1350 llvm::OwningPtr<union RSType> ST(new union RSType); 1351 RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1352 switch (getDim()) { 1353 case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1354 case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1355 case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 1356 default: slangAssert(false && "Matrix type with unsupported dimension."); 1357 } 1358 return ST.take(); 1359} 1360 1361bool RSExportMatrixType::equals(const RSExportable *E) const { 1362 CHECK_PARENT_EQUALITY(RSExportType, E); 1363 return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1364} 1365 1366/************************* RSExportConstantArrayType *************************/ 1367RSExportConstantArrayType 1368*RSExportConstantArrayType::Create(RSContext *Context, 1369 const clang::ConstantArrayType *CAT) { 1370 slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 1371 1372 slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 1373 1374 unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 1375 slangAssert((Size > 0) && "Constant array should have size greater than 0"); 1376 1377 const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 1378 RSExportType *ElementET = RSExportType::Create(Context, ElementType); 1379 1380 if (ElementET == NULL) { 1381 return NULL; 1382 } 1383 1384 return new RSExportConstantArrayType(Context, 1385 ElementET, 1386 Size); 1387} 1388 1389llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 1390 return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 1391} 1392 1393union RSType *RSExportConstantArrayType::convertToSpecType() const { 1394 llvm::OwningPtr<union RSType> ST(new union RSType); 1395 1396 RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1397 RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1398 ST, getElementType()->getSpecType()); 1399 RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1400 1401 if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1402 return ST.take(); 1403 else 1404 return NULL; 1405} 1406 1407bool RSExportConstantArrayType::keep() { 1408 if (!RSExportType::keep()) 1409 return false; 1410 const_cast<RSExportType*>(mElementType)->keep(); 1411 return true; 1412} 1413 1414bool RSExportConstantArrayType::equals(const RSExportable *E) const { 1415 CHECK_PARENT_EQUALITY(RSExportType, E); 1416 const RSExportConstantArrayType *RHS = 1417 static_cast<const RSExportConstantArrayType*>(E); 1418 return ((getSize() == RHS->getSize()) && 1419 (getElementType()->equals(RHS->getElementType()))); 1420} 1421 1422/**************************** RSExportRecordType ****************************/ 1423RSExportRecordType *RSExportRecordType::Create(RSContext *Context, 1424 const clang::RecordType *RT, 1425 const llvm::StringRef &TypeName, 1426 bool mIsArtificial) { 1427 slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1428 1429 const clang::RecordDecl *RD = RT->getDecl(); 1430 slangAssert(RD->isStruct()); 1431 1432 RD = RD->getDefinition(); 1433 if (RD == NULL) { 1434 slangAssert(false && "struct is not defined in this module"); 1435 return NULL; 1436 } 1437 1438 // Struct layout construct by clang. We rely on this for obtaining the 1439 // alloc size of a struct and offset of every field in that struct. 1440 const clang::ASTRecordLayout *RL = 1441 &Context->getASTContext().getASTRecordLayout(RD); 1442 slangAssert((RL != NULL) && 1443 "Failed to retrieve the struct layout from Clang."); 1444 1445 RSExportRecordType *ERT = 1446 new RSExportRecordType(Context, 1447 TypeName, 1448 RD->hasAttr<clang::PackedAttr>(), 1449 mIsArtificial, 1450 RL->getSize().getQuantity()); 1451 unsigned int Index = 0; 1452 1453 for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1454 FE = RD->field_end(); 1455 FI != FE; 1456 FI++, Index++) { 1457 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 1458 1459 // FIXME: All fields should be primitive type 1460 slangAssert(FI->getKind() == clang::Decl::Field); 1461 clang::FieldDecl *FD = *FI; 1462 1463 if (FD->isBitField()) { 1464 return NULL; 1465 } 1466 1467 // Type 1468 RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 1469 1470 if (ET != NULL) { 1471 ERT->mFields.push_back( 1472 new Field(ET, FD->getName(), ERT, 1473 static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 1474 } else { 1475 DiagEngine->Report( 1476 clang::FullSourceLoc(RD->getLocation(), DiagEngine->getSourceManager()), 1477 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, 1478 "field type cannot be exported: '%0.%1'")) 1479 << RD->getName() << FD->getName(); 1480 return NULL; 1481 } 1482 } 1483 1484 return ERT; 1485} 1486 1487llvm::Type *RSExportRecordType::convertToLLVMType() const { 1488 // Create an opaque type since struct may reference itself recursively. 1489 1490 // TODO(sliao): LLVM took out the OpaqueType. Any other to migrate to? 1491 std::vector<llvm::Type*> FieldTypes; 1492 1493 for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1494 FI != FE; 1495 FI++) { 1496 const Field *F = *FI; 1497 const RSExportType *FET = F->getType(); 1498 1499 FieldTypes.push_back(FET->getLLVMType()); 1500 } 1501 1502 llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 1503 FieldTypes, 1504 mIsPacked); 1505 if (ST != NULL) { 1506 return ST; 1507 } else { 1508 return NULL; 1509 } 1510} 1511 1512union RSType *RSExportRecordType::convertToSpecType() const { 1513 unsigned NumFields = getFields().size(); 1514 unsigned AllocSize = sizeof(union RSType) + 1515 sizeof(struct RSRecordField) * NumFields; 1516 llvm::OwningPtr<union RSType> ST( 1517 reinterpret_cast<union RSType*>(operator new(AllocSize))); 1518 1519 ::memset(ST.get(), 0, AllocSize); 1520 1521 RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1522 RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1523 RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1524 1525 setSpecTypeTemporarily(ST.get()); 1526 1527 unsigned FieldIdx = 0; 1528 for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1529 FI != FE; 1530 FI++, FieldIdx++) { 1531 const Field *F = *FI; 1532 1533 RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1534 RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1535 } 1536 1537 // TODO(slang): Check whether all fields were created normally. 1538 1539 return ST.take(); 1540} 1541 1542bool RSExportRecordType::keep() { 1543 if (!RSExportType::keep()) 1544 return false; 1545 for (std::list<const Field*>::iterator I = mFields.begin(), 1546 E = mFields.end(); 1547 I != E; 1548 I++) { 1549 const_cast<RSExportType*>((*I)->getType())->keep(); 1550 } 1551 return true; 1552} 1553 1554bool RSExportRecordType::equals(const RSExportable *E) const { 1555 CHECK_PARENT_EQUALITY(RSExportType, E); 1556 1557 const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1558 1559 if (ERT->getFields().size() != getFields().size()) 1560 return false; 1561 1562 const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1563 1564 for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1565 if (!(*AI)->getType()->equals((*BI)->getType())) 1566 return false; 1567 AI++; 1568 BI++; 1569 } 1570 1571 return true; 1572} 1573 1574void RSExportType::convertToRTD(RSReflectionTypeData *rtd) const { 1575 memset(rtd, 0, sizeof(*rtd)); 1576 rtd->vecSize = 1; 1577 1578 switch(getClass()) { 1579 case RSExportType::ExportClassPrimitive: { 1580 const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this); 1581 rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT); 1582 return; 1583 } 1584 case RSExportType::ExportClassPointer: { 1585 const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this); 1586 const RSExportType *PointeeType = EPT->getPointeeType(); 1587 PointeeType->convertToRTD(rtd); 1588 rtd->isPointer = true; 1589 return; 1590 } 1591 case RSExportType::ExportClassVector: { 1592 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this); 1593 rtd->type = EVT->getRSReflectionType(EVT); 1594 rtd->vecSize = EVT->getNumElement(); 1595 return; 1596 } 1597 case RSExportType::ExportClassMatrix: { 1598 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this); 1599 unsigned Dim = EMT->getDim(); 1600 slangAssert((Dim >= 2) && (Dim <= 4)); 1601 rtd->type = &gReflectionTypes[15 + Dim-2]; 1602 return; 1603 } 1604 case RSExportType::ExportClassConstantArray: { 1605 const RSExportConstantArrayType* CAT = 1606 static_cast<const RSExportConstantArrayType*>(this); 1607 CAT->getElementType()->convertToRTD(rtd); 1608 rtd->arraySize = CAT->getSize(); 1609 return; 1610 } 1611 case RSExportType::ExportClassRecord: { 1612 slangAssert(!"RSExportType::ExportClassRecord not implemented"); 1613 return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item"; 1614 } 1615 default: { 1616 slangAssert(false && "Unknown class of type"); 1617 } 1618 } 1619} 1620 1621 1622} // namespace slang 1623