1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 25bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines * 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_element.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h" 209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Type.h" 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/SourceLocation.h" 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "clang/Basic/IdentifierTable.h" 24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 256e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 286315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool RSExportElement::Initialized = false; 32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap; 33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 34474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstruct DataElementInfo { 35474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet const char *name; 36cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType dataType; 37474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet bool normalized; 38474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet int vsize; 39474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 40474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 41474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletstatic DataElementInfo DataElementInfoTable[] = { 42cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_l", DataTypeUnsigned8, true, 1}, 43cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_a", DataTypeUnsigned8, true, 1}, 44cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_la", DataTypeUnsigned8, true, 2}, 45cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_rgb", DataTypeUnsigned8, true, 3}, 46cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_rgba", DataTypeUnsigned8, true, 4}, 47cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_rgb565", DataTypeUnsigned8, true, 3}, 48cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_rgb5551", DataTypeUnsigned8, true, 4}, 49cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet {"rs_pixel_rgb4444", DataTypeUnsigned8, true, 4}, 50474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet}; 51474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 52474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletconst int DataElementInfoTableCount = sizeof(DataElementInfoTable) / sizeof(DataElementInfoTable[0]); 53474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet 54474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet// TODO Rename RSExportElement to RSExportDataElement 55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSExportElement::Init() { 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) { 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize ElementInfoMap 58474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet for (int i = 0; i < DataElementInfoTableCount; i++) { 59474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet ElementInfo *EI = new ElementInfo; 60474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet EI->type = DataElementInfoTable[i].dataType; 61474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet EI->normalized = DataElementInfoTable[i].normalized; 62474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet EI->vsize = DataElementInfoTable[i].vsize; 63474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet llvm::StringRef Name(DataElementInfoTable[i].name); 64474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet ElementInfoMap.insert(ElementInfoMapTy::value_type::Create( 652eb9a3f7c48fe54eb4e813d80e3363bc79553a1eStephen Hines Name, ElementInfoMap.getAllocator(), EI)); 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Initialized = true; 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 69462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::Create(RSContext *Context, 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo *EI) { 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create RSExportType corresponded to the @T first and then verify 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSExportType *ET = nullptr; 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert(EI != nullptr && "Element info not found"); 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (!RSExportType::NormalizeType(T, TypeName, Context, nullptr)) 855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 876315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr switch (T->getTypeClass()) { 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == 1 && "Element not a primitive class (please " 916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "check your macro)"); 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType *EPT = 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::Create(Context, 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T, 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EPT->getType() && "Element has unexpected type"); 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EPT; 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 1036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize > 1 && "Element not a vector class (please check " 1046e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "your macro)"); 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType *EVT = 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType::Create(Context, 107be27482cdeaf08576bc39b72a15d35d13014a636Logan static_cast<const clang::ExtVectorType*>( 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getCanonicalTypeInternal() 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao .getTypePtr()), 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 1136e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EVT->getType() && "Element has unexpected type"); 1146e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected " 1156e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "size of vector"); 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EVT; 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1206315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that type is not exportable 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n", 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getTypeClassName()); 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 124f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao } 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 126462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 128462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 129462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::CreateFromDecl(RSContext *Context, 1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::DeclaratorDecl *DD) { 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* T = RSExportType::GetTypeOfDecl(DD); 133b095e05fef8f0230ab42eaed7a06c3b2d698189aJean-Luc Brouillet const clang::Type* CT = GetCanonicalType(T); 1345abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes const ElementInfo* EI = nullptr; 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Note: RS element like rs_pixel_rgb elements are either in the type of 13791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // primitive or vector. 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((CT->getTypeClass() != clang::Type::Builtin) && 13992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (CT->getTypeClass() != clang::Type::ExtVector)) { 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Following the typedef chain to see whether it's an element name like 14491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // rs_pixel_rgb or its alias (via typedef). 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao while (T != CT) { 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T->getTypeClass() != clang::Type::Typedef) { 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T); 15083f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao const clang::TypedefNameDecl *TD = TT->getDecl(); 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI = GetElementInfo(TD->getName()); 1525abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (EI != nullptr) 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = TD->getUnderlyingType().getTypePtr(); 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 158462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (EI == nullptr) { 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportElement::Create(Context, T, EI); 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 164462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst RSExportElement::ElementInfo * 1676315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportElement::GetElementInfo(const llvm::StringRef &Name) { 1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (I == ElementInfoMap.end()) 1735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 177e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 178e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 179