slang_rs_export_element.cpp revision 6e6578a360497f78a181e63d7783422a9c9bfb15
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright 2010, The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 171212a022fa5f8ef9585d765b1809521812af882cIan Rogers#include "slang_rs_export_element.h" 189ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 1967f99418f648c3a95256ed3dcd8e8b64eef0b372Anwar Ghuloum#include "clang/AST/Decl.h" 2067f99418f648c3a95256ed3dcd8e8b64eef0b372Anwar Ghuloum#include "clang/AST/Type.h" 21d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes 2267f99418f648c3a95256ed3dcd8e8b64eef0b372Anwar Ghuloum#include "clang/Basic/SourceLocation.h" 23d9c67be7c116875d96b31e640ad47d587b205605Elliott Hughes#include "clang/Basic/IdentifierTable.h" 2439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison 2527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include "slang_assert.h" 261aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "slang_rs_context.h" 27a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "slang_rs_export_type.h" 289ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 29b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffraynamespace slang { 30be0e546730e532ef0987cd4bde2c6f5a1b14dd2aVladimir Marko 3189756f21c107d96e6d1bbc75811bd33078c8ceeeIan Rogersbool RSExportElement::Initialized = false; 324f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian RogersRSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap; 33c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko 342730db03beee4d6687ddfb5000c33c0370fbc6ebVladimir Markovoid RSExportElement::Init() { 352bc47809febcf36369dd40877b8226318642b428Vladimir Marko if (!Initialized) { 36ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell // Initialize ElementInfoMap 379baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#define ENUM_RS_DATA_ELEMENT(_name, _dk, _dt, _norm, _vsize) \ 386d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers { \ 391f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom ElementInfo *EI = new ElementInfo; \ 401d54e73444e017d3a65234e0f193846f3e27472bIan Rogers EI->kind = RSExportPrimitiveType::DataKind ## _dk; \ 411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers EI->type = RSExportPrimitiveType::DataType ## _dt; \ 421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers EI->normalized = _norm; \ 43ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom EI->vsize = _vsize; \ 44ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom \ 452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers llvm::StringRef Name(_name); \ 462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ElementInfoMap.insert( \ 4739ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers ElementInfoMapTy::value_type::Create( \ 482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Name.begin(), \ 492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers Name.end(), \ 502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ElementInfoMap.getAllocator(), \ 5100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EI)); \ 5200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 53c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier#include "RSDataElementEnums.inc" 5450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers 550e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier Initialized = true; 56848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers } 57d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return; 58776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers} 592bc47809febcf36369dd40877b8226318642b428Vladimir Marko 609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian CarlstromRSExportType *RSExportElement::Create(RSContext *Context, 619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const clang::Type *T, 629ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const ElementInfo *EI) { 63996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers // Create RSExportType corresponded to the @T first and then verify 64398f64b5805246765b699839b439e18c0dfbf2eeElliott Hughes 65996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers llvm::StringRef TypeName; 66996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers RSExportType *ET = NULL; 67996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 68996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (!Initialized) 69996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers Init(); 70996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 71e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers slangAssert(EI != NULL && "Element info not found"); 72996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 73996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (!RSExportType::NormalizeType(T, TypeName, NULL, NULL, NULL)) 74f096aad9203d7c50b2f9cbe1c1215a50c265a059Vladimir Marko return NULL; 75c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 76ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers switch (T->getTypeClass()) { 77ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers case clang::Type::Builtin: 78ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers case clang::Type::Pointer: { 79ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers slangAssert(EI->vsize == 1 && "Element not a primitive class (please " 80ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers "check your macro)"); 81ca190666fb11820153f74274c495ba1f913d8a69Ian Rogers RSExportPrimitiveType *EPT = 8202c42237741b5573f9d790a5a0f17f408dceb543Sameer Abu Asal RSExportPrimitiveType::Create(Context, 83fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers T, 84fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers TypeName, 852ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers EI->kind, 86c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers EI->normalized); 87c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers // Verify 882ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers slangAssert(EI->type == EPT->getType() && "Element has unexpected type"); 892ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers ET = EPT; 902ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers break; 91b25c3f6a86dc634ce44fb2849385b49465caa84dElliott Hughes } 92c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers case clang::Type::ExtVector: { 93c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers slangAssert(EI->vsize > 1 && "Element not a vector class (please check " 94c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers "your macro)"); 95c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers RSExportVectorType *EVT = 96c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers RSExportVectorType::Create(Context, 97c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers static_cast<clang::ExtVectorType*>( 98c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers T->getCanonicalTypeInternal() 99c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers .getTypePtr()), 100c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers TypeName, 101c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers EI->kind, 102c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers EI->normalized); 103fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers // Verify 104fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers slangAssert(EI->type == EVT->getType() && "Element has unexpected type"); 105fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected " 106fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers "size of vector"); 107fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers ET = EVT; 108fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers break; 109fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers } 110fae370a044f5817f69937cccfd2d12a16b374266Ian Rogers default: { 111c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers // TODO(zonr): warn that type is not exportable 1122ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n", 113c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers T->getTypeClassName()); 1142ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers break; 115c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 1162ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1172ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 1182ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return ET; 1192ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers} 1202ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 1212ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian RogersRSExportType *RSExportElement::CreateFromDecl(RSContext *Context, 1222ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers const clang::DeclaratorDecl *DD) { 1232ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers const clang::Type* T = RSExportType::GetTypeOfDecl(DD); 1242ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers const clang::Type* CT = GET_CANONICAL_TYPE(T); 1252ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers const ElementInfo* EI = NULL; 1262ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 1272ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Note: RS element like rs_pixel_rgb elements are either in the type of 1282ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // primitive or vector. 1292ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers if ((CT->getTypeClass() != clang::Type::Builtin) && 1302ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers (CT->getTypeClass() != clang::Type::ExtVector)) { 1312ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers return RSExportType::Create(Context, T); 1322ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers } 1332ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers 1342ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // Following the typedef chain to see whether it's an element name like 1352ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers // rs_pixel_rgb or its alias (via typedef). 1362ed3b9536ccfd7c7321cc18650820b093b22d6c9Ian Rogers while (T != CT) { 137c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers if (T->getTypeClass() != clang::Type::Typedef) { 138c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers break; 139996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers } else { 14050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T); 141996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers const clang::TypedefDecl *TD = TT->getDecl(); 14250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers EI = GetElementInfo(TD->getName()); 143996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers if (EI != NULL) 144996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers break; 145996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 146996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers T = TD->getUnderlyingType().getTypePtr(); 147c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 148c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 149c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 150c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers if (EI == NULL) { 151996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return RSExportType::Create(Context, T); 152c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } else { 153c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers return RSExportElement::Create(Context, T, EI); 154c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers } 155c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers} 156996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 157c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogersconst RSExportElement::ElementInfo * 158c8b306f5221658c7e4b5516be8917dc8c9288e7eIan RogersRSExportElement::GetElementInfo(const llvm::StringRef &Name) { 159c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers if (!Initialized) 160c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers Init(); 161996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers 162c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name); 163c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers if (I == ElementInfoMap.end()) 164c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers return NULL; 165c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers else 166996cc586ce76235ee3efa1eff86de51dabcc5d53Ian Rogers return I->getValue(); 167c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers} 168c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers 169c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers} // namespace slang 170c8b306f5221658c7e4b5516be8917dc8c9288e7eIan Rogers