blob: 718f84e87083383f9340d5360565b0fb2ad88548 [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
5#include "clang/AST/Decl.h" /* for class clang::*Decl */
6#include "clang/AST/Type.h" /* for class clang::*Type */
7
8#include "clang/Basic/SourceLocation.h" /* for class clang::SourceLocation */
9#include "clang/Basic/IdentifierTable.h" /* for class clang::IdentifierInfo */
10
11namespace slang {
12
13bool RSExportElement::Initialized = false;
14RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
15
16void RSExportElement::Init() {
17 if(!Initialized) {
18 /* Initialize ElementInfoMap */
19#define USE_ELEMENT_DATA_TYPE
20#define USE_ELEMENT_DATA_KIND
21#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( ElementInfoMapTy::value_type::Create(Name.begin(), \
31 Name.end(), \
32 ElementInfoMap.getAllocator(), \
33 EI)); \
34 }
35#include "slang_rs_export_element_support.inc"
36
37 Initialized = true;
38 }
39 return;
40}
41
42RSExportType* RSExportElement::Create(RSContext* Context, const Type* T, const ElementInfo* EI) {
43 /* Create RSExportType corresponded to the @T first and then verify */
44
45 llvm::StringRef TypeName;
46 RSExportType* ET = NULL;
47
48 if(!Initialized)
49 Init();
50
51 assert(EI != NULL && "Element info not found");
52
53 if(!RSExportType::NormalizeType(T, TypeName))
54 return NULL;
55
56 switch(T->getTypeClass()) {
57 case Type::Builtin:
58 case Type::Pointer:
59 {
60 assert(EI->vsize == 1 && "Element not a primitive class (please check your macro)");
61 RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized);
62 /* verify */
63 assert(EI->type == EPT->getType() && "Element has unexpected type");
64 ET = EPT;
65 }
66 break;
67
Shih-wei Liaof8149d92010-08-22 05:32:02 -070068 case Type::ConstantArray:
69 {
70 //XXX
71 break;
72 }
73
Shih-wei Liao462aefd2010-06-04 15:32:04 -070074 case Type::ExtVector:
75 {
76 assert(EI->vsize > 1 && "Element not a vector class (please check your macro)");
Shih-wei Liaof8149d92010-08-22 05:32:02 -070077 RSExportVectorType* EVT = RSExportVectorType::Create(Context,
78 static_cast<ExtVectorType*>(T->getCanonicalTypeInternal().getTypePtr()),
79 TypeName,
Shih-wei Liao462aefd2010-06-04 15:32:04 -070080 EI->kind,
81 EI->normalized);
82 /* verify */
83 assert(EI->type == EVT->getType() && "Element has unexpected type");
84 assert(EI->vsize == EVT->getNumElement() && "Element has unexpected size of vector");
85 ET = EVT;
86 }
87 break;
88
89 case Type::Record:
90 {
Shih-wei Liaof8149d92010-08-22 05:32:02 -070091 /* Must be RS object type */
92
93 if ( TypeName.equals(llvm::StringRef("rs_matrix2x2")) ||
94 TypeName.equals(llvm::StringRef("rs_matrix3x3")) ||
95 TypeName.equals(llvm::StringRef("rs_matrix4x4")) ) {
96
97 const clang::RecordType* RT = static_cast<const RecordType*> (T);
98 const RecordDecl* RD = RT->getDecl();
99 RD = RD->getDefinition();
100 //RSExportRecordType* ERT = new RSExportRecordType(Context, TypeName, RD->hasAttr<PackedAttr>());
101 RecordDecl::field_iterator fit = RD->field_begin();
102 FieldDecl* FD = *fit;
103 const Type* FT = RSExportType::GetTypeOfDecl(FD);
104 RSExportConstantArrayType* ECT = RSExportConstantArrayType::Create(Context, static_cast<const ConstantArrayType*> (FT), TypeName);
105 ET = ECT;
106
107 //RSExportType* FieldET = RSExportElement::CreateFromDecl(Context, FD);
108 //ERT->mFields.push_back( new Field(FieldET, FD->getName(), ERT, 0) );
109 //const ASTRecordLayout &ASTRL = Context->getASTContext()->getASTRecordLayout(RD);
110 //ERT->AllocSize = (ASTRL.getSize() > ASTRL.getDataSize()) ? (ASTRL.getSize() >> 3) : (ASTRL.getDataSize() >> 3);
111 //ET = ERT;
112
113 } else {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700114 RSExportPrimitiveType* EPT = RSExportPrimitiveType::Create(Context, T, TypeName, EI->kind, EI->normalized);
115 /* verify */
116 assert(EI->type == EPT->getType() && "Element has unexpected type");
117 ET = EPT;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700118 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700119 }
120 break;
121
122 default:
123 /* TODO: warning: type is not exportable */
124 printf("RSExportElement::Create : type '%s' is not exportable\n", T->getTypeClassName());
125 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700126 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700127
128 return ET;
129}
130
131RSExportType* RSExportElement::CreateFromDecl(RSContext* Context, const DeclaratorDecl* DD) {
132 const Type* T = RSExportType::GetTypeOfDecl(DD);
133 const Type* CT = GET_CANONICAL_TYPE(T);
134 const ElementInfo* EI = NULL;
135
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700136 /* For rs element that's NOT like those rs_color4f..., just call Create(Context, T) without finding EI */
137 /* Note: Those rs_color4f kind of elements are either typed primitive or vector */
138 if ((CT->getTypeClass() != Type::Builtin) && (CT->getTypeClass() != Type::ExtVector) && (CT->getTypeClass() != Type::Record)) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700139 return RSExportType::Create(Context, T);
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700140 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700141
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700142 /* Iterative query the name of type to see whether it's an element name like rs_color4f or its alias (via typedef) */
143 while (T != CT) {
144 if (T->getTypeClass() != Type::Typedef) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700145 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700146 } else {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700147 const TypedefType* TT = static_cast<const TypedefType*>(T);
148 const TypedefDecl* TD = TT->getDecl();
149 EI = GetElementInfo(TD->getName());
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700150 if (EI != NULL)
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700151 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700152
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700153 T = TD->getUnderlyingType().getTypePtr();
154 }
155 }
156
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700157 if(EI == NULL) {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700158 return RSExportType::Create(Context, T);
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700159 } else {
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700160 return RSExportElement::Create(Context, T, EI);
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700161 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700162}
163
164const RSExportElement::ElementInfo* RSExportElement::GetElementInfo(const llvm::StringRef& Name) {
165 if(!Initialized)
166 Init();
167
168 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
169 if(I == ElementInfoMap.end())
170 return NULL;
171 else
172 return I->getValue();
173}
174
175} /* namespace slang */