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 34462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSExportElement::Init() { 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) { 369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize ElementInfoMap 372b8fb64be3047df940a219872b331eb11de2758dStephen Hines#define ENUM_RS_DATA_ELEMENT(_name, _dt, _norm, _vsize) \ 38a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang { \ 39a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfo *EI = new ElementInfo; \ 40a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->type = RSExportPrimitiveType::DataType ## _dt; \ 41a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->normalized = _norm; \ 42a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->vsize = _vsize; \ 43a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang \ 44a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::StringRef Name(_name); \ 45a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMap.insert( \ 46a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMapTy::value_type::Create( \ 47a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang Name.begin(), \ 48a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang Name.end(), \ 49a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMap.getAllocator(), \ 50a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI)); \ 519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 52a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataElementEnums.inc" 53462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Initialized = true; 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 57462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::Create(RSContext *Context, 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo *EI) { 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create RSExportType corresponded to the @T first and then verify 639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI != NULL && "Element info not found"); 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), 735bfec8dd08b3bde9ba3b331e2115210b0e910eaeStephen Hines NULL)) 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 766315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr switch (T->getTypeClass()) { 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 796e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == 1 && "Element not a primitive class (please " 806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "check your macro)"); 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType *EPT = 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::Create(Context, 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T, 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 876e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EPT->getType() && "Element has unexpected type"); 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EPT; 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize > 1 && "Element not a vector class (please check " 936e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "your macro)"); 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType *EVT = 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType::Create(Context, 96be27482cdeaf08576bc39b72a15d35d13014a636Logan static_cast<const clang::ExtVectorType*>( 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getCanonicalTypeInternal() 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao .getTypePtr()), 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 1026e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EVT->getType() && "Element has unexpected type"); 1036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected " 1046e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "size of vector"); 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EVT; 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that type is not exportable 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n", 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getTypeClassName()); 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 113f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao } 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 115462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 117462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::CreateFromDecl(RSContext *Context, 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::DeclaratorDecl *DD) { 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* T = RSExportType::GetTypeOfDecl(DD); 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* CT = GET_CANONICAL_TYPE(T); 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo* EI = NULL; 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Note: RS element like rs_pixel_rgb elements are either in the type of 12691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // primitive or vector. 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((CT->getTypeClass() != clang::Type::Builtin) && 12892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (CT->getTypeClass() != clang::Type::ExtVector)) { 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13291a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Following the typedef chain to see whether it's an element name like 13391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // rs_pixel_rgb or its alias (via typedef). 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao while (T != CT) { 1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T->getTypeClass() != clang::Type::Typedef) { 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T); 13983f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao const clang::TypedefNameDecl *TD = TT->getDecl(); 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI = GetElementInfo(TD->getName()); 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI != NULL) 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 143462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = TD->getUnderlyingType().getTypePtr(); 145462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 147462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI == NULL) { 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportElement::Create(Context, T, EI); 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 153462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst RSExportElement::ElementInfo * 1566315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportElement::GetElementInfo(const llvm::StringRef &Name) { 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 159462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (I == ElementInfoMap.end()) 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 165462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 166e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 167e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 168