blob: a5985bb926d108b27281b0c1d525c90e98129645 [file] [log] [blame]
Zonr Changc383a502010-10-12 01:52:08 +08001/*
Stephen Hines5bfec8d2012-04-04 08:18:57 -07002 * Copyright 2010, The Android Open Source Project
Zonr Changc383a502010-10-12 01:52:08 +08003 *
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
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -070034struct DataElementInfo {
35 const char *name;
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -070036 DataType dataType;
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -070037 bool normalized;
38 int vsize;
39};
40
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -070041static DataElementInfo DataElementInfoTable[] = {
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -070042 {"rs_pixel_l", DataTypeUnsigned8, true, 1},
43 {"rs_pixel_a", DataTypeUnsigned8, true, 1},
44 {"rs_pixel_la", DataTypeUnsigned8, true, 2},
45 {"rs_pixel_rgb", DataTypeUnsigned8, true, 3},
46 {"rs_pixel_rgba", DataTypeUnsigned8, true, 4},
47 {"rs_pixel_rgb565", DataTypeUnsigned8, true, 3},
48 {"rs_pixel_rgb5551", DataTypeUnsigned8, true, 4},
49 {"rs_pixel_rgb4444", DataTypeUnsigned8, true, 4},
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -070050};
51
52const int DataElementInfoTableCount = sizeof(DataElementInfoTable) / sizeof(DataElementInfoTable[0]);
53
54// TODO Rename RSExportElement to RSExportDataElement
Shih-wei Liao462aefd2010-06-04 15:32:04 -070055void RSExportElement::Init() {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070056 if (!Initialized) {
57 // Initialize ElementInfoMap
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -070058 for (int i = 0; i < DataElementInfoTableCount; i++) {
59 ElementInfo *EI = new ElementInfo;
60 EI->type = DataElementInfoTable[i].dataType;
61 EI->normalized = DataElementInfoTable[i].normalized;
62 EI->vsize = DataElementInfoTable[i].vsize;
63 llvm::StringRef Name(DataElementInfoTable[i].name);
64 ElementInfoMap.insert(ElementInfoMapTy::value_type::Create(
Stephen Hines2eb9a3f2014-07-15 16:50:03 -070065 Name, ElementInfoMap.getAllocator(), EI));
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070066 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070067 Initialized = true;
68 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -070069}
70
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070071RSExportType *RSExportElement::Create(RSContext *Context,
72 const clang::Type *T,
73 const ElementInfo *EI) {
74 // Create RSExportType corresponded to the @T first and then verify
Shih-wei Liao462aefd2010-06-04 15:32:04 -070075
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070076 llvm::StringRef TypeName;
Chris Wailes5abbe0e2014-08-12 15:58:29 -070077 RSExportType *ET = nullptr;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070078
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070079 if (!Initialized)
80 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -070081
Chris Wailes5abbe0e2014-08-12 15:58:29 -070082 slangAssert(EI != nullptr && "Element info not found");
Shih-wei Liao462aefd2010-06-04 15:32:04 -070083
Chris Wailes5abbe0e2014-08-12 15:58:29 -070084 if (!RSExportType::NormalizeType(T, TypeName, Context, nullptr))
85 return nullptr;
Shih-wei Liao462aefd2010-06-04 15:32:04 -070086
zonr6315f762010-10-05 15:35:14 +080087 switch (T->getTypeClass()) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070088 case clang::Type::Builtin:
89 case clang::Type::Pointer: {
Stephen Hines6e6578a2011-02-07 18:05:48 -080090 slangAssert(EI->vsize == 1 && "Element not a primitive class (please "
91 "check your macro)");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070092 RSExportPrimitiveType *EPT =
93 RSExportPrimitiveType::Create(Context,
94 T,
95 TypeName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070096 EI->normalized);
97 // Verify
Stephen Hines6e6578a2011-02-07 18:05:48 -080098 slangAssert(EI->type == EPT->getType() && "Element has unexpected type");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -070099 ET = EPT;
100 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700101 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700102 case clang::Type::ExtVector: {
Stephen Hines6e6578a2011-02-07 18:05:48 -0800103 slangAssert(EI->vsize > 1 && "Element not a vector class (please check "
104 "your macro)");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700105 RSExportVectorType *EVT =
106 RSExportVectorType::Create(Context,
Loganbe274822011-02-16 22:02:54 +0800107 static_cast<const clang::ExtVectorType*>(
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700108 T->getCanonicalTypeInternal()
109 .getTypePtr()),
110 TypeName,
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700111 EI->normalized);
112 // Verify
Stephen Hines6e6578a2011-02-07 18:05:48 -0800113 slangAssert(EI->type == EVT->getType() && "Element has unexpected type");
114 slangAssert(EI->vsize == EVT->getNumElement() && "Element has unexpected "
115 "size of vector");
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700116 ET = EVT;
117 break;
118 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700119 default: {
zonr6315f762010-10-05 15:35:14 +0800120 // TODO(zonr): warn that type is not exportable
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700121 fprintf(stderr, "RSExportElement::Create : type '%s' is not exportable\n",
122 T->getTypeClassName());
123 break;
124 }
125 }
126
127 return ET;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700128}
129
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700130RSExportType *RSExportElement::CreateFromDecl(RSContext *Context,
131 const clang::DeclaratorDecl *DD) {
132 const clang::Type* T = RSExportType::GetTypeOfDecl(DD);
Jean-Luc Brouilletb095e052014-05-16 20:10:00 -0700133 const clang::Type* CT = GetCanonicalType(T);
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700134 const ElementInfo* EI = nullptr;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700135
Shih-wei Liao91a37832010-10-03 19:11:51 -0700136 // Note: RS element like rs_pixel_rgb elements are either in the type of
137 // primitive or vector.
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700138 if ((CT->getTypeClass() != clang::Type::Builtin) &&
Zonr Chang92b344a2010-10-05 20:39:03 +0800139 (CT->getTypeClass() != clang::Type::ExtVector)) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700140 return RSExportType::Create(Context, T);
141 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700142
Shih-wei Liao91a37832010-10-03 19:11:51 -0700143 // Following the typedef chain to see whether it's an element name like
144 // rs_pixel_rgb or its alias (via typedef).
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700145 while (T != CT) {
146 if (T->getTypeClass() != clang::Type::Typedef) {
147 break;
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700148 } else {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700149 const clang::TypedefType *TT = static_cast<const clang::TypedefType*>(T);
Shih-wei Liao83f0c622011-06-21 05:34:53 -0700150 const clang::TypedefNameDecl *TD = TT->getDecl();
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700151 EI = GetElementInfo(TD->getName());
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700152 if (EI != nullptr)
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700153 break;
154
155 T = TD->getUnderlyingType().getTypePtr();
Shih-wei Liaof8149d92010-08-22 05:32:02 -0700156 }
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700157 }
158
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700159 if (EI == nullptr) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700160 return RSExportType::Create(Context, T);
161 } else {
162 return RSExportElement::Create(Context, T, EI);
163 }
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700164}
165
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700166const RSExportElement::ElementInfo *
zonr6315f762010-10-05 15:35:14 +0800167RSExportElement::GetElementInfo(const llvm::StringRef &Name) {
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700168 if (!Initialized)
169 Init();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700170
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700171 ElementInfoMapTy::const_iterator I = ElementInfoMap.find(Name);
172 if (I == ElementInfoMap.end())
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700173 return nullptr;
Shih-wei Liao9ef2f782010-10-01 12:31:37 -0700174 else
175 return I->getValue();
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700176}
Stephen Hinese639eb52010-11-08 19:27:20 -0800177
178} // namespace slang