slang_rs_export_type.cpp revision 78e69cb06b9b0683b2ac9dcafde87b867690ef2f
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright 2010, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <vector> 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/AST/RecordLayout.h" 23462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 247207645766b118ef18081363bb58e39d3e715c2fShih-wei Liao#include "llvm/ADT/ArrayRef.h" 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/DerivedTypes.h" 28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Target/TargetData.h" 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Type.h" 320a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 36a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 37462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 40641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 41641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 42e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 44e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 45462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4624e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 4724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 4824e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 4924e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::Diagnostic *Diags, 5024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5124e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord); 5224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 5324e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic void ReportTypeError(clang::Diagnostic *Diags, 5424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 5624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const char *Message) { 5778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!Diags) { 5824e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 5924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 6024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 6178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::SourceManager &SM = Diags->getSourceManager(); 6278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 6324e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 6424e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 6524e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 6624e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 6778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(TopLevelRecord->getLocation(), SM), 6824e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, Message)) 6924e79f69125cf87fcaa78c04510a831037203eebStephen Hines << TopLevelRecord->getName(); 7024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (VD) { 7178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(VD->getLocation(), SM), 7224e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, Message)) 7324e79f69125cf87fcaa78c04510a831037203eebStephen Hines << VD->getName(); 7424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Variables should be validated before exporting"); 7624e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 7724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 7824e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 7924e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 8024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 8124e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 8224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 8324e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 8424e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::Diagnostic *Diags, 8524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 8624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord) { 8724e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 8824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 8924e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 9078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, VD, TopLevelRecord, 9124e79f69125cf87fcaa78c04510a831037203eebStephen Hines "multidimensional arrays cannot be exported: '%0'"); 9224e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 9324e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 9424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 9524e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 9624e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 9924e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 10078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, VD, TopLevelRecord, 10124e79f69125cf87fcaa78c04510a831037203eebStephen Hines "vectors of non-primitive types cannot be exported: '%0'"); 10224e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 10324e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines 10524e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 10678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, VD, TopLevelRecord, 10724e79f69125cf87fcaa78c04510a831037203eebStephen Hines "arrays of width 3 vector types cannot be exported: '%0'"); 10824e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 10924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (TypeExportableHelper(ElementType, SPS, Diags, VD, TopLevelRecord) == NULL) 11324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 11424e79f69125cf87fcaa78c04510a831037203eebStephen Hines else 11524e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 11624e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11824e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 120c808a99831115928b4648f4c8b86dc682594217aStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 121e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 122dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD, 123e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::RecordDecl *TopLevelRecord) { 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 127462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1301f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 133be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 134be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 137a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 139a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 147b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataTypeUnknown) 1496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 152cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 15378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, NULL, T->getAsUnionType()->getDecl(), 15424e79f69125cf87fcaa78c04510a831037203eebStephen Hines "unions cannot be exported: '%0'"); 155cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 156cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 1576e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 158cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 159cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 160cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 16124e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 1622ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 1642ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 16578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, NULL, T->getAsStructureType()->getDecl(), 1662ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "struct is not defined in this module"); 1672ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1682ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 1692ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 170f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 171e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 172e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 173e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 174e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 17578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, NULL, RD, 17624e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous structures cannot be exported"); 177e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 178e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 179e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 183f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 186f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 1920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 193e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 195462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 19678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!TypeExportableHelper(FT, SPS, Diags, VD, TopLevelRecord)) { 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1980da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 1992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 2002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 2012ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 2022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 2032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 20478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (Diags) { 20578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(FD->getLocation(), 20678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->getSourceManager()), 2072ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 2082ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "bit fields are not able to be exported: '%0.%1'")) 2092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName() 2102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << FD->getName(); 2112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 219e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 22078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(Diags, NULL, TopLevelRecord, 22124e79f69125cf87fcaa78c04510a831037203eebStephen Hines "structures containing pointers cannot be exported: '%0'"); 222c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 223c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 22424e79f69125cf87fcaa78c04510a831037203eebStephen Hines 225be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 226be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 2279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 228462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2292e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->getTypeClass() == clang::Type::Pointer) 2309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2312e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2322e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2332e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 23478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines (TypeExportableHelper(PointeeType, SPS, Diags, VD, 235e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 242be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 246f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 249462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 25178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines (TypeExportableHelper(ElementType, SPS, Diags, VD, 252e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2572e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 2582e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 259be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 2602e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 26178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Diags, VD, 26224e79f69125cf87fcaa78c04510a831037203eebStephen Hines TopLevelRecord); 2632e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 2649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 2659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 266462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 269462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 270e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 271e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 27278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// If the Type T is not exportable, this function returns NULL. Diags is 27378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines// used to generate proper Clang diagnostic messages when a 274e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 275e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 276e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 277e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 278e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 279dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 280e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 281e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 282e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 28378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return TypeExportableHelper(T, SPS, Diags, VD, NULL); 28478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 28578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 28678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesstatic bool ValidateVarDeclHelper( 28778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::VarDecl *VD, 28878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *&T, 28978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 29078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *UnionDecl) { 29178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = GET_CANONICAL_TYPE(T)) == NULL) 29278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 29378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 29478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (SPS.count(T)) 29578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 29678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 29778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines switch (T->getTypeClass()) { 29878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Record: { 29978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportPrimitiveType::GetRSSpecificType(T) != 30078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RSExportPrimitiveType::DataTypeUnknown) { 30178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!UnionDecl) { 30278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 30378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(T)) { 30478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::ASTContext &C = VD->getASTContext(); 30578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines ReportTypeError(&C.getDiagnostics(), VD, UnionDecl, 30678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines "unions containing RS object types are not allowed"); 30778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 30878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 30978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 31078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 31178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines clang::RecordDecl *RD = NULL; 31278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 31378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check internal struct 31478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (T->isUnionType()) { 31578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsUnionType()->getDecl(); 31678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UnionDecl = RD; 31778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else if (T->isStructureType()) { 31878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = T->getAsStructureType()->getDecl(); 31978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } else { 32078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "Unknown type cannot be exported"); 32178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 32278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 32378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 32478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD != NULL) { 32578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines RD = RD->getDefinition(); 32678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD == NULL) { 32778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // FIXME 32878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 32978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 33078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 33178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 33278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Fast check 33378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 33478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 33578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 33678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Insert myself into checking set 33778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines SPS.insert(T); 33878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 33978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines // Check all elements 34078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 34178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FE = RD->field_end(); 34278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI != FE; 34378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FI++) { 34478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::FieldDecl *FD = *FI; 34578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 34678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines FT = GET_CANONICAL_TYPE(FT); 34778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 34878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!ValidateVarDeclHelper(VD, FT, SPS, UnionDecl)) { 34978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return false; 35078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 35178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 35278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 35378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 35478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 35578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 35678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Builtin: { 35778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 35878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 35978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 36078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::Pointer: { 36178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::PointerType *PT = 36278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T); 36378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 36478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 36578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return ValidateVarDeclHelper(VD, PointeeType, SPS, UnionDecl); 36678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 36778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 36878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ExtVector: { 36978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ExtVectorType *EVT = 37078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 37178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 37278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return ValidateVarDeclHelper(VD, ElementType, SPS, UnionDecl); 37378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 37478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 37578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines case clang::Type::ConstantArray: { 37678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::ConstantArrayType *CAT = 37778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 37878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 37978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return ValidateVarDeclHelper(VD, ElementType, SPS, UnionDecl); 38078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 38178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 38278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines default: { 38378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines break; 38478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 38578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines } 38678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 38778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return true; 388e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 389e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 390e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 391e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 392e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 393e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 394e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 395e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 396dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 39778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if ((T = TypeExportable(T, Diags, VD)) == NULL) { 398e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 399e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 400e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 401e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 402e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TypeName.empty()) { 40378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (Diags) { 40424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (VD) { 40578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(VD->getLocation(), 40678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->getSourceManager()), 40724e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 40824e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 40924e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 41024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 41124e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 41224e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 41324e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 41424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 415e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 416e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 417e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 418e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 419e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 420e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 421e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 42278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hinesbool RSExportType::ValidateVarDecl(clang::VarDecl *VD) { 42378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines const clang::Type *T = VD->getType().getTypePtr(); 42478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 42578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 42678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 42778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines return ValidateVarDeclHelper(VD, T, SPS, NULL); 42878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines} 42978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines 430e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 431e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 432e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 433e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::QualType T; 434e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD->getTypeSourceInfo()) 435e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getTypeSourceInfo()->getType(); 436e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 437e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getType(); 438e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 439e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 440e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 441e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 442e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 443e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 444e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 445e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 446e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 447e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 448e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 449e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 450e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 451e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 452e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 453e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 454be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 455be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 456e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 457e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 458e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 459e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 460e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 461e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 462e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 463e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 4646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type of the builtin"); 465e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 466e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 467e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 468e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 469e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 470e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 471cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 472cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 473cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 474dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 475cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 476cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 477cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 478e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 479e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 480e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getTypedefForAnonDecl() != NULL) 481e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = RD->getTypedefForAnonDecl()->getName(); 482e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 483e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) 484e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Try to find a name from redeclaration (i.e. typedef) 485e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 486e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RE = RD->redecls_end(); 487e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI != RE; 488e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI++) { 4896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(*RI != NULL && "cannot be NULL object"); 490e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 491e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = (*RI)->getName(); 492e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!Name.empty()) 493e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 494e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 495e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 496e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 497e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 498e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 499e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 500e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 501e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 50278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL)) { 503e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 504e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 505e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 506e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 507e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 508e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 509e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 510e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 511e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 512e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 513be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 514e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 515e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 516e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 517e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 518e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 519e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 520e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 521e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 522e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 523e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 524e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 525e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 526e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 527e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 528e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 529e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 5309ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 5319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 5329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 5339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 5349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 5359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 5369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 5379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 5399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 5409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 5429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 5439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 5449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 545b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 5469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 54792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 54892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 5499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 5509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 5519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 5529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 55492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 55592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 55692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 55792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 55892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 55992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 56092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 56192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 56292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 56392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 56492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 56592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 56692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 56792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 56892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 56992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 5709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 57192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 57292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 57392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 57492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 57592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 5769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 57992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 5809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 5819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 5879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 5889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 5919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 592be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T), 5939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 59492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 5959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 5969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 5999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 600be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), 6019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 6029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 6052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 6062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 607be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 6082e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 6092e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 6109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 6112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 6122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 6132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "unknown type cannot be exported: '%0'")) 6142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 6159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 620462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 6211f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 6226315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 6239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 62478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (NormalizeType(T, TypeName, Context->getDiagnostics(), NULL)) 6259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 6269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 628462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 629462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6309ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 6319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 6329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 633462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 634462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 6369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 6376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 638462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 639462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 6419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 6429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 6439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 6456315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 646462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 647462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6486b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 6496b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 6506b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 651a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 6526b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 6530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 6540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 6556315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 656a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 657a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 6580da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 6590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 6600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 6610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 6620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 6630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 6649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 665462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 666462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6673cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 6683cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 6693cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 670641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 671641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 6723cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 673641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 674641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 675641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 676641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 677641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 678641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 679641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 680a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 681a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 682a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 683a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 6849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 685b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 686b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 6879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 689462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 6929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 6939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 695462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 696462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6979ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 698b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 6999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 7009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 701462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 702b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 703b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 704b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 705b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 706a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 707b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 708a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 7099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 710462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 711b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 712b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 7139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 7149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 7159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 7169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 7179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 719b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 7209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 7219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 7229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 7239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 724b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 725b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 726b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 727b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 728b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 729b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 730b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 731b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 732b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 7339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 7349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 735feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 736feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 737feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 738feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 739feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 740feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 741feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 742feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 743feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 744feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 745feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 746feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RD = RD->getDefinition(); 747feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 748feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 749feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 750feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 751feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 752feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 753feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 754feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 755feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 756feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 757feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 758feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 759feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 760feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 761feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 762feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 763feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 764feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 765feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 766feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 767feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 768feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 769feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 770feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 771feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 772feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 773feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 774feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 775feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 776feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 777feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 778feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 779feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 780feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 781feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 782feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 783feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 784feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 785feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 786feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 787feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 788feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 789a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 790a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 791a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 792a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 793a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 794462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 795462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 7976e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 7986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 7996e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 8009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 801462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 802462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 8042ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 8059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 807462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 8099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 810be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 811be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 8129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 813a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 814a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 815a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 8169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 817a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 818a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 819a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 8209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8212ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 8222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 8232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "built-in type cannot be exported: '%0'")) 8242ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 826462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 8319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 832b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 8339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8352ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 8362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 8372ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "primitive type cannot be exported: '%0'")) 8382ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 8399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 840462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 842462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 844462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 845462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 8489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 8509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 8522ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 853462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 8559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8576b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 8586b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang DT, DK, Normalized); 859462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 860462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 8639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK) { 8649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 86578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), NULL) 86678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 8679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName, DK); 868e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 8699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 870e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 871462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 872462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 8749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 8759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 8779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 8789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 8799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 8809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 8829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 8849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 8869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type *> Elements; 8876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 8889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 889462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 8919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 892462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 8949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 8959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 8969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 8999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 9009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 90291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 90391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 90491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 90591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 9069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 9079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 9089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 9099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 9129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 9149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 9159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 9169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 9179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 9209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 9219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 9229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 924a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 925a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 9269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 9279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 931462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 933462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 935462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 936462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 937a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 938a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 939a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 940a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 941a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 942a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 943a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 944a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 945a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 946641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 947641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 948641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 949641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 950641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 952462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9539ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 9549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 9559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 9569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 9579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 9589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 959462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 9619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 9629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 9639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 9642ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 9652ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 9669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 967462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 9692ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 9709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 9719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 972462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 974462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 975462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPointerType::convertToLLVMType() const { 9779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::Type *PointeeType = mPointeeType->getLLVMType(); 9789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 979462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 980462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 981a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 982a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 983a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 984a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 985a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 986a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 987a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 988a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 989a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 990a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 991a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 992a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 9933cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 9943cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 9953cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 996641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 9973cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 998641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 999641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1000641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 1001641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1002641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1003641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1004641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1005641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 10066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 10076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 10086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 10099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1010462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 10129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 10139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1014be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 10159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1016a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1017a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1018a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 10199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 10219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 10229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1023a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1024a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 1025a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1026a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 1027a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 1028a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 1029a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 10309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 10319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 1032462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1034462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1035462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10369ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 10389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 10409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 10416e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1042462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 10449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 10452ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1046462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 10489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DK, 10529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 10549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 10552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1056462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1057462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10586315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportVectorType::convertToLLVMType() const { 10596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 10609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1061462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1062462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1063a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1064a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1065a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1066a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1067a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1068a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1069a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1070a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1071a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1072a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1073641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1074641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1075641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1076641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1077641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1078641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 107992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 108092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 108192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 108292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 108392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 10846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 10856e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 108692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 108792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 108892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 108992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 109092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 109192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 10922ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 10932ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 109492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 109592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 10962ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have 1 field for saving " 10992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "values: '%0'")) 11002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 110192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 110292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 110392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 110492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 110592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 110692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 110792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 11082ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 11112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with constant size: '%0'")) 11122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 111392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 111492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 111592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 111692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 11172e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 111892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 111992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 112092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (static_cast<const clang::BuiltinType *>(ElementType)->getKind() 112192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang != clang::BuiltinType::Float)) { 11222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11242ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be a " 11252ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "float array: '%0'")) 11262ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 112792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 112892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 112992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 113092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 11312ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11332ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 11342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with size %0: '%1'")) 11352ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << Dim * Dim 11362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 113792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 113892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 113992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 114092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 114192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 11422ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11442ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have exactly 1 field: " 11452ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "'%0'")) 11462ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 114792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 114892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 114992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 115092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 115192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 115292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 115392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 115492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Changconst llvm::Type *RSExportMatrixType::convertToLLVMType() const { 115592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 115692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 115792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 115892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 115992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 116092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 116192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 116292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 11637207645766b118ef18081363bb58e39d3e715c2fShih-wei Liao return llvm::StructType::get(C, llvm::ArrayRef<const llvm::Type*>(X), false); 116492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 116592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1166a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1167a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1168a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1169a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1170a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1171a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1172a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 11736e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1174a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1175a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1176a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1177a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1178641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1179641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1180641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1181641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1182641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11832e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 11842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 11852e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 11862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 11876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 11882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 11902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 11926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 11932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 11952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 11962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 11982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 11992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 12002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 12022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 12032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 12042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 12052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Changconst llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 12072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 12082e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 12092e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1210a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1211a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1212a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1213a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1214a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1215a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1216a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1217a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1218a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1219a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1220a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1221a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1222a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1223a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 12243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 12253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1227641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 12283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1229641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1230641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1231641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1232641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1233a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1234a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1235a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1236a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1237641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1238641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 12409ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 12419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 12429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 12446e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1245462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 12476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1248462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 12509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 12516e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 12529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 12539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1254462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 12560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 12570da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 12589e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 12610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 12620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 12630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 12640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 12650da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 12660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 126768318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 12689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 12699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 12719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 12729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 127391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 12742ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 12759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 12776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((*FI)->getKind() == clang::Decl::Field); 12789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 12799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12802ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 12812ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 12822ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 12832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 12849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 12866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 12879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12882ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 12890da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 12900da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 12910da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 12922ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 129378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), 129478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->getSourceManager()), 12952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 12962ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "field type cannot be exported: '%0.%1'")) 12972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName() 12982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << FD->getName(); 12992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 13002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 13012ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 13029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 13030a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 13049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1305462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1306462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportRecordType::convertToLLVMType() const { 13083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 13093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::PATypeHolder ResultHolder = 13103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::OpaqueType::get(getRSContext()->getLLVMContext()); 13113cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang setAbstractLLVMType(ResultHolder.get()); 13123cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 13139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type*> FieldTypes; 1314462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13153cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 13169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 13179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 13189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 13199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 13201f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 13219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 13229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1323462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 13253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 13263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 13273cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (ST != NULL) 13283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang static_cast<llvm::OpaqueType*>(ResultHolder.get()) 13293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang ->refineAbstractTypeTo(ST); 13303cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang else 13313cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 13323cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return ResultHolder.get(); 1333462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1334641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1335a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1336a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1337a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1338a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1339a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1340e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1341a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1342a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1343a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1344a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1345a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1346a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1347a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1348a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1349a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1350a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1351a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1352a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1353a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1354a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1355a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1356a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1357a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1358a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1359a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang enum RSDataKind DK = RS_DK_User; 1360a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if ((F->getType()->getClass() == ExportClassPrimitive) || 1361a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang (F->getType()->getClass() == ExportClassVector)) { 1362a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const RSExportPrimitiveType *EPT = 1363a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang static_cast<const RSExportPrimitiveType*>(F->getType()); 1364a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataKind is synced with enum RSDataKind in 1365a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1366a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang DK = static_cast<enum RSDataKind>(EPT->getKind()); 1367a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1368a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_DATA_KIND(ST, FieldIdx, DK); 1369a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1370a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1371e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1372a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1373a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1374a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1375a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 13763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 13773cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 13783cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1379641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1380641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1381641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1382641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1383641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1384641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 13853cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1386641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1387641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1388641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1389641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1390641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1391641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1392641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1393641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1394641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1395641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1396641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1397641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1398641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1399641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1400641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1401641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1402641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1403641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1404641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1405641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1406641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1407e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1408e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1409