blob: 9887f0b394e23b04cac7ea0889417cb580348dc0 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
zonr6315f762010-10-05 15:35:14 +080017#include "slang_rs_export_element.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070018
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070019#include "clang/AST/Decl.h"
20#include "clang/AST/Type.h"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070021
Stephen Hinese639eb52010-11-08 19:27:20 -080022#include "clang/Basic/SourceLocation.h"
23#include "clang/Basic/IdentifierTable.h"
24
Stephen Hines6e6578a2011-02-07 18:05:48 -080025#include "slang_assert.h"
zonr6315f762010-10-05 15:35:14 +080026#include "slang_rs_context.h"
27#include "slang_rs_export_type.h"
28
Stephen Hinese639eb52010-11-08 19:27:20 -080029namespace slang {
Shih-wei Liao462aefd2010-06-04 15:32:04 -070030
31bool RSExportElement::Initialized = false;
32RSExportElement::ElementInfoMapTy RSExportElement::ElementInfoMap;
33
34void RSExportElement::Init() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070035 if (!Initialized) {
36 // Initialize ElementInfoMap
Zonr Changa65ec162010-10-17 01:53:05 +080037#define ENUM_RS_DATA_ELEMENT(_name, _dk, _dt, _norm, _vsize) \
38 { \
39 ElementInfo *EI = new ElementInfo; \
40 EI->kind = RSExportPrimitiveType::DataKind ## _dk; \
41 EI->type = RSExportPrimitiveType::DataType ## _dt; \
42 EI->normalized = _norm; \
43 EI->vsize = _vsize; \
44 \
45 llvm::StringRef Name(_name); \
46 ElementInfoMap.insert( \
47 ElementInfoMapTy::value_type::Create( \
48 Name.begin(), \
49 Name.end(), \
50 ElementInfoMap.getAllocator(), \
51 EI)); \
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070052 }
Zonr Changa65ec162010-10-17 01:53:05 +080053#include "RSDataElementEnums.inc"
Shih-wei Liao462aefd2010-06-04 15:32:04 -070054
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070055 Initialized = true;
56 }
57 return;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070058}
59
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070060RSExportType *RSExportElement::Create(RSContext *Context,
61 const clang::Type *T,
62 const ElementInfo *EI) {
63 // Create RSExportType corresponded to the @T first and then verify
Shih-wei Liao462aefd2010-06-04 15:32:04 -070064
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070065 llvm::StringRef TypeName;
66 RSExportType *ET = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070067
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070068 if (!Initialized)
69 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070070
Stephen Hines6e6578a2011-02-07 18:05:48 -080071 slangAssert(EI != NULL && "Element info not found");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070072
Stephen Hinesdd6206b2010-12-09 19:39:22 -080073 if (!RSExportType::NormalizeType(T, TypeName, NULL, NULL, NULL))
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070074 return NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070075
zonr6315f762010-10-05 15:35:14 +080076 switch (T->getTypeClass()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070077 case clang::Type::Builtin:
78 case clang::Type::Pointer: {
Stephen Hines6e6578a2011-02-07 18:05:48 -080079 slangAssert(EI->vsize == 1 && "Element not a primitive class (please "
80 "check your macro)");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070081 RSExportPrimitiveType *EPT =
82 RSExportPrimitiveType::Create(Context,
83 T,
84 TypeName,
85 EI->kind,
86 EI->normalized);
87 // Verify
Stephen Hines6e6578a2011-02-07 18:05:48 -080088 slangAssert(EI->type == EPT->getType() && "Element has unexpected type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070089 ET = EPT;
90 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -070091 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070092 case clang::Type::ExtVector: {
Stephen Hines6e6578a2011-02-07 18:05:48 -080093 slangAssert(EI->vsize > 1 && "Element not a vector class (please check "
94 "your macro)");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070095 RSExportVectorType *EVT =
96 RSExportVectorType::Create(Context,
97 static_cast<clang::ExtVectorType*>(
98 T->getCanonicalTypeInternal()
99 .getTypePtr()),
100 TypeName,
101 EI->kind,
102 EI->normalized);
103 // Verify
Stephen Hines6e6578a2011-02-07 18:05:48 -0800104 slangAssert(EI->type == EVT->getType() && "Element has unexpected type");
105 slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected "
106 "size of vector");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700107 ET = EVT;
108 break;
109 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700110 default: {
zonr6315f762010-10-05 15:35:14 +0800111 // TODO(zonr): warn that type is not exportable
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700112 fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
113 T->getTypeClassName());
114 break;
115 }
116 }
117
118 return ET;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700119}
120
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700121RSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
122 const clang::DeclaratorDecl *DD) {
123 const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
124 const clang::Type* CT = GET_CANONICAL_TYPE(T);
125 const ElementInfo* EI = NULL;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700126
Shih-wei Liao91a37832010-10-03 19:11:51 -0700127 // Note: RS element like rs_pixel_rgb elements are either in the type of
128 // primitive or vector.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700129 if ((CT->getTypeClass() != clang::Type::Builtin) &&
Zonr Chang92b344a2010-10-05 20:39:03 +0800130 (CT->getTypeClass() != clang::Type::ExtVector)) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700131 return RSExportType::Create(Context, T);
132 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700133
Shih-wei Liao91a37832010-10-03 19:11:51 -0700134 // Following the typedef chain to see whether it's an element name like
135 // rs_pixel_rgb or its alias (via typedef).
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700136 while (T != CT) {
137 if (T->getTypeClass() != clang::Type::Typedef) {
138 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700139 } else {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140 const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
141 const clang::TypedefDecl *TD = TT->getDecl();
142 EI = GetElementInfo(TD->getName());
143 if (EI != NULL)
144 break;
145
146 T = TD->getUnderlyingType().getTypePtr();
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700147 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700148 }
149
150 if (EI == NULL) {
151 return RSExportType::Create(Context, T);
152 } else {
153 return RSExportElement::Create(Context, T, EI);
154 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700155}
156
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700157const RSExportElement::ElementInfo *
zonr6315f762010-10-05 15:35:14 +0800158RSExportElement::GetElementInfo(const llvm::StringRef &Name) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700159 if (!Initialized)
160 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700161
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700162 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
163 if (I == ElementInfoMap.end())
164 return NULL;
165 else
166 return I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700167}
Stephen Hinese639eb52010-11-08 19:27:20 -0800168
169} // namespace slang