slang_rs_export_type.cpp revision 7207645766b118ef18081363bb58e39d3e715c2f
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 clang::SourceManager *SM, 5124e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5224e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord); 5324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 5424e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic void ReportTypeError(clang::Diagnostic *Diags, 552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM, 5624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 5824e79f69125cf87fcaa78c04510a831037203eebStephen Hines const char *Message) { 5924e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!Diags || !SM) { 6024e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 6124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 6224e79f69125cf87fcaa78c04510a831037203eebStephen 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) { 6724e79f69125cf87fcaa78c04510a831037203eebStephen 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) { 7124e79f69125cf87fcaa78c04510a831037203eebStephen 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 clang::SourceManager *SM, 8624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 8724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord) { 8824e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 8924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 9024e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 9124e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 9224e79f69125cf87fcaa78c04510a831037203eebStephen Hines "multidimensional arrays cannot be exported: '%0'"); 9324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 9424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 9524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 9624e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 9924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 10024e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 10124e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 10224e79f69125cf87fcaa78c04510a831037203eebStephen Hines "vectors of non-primitive types cannot be exported: '%0'"); 10324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 10524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 10624e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 10724e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 10824e79f69125cf87fcaa78c04510a831037203eebStephen Hines "arrays of width 3 vector types cannot be exported: '%0'"); 10924e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 11024e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11124e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11224e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11324e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TypeExportableHelper(ElementType, SPS, Diags, SM, VD, 11424e79f69125cf87fcaa78c04510a831037203eebStephen Hines TopLevelRecord) == NULL) 11524e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 11624e79f69125cf87fcaa78c04510a831037203eebStephen Hines else 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 11824e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 11924e79f69125cf87fcaa78c04510a831037203eebStephen Hines 12024e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 122c808a99831115928b4648f4c8b86dc682594217aStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 123e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 124e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::SourceManager *SM, 125dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD, 126e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::RecordDecl *TopLevelRecord) { 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 130462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1331f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 136be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 137be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 138462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 140a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 142a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 150b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataTypeUnknown) 1526315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 155cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 15624e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, T->getAsUnionType()->getDecl(), 15724e79f69125cf87fcaa78c04510a831037203eebStephen Hines "unions cannot be exported: '%0'"); 158cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 159cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 1606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown type cannot be exported"); 161cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 162cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 163cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 16424e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 1652ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD != NULL) { 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 1672ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (RD == NULL) { 1682ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines ReportTypeError(Diags, SM, NULL, T->getAsStructureType()->getDecl(), 1692ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "struct is not defined in this module"); 1702ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 1712ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 1722ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 173f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 174e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 175e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 176e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 177e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 17824e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, RD, 17924e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous structures cannot be exported"); 180e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 181e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 182e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 186f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 189f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 1949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 1950da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 196e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 198462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 199dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (!TypeExportableHelper(FT, SPS, Diags, SM, VD, TopLevelRecord)) { 2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2010da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 2022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines 2032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // We don't support bit fields yet 2042ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // 2052ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // TODO(zonr/srhines): allow bit fields of size 8, 16, 32 2062ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 2072ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (Diags && SM) { 2082ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(FD->getLocation(), *SM), 2092ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 2102ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "bit fields are not able to be exported: '%0.%1'")) 2112ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName() 2122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << FD->getName(); 2132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 2152ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 221e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 22224e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, TopLevelRecord, 22324e79f69125cf87fcaa78c04510a831037203eebStephen Hines "structures containing pointers cannot be exported: '%0'"); 224c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 225c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 22624e79f69125cf87fcaa78c04510a831037203eebStephen Hines 227be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::PointerType *PT = 228be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T); 2299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 230462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2312e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->getTypeClass() == clang::Type::Pointer) 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2332e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2342e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2352e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 236dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines (TypeExportableHelper(PointeeType, SPS, Diags, SM, VD, 237e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 244be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 248f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 251462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 253dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines (TypeExportableHelper(ElementType, SPS, Diags, SM, VD, 254e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2592e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 2602e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 261be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T); 2622e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 26324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Diags, SM, VD, 26424e79f69125cf87fcaa78c04510a831037203eebStephen Hines TopLevelRecord); 2652e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 2669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 2679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 268462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 271462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 272e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 273e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 274e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// If the Type T is not exportable, this function returns NULL. Diags and SM 275e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// are used to generate proper Clang diagnostic messages when a 276e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 277e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 278e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 279e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 280e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 281dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines clang::SourceManager *SM, 282dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 283e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 284e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 285e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 286dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines return TypeExportableHelper(T, SPS, Diags, SM, VD, NULL); 287e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 288e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 289e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 290e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 291e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 292e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 293e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 294e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 295dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines clang::SourceManager *SM, 296dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 297dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if ((T = TypeExportable(T, Diags, SM, VD)) == NULL) { 298e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 299e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 300e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 301e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 302e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TypeName.empty()) { 303e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Diags && SM) { 30424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (VD) { 30524e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(clang::FullSourceLoc(VD->getLocation(), *SM), 30624e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 30724e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 30824e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 30924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 31024e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 31124e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 31224e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 31324e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 314e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 315e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 316e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 317e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 318e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 319e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 320e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 321e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 322e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 323e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 324e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::QualType T; 325e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD->getTypeSourceInfo()) 326e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getTypeSourceInfo()->getType(); 327e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 328e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getType(); 329e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 330e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 331e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 332e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 333e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 334e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 335e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 336e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 337e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 338e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 339e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 340e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 341e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 342e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 343e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 344e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 345be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 346be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 347e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 348e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 349e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 350e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 351e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 352e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 353e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 354e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 3556e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type of the builtin"); 356e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 357e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 358e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 359e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 360e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 361e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 362cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 363cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 364cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 365dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 366cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 367cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 368cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 369e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 370e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 371e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getTypedefForAnonDecl() != NULL) 372e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = RD->getTypedefForAnonDecl()->getName(); 373e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 374e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) 375e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Try to find a name from redeclaration (i.e. typedef) 376e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 377e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RE = RD->redecls_end(); 378e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI != RE; 379e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI++) { 3806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(*RI != NULL && "cannot be NULL object"); 381e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 382e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = (*RI)->getName(); 383e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!Name.empty()) 384e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 385e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 386e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 387e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 388e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 389e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 390e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 391e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 392e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 393dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL, NULL)) { 394e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 395e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 396e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 397e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 398e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 399e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 400e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 401e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 402e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 403e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 404be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T); 405e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 406e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 407e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 408e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 409e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 410e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 411e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 412e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 413e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 414e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 415e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 416e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 417e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 418e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 419e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 420e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 4219ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 4229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 4239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 4249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 4259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 4269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 4279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 4289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 4309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 4319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 4339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 4349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 4359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 436b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 4379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 43892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 43992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 4409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 4419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 44592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 44692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 44792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 44892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 44992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 45092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 45192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 45292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 45392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 45492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 45592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 45692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 45792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 45892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 45992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 46092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 46292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 46392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 46492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 46592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 46692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 47092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 4719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 4729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 483be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::PointerType, T), 4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 48592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 4869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 4879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 4909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 491be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ExtVectorType, T), 4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 4962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 4972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 498be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::ConstantArrayType, T)); 4992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 5002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 5022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 5032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 5042ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "unknown type cannot be exported: '%0'")) 5052ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 5079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 5099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 511462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 5121f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 5136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 5149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 515dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (NormalizeType(T, TypeName, NULL, NULL, NULL)) 5169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 5179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 519462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 520462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5219ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 5229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 5239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 524462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 525462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 5279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 5286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 529462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 530462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 5329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 5339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 5349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 5366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 537462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 538462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5396b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 5406b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 5416b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 542a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 5436b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 5440da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 5450da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 5466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 547a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 548a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 5490da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 5500da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 5510da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 5520da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 5530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 5540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 5559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 556462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 557462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5583cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 5593cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 5603cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 561641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 562641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 5633cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 564641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 565641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 566641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 567641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 568641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 569641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 570641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 571a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 572a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 573a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 574a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 5759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 576b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 577b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 5789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 580462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 5829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 5839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 5849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 586462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 587462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5889ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 589b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 5909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 5919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 592462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 593b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 594b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 595b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 596b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 597a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 598b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 599a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 6009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 601462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 602b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 603b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 6049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 6059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 6079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 6089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6099ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 610b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 6119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 6129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 6139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 6149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 615b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 616b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 617b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 618b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 619b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 620b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 621b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 622b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 623b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 6249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 6259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 626feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hinesbool RSExportPrimitiveType::IsStructureTypeWithRSObject(const clang::Type *T) { 627feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines bool RSObjectTypeSeen = false; 628feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (T && T->isArrayType()) { 629feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 630feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 631feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 632feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordType *RT = T->getAsStructureType(); 633feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (!RT) { 634feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 635feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 636feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::RecordDecl *RD = RT->getDecl(); 637feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RD = RD->getDefinition(); 638feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 639feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FE = RD->field_end(); 640feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI != FE; 641feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FI++) { 642feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // We just look through all field declarations to see if we find a 643feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // declaration for an RS object type (or an array of one). 644feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::FieldDecl *FD = *FI; 645feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 646feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 647feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 648feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 649feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 650feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSExportPrimitiveType::DataType DT = GetRSSpecificType(FT); 651feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (IsRSObjectType(DT)) { 652feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // RS object types definitely need to be zero-initialized 653feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 654feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 655feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines switch (DT) { 656feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 657feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 658feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: 659feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Matrix types should get zero-initialized as well 660feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen = true; 661feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 662feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines default: 663feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Ignore all other primitive types 664feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines break; 665feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 666feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines while (FT && FT->isArrayType()) { 667feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 668feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 669feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (FT->isStructureType()) { 670feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // Recursively handle structs of structs (even though these can't 671feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines // be exported, it is possible for a user to have them internally). 672feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines RSObjectTypeSeen |= IsStructureTypeWithRSObject(FT); 673feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 674feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 675feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 676feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 677feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return RSObjectTypeSeen; 678feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines} 679feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines 680a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 681a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 682a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 683a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 684a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 685462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 686462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 6886e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(((EPT->getType() > DataTypeUnknown) && 6896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines (EPT->getType() < DataTypeMax)) && 6906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 692462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 693462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6949ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 6952ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen HinesRSExportPrimitiveType::GetDataType(RSContext *Context, const clang::Type *T) { 6969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 6979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 698462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 7009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 701be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = 702be27482cdeaf08576bc39b72a15d35d13014a636Logan UNSAFE_CAST_TYPE(const clang::BuiltinType, T); 7039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 704a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 705a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 706a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 708a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 709a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 710a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 7119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 7122ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 7132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 7142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "built-in type cannot be exported: '%0'")) 7152ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 7169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 717462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 7229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 723b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 7249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 7262ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 7272ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 7282ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "primitive type cannot be exported: '%0'")) 7292ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << T->getTypeClassName(); 7309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 731462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 7329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 733462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 735462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 736462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7379ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 7389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 7399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 7409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 7419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 7429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 7432ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines DataType DT = GetDataType(Context, T); 744462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 7469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 7479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 7486b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 7496b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang DT, DK, Normalized); 750462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 751462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7529ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 7539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 7549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK) { 7559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 756dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (RSExportType::NormalizeType(T, TypeName, NULL, NULL, NULL) && 757e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines IsPrimitiveType(T)) { 7589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName, DK); 759e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 761e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 762462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 763462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 7659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 7669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 7689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 7699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 7709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 7719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 7729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 7739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 7749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 7759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 7769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 7779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type *> Elements; 7786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 7799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 780462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 7819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 7829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 783462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 7859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 7869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 7879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 7909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 7919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 79391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 79491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 79591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 79691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 7979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 7989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 7999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 8009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 8039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 8049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 8059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 8069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 8079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 8089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 8119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 8129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 8139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 815a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 816a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 8179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 8199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 8209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8216e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown data type"); 822462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 824462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 826462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 827462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 828a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 829a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 830a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 831a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 832a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 833a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 834a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 835a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 836a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 837641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 838641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 839641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 840641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 841641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 8429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 843462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8449ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 8489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 850462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 8539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 8552ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines PointeeET = RSExportPrimitiveType::Create(Context, 8562ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Context->getASTContext().IntTy.getTypePtr()); 8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 858462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 8602ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines // Error diagnostic is emitted for corresponding pointee type 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 863462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 865462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 866462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPointerType::convertToLLVMType() const { 8689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::Type *PointeeType = mPointeeType->getLLVMType(); 8699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 870462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 871462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 872a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 873a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 874a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 875a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 876a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 877a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 878a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 879a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 880a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 881a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 882a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 883a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 8843cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 8853cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 8863cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 887641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 8883cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 889641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 890641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 891641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 892641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 893641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 894641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 895641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 896641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 8976315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 8986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 8996315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 9009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 901462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 9039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 9049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 905be27482cdeaf08576bc39b72a15d35d13014a636Logan const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(const clang::BuiltinType, 9069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 907a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 908a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 909a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 9109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 9119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 9129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 9139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 914a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 915a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 916a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 917a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 918a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 919a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 920a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 9219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 9229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 923462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 9249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 925462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 926462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9279ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 9289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 9299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 9309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 9319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 9326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 933462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 9359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 9362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines RSExportPrimitiveType::GetDataType(Context, ElementType); 937462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 9399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 9409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 9419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 9429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DK, 9439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 9449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 9459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 9462ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 947462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 948462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 9496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportVectorType::convertToLLVMType() const { 9506315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 9519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 952462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 953462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 954a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 955a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 956a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 957a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 958a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 959a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 960a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 961a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 962a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 963a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 964641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 965641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 966641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 967641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 968641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 969641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 97092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 97192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 97292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 97392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 97492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 9756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 9766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Dim > 1) && "Invalid dimension of matrix"); 97792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 97892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 97992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 98092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 98192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 98292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 9832ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 9842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 98592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 98692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 9872ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 9882ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 9892ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have 1 field for saving " 9902ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "values: '%0'")) 9912ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 99292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 99392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 99492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 99592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 99692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 99792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 99892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 9992ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10002ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10012ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 10022ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with constant size: '%0'")) 10032ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 100492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 100592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 100692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 100792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 10082e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 100992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 101092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 101192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (static_cast<const clang::BuiltinType *>(ElementType)->getKind() 101292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang != clang::BuiltinType::Float)) { 10132ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10142ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10152ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be a " 10162ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "float array: '%0'")) 10172ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 101892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 101992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 102092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 102192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 10222ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10232ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10242ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: first field should be an " 10252ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "array with size %0: '%1'")) 10262ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << Dim * Dim 10272ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 102892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 102992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 103092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 103192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 103292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 10332ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 10342ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 10352ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "invalid matrix struct: must have exactly 1 field: " 10362ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "'%0'")) 10372ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName(); 103892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 103992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 104092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 104192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 104292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 104392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 104492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 104592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Changconst llvm::Type *RSExportMatrixType::convertToLLVMType() const { 104692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 104792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 104892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 104992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 105092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 105192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 105292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 105392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 10547207645766b118ef18081363bb58e39d3e715c2fShih-wei Liao return llvm::StructType::get(C, llvm::ArrayRef<const llvm::Type*>(X), false); 105592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 105692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 1057a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 1058a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1059a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 1060a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 1061a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 1062a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 1063a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 10646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines default: slangAssert(false && "Matrix type with unsupported dimension."); 1065a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1066a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1067a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1068a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1069641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 1070641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1071641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 1072641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1073641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 10742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 10752e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 10762e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 10772e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 10786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 10792e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((CAT->getSize().getActiveBits() < 32) && "array too large"); 10812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 10836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((Size > 0) && "Constant array should have size greater than 0"); 10842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10852e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 10862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 10872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 10892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 10902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 10912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 10932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 10942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 10952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 10962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Changconst llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 10982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 10992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 11002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1101a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1102a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1103a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1104a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1105a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1106a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1107a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1108a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1109a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1110a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1111a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1112a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1113a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1114a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 11153cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 11163cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 11173cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1118641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 11193cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1120641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1121641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1122641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1123641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1124a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1125a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1126a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1127a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1128641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1129641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 11309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 11319ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 11329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 11339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 11349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 11356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1136462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 11386e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RD->isStruct()); 1139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 11419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 11426e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "struct is not defined in this module"); 11439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 11449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11460da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 11470da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 11480da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 11499e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 1150f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RL != NULL) && 1151f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Failed to retrieve the struct layout from Clang."); 11520da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 11530da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 11540da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 11550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 11560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 11570da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 115868318a14fe6d2debc1b9dce3fe71c42f5916eef5Shih-wei Liao RL->getSize().getQuantity()); 11599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 11609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 11629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 11639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 116491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 11652ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines clang::Diagnostic *Diags = Context->getDiagnostics(); 11662ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 11679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 11696e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((*FI)->getKind() == clang::Decl::Field); 11709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 11719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11722ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (FD->isBitField()) { 11732ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 11742ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 11752ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 11769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 11786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 11799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 11802ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines if (ET != NULL) { 11810da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 11820da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 11830da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 11842ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } else { 11852ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->Report(clang::FullSourceLoc(RD->getLocation(), *SM), 11862ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 11872ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines "field type cannot be exported: '%0.%1'")) 11882ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << RD->getName() 11892ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines << FD->getName(); 11902ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines delete ERT; 11912ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines return NULL; 11922ef9bc0cfbca2152d972c0975005f8c897c2a42cStephen Hines } 11939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11940a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 11959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1196462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1197462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11986315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportRecordType::convertToLLVMType() const { 11993cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 12003cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::PATypeHolder ResultHolder = 12013cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::OpaqueType::get(getRSContext()->getLLVMContext()); 12023cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang setAbstractLLVMType(ResultHolder.get()); 12033cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 12049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type*> FieldTypes; 1205462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12063cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 12079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 12089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 12099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 12109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 12111f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 12129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 12139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1214462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 12153cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 12163cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 12173cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 12183cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (ST != NULL) 12193cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang static_cast<llvm::OpaqueType*>(ResultHolder.get()) 12203cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang ->refineAbstractTypeTo(ST); 12213cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang else 12223cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 12233cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return ResultHolder.get(); 1224462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1225641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1226a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1227a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1228a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1229a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1230a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1231e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1232a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1233a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1234a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1235a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1236a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1237a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1238a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1239a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1240a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1241a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1242a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1243a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1244a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1245a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1246a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1247a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1248a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1249a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1250a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang enum RSDataKind DK = RS_DK_User; 1251a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if ((F->getType()->getClass() == ExportClassPrimitive) || 1252a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang (F->getType()->getClass() == ExportClassVector)) { 1253a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const RSExportPrimitiveType *EPT = 1254a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang static_cast<const RSExportPrimitiveType*>(F->getType()); 1255a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataKind is synced with enum RSDataKind in 1256a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1257a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang DK = static_cast<enum RSDataKind>(EPT->getKind()); 1258a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1259a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_DATA_KIND(ST, FieldIdx, DK); 1260a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1261a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1262e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1263a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1264a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1265a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1266a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 12673cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 12683cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 12693cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1270641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1271641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1272641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1273641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1274641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1275641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 12763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1277641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1278641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1279641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1280641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1281641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1282641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1283641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1284641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1285641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1286641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1287641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1288641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1289641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1290641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1291641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1292641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1293641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1294641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1295641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1296641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1297641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1298e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1299e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1300