blob: a5375f87e6ff11b4a7ad5fb2f08d66f2b09c4e2a [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#include "slang_rs_context.hpp"
2#include "slang_rs_export_type.hpp"
3#include "slang_rs_export_element.hpp"
4
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07005#include "clang/Basic/SourceLocation.h"
6#include "clang/Basic/IdentifierTable.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -07007
Shih-wei Liao9ef2f782010-10-01 12:31:37 -07008#include "clang/AST/Decl.h"
9#include "clang/AST/Type.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070010
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070011using namespace slang;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070012
13bool RSExportElement::Initialized = false;
14RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
15
16void RSExportElement::Init() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070017 if (!Initialized) {
18 // Initialize ElementInfoMap
Shih-wei Liao462aefd2010-06-04 15:32:04 -070019#define USE_ELEMENT_DATA_TYPE
20#define USE_ELEMENT_DATA_KIND
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070021#define DEF_ELEMENT(_name, _dk, _dt, _norm, _vsize) \
22 { \
23 ElementInfo *EI = new ElementInfo; \
24 EI->kind = GET_ELEMENT_DATA_KIND(_dk); \
25 EI->type = GET_ELEMENT_DATA_TYPE(_dt); \
26 EI->normalized = _norm; \
27 EI->vsize = _vsize; \
28 \
29 llvm::StringRef Name(_name); \
30 ElementInfoMap.insert( \
31 ElementInfoMapTy::value_type::Create( \
32 Name.begin(), \
33 Name.end(), \
34 ElementInfoMap.getAllocator(), \
35 EI \
36 )); \
37 }
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
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070061 switch(T->getTypeClass()) {
62 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 Liao462aefd2010-06-04 15:32:04 -070077
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070078 case clang::Type::ConstantArray: {
79 //XXX
80 break;
81 }
82
83 case clang::Type::ExtVector: {
84 assert(EI->vsize > 1 && "Element not a vector class (please check your "
85 "macro)");
86 RSExportVectorType *EVT =
87 RSExportVectorType::Create(Context,
88 static_cast<clang::ExtVectorType*>(
89 T->getCanonicalTypeInternal()
90 .getTypePtr()),
91 TypeName,
92 EI->kind,
93 EI->normalized);
94 // Verify
95 assert(EI->type == EVT->getType() && "Element has unexpected type");
96 assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size "
97 "of vector");
98 ET = EVT;
99 break;
100 }
101
102 case clang::Type::Record: {
103 // Must be RS object type
104
105 if ( TypeName.equals(llvm::StringRef("rs_matrix2x2")) ||
106 TypeName.equals(llvm::StringRef("rs_matrix3x3")) ||
107 TypeName.equals(llvm::StringRef("rs_matrix4x4")) ) {
108
109 const clang::RecordType *RT = static_cast<const clang::RecordType*> (T);
110 const clang::RecordDecl *RD = RT->getDecl();
111 RD = RD->getDefinition();
112 clang::RecordDecl::field_iterator fit = RD->field_begin();
113 clang::FieldDecl *FD = *fit;
114 const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
115 RSExportConstantArrayType *ECT =
116 RSExportConstantArrayType::Create(
117 Context,
118 static_cast<const clang::ConstantArrayType*> (FT),
119 TypeName
120 );
121 ET = ECT;
122 } else {
123 RSExportPrimitiveType* EPT =
124 RSExportPrimitiveType::Create(Context,
125 T,
126 TypeName,
127 EI->kind,
128 EI->normalized);
129 // Verify
130 assert(EI->type == EPT->getType() && "Element has unexpected type");
131 ET = EPT;
132 }
133 break;
134 }
135
136 default: {
137 // TODO: warning: type is not exportable
138 fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
139 T->getTypeClassName());
140 break;
141 }
142 }
143
144 return ET;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700145}
146
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700147RSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
148 const clang::DeclaratorDecl *DD) {
149 const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
150 const clang::Type* CT = GET_CANONICAL_TYPE(T);
151 const ElementInfo* EI = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700152
Shih-wei Liao91a37832010-10-03 19:11:51 -0700153 // Note: RS element like rs_pixel_rgb elements are either in the type of
154 // primitive or vector.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700155 if ((CT->getTypeClass() != clang::Type::Builtin) &&
156 (CT->getTypeClass() != clang::Type::ExtVector) &&
157 (CT->getTypeClass() != clang::Type::Record)) {
158 return RSExportType::Create(Context, T);
159 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700160
Shih-wei Liao91a37832010-10-03 19:11:51 -0700161 // Following the typedef chain to see whether it's an element name like
162 // rs_pixel_rgb or its alias (via typedef).
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700163 while (T != CT) {
164 if (T->getTypeClass() != clang::Type::Typedef) {
165 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700166 } else {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700167 const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
168 const clang::TypedefDecl *TD = TT->getDecl();
169 EI = GetElementInfo(TD->getName());
170 if (EI != NULL)
171 break;
172
173 T = TD->getUnderlyingType().getTypePtr();
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700174 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700175 }
176
177 if (EI == NULL) {
178 return RSExportType::Create(Context, T);
179 } else {
180 return RSExportElement::Create(Context, T, EI);
181 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700182}
183
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700184const RSExportElement::ElementInfo *
185RSExportElement::GetElementInfo(const llvm::StringRef& Name) {
186 if (!Initialized)
187 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700188
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700189 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
190 if (I == ElementInfoMap.end())
191 return NULL;
192 else
193 return I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700194}