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_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 37a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_ELEMENT(_name, _dk, _dt, _norm, _vsize) \ 38a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang { \ 39a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfo *EI = new ElementInfo; \ 40a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->kind = RSExportPrimitiveType::DataKind ## _dk; \ 41a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->type = RSExportPrimitiveType::DataType ## _dt; \ 42a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->normalized = _norm; \ 43a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI->vsize = _vsize; \ 44a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang \ 45a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang llvm::StringRef Name(_name); \ 46a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMap.insert( \ 47a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMapTy::value_type::Create( \ 48a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang Name.begin(), \ 49a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang Name.end(), \ 50a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang ElementInfoMap.getAllocator(), \ 51a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang EI)); \ 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 53a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#include "RSDataElementEnums.inc" 54462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Initialized = true; 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 58462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 59462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::Create(RSContext *Context, 619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo *EI) { 639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create RSExportType corresponded to the @T first and then verify 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 716e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI != NULL && "Element info not found"); 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 7378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines if (!RSExportType::NormalizeType(T, TypeName, Context->getDiagnostics(), 7478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines NULL)) 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 776315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr switch (T->getTypeClass()) { 789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == 1 && "Element not a primitive class (please " 816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "check your macro)"); 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType *EPT = 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::Create(Context, 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T, 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind, 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EPT->getType() && "Element has unexpected type"); 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EPT; 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 946e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize > 1 && "Element not a vector class (please check " 956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "your macro)"); 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType *EVT = 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType::Create(Context, 98be27482cdeaf08576bc39b72a15d35d13014a636Logan static_cast<const clang::ExtVectorType*>( 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getCanonicalTypeInternal() 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao .getTypePtr()), 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind, 1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 1056e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->type == EVT->getType() && "Element has unexpected type"); 1066e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected " 1076e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "size of vector"); 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EVT; 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that type is not exportable 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n", 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getTypeClassName()); 1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 116f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao } 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 120462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::CreateFromDecl(RSContext *Context, 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::DeclaratorDecl *DD) { 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* T = RSExportType::GetTypeOfDecl(DD); 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* CT = GET_CANONICAL_TYPE(T); 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo* EI = NULL; 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 12891a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Note: RS element like rs_pixel_rgb elements are either in the type of 12991a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // primitive or vector. 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((CT->getTypeClass() != clang::Type::Builtin) && 13192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang (CT->getTypeClass() != clang::Type::ExtVector)) { 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 13591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Following the typedef chain to see whether it's an element name like 13691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // rs_pixel_rgb or its alias (via typedef). 1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao while (T != CT) { 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T->getTypeClass() != clang::Type::Typedef) { 1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T); 14283f0c6261efc8f397fc2509e3862bc6d0eb1e1c4Shih-wei Liao const clang::TypedefNameDecl *TD = TT->getDecl(); 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI = GetElementInfo(TD->getName()); 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI != NULL) 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = TD->getUnderlyingType().getTypePtr(); 148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 150462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI == NULL) { 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportElement::Create(Context, T, EI); 1559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 156462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 157462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst RSExportElement::ElementInfo * 1596315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportElement::GetElementInfo(const llvm::StringRef &Name) { 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 162462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (I == ElementInfoMap.end()) 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 169e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 170e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 171