slang_rs_export_element.cpp revision e639eb5caa2c386b4a60659a4929e8a6141a2cbe
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
256315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h"
266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h"
276315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang {
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
30462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaobool RSExportElement::Initialized = false;
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoRSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
32462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
33462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid RSExportElement::Init() {
349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Initialized) {
359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Initialize ElementInfoMap
36a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang#define ENUM_RS_DATA_ELEMENT(_name, _dk, _dt, _norm, _vsize)  \
37a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    {                                                         \
38a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      ElementInfo *EI = new ElementInfo;                      \
39a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang      EI->kind = RSExportPrimitiveType::DataKind ## _dk;      \
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
709ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  assert(EI != NULL && "Element info not found");
719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!RSExportType::NormalizeType(T, TypeName))
739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return NULL;
749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
756315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr  switch (T->getTypeClass()) {
769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case clang::Type::Builtin:
779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case clang::Type::Pointer: {
789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      assert(EI->vsize == 1 && "Element not a primitive class (please check "
799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                               "your macro)");
809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      RSExportPrimitiveType *EPT =
819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          RSExportPrimitiveType::Create(Context,
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        T,
839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        TypeName,
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        EI->kind,
859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        EI->normalized);
869ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Verify
879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      assert(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: {
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      assert(EI->vsize > 1 && "Element not a vector class (please check your "
939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                              "macro)");
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      RSExportVectorType *EVT =
959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          RSExportVectorType::Create(Context,
969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     static_cast<clang::ExtVectorType*>(
979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                         T->getCanonicalTypeInternal()
989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                             .getTypePtr()),
999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     TypeName,
1009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     EI->kind,
1019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     EI->normalized);
1029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      // Verify
1039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      assert(EI->type == EVT->getType() && "Element has unexpected type");
1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size "
1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                                  "of vector");
1069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      ET = EVT;
1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
1089ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
1099ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    default: {
1106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      // TODO(zonr): warn that type is not exportable
1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
1129ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao              T->getTypeClassName());
1139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
114f8149d9e5a3795e9952717ee6346789a134c55c7Shih-wei Liao    }
1159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
116462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  return ET;
118462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
119462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1209ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
1219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                              const clang::DeclaratorDecl *DD) {
1229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
1239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const clang::Type* CT = GET_CANONICAL_TYPE(T);
1249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const ElementInfo* EI = NULL;
1259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
12691a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao  // Note: RS element like rs_pixel_rgb elements are either in the type of
12791a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao  // primitive or vector.
1289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if ((CT->getTypeClass() != clang::Type::Builtin) &&
12992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang      (CT->getTypeClass() != clang::Type::ExtVector)) {
1309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return RSExportType::Create(Context, T);
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
1329ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
13391a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao  // Following the typedef chain to see whether it's an element name like
13491a3783ce1f4eb9ad6e9c1ecdbd27f3d6dc58634Shih-wei Liao  // rs_pixel_rgb or its alias (via typedef).
1359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  while (T != CT) {
1369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (T->getTypeClass() != clang::Type::Typedef) {
1379ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      break;
1389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    } else {
1399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
1409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      const clang::TypedefDecl *TD = TT->getDecl();
1419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      EI = GetElementInfo(TD->getName());
1429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      if (EI != NULL)
1439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
144462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      T = TD->getUnderlyingType().getTypePtr();
146462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
1479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
148462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (EI == NULL) {
1509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return RSExportType::Create(Context, T);
1519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  } else {
1529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return RSExportElement::Create(Context, T, EI);
1539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  }
154462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
155462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoconst RSExportElement::ElementInfo *
1576315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrRSExportElement::GetElementInfo(const llvm::StringRef &Name) {
1589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (!Initialized)
1599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    Init();
160462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
1619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
1629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (I == ElementInfoMap.end())
1639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return NULL;
1649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  else
1659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return I->getValue();
166462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
167e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
168e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
169