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