blob: 1ecacceb96026bb72b7fa8bb60deefff050ef447 [file] [log] [blame]
zonr6315f762010-10-05 15:35:14 +08001#include "slang_rs_export_element.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07002
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07003#include "clang/Basic/SourceLocation.h"
4#include "clang/Basic/IdentifierTable.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07005
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07006#include "clang/AST/Decl.h"
7#include "clang/AST/Type.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07008
zonr6315f762010-10-05 15:35:14 +08009#include "slang_rs_context.h"
10#include "slang_rs_export_type.h"
11
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070012using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070013
14bool RSExportElement::Initialized = false;
15RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
16
17void RSExportElement::Init() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070018 if (!Initialized) {
19 // Initialize ElementInfoMap
Shih-wei Liao462aefd2010-06-04 15:32:04 -070020#define USE_ELEMENT_DATA_TYPE
21#define USE_ELEMENT_DATA_KIND
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070022#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \
23 { \
24 ElementInfo *EI = new ElementInfo; \
25 EI->kind = GET_ELEMENT_DATA_KIND(_dk); \
26 EI->type = GET_ELEMENT_DATA_TYPE(_dt); \
27 EI->normalized = _norm; \
28 EI->vsize = _vsize; \
29 \
30 llvm::StringRef Name(_name); \
31 ElementInfoMap.insert( \
32 ElementInfoMapTy::value_type::Create( \
33 Name.begin(), \
34 Name.end(), \
35 ElementInfoMap.getAllocator(), \
zonr6315f762010-10-05 15:35:14 +080036 EI)); \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070037 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070038#include "slang_rs_export_element_support.inc"
39
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070040 Initialized = true;
41 }
42 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070043}
44
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070045RSExportType *RSExportElement::Create(RSContext *Context,
46 const clang::Type *T,
47 const ElementInfo *EI) {
48 // Create RSExportType corresponded to the @T first and then verify
Shih-wei Liao462aefd2010-06-04 15:32:04 -070049
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070050 llvm::StringRef TypeName;
51 RSExportType *ET = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070052
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070053 if (!Initialized)
54 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070055
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 assert(EI != NULL && "Element info not found");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070057
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070058 if (!RSExportType::NormalizeType(T, TypeName))
59 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070060
zonr6315f762010-10-05 15:35:14 +080061 switch (T->getTypeClass()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070062 case clang::Type::Builtin:
63 case clang::Type::Pointer: {
64 assert(EI->vsize == 1 && "Element not a primitive class (please check "
65 "your macro)");
66 RSExportPrimitiveType *EPT =
67 RSExportPrimitiveType::Create(Context,
68 T,
69 TypeName,
70 EI->kind,
71 EI->normalized);
72 // Verify
73 assert(EI->type == EPT->getType() && "Element has unexpected type");
74 ET = EPT;
75 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -070076 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070077 case clang::Type::ConstantArray: {
zonr6315f762010-10-05 15:35:14 +080078 // XXX
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070079 break;
80 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070081 case clang::Type::ExtVector: {
82 assert(EI->vsize > 1 && "Element not a vector class (please check your "
83 "macro)");
84 RSExportVectorType *EVT =
85 RSExportVectorType::Create(Context,
86 static_cast<clang::ExtVectorType*>(
87 T->getCanonicalTypeInternal()
88 .getTypePtr()),
89 TypeName,
90 EI->kind,
91 EI->normalized);
92 // Verify
93 assert(EI->type == EVT->getType() && "Element has unexpected type");
94 assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size "
95 "of vector");
96 ET = EVT;
97 break;
98 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070099 case clang::Type::Record: {
100 // Must be RS object type
101
zonr6315f762010-10-05 15:35:14 +0800102 if (TypeName.equals(llvm::StringRef("rs_matrix2x2")) ||
103 TypeName.equals(llvm::StringRef("rs_matrix3x3")) ||
104 TypeName.equals(llvm::StringRef("rs_matrix4x4"))) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 const clang::RecordType *RT = static_cast<const clang::RecordType*> (T);
106 const clang::RecordDecl *RD = RT->getDecl();
107 RD = RD->getDefinition();
108 clang::RecordDecl::field_iterator fit = RD->field_begin();
109 clang::FieldDecl *FD = *fit;
110 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
111 RSExportConstantArrayType *ECT =
112 RSExportConstantArrayType::Create(
113 Context,
114 static_cast<const clang::ConstantArrayType*> (FT),
zonr6315f762010-10-05 15:35:14 +0800115 TypeName);
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116 ET = ECT;
117 } else {
118 RSExportPrimitiveType* EPT =
119 RSExportPrimitiveType::Create(Context,
120 T,
121 TypeName,
122 EI->kind,
123 EI->normalized);
124 // Verify
125 assert(EI->type == EPT->getType() && "Element has unexpected type");
126 ET = EPT;
127 }
128 break;
129 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130 default: {
zonr6315f762010-10-05 15:35:14 +0800131 // TODO(zonr): warn that type is not exportable
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700132 fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
133 T->getTypeClassName());
134 break;
135 }
136 }
137
138 return ET;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700139}
140
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700141RSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
142 const clang::DeclaratorDecl *DD) {
143 const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
144 const clang::Type* CT = GET_CANONICAL_TYPE(T);
145 const ElementInfo* EI = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700146
Shih-wei Liao91a37832010-10-03 19:11:51 -0700147 // Note: RS element like rs_pixel_rgb elements are either in the type of
148 // primitive or vector.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700149 if ((CT->getTypeClass() != clang::Type::Builtin) &&
150 (CT->getTypeClass() != clang::Type::ExtVector) &&
151 (CT->getTypeClass() != clang::Type::Record)) {
152 return RSExportType::Create(Context, T);
153 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700154
Shih-wei Liao91a37832010-10-03 19:11:51 -0700155 // Following the typedef chain to see whether it's an element name like
156 // rs_pixel_rgb or its alias (via typedef).
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700157 while (T != CT) {
158 if (T->getTypeClass() != clang::Type::Typedef) {
159 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700160 } else {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700161 const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
162 const clang::TypedefDecl *TD = TT->getDecl();
163 EI = GetElementInfo(TD->getName());
164 if (EI != NULL)
165 break;
166
167 T = TD->getUnderlyingType().getTypePtr();
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700168 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700169 }
170
171 if (EI == NULL) {
172 return RSExportType::Create(Context, T);
173 } else {
174 return RSExportElement::Create(Context, T, EI);
175 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700176}
177
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700178const RSExportElement::ElementInfo *
zonr6315f762010-10-05 15:35:14 +0800179RSExportElement::GetElementInfo(const llvm::StringRef &Name) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700180 if (!Initialized)
181 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700182
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700183 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
184 if (I == ElementInfoMap.end())
185 return NULL;
186 else
187 return I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700188}