slang_rs_export_type.cpp revision 5baf6324a97430016026419deaef246ad75430fc
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, 5925baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::PointerType, T), TypeName); 59392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 5949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 5959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 5989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 5995baf6324a97430016026419deaef246ad75430fcStephen Hines UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), TypeName); 6009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 6032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 6042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 605be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 6062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 6072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 6089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 6092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 6102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 6112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "unknown type cannot be exported: '%0'")) 6122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 6139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 618462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 6191f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 6206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 6219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 62278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (NormalizeType(T, TypeName, Context->getDiagnostics(), NULL)) 6239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 6249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 626462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 627462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6289ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 6299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 6309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 631462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 632462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 6349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 6356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 636462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 637462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 6399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 6409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 6419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 6436315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 644462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 645462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6466b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 6476b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 6486b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 649a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 6506b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 6510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 6520da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 6536315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 654a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 655a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 6560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 6570da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 6580da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 6590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 6600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 6610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 6629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 663462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 664462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6653cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 6663cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 6673cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 668641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 669641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 6703cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 671641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 672641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 673641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 674641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 675641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 676641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 677641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 678a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 679a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 680a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 681a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 6829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 683b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 684b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 6859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 687462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 6899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 6909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 693462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 694462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6959ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 696b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 6979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 6989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 699462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 700b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 701b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 702b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 703b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 704a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 705b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 706a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 708462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 709b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 710b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 7129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 7139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 7149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 7159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7169ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 717b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 7209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 7219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 722b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 723b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 724b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 725b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 726b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 727b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 728b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 729b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 730b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 7319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 7329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 733feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 734feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 735feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 736feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 737feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 738feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 739feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 740feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 741feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 742feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 743feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 744feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RD = RD->getDefinition(); 745feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 746feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 747feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 748feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 749feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 750feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 751feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 752feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 753feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 754feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 755feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 756feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 757feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 758feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 759feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 760feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 761feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 762feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 763feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 764feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 765feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 766feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 767feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 768feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 769feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 770feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 771feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 772feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 773feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 774feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 775feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 776feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 777feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 778feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 779feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 780feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 781feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 782feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 783feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 784feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 785feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 786feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 787a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 788a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 789a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 790a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 791a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 792462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 793462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 7956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 7966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 7976e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 7989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 799462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 800462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8019ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 8022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 805462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 808be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 809be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 8109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 811a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 812a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 813a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 8149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 815a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 816a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 817a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8192ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 8202ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 8212ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "built-in type cannot be exported: '%0'")) 8222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 8239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 824462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 830b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 8319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8332ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 8342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 8352ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "primitive type cannot be exported: '%0'")) 8362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 8379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 838462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 840462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 842462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 843462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 8489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 8502ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 851462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 8539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8556b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 8566b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang DT, DK, Normalized); 857462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 858462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 8609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK) { 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 86378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), NULL) 86478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines && IsPrimitiveType(T)) { 8659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName, DK); 866e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 8679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 868e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 869462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 870462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 8729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 8739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 8759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 8769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 8779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 8789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 8809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 8829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 8839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 8849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type *> Elements; 8856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 8869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 887462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 8899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 890462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 8929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 8939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 8949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 8979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 8989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 90091a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 90191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 90291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 90391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 9049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 9059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 9069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 9079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 9109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 9119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 9129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 9149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 9159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 9189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 9199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 9209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 922a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 923a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 9249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 9259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 9269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 9279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 929462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 931462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 933462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 934462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 935a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 936a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 937a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 938a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 939a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 940a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 941a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 942a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 943a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 944641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 945641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 946641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 947641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 948641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 9499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 950462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 9529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 9539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 9549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 9559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 9569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 957462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 9599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 9609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 9619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 9622ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 9632ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 9649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 965462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 9672ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 9689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 9699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 970462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 972462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 973462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPointerType::convertToLLVMType() const { 9759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::Type *PointeeType = mPointeeType->getLLVMType(); 9769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 977462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 978462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 979a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 980a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 981a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 982a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 983a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 984a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 985a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 986a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 987a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 988a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 989a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 990a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 9913cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 9923cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 9933cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 994641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 9953cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 996641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 997641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 998641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 999641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1000641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 1001641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 1002641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1003641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 10046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 10056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 10066315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 10079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 1008462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 10109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 10119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1012be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 10139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 1014a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 1015a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 1016a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 10179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 10199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 10209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 1021a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1022a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 1023a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 1024a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 1025a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 1026a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 1027a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 10289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 10299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 1030462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 10319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1032462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1033462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10349ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 10359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 10369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 10389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 10396e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 1040462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 10429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 10432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 1044462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 10469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 10489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 10499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DK, 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 10529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 10532ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1054462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1055462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportVectorType::convertToLLVMType() const { 10576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 10589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 1059462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1060462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1061a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 1062a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1063a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1064a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 1065a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 1066a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 1067a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1068a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1069a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1070a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1071641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 1072641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 1073641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 1074641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 1075641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1076641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 107792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 107892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 107992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 108092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 108192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 10826e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 10836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 108492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 108592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 108692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 108792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 108892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 108992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 10902ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 10912ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 109292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 109392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 10942ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10962ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have 1 field for saving " 10972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "values: '%0'")) 10982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 109992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 110092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 110192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 110292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 110392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 110492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 110592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 11062ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11072ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11082ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 11092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with constant size: '%0'")) 11102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 111192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 111292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 111392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 111492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 11152e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 111692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 111792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 111892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (static_cast<const clang::BuiltinType *>(ElementType)->getKind() 111992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang != clang::BuiltinType::Float)) { 11202ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11212ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be a " 11232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "float array: '%0'")) 11242ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 112592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 112692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 112792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 112892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 11292ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11302ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11312ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 11322ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with size %0: '%1'")) 11332ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << Dim * Dim 11342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 113592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 113692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 113792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 113892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 113992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 11402ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11412ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11422ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have exactly 1 field: " 11432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "'%0'")) 11442ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 114592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 114692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 114792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 114892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 114992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 115092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 115192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 115292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Changconst llvm::Type *RSExportMatrixType::convertToLLVMType() const { 115392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 115492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 115592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 115692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 115792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 115892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 115992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 116092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 11617207645766b118ef18081363bb58e39d3e715c2fShih-wei Liao return llvm::StructType::get(C, llvm::ArrayRef<const llvm::Type*>(X), false); 116292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 116392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1164a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1165a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1166a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1167a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1168a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1169a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1170a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 11716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1172a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1173a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1174a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1175a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1176641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1177641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1178641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1179641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1180641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 11822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 11832e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 11842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 11856e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 11862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 11882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 11906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 11912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 11932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 11942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 11962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 11972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 11982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 11992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 12002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 12012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 12022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 12032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 12042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Changconst llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 12052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 12062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 12072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1208a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1209a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1210a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1211a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1212a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1213a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1214a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1215a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1216a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1217a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1218a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1219a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1220a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1221a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 12223cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 12233cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1225641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 12263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1227641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1228641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1229641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1230641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1231a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1232a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1233a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1234a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1235641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1236641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 12379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 12389ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 12399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 12409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 12419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 12426e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1243462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 12456e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1246462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 12489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 12496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 12509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 12519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1252462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 12540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 12550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 12569e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 12590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 12600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 12610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 12620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 12630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 12640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 126568318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 12669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 12679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 12699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 12709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 127191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 12722ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 12739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 12756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((*FI)->getKind() == clang::Decl::Field); 12769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 12779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12782ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 12792ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 12802ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 12812ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 12829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 12846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 12859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12862ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 12870da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 12880da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 12890da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 12902ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 129178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), 129278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines Diags->getSourceManager()), 12932ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 12942ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "field type cannot be exported: '%0.%1'")) 12952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName() 12962ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << FD->getName(); 12972ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 12982ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 12992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 13009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 13010a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 13029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1304462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13056315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportRecordType::convertToLLVMType() const { 13063cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 13073cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::PATypeHolder ResultHolder = 13083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::OpaqueType::get(getRSContext()->getLLVMContext()); 13093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang setAbstractLLVMType(ResultHolder.get()); 13103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 13119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type*> FieldTypes; 1312462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13133cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 13149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 13159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 13169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 13179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 13181f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 13199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 13209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1321462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 13223cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 13233cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 13243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 13253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (ST != NULL) 13263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang static_cast<llvm::OpaqueType*>(ResultHolder.get()) 13273cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang ->refineAbstractTypeTo(ST); 13283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang else 13293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 13303cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return ResultHolder.get(); 1331462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1332641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1333a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1334a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1335a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1336a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1337a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1338e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1339a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1340a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1341a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1342a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1343a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1344a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1345a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1346a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1347a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1348a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1349a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1350a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1351a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1352a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1353a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1354a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1355a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1356a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1357a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang enum RSDataKind DK = RS_DK_User; 1358a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if ((F->getType()->getClass() == ExportClassPrimitive) || 1359a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang (F->getType()->getClass() == ExportClassVector)) { 1360a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const RSExportPrimitiveType *EPT = 1361a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang static_cast<const RSExportPrimitiveType*>(F->getType()); 1362a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataKind is synced with enum RSDataKind in 1363a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1364a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang DK = static_cast<enum RSDataKind>(EPT->getKind()); 1365a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1366a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_DATA_KIND(ST, FieldIdx, DK); 1367a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1368a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1369e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1370a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1371a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1372a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1373a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 13743cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 13753cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 13763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1377641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1378641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1379641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1380641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1381641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1382641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 13833cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1384641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1385641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1386641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1387641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1388641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1389641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1390641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1391641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1392641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1393641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1394641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1395641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1396641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1397641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1398641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1399641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1400641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1401641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1402641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1403641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1404641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1405e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1406e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1407