slang_rs_export_element.cpp revision 6315f76e3cc6ff2d012d1183a0b030d4ff0dc808
16315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_element.h" 2462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 39ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/SourceLocation.h" 49ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/Basic/IdentifierTable.h" 5462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 69ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Decl.h" 79ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Type.h" 8462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 96315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaousing namespace slang; 13462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 14462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool RSExportElement::Initialized = false; 15462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap; 16462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 17462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSExportElement::Init() { 189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) { 199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Initialize ElementInfoMap 20462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define USE_ELEMENT_DATA_TYPE 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#define USE_ELEMENT_DATA_KIND 229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \ 239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao { \ 249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfo *EI = new ElementInfo; \ 259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind = GET_ELEMENT_DATA_KIND(_dk); \ 269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->type = GET_ELEMENT_DATA_TYPE(_dt); \ 279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized = _norm; \ 289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->vsize = _vsize; \ 299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao \ 309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef Name(_name); \ 319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMap.insert( \ 329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMapTy::value_type::Create( \ 339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Name.begin(), \ 349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Name.end(), \ 359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMap.getAllocator(), \ 366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr EI)); \ 379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 38462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "slang_rs_export_element_support.inc" 39462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Initialized = true; 419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return; 43462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 459ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::Create(RSContext *Context, 469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *T, 479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo *EI) { 489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Create RSExportType corresponded to the @T first and then verify 499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao llvm::StringRef TypeName; 519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportType *ET = NULL; 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI != NULL && "Element info not found"); 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!RSExportType::NormalizeType(T, TypeName)) 599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr switch (T->getTypeClass()) { 629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Builtin: 639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Pointer: { 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->vsize == 1 && "Element not a primitive class (please check " 659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "your macro)"); 669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType *EPT = 679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::Create(Context, 689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T, 699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind, 719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->type == EPT->getType() && "Element has unexpected type"); 749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EPT; 759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ConstantArray: { 786315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // XXX 799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::ExtVector: { 829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->vsize > 1 && "Element not a vector class (please check your " 839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "macro)"); 849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType *EVT = 859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportVectorType::Create(Context, 869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao static_cast<clang::ExtVectorType*>( 879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getCanonicalTypeInternal() 889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao .getTypePtr()), 899ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind, 919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->type == EVT->getType() && "Element has unexpected type"); 949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size " 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao "of vector"); 969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EVT; 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case clang::Type::Record: { 1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Must be RS object type 1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 1026315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr if (TypeName.equals(llvm::StringRef("rs_matrix2x2")) || 1036315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr TypeName.equals(llvm::StringRef("rs_matrix3x3")) || 1046315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr TypeName.equals(llvm::StringRef("rs_matrix4x4"))) { 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordType *RT = static_cast<const clang::RecordType*> (T); 1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::RecordDecl *RD = RT->getDecl(); 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RD = RD->getDefinition(); 1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::RecordDecl::field_iterator fit = RD->field_begin(); 1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::FieldDecl *FD = *fit; 1109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportConstantArrayType *ECT = 1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportConstantArrayType::Create( 1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Context, 1149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao static_cast<const clang::ConstantArrayType*> (FT), 1156315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr TypeName); 1169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = ECT; 1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType* EPT = 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao RSExportPrimitiveType::Create(Context, 1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T, 1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao TypeName, 1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->kind, 1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI->normalized); 1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // Verify 1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao assert(EI->type == EPT->getType() && "Element has unexpected type"); 1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ET = EPT; 1279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr // TODO(zonr): warn that type is not exportable 1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n", 1339ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T->getTypeClassName()); 1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 135f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao } 1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 137462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return ET; 139462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 140462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::CreateFromDecl(RSContext *Context, 1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::DeclaratorDecl *DD) { 1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* T = RSExportType::GetTypeOfDecl(DD); 1449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Type* CT = GET_CANONICAL_TYPE(T); 1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const ElementInfo* EI = NULL; 1469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 14791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Note: RS element like rs_pixel_rgb elements are either in the type of 14891a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // primitive or vector. 1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if ((CT->getTypeClass() != clang::Type::Builtin) && 1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao (CT->getTypeClass() != clang::Type::ExtVector) && 1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao (CT->getTypeClass() != clang::Type::Record)) { 1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 15591a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // Following the typedef chain to see whether it's an element name like 15691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao // rs_pixel_rgb or its alias (via typedef). 1579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao while (T != CT) { 1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (T->getTypeClass() != clang::Type::Typedef) { 1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 1609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T); 1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::TypedefDecl *TD = TT->getDecl(); 1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao EI = GetElementInfo(TD->getName()); 1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI != NULL) 1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao break; 166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao T = TD->getUnderlyingType().getTypePtr(); 168462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao } 1699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 170462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (EI == NULL) { 1729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportType::Create(Context, T); 1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } else { 1749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return RSExportElement::Create(Context, T, EI); 1759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 176462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 177462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst RSExportElement::ElementInfo * 1796315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportElement::GetElementInfo(const llvm::StringRef &Name) { 1809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (!Initialized) 1819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao Init(); 182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 1839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 1849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (I == ElementInfoMap.end()) 1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return NULL; 1869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao else 1879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao return I->getValue(); 188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 189