slang_rs_export_type.cpp revision 24e79f69125cf87fcaa78c04510a831037203eeb
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 249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/ADT/StringExtras.h" 25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 26e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/DerivedTypes.h" 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "llvm/Target/TargetData.h" 29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/Type.h" 310a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 34a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang#include "slang_rs_type_spec.h" 35462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 36641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang#define CHECK_PARENT_EQUALITY(ParentClass, E) \ 37641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!ParentClass::equals(E)) \ 38641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 39641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 41462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 42e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesnamespace { 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4424e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 4524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *T, 4624e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 4724e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::Diagnostic *Diags, 4824e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::SourceManager *SM, 4924e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord); 5124e79f69125cf87fcaa78c04510a831037203eebStephen Hines 5224e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic void ReportTypeError(clang::Diagnostic *Diags, 5324e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::SourceManager *SM, 5424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 5524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord, 5624e79f69125cf87fcaa78c04510a831037203eebStephen Hines const char *Message) { 5724e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!Diags || !SM) { 5824e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 5924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 6024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 6124e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Attempt to use the type declaration first (if we have one). 6224e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Fall back to the variable definition, if we are looking at something 6324e79f69125cf87fcaa78c04510a831037203eebStephen Hines // like an array declaration that can't be exported. 6424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TopLevelRecord) { 6524e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(clang::FullSourceLoc(TopLevelRecord->getLocation(), *SM), 6624e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, Message)) 6724e79f69125cf87fcaa78c04510a831037203eebStephen Hines << TopLevelRecord->getName(); 6824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (VD) { 6924e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(clang::FullSourceLoc(VD->getLocation(), *SM), 7024e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, Message)) 7124e79f69125cf87fcaa78c04510a831037203eebStephen Hines << VD->getName(); 7224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 7324e79f69125cf87fcaa78c04510a831037203eebStephen Hines assert(false && "Variables should be validated before exporting"); 7424e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 7524e79f69125cf87fcaa78c04510a831037203eebStephen Hines 7624e79f69125cf87fcaa78c04510a831037203eebStephen Hines return; 7724e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 7824e79f69125cf87fcaa78c04510a831037203eebStephen Hines 7924e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *ConstantArrayTypeExportableHelper( 8024e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ConstantArrayType *CAT, 8124e79f69125cf87fcaa78c04510a831037203eebStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 8224e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::Diagnostic *Diags, 8324e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::SourceManager *SM, 8424e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::VarDecl *VD, 8524e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::RecordDecl *TopLevelRecord) { 8624e79f69125cf87fcaa78c04510a831037203eebStephen Hines // Check element type 8724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 8824e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (ElementType->isArrayType()) { 8924e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 9024e79f69125cf87fcaa78c04510a831037203eebStephen Hines "multidimensional arrays cannot be exported: '%0'"); 9124e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 9224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else if (ElementType->isExtVectorType()) { 9324e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::ExtVectorType *EVT = 9424e79f69125cf87fcaa78c04510a831037203eebStephen Hines static_cast<const clang::ExtVectorType*>(ElementType); 9524e79f69125cf87fcaa78c04510a831037203eebStephen Hines unsigned numElements = EVT->getNumElements(); 9624e79f69125cf87fcaa78c04510a831037203eebStephen Hines 9724e79f69125cf87fcaa78c04510a831037203eebStephen Hines const clang::Type *BaseElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 9824e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (!RSExportPrimitiveType::IsPrimitiveType(BaseElementType)) { 9924e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 10024e79f69125cf87fcaa78c04510a831037203eebStephen Hines "vectors of non-primitive types cannot be exported: '%0'"); 10124e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 10224e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 10324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 10424e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (numElements == 3 && CAT->getSize() != 1) { 10524e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, VD, TopLevelRecord, 10624e79f69125cf87fcaa78c04510a831037203eebStephen Hines "arrays of width 3 vector types cannot be exported: '%0'"); 10724e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 10824e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 10924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 11024e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11124e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (TypeExportableHelper(ElementType, SPS, Diags, SM, VD, 11224e79f69125cf87fcaa78c04510a831037203eebStephen Hines TopLevelRecord) == NULL) 11324e79f69125cf87fcaa78c04510a831037203eebStephen Hines return NULL; 11424e79f69125cf87fcaa78c04510a831037203eebStephen Hines else 11524e79f69125cf87fcaa78c04510a831037203eebStephen Hines return CAT; 11624e79f69125cf87fcaa78c04510a831037203eebStephen Hines} 11724e79f69125cf87fcaa78c04510a831037203eebStephen Hines 11824e79f69125cf87fcaa78c04510a831037203eebStephen Hinesstatic const clang::Type *TypeExportableHelper( 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 120c808a99831115928b4648f4c8b86dc682594217aStephen Hines llvm::SmallPtrSet<const clang::Type*, 8>& SPS, 121e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 122e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::SourceManager *SM, 123dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD, 124e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::RecordDecl *TopLevelRecord) { 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Normalize first 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T = GET_CANONICAL_TYPE(T)) == NULL) 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (SPS.count(T)) 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1311f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T); 135462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 137a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case builtin_type: 139a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 147b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSExportPrimitiveType::GetRSSpecificType(T) != 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataTypeUnknown) 1496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr return T; // RS object type, no further checks are needed 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check internal struct 152cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isUnionType()) { 15324e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, T->getAsUnionType()->getDecl(), 15424e79f69125cf87fcaa78c04510a831037203eebStephen Hines "unions cannot be exported: '%0'"); 155cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 156cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } else if (!T->isStructureType()) { 157cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines assert(false && "Unknown type cannot be exported"); 158cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines return NULL; 159cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 160cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 16124e79f69125cf87fcaa78c04510a831037203eebStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD != NULL) 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 164f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 165e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!TopLevelRecord) { 166e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord = RD; 167e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 168e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getName().empty()) { 16924e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, RD, 17024e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous structures cannot be exported"); 171e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 172e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 173e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Fast check 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD->hasFlexibleArrayMember() || RD->hasObjectMember()) 1769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 177f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Insert myself into checking set 1799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao SPS.insert(T); 180f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check all element 1829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 1860da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::FieldDecl *FD = *FI; 187e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FT = GET_CANONICAL_TYPE(FT); 189462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 190dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (!TypeExportableHelper(FT, SPS, Diags, SM, VD, TopLevelRecord)) { 1919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1920da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang } 1939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 194462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 198e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TopLevelRecord) { 19924e79f69125cf87fcaa78c04510a831037203eebStephen Hines ReportTypeError(Diags, SM, NULL, TopLevelRecord, 20024e79f69125cf87fcaa78c04510a831037203eebStephen Hines "structures containing pointers cannot be exported: '%0'"); 201c808a99831115928b4648f4c8b86dc682594217aStephen Hines return NULL; 202c808a99831115928b4648f4c8b86dc682594217aStephen Hines } 20324e79f69125cf87fcaa78c04510a831037203eebStephen Hines 2049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT = UNSAFE_CAST_TYPE(clang::PointerType, T); 2059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 206462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2072e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->getTypeClass() == clang::Type::Pointer) 2089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2092e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // We don't support pointer with array-type pointee or unsupported pointee 2102e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang // type 2112e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (PointeeType->isArrayType() || 212dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines (TypeExportableHelper(PointeeType, SPS, Diags, SM, VD, 213e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT = 2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao UNSAFE_CAST_TYPE(clang::ExtVectorType, T); 2219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Only vector with size 2, 3 and 4 are supported. 2229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EVT->getNumElements() < 2 || EVT->getNumElements() > 4) 2239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 224f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao 2259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Check base element type 2269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 227462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 2289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin) || 229dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines (TypeExportableHelper(ElementType, SPS, Diags, SM, VD, 230e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TopLevelRecord) == NULL)) 2319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 2329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 2339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return T; 2349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2352e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 2362e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT = 2372e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang UNSAFE_CAST_TYPE(clang::ConstantArrayType, T); 2382e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 23924e79f69125cf87fcaa78c04510a831037203eebStephen Hines return ConstantArrayTypeExportableHelper(CAT, SPS, Diags, SM, VD, 24024e79f69125cf87fcaa78c04510a831037203eebStephen Hines TopLevelRecord); 2412e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 2429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 2439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 244462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 2459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 2469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 247462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 248e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// Return the type that can be used to create RSExportType, will always return 249e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// the canonical type 250e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// If the Type T is not exportable, this function returns NULL. Diags and SM 251e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// are used to generate proper Clang diagnostic messages when a 252e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// non-exportable type is detected. TopLevelRecord is used to capture the 253e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// highest struct (in the case of a nested hierarchy) for detecting other 254e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines// types that cannot be exported (mostly pointers within a struct). 255e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesstatic const clang::Type *TypeExportable(const clang::Type *T, 256e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 257dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines clang::SourceManager *SM, 258dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 259e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8> SPS = 260e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::SmallPtrSet<const clang::Type*, 8>(); 261e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 262dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines return TypeExportableHelper(T, SPS, Diags, SM, VD, NULL); 263e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 264e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 265e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} // namespace 266e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 267e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines/****************************** RSExportType ******************************/ 268e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesbool RSExportType::NormalizeType(const clang::Type *&T, 269e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef &TypeName, 270e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::Diagnostic *Diags, 271dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines clang::SourceManager *SM, 272dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines const clang::VarDecl *VD) { 273dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if ((T = TypeExportable(T, Diags, SM, VD)) == NULL) { 274e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 275e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 276e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Get type name 277e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines TypeName = RSExportType::GetTypeName(T); 278e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (TypeName.empty()) { 279e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Diags && SM) { 28024e79f69125cf87fcaa78c04510a831037203eebStephen Hines if (VD) { 28124e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(clang::FullSourceLoc(VD->getLocation(), *SM), 28224e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 28324e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 28424e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 28524e79f69125cf87fcaa78c04510a831037203eebStephen Hines } else { 28624e79f69125cf87fcaa78c04510a831037203eebStephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 28724e79f69125cf87fcaa78c04510a831037203eebStephen Hines "anonymous types cannot " 28824e79f69125cf87fcaa78c04510a831037203eebStephen Hines "be exported")); 28924e79f69125cf87fcaa78c04510a831037203eebStephen Hines } 290e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 291e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return false; 292e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 293e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 294e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return true; 295e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 296e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 297e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesconst clang::Type 298e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines*RSExportType::GetTypeOfDecl(const clang::DeclaratorDecl *DD) { 299e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD) { 300e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines clang::QualType T; 301e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (DD->getTypeSourceInfo()) 302e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getTypeSourceInfo()->getType(); 303e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 304e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = DD->getType(); 305e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 306e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T.isNull()) 307e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 308e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines else 309e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return T.getTypePtr(); 310e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 311e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return NULL; 312e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 313e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 314e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hinesllvm::StringRef RSExportType::GetTypeName(const clang::Type* T) { 315e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines T = GET_CANONICAL_TYPE(T); 316e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (T == NULL) 317e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 318e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 319e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (T->getTypeClass()) { 320e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Builtin: { 321e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T); 322e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 323e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines switch (BT->getKind()) { 324e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 325e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case builtin_type: \ 326e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return cname; \ 327e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 328e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines#include "RSClangBuiltinEnums.inc" 329e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 330e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines assert(false && "Unknown data type of the builtin"); 331e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 332e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 333e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 334e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 335e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 336e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Record: { 337cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines clang::RecordDecl *RD; 338cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines if (T->isStructureType()) { 339cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines RD = T->getAsStructureType()->getDecl(); 340dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines } else { 341cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines break; 342cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines } 343cd440ee9b3bdb7985a20b2cd4b0f8229de34f0a9Stephen Hines 344e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef Name = RD->getName(); 345e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) { 346e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (RD->getTypedefForAnonDecl() != NULL) 347e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = RD->getTypedefForAnonDecl()->getName(); 348e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 349e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (Name.empty()) 350e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Try to find a name from redeclaration (i.e. typedef) 351e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines for (clang::TagDecl::redecl_iterator RI = RD->redecls_begin(), 352e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RE = RD->redecls_end(); 353e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI != RE; 354e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines RI++) { 355e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines assert(*RI != NULL && "cannot be NULL object"); 356e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 357e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name = (*RI)->getName(); 358e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines if (!Name.empty()) 359e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 360e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 361e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 362e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 363e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 364e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::Pointer: { 365e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // "*" plus pointee name 366e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::Type *PT = GET_POINTEE_TYPE(T); 367e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines llvm::StringRef PointeeName; 368dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (NormalizeType(PT, PointeeName, NULL, NULL, NULL)) { 369e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines char *Name = new char[ 1 /* * */ + PointeeName.size() + 1 ]; 370e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[0] = '*'; 371e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines memcpy(Name + 1, PointeeName.data(), PointeeName.size()); 372e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines Name[PointeeName.size() + 1] = '\0'; 373e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return Name; 374e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 375e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 376e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 377e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ExtVector: { 378e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines const clang::ExtVectorType *EVT = 379e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines UNSAFE_CAST_TYPE(clang::ExtVectorType, T); 380e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return RSExportVectorType::GetTypeName(EVT); 381e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 382e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 383e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines case clang::Type::ConstantArray : { 384e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines // Construct name for a constant array is too complicated. 385e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return DUMMY_TYPE_NAME_FOR_RS_CONSTANT_ARRAY_TYPE; 386e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 387e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines default: { 388e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines break; 389e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 390e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 391e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 392e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines return llvm::StringRef(); 393e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines} 394e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 395e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines 3969ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::Create(RSContext *Context, 3979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 3989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 3999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Lookup the context to see whether the type was processed before. 4009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Newly created RSExportType will insert into context 4019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // in RSExportType::RSExportType() 4029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSContext::export_type_iterator ETI = Context->findExportType(TypeName); 4039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ETI != Context->export_types_end()) 4059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ETI->second; 4069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 4089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 4099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 4109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType dt = 411b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSExportPrimitiveType::GetRSSpecificType(TypeName); 4129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (dt) { 41392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeUnknown: { 41492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // User-defined types 4159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportRecordType::Create(Context, 4169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getAsStructureType(), 4179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 4189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 42092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix2x2: { 42192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 2 x 2 Matrix type 42292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 42392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 42492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 42592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 2); 42692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 42792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 42892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang case RSExportPrimitiveType::DataTypeRSMatrix3x3: { 42992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 3 x 3 Matrix type 43092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 43192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 43292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 43392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 3); 43492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang break; 43592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 4369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 43792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // 4 x 4 Matrix type 43892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang ET = RSExportMatrixType::Create(Context, 43992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang T->getAsStructureType(), 44092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName, 44192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 4); 4429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 44592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Others are primitive types 4469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 4479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 4539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPrimitiveType::Create(Context, T, TypeName); 4549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 4579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportPointerType::Create(Context, 4589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao UNSAFE_CAST_TYPE(clang::PointerType, T), 4599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 46092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // FIXME: free the name (allocated in RSExportType::GetTypeName) 4619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete [] TypeName.data(); 4629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 4659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = RSExportVectorType::Create(Context, 4669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao UNSAFE_CAST_TYPE(clang::ExtVectorType, T), 4679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName); 4689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4702e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang case clang::Type::ConstantArray: { 4712e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ET = RSExportConstantArrayType::Create( 4722e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Context, 4732e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang UNSAFE_CAST_TYPE(clang::ConstantArrayType, T)); 4742e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang break; 4752e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 4769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 4776315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that type is not exportable. 4789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, 4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "RSExportType::Create : type '%s' is not exportable\n", 4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getTypeClassName()); 4819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 4829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 4849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 4859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 486462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 4871f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 4886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportType *RSExportType::Create(RSContext *Context, const clang::Type *T) { 4899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 490dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (NormalizeType(T, TypeName, NULL, NULL, NULL)) 4919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName); 4929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 4939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 494462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 495462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 4969ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportType::CreateFromDecl(RSContext *Context, 4979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD) { 4989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, GetTypeOfDecl(VD)); 499462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 500462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeStoreSize(const RSExportType *ET) { 5029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeStoreSize( 5036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 504462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 505462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportType::GetTypeAllocSize(const RSExportType *ET) { 5079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (ET->getClass() == RSExportType::ExportClassRecord) 5089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return static_cast<const RSExportRecordType*>(ET)->getAllocSize(); 5099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET->getRSContext()->getTargetData()->getTypeAllocSize( 5116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr ET->getLLVMType()); 512462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 513462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5146b6320ad5faee29e0f75fe937e40156746ef9e80Zonr ChangRSExportType::RSExportType(RSContext *Context, 5156b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang ExportClass Class, 5166b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang const llvm::StringRef &Name) 517a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_TYPE), 5186b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang mClass(Class), 5190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Make a copy on Name since memory stored @Name is either allocated in 5200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // ASTContext or allocated in GetTypeName which will be destroyed later. 5216315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(Name.data(), Name.size()), 522a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mLLVMType(NULL), 523a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang mSpecType(NULL) { 5240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Don't cache the type whose name start with '<'. Those type failed to 5250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // get their name since constructing their name in GetTypeName() requiring 5260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // complicated work. 5270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang if (!Name.startswith(DUMMY_RS_TYPE_NAME_PREFIX)) 5280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // TODO(zonr): Need to check whether the insertion is successful or not. 5290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang Context->insertExportType(llvm::StringRef(Name), this); 5309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 531462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 532462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5333cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportType::keep() { 5343cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportable::keep()) 5353cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 536641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang // Invalidate converted LLVM type. 537641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang mLLVMType = NULL; 5383cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 539641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 540641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 541641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportType::equals(const RSExportable *E) const { 542641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportable, E); 543641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportType*>(E)->getClass() == getClass()); 544641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 545641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 546a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr ChangRSExportType::~RSExportType() { 547a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang delete mSpecType; 548a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 549a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 5509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/************************** RSExportPrimitiveType **************************/ 551b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changllvm::ManagedStatic<RSExportPrimitiveType::RSSpecificTypeMapTy> 552b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::RSSpecificTypeMap; 5539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5546315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::Type *RSExportPrimitiveType::RSObjectLLVMType = NULL; 555462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaobool RSExportPrimitiveType::IsPrimitiveType(const clang::Type *T) { 5579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T != NULL) && (T->getTypeClass() == clang::Type::Builtin)) 5589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return true; 5599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return false; 561462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 562462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 5639ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 564b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const llvm::StringRef &TypeName) { 5659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (TypeName.empty()) 5669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 567462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 568b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (RSSpecificTypeMap->empty()) { 569b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#define ENUM_RS_MATRIX_TYPE(type, cname, dim) \ 570b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 571b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang#include "RSMatrixTypeEnums.inc" 572a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_OBJECT_TYPE(type, cname) \ 573b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMap->GetOrCreateValue(cname, DataType ## type); 574a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSObjectTypeEnums.inc" 5759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 576462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 577b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang RSSpecificTypeMapTy::const_iterator I = RSSpecificTypeMap->find(TypeName); 578b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang if (I == RSSpecificTypeMap->end()) 5799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 5809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 5819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 5829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 5839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 5849ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 585b1771ef128b10c4d4575634828006bfba20b1d9cZonr ChangRSExportPrimitiveType::GetRSSpecificType(const clang::Type *T) { 5869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = GET_CANONICAL_TYPE(T); 5879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((T == NULL) || (T->getTypeClass() != clang::Type::Record)) 5889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 5899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 590b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return GetRSSpecificType( RSExportType::GetTypeName(T) ); 591b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 592b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 593b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSMatrixType(DataType DT) { 594b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSMatrixType) && (DT <= LastRSMatrixType)); 595b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang} 596b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang 597b1771ef128b10c4d4575634828006bfba20b1d9cZonr Changbool RSExportPrimitiveType::IsRSObjectType(DataType DT) { 598b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return ((DT >= FirstRSObjectType) && (DT <= LastRSObjectType)); 5999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao} 6009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 601a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changconst size_t RSExportPrimitiveType::SizeOfDataTypeInBits[] = { 602a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_TYPE(type, cname, bits) \ 603a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang bits, 604a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataTypeEnums.inc" 605a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang 0 // DataTypeMax 606462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}; 607462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaosize_t RSExportPrimitiveType::GetSizeInBits(const RSExportPrimitiveType *EPT) { 609a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang assert(((EPT->getType() > DataTypeUnknown) && 6109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao (EPT->getType() < DataTypeMax)) && 6119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "RSExportPrimitiveType::GetSizeInBits : unknown data type"); 6129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return SizeOfDataTypeInBits[ static_cast<int>(EPT->getType()) ]; 613462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 614462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6159ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType::DataType 6166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportPrimitiveType::GetDataType(const clang::Type *T) { 6179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T == NULL) 6189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 619462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (T->getTypeClass()) { 6219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: { 6229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, T); 6239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 624a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 625a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 626a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return DataType ## type; \ 6279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 628a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 629a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // The size of type WChar depend on platform so we abandon the support 630a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang // to them. 6319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 632a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang fprintf(stderr, "RSExportPrimitiveType::GetDataType : unsupported " 633a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang "built-in type '%s'\n.", T->getTypeClassName()); 6349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 635462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 6369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 6389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 6409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // must be RS object type 641b1771ef128b10c4d4575634828006bfba20b1d9cZonr Chang return RSExportPrimitiveType::GetRSSpecificType(T); 6429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 6439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 6449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportPrimitiveType::GetDataType : type '%s' is not " 645a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang "supported primitive type\n", T->getTypeClassName()); 6469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 647462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 6489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 649462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return DataTypeUnknown; 651462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 652462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6539ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType 6549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPrimitiveType::Create(RSContext *Context, 6559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 6569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 6579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 6589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 6599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataType DT = GetDataType(T); 660462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((DT == DataTypeUnknown) || TypeName.empty()) 6629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 6639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 6646b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang return new RSExportPrimitiveType(Context, ExportClassPrimitive, TypeName, 6656b6320ad5faee29e0f75fe937e40156746ef9e80Zonr Chang DT, DK, Normalized); 666462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 667462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6689ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPrimitiveType *RSExportPrimitiveType::Create(RSContext *Context, 6699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 6709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK) { 6719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 672dd6206bb61bf8df2ed6b643abe8a29c48a315685Stephen Hines if (RSExportType::NormalizeType(T, TypeName, NULL, NULL, NULL) && 673e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines IsPrimitiveType(T)) { 6749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return Create(Context, T, TypeName, DK); 675e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } else { 6769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 677e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines } 678462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 679462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 6809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPrimitiveType::convertToLLVMType() const { 6819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 6829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 6839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (isRSObjectType()) { 6849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // struct { 6859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // int *p; 6869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // } __attribute__((packed, aligned(pointer_size))) 6879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 6889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // which is 6899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 6909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // <{ [1 x i32] }> in LLVM 6919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 6929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RSObjectLLVMType == NULL) { 6939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type *> Elements; 6946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr Elements.push_back(llvm::ArrayType::get(llvm::Type::getInt32Ty(C), 1)); 6959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSObjectLLVMType = llvm::StructType::get(C, Elements, true); 696462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 6979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSObjectLLVMType; 6989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 699462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (mType) { 7019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat32: { 7029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getFloatTy(C); 7039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeFloat64: { 7069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getDoubleTy(C); 7079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 70991a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao case DataTypeBoolean: { 71091a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao return llvm::Type::getInt1Ty(C); 71191a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao break; 71291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao } 7139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned8: 7149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned8: { 7159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt8Ty(C); 7169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned16: 7199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned16: 7209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned565: 7219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned5551: 7229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned4444: { 7239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt16Ty(C); 7249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeSigned32: 7279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case DataTypeUnsigned32: { 7289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt32Ty(C); 7299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 731a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeSigned64: 732a5d2c232d56b04292cb51c8fb343aef990f7970fStephen Hines case DataTypeUnsigned64: { 7339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::Type::getInt64Ty(C); 7349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 7359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 7369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 7379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(false && "Unknown data type"); 738462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 7399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 740462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 742462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 743462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 744a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPrimitiveType::convertToSpecType() const { 745a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 746a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Primitive); 747a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataType is synced with enum RSDataType in 748a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 749a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_PRIMITIVE_TYPE_SET_DATA_TYPE(ST, getType()); 750a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 751a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 752a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 753641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPrimitiveType::equals(const RSExportable *E) const { 754641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 755641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPrimitiveType*>(E)->getType() == getType()); 756641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 757641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 7589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportPointerType ****************************/ 759462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst clang::Type *RSExportPointerType::IntegerType = NULL; 761462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7629ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportPointerType 7639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao*RSExportPointerType::Create(RSContext *Context, 7649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::PointerType *PT, 7659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName) { 7669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *PointeeType = GET_POINTEE_TYPE(PT); 7679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *PointeeET; 768462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeType->getTypeClass() != clang::Type::Pointer) { 7709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportType::Create(Context, PointeeType); 7719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 7729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Double or higher dimension of pointer, export as int* 7739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(IntegerType != NULL && "Built-in integer type is not set"); 7749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao PointeeET = RSExportPrimitiveType::Create(Context, IntegerType); 7759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 776462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (PointeeET == NULL) { 7789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "Failed to create type for pointee"); 7799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 7809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 781462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportPointerType(Context, TypeName, PointeeET); 783462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 784462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 7859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst llvm::Type *RSExportPointerType::convertToLLVMType() const { 7869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::Type *PointeeType = mPointeeType->getLLVMType(); 7879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::PointerType::getUnqual(PointeeType); 788462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 789462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 790a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportPointerType::convertToSpecType() const { 791a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 792a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 793a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Pointer); 794a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_POINTER_TYPE_SET_POINTEE_TYPE(ST, getPointeeType()->getSpecType()); 795a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 796a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_POINTER_TYPE_GET_POINTEE_TYPE(ST) != NULL) 797a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 798a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 799a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 800a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 801a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 8023cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportPointerType::keep() { 8033cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 8043cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 805641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mPointeeType)->keep(); 8063cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 807641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 808641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 809641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportPointerType::equals(const RSExportable *E) const { 810641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 811641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportPointerType*>(E) 812641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang ->getPointeeType()->equals(getPointeeType())); 813641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 814641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 8156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/***************************** RSExportVectorType *****************************/ 8166315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrllvm::StringRef 8176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportVectorType::GetTypeName(const clang::ExtVectorType *EVT) { 8189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 819462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((ElementType->getTypeClass() != clang::Type::Builtin)) 8219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 8229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::BuiltinType *BT = UNSAFE_CAST_TYPE(clang::BuiltinType, 8249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementType); 825a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang if ((EVT->getNumElements() < 1) || 826a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang (EVT->getNumElements() > 4)) 827a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return llvm::StringRef(); 8289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 8299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (BT->getKind()) { 8309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Compiler is smart enough to optimize following *big if branches* since 8319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // they all become "constant comparison" after macro expansion 832a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname) \ 833a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang case builtin_type: { \ 834a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang const char *Name[] = { cname"2", cname"3", cname"4" }; \ 835a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang return Name[EVT->getNumElements() - 2]; \ 836a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang break; \ 837a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang } 838a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSClangBuiltinEnums.inc" 8399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 8409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::StringRef(); 841462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 8429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 843462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 844462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8459ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVectorType *RSExportVectorType::Create(RSContext *Context, 8469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::ExtVectorType *EVT, 8479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 8489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DataKind DK, 8499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool Normalized) { 85092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang assert(EVT != NULL && EVT->getTypeClass() == clang::Type::ExtVector); 851462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *ElementType = GET_EXT_VECTOR_ELEMENT_TYPE(EVT); 8539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::DataType DT = 8549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::GetDataType(ElementType); 855462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (DT != RSExportPrimitiveType::DataTypeUnknown) 8579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return new RSExportVectorType(Context, 8589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 8599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DT, 8609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao DK, 8619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Normalized, 8629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EVT->getNumElements()); 8639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 8649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportVectorType::Create : unsupported base element " 8659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "type\n"); 8669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 867462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 868462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 8696315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportVectorType::convertToLLVMType() const { 8706315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const llvm::Type *ElementType = RSExportPrimitiveType::convertToLLVMType(); 8719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return llvm::VectorType::get(ElementType, getNumElement()); 872462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 873462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 874a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportVectorType::convertToSpecType() const { 875a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 876a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 877a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Vector); 878a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_ELEMENT_TYPE(ST, getType()); 879a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_VECTOR_TYPE_SET_VECTOR_SIZE(ST, getNumElement()); 880a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 881a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 882a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 883a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 884641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportVectorType::equals(const RSExportable *E) const { 885641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportPrimitiveType, E); 886641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportVectorType*>(E)->getNumElement() 887641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang == getNumElement()); 888641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 889641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 89092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang/***************************** RSExportMatrixType *****************************/ 89192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr ChangRSExportMatrixType *RSExportMatrixType::Create(RSContext *Context, 89292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordType *RT, 89392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const llvm::StringRef &TypeName, 89492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang unsigned Dim) { 89592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang assert((RT != NULL) && (RT->getTypeClass() == clang::Type::Record)); 89692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang assert((Dim > 1) && "Invalid dimension of matrix"); 89792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 89892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Check whether the struct rs_matrix is in our expected form (but assume it's 89992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // correct if we're not sure whether it's correct or not) 90092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::RecordDecl* RD = RT->getDecl(); 90192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang RD = RD->getDefinition(); 90292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD != NULL) { 90392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Find definition, perform further examination 90492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (RD->field_empty()) { 90592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: " 90692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang "must have 1 field for saving values", TypeName.data()); 90792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 90892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 90992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 91092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang clang::RecordDecl::field_iterator FIT = RD->field_begin(); 91192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::FieldDecl *FD = *FIT; 91292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 91392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((FT == NULL) || (FT->getTypeClass() != clang::Type::ConstantArray)) { 91492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: " 91592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang "first field should be an array with constant size", 91692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName.data()); 91792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 91892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 91992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang const clang::ConstantArrayType *CAT = 92092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang static_cast<const clang::ConstantArrayType *>(FT); 9212e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 92292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if ((ElementType == NULL) || 92392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (ElementType->getTypeClass() != clang::Type::Builtin) || 92492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (static_cast<const clang::BuiltinType *>(ElementType)->getKind() 92592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang != clang::BuiltinType::Float)) { 92692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: " 92792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang "first field should be a float array", TypeName.data()); 92892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 92992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 93092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 93192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (CAT->getSize() != Dim * Dim) { 93292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: " 93392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang "first field should be an array with size %d", 93492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang TypeName.data(), Dim * Dim); 93592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 93692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 93792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 93892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang FIT++; 93992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang if (FIT != RD->field_end()) { 94092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang fprintf(stderr, "RSExportMatrixType::Create : invalid %s struct: " 94192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang "must have exactly 1 field", TypeName.data()); 94292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return NULL; 94392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 94492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang } 94592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 94692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return new RSExportMatrixType(Context, TypeName, Dim); 94792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 94892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 94992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Changconst llvm::Type *RSExportMatrixType::convertToLLVMType() const { 95092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // Construct LLVM type: 95192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // struct { 95292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // float X[mDim * mDim]; 95392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang // } 95492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 95592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::LLVMContext &C = getRSContext()->getLLVMContext(); 95692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang llvm::ArrayType *X = llvm::ArrayType::get(llvm::Type::getFloatTy(C), 95792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang mDim * mDim); 95892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang return llvm::StructType::get(C, X, NULL); 95992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang} 96092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang 961a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportMatrixType::convertToSpecType() const { 962a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 963a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Matrix); 964a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang switch (getDim()) { 965a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 2: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix2x2); break; 966a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 3: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix3x3); break; 967a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang case 4: RS_MATRIX_TYPE_SET_DATA_TYPE(ST, RS_DT_RSMatrix4x4); break; 968a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang default: assert(false && "Matrix type with unsupported dimension."); 969a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 970a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 971a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 972a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 973641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportMatrixType::equals(const RSExportable *E) const { 974641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 975641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return (static_cast<const RSExportMatrixType*>(E)->getDim() == getDim()); 976641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 977641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 9782e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang/************************* RSExportConstantArrayType *************************/ 9792e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr ChangRSExportConstantArrayType 9802e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang*RSExportConstantArrayType::Create(RSContext *Context, 9812e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::ConstantArrayType *CAT) { 9822e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang assert(CAT != NULL && CAT->getTypeClass() == clang::Type::ConstantArray); 9832e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 9842e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang assert((CAT->getSize().getActiveBits() < 32) && "array too large"); 9852e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 9862e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang unsigned Size = static_cast<unsigned>(CAT->getSize().getZExtValue()); 9872e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang assert((Size > 0) && "Constant array should have size greater than 0"); 9882e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 9892e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang const clang::Type *ElementType = GET_CONSTANT_ARRAY_ELEMENT_TYPE(CAT); 9902e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang RSExportType *ElementET = RSExportType::Create(Context, ElementType); 9912e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 9922e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang if (ElementET == NULL) { 9932e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang fprintf(stderr, "RSExportConstantArrayType::Create : failed to create " 9942e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang "RSExportType for array element.\n"); 9952e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return NULL; 9962e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang } 9972e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 9982e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return new RSExportConstantArrayType(Context, 9992e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang ElementET, 10002e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang Size); 10012e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 10022e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 10032e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Changconst llvm::Type *RSExportConstantArrayType::convertToLLVMType() const { 10042e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang return llvm::ArrayType::get(mElementType->getLLVMType(), getSize()); 10052e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang} 10062e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang 1007a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportConstantArrayType::convertToSpecType() const { 1008a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST(new union RSType); 1009a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1010a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_ConstantArray); 1011a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_TYPE( 1012a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ST, getElementType()->getSpecType()); 1013a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_CONSTANT_ARRAY_TYPE_SET_ELEMENT_SIZE(ST, getSize()); 1014a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1015a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if (RS_CONSTANT_ARRAY_TYPE_GET_ELEMENT_TYPE(ST) != NULL) 1016a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1017a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang else 1018a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return NULL; 1019a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1020a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 10213cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportConstantArrayType::keep() { 10223cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 10233cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1024641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>(mElementType)->keep(); 10253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1026641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1027641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1028641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportConstantArrayType::equals(const RSExportable *E) const { 1029641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1030a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines const RSExportConstantArrayType *RHS = 1031a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines static_cast<const RSExportConstantArrayType*>(E); 1032a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines return ((getSize() == RHS->getSize()) && 1033a7b7518aa3725d5cff1c1a6319ec7a6b8b244e0eStephen Hines (getElementType()->equals(RHS->getElementType()))); 1034641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1035641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 10369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao/**************************** RSExportRecordType ****************************/ 10379ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportRecordType *RSExportRecordType::Create(RSContext *Context, 10389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT, 10399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const llvm::StringRef &TypeName, 10409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao bool mIsArtificial) { 104192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang assert(RT != NULL && RT->getTypeClass() == clang::Type::Record); 1042462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 10449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(RD->isStruct()); 1045462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 10479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (RD == NULL) { 10486315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that actual struct definition isn't declared in this 10496315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // moudle. 10509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportRecordType::Create : this struct is not defined " 10519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "in this module."); 10529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 10539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1054462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 10550da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // Struct layout construct by clang. We rely on this for obtaining the 10560da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang // alloc size of a struct and offset of every field in that struct. 10570da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang const clang::ASTRecordLayout *RL = 10589e5b503349719144f63ccb7c62ee9c291a7d83b8Stephen Hines &Context->getASTContext().getASTRecordLayout(RD); 10590da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang assert((RL != NULL) && "Failed to retrieve the struct layout from Clang."); 10600da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang 10610da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RSExportRecordType *ERT = 10620da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new RSExportRecordType(Context, 10630da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang TypeName, 10640da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang RD->hasAttr<clang::PackedAttr>(), 10650da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang mIsArtificial, 10660da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang (RL->getSize() >> 3)); 10679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao unsigned int Index = 0; 10689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 10709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FE = RD->field_end(); 10719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 107291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao FI++, Index++) { 10739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define FAILED_CREATE_FIELD(err) do { \ 10749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (*err) \ 10759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, \ 10769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "RSExportRecordType::Create : failed to create field (%s)\n", \ 10779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao err); \ 10789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao delete ERT; \ 10799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; \ 10809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } while (false) 10819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // FIXME: All fields should be primitive type 10839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert((*FI)->getKind() == clang::Decl::Field); 10849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *FI; 10859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // We don't support bit field 10879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // 10886315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): allow bitfield with size 8, 16, 32 10899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (FD->isBitField()) 10909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FAILED_CREATE_FIELD("bit field is not supported"); 10919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Type 10936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr RSExportType *ET = RSExportElement::CreateFromDecl(Context, FD); 10949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 10956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (ET != NULL) 10960da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang ERT->mFields.push_back( 10970da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang new Field(ET, FD->getName(), ERT, 10980da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang static_cast<size_t>(RL->getFieldOffset(Index) >> 3))); 10999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 11009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FAILED_CREATE_FIELD(FD->getName().str().c_str()); 1101462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#undef FAILED_CREATE_FIELD 11029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 11030a3f20ec28ed6f5ae1ed5d61f6b6e3e577f7f5d1Shih-wei Liao 11049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ERT; 1105462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11076315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrconst llvm::Type *RSExportRecordType::convertToLLVMType() const { 11083cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang // Create an opaque type since struct may reference itself recursively. 11093cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::PATypeHolder ResultHolder = 11103cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::OpaqueType::get(getRSContext()->getLLVMContext()); 11113cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang setAbstractLLVMType(ResultHolder.get()); 11123cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang 11139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao std::vector<const llvm::Type*> FieldTypes; 1114462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11153cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 11169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI != FE; 11179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FI++) { 11189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const Field *F = *FI; 11199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const RSExportType *FET = F->getType(); 11201f0d88fbff28e4e2dd563d93c8fe0047381c09ccShih-wei Liao 11219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao FieldTypes.push_back(FET->getLLVMType()); 11229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1123462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 11243cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(), 11253cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang FieldTypes, 11263cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang mIsPacked); 11273cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (ST != NULL) 11283cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang static_cast<llvm::OpaqueType*>(ResultHolder.get()) 11293cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang ->refineAbstractTypeTo(ST); 11303cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang else 11313cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return NULL; 11323cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return ResultHolder.get(); 1133462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 1134641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1135a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Changunion RSType *RSExportRecordType::convertToSpecType() const { 1136a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned NumFields = getFields().size(); 1137a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned AllocSize = sizeof(union RSType) + 1138a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang sizeof(struct RSRecordField) * NumFields; 1139a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang llvm::OwningPtr<union RSType> ST( 1140e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines reinterpret_cast<union RSType*>(operator new(AllocSize))); 1141a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1142a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang ::memset(ST.get(), 0, AllocSize); 1143a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1144a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_TYPE_SET_CLASS(ST, RS_TC_Record); 1145a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NAME(ST, getName().c_str()); 1146a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_NUM_FIELDS(ST, NumFields); 1147a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1148a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang setSpecTypeTemporarily(ST.get()); 1149a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1150a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang unsigned FieldIdx = 0; 1151a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang for (const_field_iterator FI = fields_begin(), FE = fields_end(); 1152a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI != FE; 1153a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang FI++, FieldIdx++) { 1154a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const Field *F = *FI; 1155a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1156a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_NAME(ST, FieldIdx, F->getName().c_str()); 1157a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_TYPE(ST, FieldIdx, F->getType()->getSpecType()); 1158a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1159a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang enum RSDataKind DK = RS_DK_User; 1160a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang if ((F->getType()->getClass() == ExportClassPrimitive) || 1161a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang (F->getType()->getClass() == ExportClassVector)) { 1162a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang const RSExportPrimitiveType *EPT = 1163a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang static_cast<const RSExportPrimitiveType*>(F->getType()); 1164a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // enum RSExportPrimitiveType::DataKind is synced with enum RSDataKind in 1165a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang // slang_rs_type_spec.h 1166a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang DK = static_cast<enum RSDataKind>(EPT->getKind()); 1167a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1168a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang RS_RECORD_TYPE_SET_FIELD_DATA_KIND(ST, FieldIdx, DK); 1169a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang } 1170a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1171e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(slang): Check whether all fields were created normally. 1172a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 1173a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang return ST.take(); 1174a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang} 1175a7a828d1ff95c5a8f2327f56a137a2bcb3a9a8faZonr Chang 11763cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Changbool RSExportRecordType::keep() { 11773cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang if (!RSExportType::keep()) 11783cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return false; 1179641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (std::list<const Field*>::iterator I = mFields.begin(), 1180641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang E = mFields.end(); 1181641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I != E; 1182641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang I++) { 1183641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_cast<RSExportType*>((*I)->getType())->keep(); 1184641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 11853cd3dd327445fcfa49f0e96cb2de2055bce541e9Zonr Chang return true; 1186641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1187641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1188641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Changbool RSExportRecordType::equals(const RSExportable *E) const { 1189641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang CHECK_PARENT_EQUALITY(RSExportType, E); 1190641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1191641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const RSExportRecordType *ERT = static_cast<const RSExportRecordType*>(E); 1192641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1193641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (ERT->getFields().size() != getFields().size()) 1194641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1195641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1196641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang const_field_iterator AI = fields_begin(), BI = ERT->fields_begin(); 1197641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1198641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang for (unsigned i = 0, e = getFields().size(); i != e; i++) { 1199641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang if (!(*AI)->getType()->equals((*BI)->getType())) 1200641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return false; 1201641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang AI++; 1202641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang BI++; 1203641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang } 1204641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang 1205641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang return true; 1206641558f02fe6ce0ee3ae5076eb366c25e2ad5903Zonr Chang} 1207e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1208e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1209