blob: 256b052b799e3c48e233004a2d4c79a8c51ead7e [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 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
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "Type.h"
18
Timur Iskhakov891a8662017-08-25 21:53:48 -070019#include "ConstantExpression.h"
Timur Iskhakov40731af2017-08-24 14:18:35 -070020#include "NamedType.h"
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070021#include "ScalarType.h"
Timur Iskhakov63f39902017-08-29 15:47:29 -070022#include "Scope.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023
24#include <android-base/logging.h>
Timur Iskhakovb58f4182017-08-29 15:19:24 -070025#include <hidl-util/Formatter.h>
26#include <algorithm>
Timur Iskhakove8ee6a02017-09-06 11:42:10 -070027#include <iostream>
Andreas Huber881227d2016-08-02 14:20:21 -070028
Andreas Huberc9410c72016-07-28 12:18:40 -070029namespace android {
30
Timur Iskhakov63f39902017-08-29 15:47:29 -070031Type::Type(Scope* parent) : mParent(parent) {}
Andreas Huber7c5ddfb2016-09-29 13:45:22 -070032
Andreas Huberc9410c72016-07-28 12:18:40 -070033Type::~Type() {}
34
Andreas Huber5345ec22016-07-29 13:33:27 -070035bool Type::isScope() const {
36 return false;
37}
38
Andreas Hubera2723d22016-07-29 15:36:07 -070039bool Type::isInterface() const {
40 return false;
41}
42
Yifan Hongabf73ee2016-12-05 18:47:00 -080043bool Type::isScalar() const {
44 return false;
45}
46
47bool Type::isString() const {
48 return false;
49}
50
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070051bool Type::isEnum() const {
52 return false;
53}
54
Yifan Hongabf73ee2016-12-05 18:47:00 -080055bool Type::isBitField() const {
56 return false;
57}
58
59bool Type::isHandle() const {
60 return false;
61}
62
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070063bool Type::isTypeDef() const {
64 return false;
65}
66
Andreas Huber39fa7182016-08-19 14:27:33 -070067bool Type::isNamedType() const {
68 return false;
69}
70
Steven Moreland397b5e12017-06-08 14:02:26 -070071bool Type::isMemory() const {
72 return false;
73}
74
Andreas Huberf630bc82016-09-09 14:52:25 -070075bool Type::isCompoundType() const {
76 return false;
77}
78
Andreas Huber709b62d2016-09-19 11:21:18 -070079bool Type::isArray() const {
80 return false;
81}
82
83bool Type::isVector() const {
84 return false;
85}
86
Yifan Hongabf73ee2016-12-05 18:47:00 -080087bool Type::isTemplatedType() const {
88 return false;
89}
90
Martijn Coenen99e6beb2016-12-01 15:48:42 +010091bool Type::isPointer() const {
92 return false;
93}
94
Timur Iskhakovdbaed332017-08-31 16:33:41 -070095Type* Type::resolve() {
96 return const_cast<Type*>(static_cast<const Type*>(this)->resolve());
97}
98
99const Type* Type::resolve() const {
100 return this;
101}
102
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700103std::vector<Type*> Type::getDefinedTypes() {
104 const auto& constRet = static_cast<const Type*>(this)->getDefinedTypes();
105 std::vector<Type*> ret(constRet.size());
106 std::transform(constRet.begin(), constRet.end(), ret.begin(),
107 [](const auto* type) { return const_cast<Type*>(type); });
108 return ret;
109}
110
111std::vector<const Type*> Type::getDefinedTypes() const {
Timur Iskhakov33431e62017-08-21 17:31:23 -0700112 return {};
113}
114
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700115std::vector<Reference<Type>*> Type::getReferences() {
116 const auto& constRet = static_cast<const Type*>(this)->getReferences();
117 std::vector<Reference<Type>*> ret(constRet.size());
118 std::transform(constRet.begin(), constRet.end(), ret.begin(),
119 [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
120 return ret;
121}
122
123std::vector<const Reference<Type>*> Type::getReferences() const {
Timur Iskhakov33431e62017-08-21 17:31:23 -0700124 return {};
125}
126
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700127std::vector<ConstantExpression*> Type::getConstantExpressions() {
128 const auto& constRet = static_cast<const Type*>(this)->getConstantExpressions();
129 std::vector<ConstantExpression*> ret(constRet.size());
130 std::transform(constRet.begin(), constRet.end(), ret.begin(),
131 [](const auto* ce) { return const_cast<ConstantExpression*>(ce); });
132 return ret;
133}
134
135std::vector<const ConstantExpression*> Type::getConstantExpressions() const {
Timur Iskhakov891a8662017-08-25 21:53:48 -0700136 return {};
137}
138
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700139std::vector<Reference<Type>*> Type::getStrongReferences() {
140 const auto& constRet = static_cast<const Type*>(this)->getStrongReferences();
141 std::vector<Reference<Type>*> ret(constRet.size());
142 std::transform(constRet.begin(), constRet.end(), ret.begin(),
143 [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
144 return ret;
145}
146
147std::vector<const Reference<Type>*> Type::getStrongReferences() const {
Timur Iskhakovff5e64a2017-09-11 14:56:18 -0700148 std::vector<const Reference<Type>*> ret;
149 for (const auto* ref : getReferences()) {
150 if (!ref->shallowGet()->isNeverStrongReference()) {
151 ret.push_back(ref);
152 }
153 }
154 return ret;
Timur Iskhakov40731af2017-08-24 14:18:35 -0700155}
156
Yifan Hong0e192c42018-10-23 15:32:19 -0700157status_t Type::recursivePass(ParseStage stage, const std::function<status_t(Type*)>& func,
Timur Iskhakov33431e62017-08-21 17:31:23 -0700158 std::unordered_set<const Type*>* visited) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700159 if (mParseStage > stage) return OK;
160 if (mParseStage < stage) return UNKNOWN_ERROR;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700161
Timur Iskhakov33431e62017-08-21 17:31:23 -0700162 if (visited->find(this) != visited->end()) return OK;
163 visited->insert(this);
164
165 status_t err = func(this);
166 if (err != OK) return err;
167
168 for (auto* nextType : getDefinedTypes()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700169 err = nextType->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700170 if (err != OK) return err;
171 }
172
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700173 for (auto* nextRef : getReferences()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700174 err = nextRef->shallowGet()->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700175 if (err != OK) return err;
176 }
177
178 return OK;
179}
180
Yifan Hong0e192c42018-10-23 15:32:19 -0700181status_t Type::recursivePass(ParseStage stage, const std::function<status_t(const Type*)>& func,
Timur Iskhakov33431e62017-08-21 17:31:23 -0700182 std::unordered_set<const Type*>* visited) const {
Yifan Hong0e192c42018-10-23 15:32:19 -0700183 if (mParseStage > stage) return OK;
184 if (mParseStage < stage) return UNKNOWN_ERROR;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700185
Timur Iskhakov33431e62017-08-21 17:31:23 -0700186 if (visited->find(this) != visited->end()) return OK;
187 visited->insert(this);
188
189 status_t err = func(this);
190 if (err != OK) return err;
191
192 for (const auto* nextType : getDefinedTypes()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700193 err = nextType->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700194 if (err != OK) return err;
195 }
196
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700197 for (const auto* nextRef : getReferences()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700198 err = nextRef->shallowGet()->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700199 if (err != OK) return err;
200 }
201
202 return OK;
203}
204
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700205status_t Type::resolveInheritance() {
206 return OK;
207}
208
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700209status_t Type::validate() const {
210 return OK;
211}
212
Timur Iskhakov40731af2017-08-24 14:18:35 -0700213Type::CheckAcyclicStatus::CheckAcyclicStatus(status_t status, const Type* cycleEnd)
214 : status(status), cycleEnd(cycleEnd) {
215 CHECK(cycleEnd == nullptr || status != OK);
216}
217
Timur Iskhakov458ca362017-09-12 23:16:03 -0700218Type::CheckAcyclicStatus Type::topologicalOrder(
219 std::unordered_map<const Type*, size_t>* reversedOrder,
220 std::unordered_set<const Type*>* stack) const {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700221 if (stack->find(this) != stack->end()) {
222 std::cerr << "ERROR: Cyclic declaration:\n";
223 return CheckAcyclicStatus(UNKNOWN_ERROR, this);
224 }
225
Timur Iskhakov458ca362017-09-12 23:16:03 -0700226 if (reversedOrder->find(this) != reversedOrder->end()) return CheckAcyclicStatus(OK);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700227 stack->insert(this);
228
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700229 for (const auto* nextType : getDefinedTypes()) {
Timur Iskhakov458ca362017-09-12 23:16:03 -0700230 auto err = nextType->topologicalOrder(reversedOrder, stack);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700231
232 if (err.status != OK) {
233 if (err.cycleEnd == nullptr) return err;
234
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700235 std::cerr << " '" << nextType->typeName() << "' in '" << typeName() << "'";
Timur Iskhakov40731af2017-08-24 14:18:35 -0700236 if (nextType->isNamedType()) {
237 std::cerr << " at " << static_cast<const NamedType*>(nextType)->location();
238 }
239 std::cerr << "\n";
240
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700241 if (err.cycleEnd == this) {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700242 return CheckAcyclicStatus(err.status);
243 }
244 return err;
245 }
246 }
247
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700248 for (const auto* nextRef : getStrongReferences()) {
Timur Iskhakovdbaed332017-08-31 16:33:41 -0700249 const auto* nextType = nextRef->shallowGet();
Timur Iskhakov458ca362017-09-12 23:16:03 -0700250 auto err = nextType->topologicalOrder(reversedOrder, stack);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700251
252 if (err.status != OK) {
253 if (err.cycleEnd == nullptr) return err;
254
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700255 std::cerr << " '" << nextType->typeName() << "' in '" << typeName() << "' at "
256 << nextRef->location() << "\n";
Timur Iskhakov40731af2017-08-24 14:18:35 -0700257
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700258 if (err.cycleEnd == this) {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700259 return CheckAcyclicStatus(err.status);
260 }
261 return err;
262 }
263 }
264
265 CHECK(stack->find(this) != stack->end());
266 stack->erase(this);
Timur Iskhakov458ca362017-09-12 23:16:03 -0700267
268 CHECK(reversedOrder->find(this) == reversedOrder->end());
269 // Do not call insert and size in one statement to not rely on
270 // evaluation order.
271 size_t index = reversedOrder->size();
272 reversedOrder->insert({this, index});
273
Timur Iskhakov40731af2017-08-24 14:18:35 -0700274 return CheckAcyclicStatus(OK);
275}
276
Timur Iskhakov458ca362017-09-12 23:16:03 -0700277status_t Type::checkForwardReferenceRestrictions(const Reference<Type>& ref) const {
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700278 const Location& refLoc = ref.location();
279 const Type* refType = ref.shallowGet();
280
281 // Not NamedTypes are avaiable everywhere.
Timur Iskhakov78821ed2017-09-09 23:40:13 -0700282 // Only ArrayType and TemplatedType contain additional types in
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700283 // their reference (which is actually a part of type definition),
284 // so they are proceeded in this case.
285 //
286 // If we support named templated types one day, we will need to change
287 // this logic.
288 if (!refType->isNamedType()) {
Timur Iskhakov458ca362017-09-12 23:16:03 -0700289 for (const Reference<Type>* innerRef : refType->getReferences()) {
290 status_t err = checkForwardReferenceRestrictions(*innerRef);
291 if (err != OK) return err;
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700292 }
293 return OK;
294 }
295
296 const Location& typeLoc = static_cast<const NamedType*>(refType)->location();
297
298 // If referenced type is declared in another file or before reference,
299 // there is no forward reference here.
300 if (!Location::inSameFile(refLoc, typeLoc) ||
301 (!Location::intersect(refLoc, typeLoc) && typeLoc < refLoc)) {
302 return OK;
303 }
304
305 // Type must be declared somewhere in the current stack to make it
306 // available for forward referencing.
307 const Type* refTypeParent = refType->parent();
308 for (const Type* ancestor = this; ancestor != nullptr; ancestor = ancestor->parent()) {
309 if (ancestor == refTypeParent) return OK;
310 }
311
312 std::cerr << "ERROR: Forward reference of '" << refType->typeName() << "' at " << ref.location()
313 << " is not supported.\n"
314 << "C++ forward declaration doesn't support inner types.\n";
315
316 return UNKNOWN_ERROR;
317}
318
Andreas Huber737080b2016-08-02 15:38:04 -0700319const ScalarType *Type::resolveToScalarType() const {
Yi Kong56758da2018-07-24 16:21:37 -0700320 return nullptr;
Andreas Huber737080b2016-08-02 15:38:04 -0700321}
322
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700323bool Type::isValidEnumStorageType() const {
324 const ScalarType *scalarType = resolveToScalarType();
325
Yi Kong56758da2018-07-24 16:21:37 -0700326 if (scalarType == nullptr) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700327 return false;
328 }
329
330 return scalarType->isValidEnumStorageType();
331}
332
Steven Moreland9df52442016-12-12 08:51:14 -0800333bool Type::isElidableType() const {
334 return false;
335}
336
Yifan Hongc6752dc2016-12-20 14:00:14 -0800337bool Type::canCheckEquality() const {
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700338 std::unordered_set<const Type*> visited;
339 return canCheckEquality(&visited);
340}
341
342bool Type::canCheckEquality(std::unordered_set<const Type*>* visited) const {
343 // See isJavaCompatible for similar structure.
344 if (visited->find(this) != visited->end()) {
345 return true;
346 }
347 visited->insert(this);
348 return deepCanCheckEquality(visited);
349}
350
351bool Type::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
Yifan Hongc6752dc2016-12-20 14:00:14 -0800352 return false;
353}
354
Yifan Hong0e192c42018-10-23 15:32:19 -0700355Type::ParseStage Type::getParseStage() const {
356 return mParseStage;
357}
358
359void Type::setParseStage(ParseStage stage) {
360 CHECK(mParseStage < stage);
361 mParseStage = stage;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700362}
363
Timur Iskhakov63f39902017-08-29 15:47:29 -0700364Scope* Type::parent() {
365 return mParent;
366}
367
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700368const Scope* Type::parent() const {
369 return mParent;
370}
371
Yifan Hong3b320f82016-11-01 15:15:54 -0700372std::string Type::getCppType(StorageMode, bool) const {
Steven Moreland47834482018-10-16 16:58:43 -0700373 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700374 return std::string();
375}
376
Yifan Hong3b320f82016-11-01 15:15:54 -0700377std::string Type::decorateCppName(
378 const std::string &name, StorageMode mode, bool specifyNamespaces) const {
379 return getCppType(mode, specifyNamespaces) + " " + name;
380}
381
Yifan Hong4ed13472016-11-02 10:44:11 -0700382std::string Type::getJavaType(bool /* forInitializer */) const {
Steven Moreland47834482018-10-16 16:58:43 -0700383 CHECK(!"Should not be here") << typeName();
Andreas Huber4c865b72016-09-14 15:26:27 -0700384 return std::string();
385}
386
Nirav Atre66842a92018-06-28 18:14:13 -0700387std::string Type::getJavaTypeClass() const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700388 return getJavaType();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700389}
390
Nirav Atre66842a92018-06-28 18:14:13 -0700391std::string Type::getJavaTypeCast(const std::string& objName) const {
392 return "(" + getJavaType() + ") " + objName;
393}
394
Andreas Huber2831d512016-08-15 09:33:47 -0700395std::string Type::getJavaSuffix() const {
Steven Moreland47834482018-10-16 16:58:43 -0700396 CHECK(!"Should not be here") << typeName();
Andreas Huber2831d512016-08-15 09:33:47 -0700397 return std::string();
398}
399
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700400std::string Type::getVtsType() const {
Steven Moreland47834482018-10-16 16:58:43 -0700401 CHECK(!"Should not be here") << typeName();
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700402 return std::string();
403}
404
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800405std::string Type::getVtsValueName() const {
Steven Moreland47834482018-10-16 16:58:43 -0700406 CHECK(!"Should not be here") << typeName();
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800407 return std::string();
408}
409
Andreas Huber881227d2016-08-02 14:20:21 -0700410void Type::emitReaderWriter(
411 Formatter &,
412 const std::string &,
413 const std::string &,
414 bool,
415 bool,
416 ErrorMode) const {
Steven Moreland47834482018-10-16 16:58:43 -0700417 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700418}
419
Yifan Hongbf459bc2016-08-23 16:50:37 -0700420void Type::emitResolveReferences(
421 Formatter &,
422 const std::string &,
423 bool,
424 const std::string &,
425 bool,
426 bool,
427 ErrorMode) const {
Steven Moreland47834482018-10-16 16:58:43 -0700428 CHECK(!"Should not be here") << typeName();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700429}
430
431void Type::emitResolveReferencesEmbedded(
432 Formatter &,
433 size_t,
434 const std::string &,
435 const std::string &,
436 bool,
437 const std::string &,
438 bool,
439 bool,
440 ErrorMode,
441 const std::string &,
442 const std::string &) const {
Steven Moreland47834482018-10-16 16:58:43 -0700443 CHECK(!"Should not be here") << typeName();
Yifan Hongbf459bc2016-08-23 16:50:37 -0700444}
445
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800446void Type::emitDump(
447 Formatter &out,
448 const std::string &streamName,
449 const std::string &name) const {
Hridya Valsaraju9ab1e9e2017-03-10 07:52:23 -0800450 emitDumpWithMethod(out, streamName, "::android::hardware::toString", name);
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800451}
452
453void Type::emitDumpWithMethod(
454 Formatter &out,
455 const std::string &streamName,
456 const std::string &methodName,
457 const std::string &name) const {
458 out << streamName
459 << " += "
460 << methodName
461 << "("
462 << name
463 << ");\n";
464}
465
Yifan Honge45b5302017-02-22 10:49:07 -0800466void Type::emitJavaDump(
467 Formatter &out,
468 const std::string &streamName,
469 const std::string &name) const {
470 out << streamName << ".append(" << name << ");\n";
471}
472
Yifan Hong00f47172016-09-30 14:40:45 -0700473bool Type::useParentInEmitResolveReferencesEmbedded() const {
Yifan Hong244e82d2016-11-11 11:13:57 -0800474 return needsResolveReferences();
475}
476
Andreas Huber881227d2016-08-02 14:20:21 -0700477void Type::emitReaderWriterEmbedded(
478 Formatter &,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700479 size_t,
Andreas Huber881227d2016-08-02 14:20:21 -0700480 const std::string &,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700481 const std::string &,
Andreas Huber881227d2016-08-02 14:20:21 -0700482 bool,
483 const std::string &,
484 bool,
485 bool,
486 ErrorMode,
487 const std::string &,
488 const std::string &) const {
Steven Moreland47834482018-10-16 16:58:43 -0700489 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700490}
491
Andreas Huber2831d512016-08-15 09:33:47 -0700492void Type::emitJavaReaderWriter(
493 Formatter &out,
494 const std::string &parcelObj,
495 const std::string &argName,
496 bool isReader) const {
497 emitJavaReaderWriterWithSuffix(
498 out,
499 parcelObj,
500 argName,
501 isReader,
502 getJavaSuffix(),
503 "" /* extra */);
504}
505
Andreas Huber85eabdb2016-08-25 11:24:49 -0700506void Type::emitJavaFieldInitializer(
507 Formatter &out,
508 const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700509 out << getJavaType()
Andreas Huber85eabdb2016-08-25 11:24:49 -0700510 << " "
511 << fieldName
512 << ";\n";
513}
514
Nirav Atre66842a92018-06-28 18:14:13 -0700515void Type::emitJavaFieldDefaultInitialValue(Formatter &, const std::string &) const {}
516
Andreas Huber85eabdb2016-08-25 11:24:49 -0700517void Type::emitJavaFieldReaderWriter(
518 Formatter &,
Andreas Huber4c865b72016-09-14 15:26:27 -0700519 size_t,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700520 const std::string &,
521 const std::string &,
522 const std::string &,
Andreas Huber709b62d2016-09-19 11:21:18 -0700523 const std::string &,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700524 bool) const {
Steven Moreland47834482018-10-16 16:58:43 -0700525 CHECK(!"Should not be here") << typeName();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700526}
527
Andreas Huber881227d2016-08-02 14:20:21 -0700528void Type::handleError(Formatter &out, ErrorMode mode) const {
529 switch (mode) {
530 case ErrorMode_Ignore:
531 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700532 out << "/* _hidl_err ignored! */\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700533 break;
534 }
535
536 case ErrorMode_Goto:
537 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700538 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700539 break;
540 }
541
542 case ErrorMode_Break:
543 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700544 out << "if (_hidl_err != ::android::OK) { break; }\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700545 break;
546 }
Andreas Huber737080b2016-08-02 15:38:04 -0700547
548 case ErrorMode_Return:
549 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700550 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
Andreas Huber737080b2016-08-02 15:38:04 -0700551 break;
552 }
Andreas Huber881227d2016-08-02 14:20:21 -0700553 }
554}
555
Andreas Huber881227d2016-08-02 14:20:21 -0700556void Type::emitReaderWriterEmbeddedForTypeName(
557 Formatter &out,
558 const std::string &name,
559 bool nameIsPointer,
560 const std::string &parcelObj,
561 bool parcelObjIsPointer,
562 bool isReader,
563 ErrorMode mode,
564 const std::string &parentName,
565 const std::string &offsetText,
566 const std::string &typeName,
Yifan Hong244e82d2016-11-11 11:13:57 -0800567 const std::string &childName,
568 const std::string &funcNamespace) const {
569
570 const std::string parcelObjDeref =
Andreas Huber881227d2016-08-02 14:20:21 -0700571 parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
572
573 const std::string parcelObjPointer =
574 parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
575
Yifan Hong244e82d2016-11-11 11:13:57 -0800576 const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
Andreas Huber881227d2016-08-02 14:20:21 -0700577 const std::string namePointer = nameIsPointer ? name : ("&" + name);
578
Iliyan Malchev549e2592016-08-10 08:59:12 -0700579 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -0700580
Yifan Hong244e82d2016-11-11 11:13:57 -0800581 if (!funcNamespace.empty()) {
582 out << funcNamespace << "::";
583 }
584
585 out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
586
587 out.indent();
588 out.indent();
589
Andreas Huber881227d2016-08-02 14:20:21 -0700590 if (isReader) {
591 out << "const_cast<"
592 << typeName
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700593 << " &>("
594 << nameDerefed
Yifan Hong244e82d2016-11-11 11:13:57 -0800595 << "),\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700596 } else {
Yifan Hong244e82d2016-11-11 11:13:57 -0800597 out << nameDerefed
598 << ",\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700599 }
600
Andreas Huber881227d2016-08-02 14:20:21 -0700601 out << (isReader ? parcelObjDeref : parcelObjPointer)
602 << ",\n"
603 << parentName
604 << ",\n"
605 << offsetText;
606
607 if (!childName.empty()) {
608 out << ", &"
609 << childName;
610 }
611
612 out << ");\n\n";
613
614 out.unindent();
615 out.unindent();
616
617 handleError(out, mode);
618}
619
Steven Moreland368e4602018-02-16 14:21:49 -0800620void Type::emitTypeDeclarations(Formatter&) const {}
Andreas Huber881227d2016-08-02 14:20:21 -0700621
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700622void Type::emitTypeForwardDeclaration(Formatter&) const {}
623
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800624void Type::emitGlobalTypeDeclarations(Formatter&) const {}
625
Steven Moreland368e4602018-02-16 14:21:49 -0800626void Type::emitPackageTypeDeclarations(Formatter&) const {}
Andreas Hubere3f769a2016-10-10 10:54:44 -0700627
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700628void Type::emitPackageTypeHeaderDefinitions(Formatter&) const {}
629
Steven Moreland368e4602018-02-16 14:21:49 -0800630void Type::emitPackageHwDeclarations(Formatter&) const {}
Yifan Hong244e82d2016-11-11 11:13:57 -0800631
Steven Moreland368e4602018-02-16 14:21:49 -0800632void Type::emitTypeDefinitions(Formatter&, const std::string&) const {}
Andreas Huber881227d2016-08-02 14:20:21 -0700633
Steven Moreland368e4602018-02-16 14:21:49 -0800634void Type::emitJavaTypeDeclarations(Formatter&, bool) const {}
Andreas Huber2831d512016-08-15 09:33:47 -0700635
Andreas Huber881227d2016-08-02 14:20:21 -0700636bool Type::needsEmbeddedReadWrite() const {
637 return false;
638}
639
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700640bool Type::resultNeedsDeref() const {
Yifan Hongbf459bc2016-08-23 16:50:37 -0700641 return false;
642}
643
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700644bool Type::needsResolveReferences() const {
645 std::unordered_set<const Type*> visited;
646 return needsResolveReferences(&visited);
647}
648
649bool Type::needsResolveReferences(std::unordered_set<const Type*>* visited) const {
650 // See isJavaCompatible for similar structure.
651 if (visited->find(this) != visited->end()) {
652 return false;
653 }
654 visited->insert(this);
655 return deepNeedsResolveReferences(visited);
656}
657
658bool Type::deepNeedsResolveReferences(std::unordered_set<const Type*>* /* visited */) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700659 return false;
660}
661
Yifan Hong3b320f82016-11-01 15:15:54 -0700662std::string Type::getCppStackType(bool specifyNamespaces) const {
663 return getCppType(StorageMode_Stack, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700664}
665
Yifan Hong3b320f82016-11-01 15:15:54 -0700666std::string Type::getCppResultType(bool specifyNamespaces) const {
667 return getCppType(StorageMode_Result, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700668}
669
Yifan Hong3b320f82016-11-01 15:15:54 -0700670std::string Type::getCppArgumentType(bool specifyNamespaces) const {
671 return getCppType(StorageMode_Argument, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700672}
673
Nirav Atreca7a5022018-06-29 20:43:49 -0700674std::string Type::getCppTypeCast(const std::string& objName, bool specifyNamespaces) const {
675 return "(" + getCppStackType(specifyNamespaces) + ") " + objName;
676}
677
Andreas Huber2831d512016-08-15 09:33:47 -0700678void Type::emitJavaReaderWriterWithSuffix(
679 Formatter &out,
680 const std::string &parcelObj,
681 const std::string &argName,
682 bool isReader,
683 const std::string &suffix,
684 const std::string &extra) const {
685 out << parcelObj
686 << "."
687 << (isReader ? "read" : "write")
688 << suffix
689 << "(";
690
691 if (isReader) {
692 out << extra;
693 } else {
694 out << (extra.empty() ? "" : (extra + ", "));
695 out << argName;
696 }
697
698 out << ");\n";
699}
700
Steven Moreland368e4602018-02-16 14:21:49 -0800701void Type::emitVtsTypeDeclarations(Formatter&) const {}
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700702
Steven Moreland368e4602018-02-16 14:21:49 -0800703void Type::emitVtsAttributeType(Formatter& out) const {
704 emitVtsTypeDeclarations(out);
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700705}
706
Andreas Huber70a59e12016-08-16 12:57:01 -0700707bool Type::isJavaCompatible() const {
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700708 std::unordered_set<const Type*> visited;
709 return isJavaCompatible(&visited);
710}
711
712bool Type::containsPointer() const {
713 std::unordered_set<const Type*> visited;
714 return containsPointer(&visited);
715}
716
717bool Type::isJavaCompatible(std::unordered_set<const Type*>* visited) const {
718 // We need to find al least one path from requested vertex
719 // to not java compatible.
720 // That means that if we have already visited some vertex,
721 // there is no need to determine whether it is java compatible
722 // (and we can assume that it is java compatible),
723 // as if not, the information about that would appear in the
724 // requested vertex through another path.
725 if (visited->find(this) != visited->end()) {
726 return true;
727 }
728 visited->insert(this);
729 return deepIsJavaCompatible(visited);
730}
731
732bool Type::containsPointer(std::unordered_set<const Type*>* visited) const {
733 // See isJavaCompatible for similar structure.
734 if (visited->find(this) != visited->end()) {
735 return false;
736 }
737 visited->insert(this);
738 return deepContainsPointer(visited);
739}
740
741bool Type::deepIsJavaCompatible(std::unordered_set<const Type*>* /* visited */) const {
Andreas Huber70a59e12016-08-16 12:57:01 -0700742 return true;
743}
744
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700745bool Type::deepContainsPointer(std::unordered_set<const Type*>* /* visited */) const {
746 return false;
747}
748
Andreas Huber60d3b222017-03-30 09:10:56 -0700749void Type::getAlignmentAndSize(
750 size_t * /* align */, size_t * /* size */) const {
751 CHECK(!"Should not be here.");
752}
753
Andreas Huber019d21d2016-10-03 12:59:47 -0700754void Type::appendToExportedTypesVector(
755 std::vector<const Type *> * /* exportedTypes */) const {
756}
757
Steven Moreland368e4602018-02-16 14:21:49 -0800758void Type::emitExportedHeader(Formatter& /* out */, bool /* forJava */) const {}
Andreas Huber019d21d2016-10-03 12:59:47 -0700759
Timur Iskhakovff5e64a2017-09-11 14:56:18 -0700760bool Type::isNeverStrongReference() const {
761 return false;
762}
763
Yifan Hongbf459bc2016-08-23 16:50:37 -0700764////////////////////////////////////////
765
Timur Iskhakov63f39902017-08-29 15:47:29 -0700766TemplatedType::TemplatedType(Scope* parent) : Type(parent) {}
Steven Moreland30bb6a82016-11-30 09:18:34 -0800767
Timur Iskhakov3f1d26e2017-08-30 15:35:53 -0700768std::string TemplatedType::typeName() const {
769 return templatedTypeName() + " of " + mElementType->typeName();
770}
771
Timur Iskhakov505316c2017-08-05 03:38:59 +0000772void TemplatedType::setElementType(const Reference<Type>& elementType) {
773 // can only be set once.
774 CHECK(mElementType.isEmptyReference());
775 CHECK(!elementType.isEmptyReference());
776
Yifan Hongbf459bc2016-08-23 16:50:37 -0700777 mElementType = elementType;
778}
779
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700780const Type* TemplatedType::getElementType() const {
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700781 return mElementType.get();
Yifan Hongabf73ee2016-12-05 18:47:00 -0800782}
783
784bool TemplatedType::isTemplatedType() const {
785 return true;
786}
787
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700788std::vector<const Reference<Type>*> TemplatedType::getReferences() const {
789 return {&mElementType};
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700790}
791
792status_t TemplatedType::validate() const {
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700793 if (!isCompatibleElementType(mElementType.get())) {
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700794 std::cerr << "ERROR: " << typeName() /* contains element type */
795 << " is not supported at " << mElementType.location() << "\n";
796 return UNKNOWN_ERROR;
797 }
798
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700799 return Type::validate();
800}
801
Steven Moreland368e4602018-02-16 14:21:49 -0800802void TemplatedType::emitVtsTypeDeclarations(Formatter& out) const {
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800803 out << "type: " << getVtsType() << "\n";
804 out << getVtsValueName() << ": {\n";
805 out.indent();
Steven Moreland368e4602018-02-16 14:21:49 -0800806 mElementType->emitVtsTypeDeclarations(out);
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800807 out.unindent();
808 out << "}\n";
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800809}
810
Steven Moreland368e4602018-02-16 14:21:49 -0800811void TemplatedType::emitVtsAttributeType(Formatter& out) const {
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800812 out << "type: " << getVtsType() << "\n";
813 out << getVtsValueName() << ": {\n";
814 out.indent();
Steven Moreland368e4602018-02-16 14:21:49 -0800815 mElementType->emitVtsAttributeType(out);
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800816 out.unindent();
817 out << "}\n";
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800818}
Timur Iskhakov505316c2017-08-05 03:38:59 +0000819
Andreas Huberc9410c72016-07-28 12:18:40 -0700820} // namespace android
821