blob: 9eab914ba7aee0888e707cb78c0076929ba0e72c [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>
Neel Mehta3b414a82019-07-02 15:47:48 -070028#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070029
Andreas Huberc9410c72016-07-28 12:18:40 -070030namespace android {
31
Neel Mehta3b414a82019-07-02 15:47:48 -070032Type::Type(Scope* parent, const std::string& definedName)
33 : mDefinedName(definedName), mParent(parent) {}
Andreas Huber7c5ddfb2016-09-29 13:45:22 -070034
Andreas Huberc9410c72016-07-28 12:18:40 -070035Type::~Type() {}
36
Andreas Huber5345ec22016-07-29 13:33:27 -070037bool Type::isScope() const {
38 return false;
39}
40
Andreas Hubera2723d22016-07-29 15:36:07 -070041bool Type::isInterface() const {
42 return false;
43}
44
Yifan Hongabf73ee2016-12-05 18:47:00 -080045bool Type::isScalar() const {
46 return false;
47}
48
49bool Type::isString() const {
50 return false;
51}
52
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070053bool Type::isEnum() const {
54 return false;
55}
56
Yifan Hongabf73ee2016-12-05 18:47:00 -080057bool Type::isBitField() const {
58 return false;
59}
60
61bool Type::isHandle() const {
62 return false;
63}
64
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070065bool Type::isTypeDef() const {
66 return false;
67}
68
Andreas Huber39fa7182016-08-19 14:27:33 -070069bool Type::isNamedType() const {
70 return false;
71}
72
Steven Moreland397b5e12017-06-08 14:02:26 -070073bool Type::isMemory() const {
74 return false;
75}
76
Andreas Huberf630bc82016-09-09 14:52:25 -070077bool Type::isCompoundType() const {
78 return false;
79}
80
Andreas Huber709b62d2016-09-19 11:21:18 -070081bool Type::isArray() const {
82 return false;
83}
84
85bool Type::isVector() const {
86 return false;
87}
88
Yifan Hongabf73ee2016-12-05 18:47:00 -080089bool Type::isTemplatedType() const {
90 return false;
91}
92
Martijn Coenen99e6beb2016-12-01 15:48:42 +010093bool Type::isPointer() const {
94 return false;
95}
96
Neel Mehtad3375f12019-08-19 09:58:46 -070097bool Type::isFmq() const {
98 return false;
99}
100
Timur Iskhakovdbaed332017-08-31 16:33:41 -0700101Type* Type::resolve() {
102 return const_cast<Type*>(static_cast<const Type*>(this)->resolve());
103}
104
105const Type* Type::resolve() const {
106 return this;
107}
108
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700109std::vector<Type*> Type::getDefinedTypes() {
110 const auto& constRet = static_cast<const Type*>(this)->getDefinedTypes();
111 std::vector<Type*> ret(constRet.size());
112 std::transform(constRet.begin(), constRet.end(), ret.begin(),
113 [](const auto* type) { return const_cast<Type*>(type); });
114 return ret;
115}
116
117std::vector<const Type*> Type::getDefinedTypes() const {
Timur Iskhakov33431e62017-08-21 17:31:23 -0700118 return {};
119}
120
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700121std::vector<Reference<Type>*> Type::getReferences() {
122 const auto& constRet = static_cast<const Type*>(this)->getReferences();
123 std::vector<Reference<Type>*> ret(constRet.size());
124 std::transform(constRet.begin(), constRet.end(), ret.begin(),
125 [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
126 return ret;
127}
128
129std::vector<const Reference<Type>*> Type::getReferences() const {
Timur Iskhakov33431e62017-08-21 17:31:23 -0700130 return {};
131}
132
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700133std::vector<ConstantExpression*> Type::getConstantExpressions() {
134 const auto& constRet = static_cast<const Type*>(this)->getConstantExpressions();
135 std::vector<ConstantExpression*> ret(constRet.size());
136 std::transform(constRet.begin(), constRet.end(), ret.begin(),
137 [](const auto* ce) { return const_cast<ConstantExpression*>(ce); });
138 return ret;
139}
140
141std::vector<const ConstantExpression*> Type::getConstantExpressions() const {
Timur Iskhakov891a8662017-08-25 21:53:48 -0700142 return {};
143}
144
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700145std::vector<Reference<Type>*> Type::getStrongReferences() {
146 const auto& constRet = static_cast<const Type*>(this)->getStrongReferences();
147 std::vector<Reference<Type>*> ret(constRet.size());
148 std::transform(constRet.begin(), constRet.end(), ret.begin(),
149 [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
150 return ret;
151}
152
153std::vector<const Reference<Type>*> Type::getStrongReferences() const {
Timur Iskhakovff5e64a2017-09-11 14:56:18 -0700154 std::vector<const Reference<Type>*> ret;
155 for (const auto* ref : getReferences()) {
156 if (!ref->shallowGet()->isNeverStrongReference()) {
157 ret.push_back(ref);
158 }
159 }
160 return ret;
Timur Iskhakov40731af2017-08-24 14:18:35 -0700161}
162
Yifan Hong0e192c42018-10-23 15:32:19 -0700163status_t Type::recursivePass(ParseStage stage, const std::function<status_t(Type*)>& func,
Timur Iskhakov33431e62017-08-21 17:31:23 -0700164 std::unordered_set<const Type*>* visited) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700165 if (mParseStage > stage) return OK;
166 if (mParseStage < stage) return UNKNOWN_ERROR;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700167
Timur Iskhakov33431e62017-08-21 17:31:23 -0700168 if (visited->find(this) != visited->end()) return OK;
169 visited->insert(this);
170
171 status_t err = func(this);
172 if (err != OK) return err;
173
174 for (auto* nextType : getDefinedTypes()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700175 err = nextType->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700176 if (err != OK) return err;
177 }
178
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700179 for (auto* nextRef : getReferences()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700180 err = nextRef->shallowGet()->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700181 if (err != OK) return err;
182 }
183
184 return OK;
185}
186
Yifan Hong0e192c42018-10-23 15:32:19 -0700187status_t Type::recursivePass(ParseStage stage, const std::function<status_t(const Type*)>& func,
Timur Iskhakov33431e62017-08-21 17:31:23 -0700188 std::unordered_set<const Type*>* visited) const {
Yifan Hong0e192c42018-10-23 15:32:19 -0700189 if (mParseStage > stage) return OK;
190 if (mParseStage < stage) return UNKNOWN_ERROR;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700191
Timur Iskhakov33431e62017-08-21 17:31:23 -0700192 if (visited->find(this) != visited->end()) return OK;
193 visited->insert(this);
194
195 status_t err = func(this);
196 if (err != OK) return err;
197
198 for (const auto* nextType : getDefinedTypes()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700199 err = nextType->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700200 if (err != OK) return err;
201 }
202
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700203 for (const auto* nextRef : getReferences()) {
Yifan Hong0e192c42018-10-23 15:32:19 -0700204 err = nextRef->shallowGet()->recursivePass(stage, func, visited);
Timur Iskhakov33431e62017-08-21 17:31:23 -0700205 if (err != OK) return err;
206 }
207
208 return OK;
209}
210
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700211status_t Type::resolveInheritance() {
212 return OK;
213}
214
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700215status_t Type::validate() const {
216 return OK;
217}
218
Timur Iskhakov40731af2017-08-24 14:18:35 -0700219Type::CheckAcyclicStatus::CheckAcyclicStatus(status_t status, const Type* cycleEnd)
220 : status(status), cycleEnd(cycleEnd) {
221 CHECK(cycleEnd == nullptr || status != OK);
222}
223
Timur Iskhakov458ca362017-09-12 23:16:03 -0700224Type::CheckAcyclicStatus Type::topologicalOrder(
225 std::unordered_map<const Type*, size_t>* reversedOrder,
226 std::unordered_set<const Type*>* stack) const {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700227 if (stack->find(this) != stack->end()) {
228 std::cerr << "ERROR: Cyclic declaration:\n";
229 return CheckAcyclicStatus(UNKNOWN_ERROR, this);
230 }
231
Timur Iskhakov458ca362017-09-12 23:16:03 -0700232 if (reversedOrder->find(this) != reversedOrder->end()) return CheckAcyclicStatus(OK);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700233 stack->insert(this);
234
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700235 for (const auto* nextType : getDefinedTypes()) {
Timur Iskhakov458ca362017-09-12 23:16:03 -0700236 auto err = nextType->topologicalOrder(reversedOrder, stack);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700237
238 if (err.status != OK) {
239 if (err.cycleEnd == nullptr) return err;
240
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700241 std::cerr << " '" << nextType->typeName() << "' in '" << typeName() << "'";
Timur Iskhakov40731af2017-08-24 14:18:35 -0700242 if (nextType->isNamedType()) {
243 std::cerr << " at " << static_cast<const NamedType*>(nextType)->location();
244 }
245 std::cerr << "\n";
246
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700247 if (err.cycleEnd == this) {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700248 return CheckAcyclicStatus(err.status);
249 }
250 return err;
251 }
252 }
253
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700254 for (const auto* nextRef : getStrongReferences()) {
Timur Iskhakovdbaed332017-08-31 16:33:41 -0700255 const auto* nextType = nextRef->shallowGet();
Timur Iskhakov458ca362017-09-12 23:16:03 -0700256 auto err = nextType->topologicalOrder(reversedOrder, stack);
Timur Iskhakov40731af2017-08-24 14:18:35 -0700257
258 if (err.status != OK) {
259 if (err.cycleEnd == nullptr) return err;
260
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700261 std::cerr << " '" << nextType->typeName() << "' in '" << typeName() << "' at "
262 << nextRef->location() << "\n";
Timur Iskhakov40731af2017-08-24 14:18:35 -0700263
Timur Iskhakov308d0f52017-08-31 14:18:46 -0700264 if (err.cycleEnd == this) {
Timur Iskhakov40731af2017-08-24 14:18:35 -0700265 return CheckAcyclicStatus(err.status);
266 }
267 return err;
268 }
269 }
270
271 CHECK(stack->find(this) != stack->end());
272 stack->erase(this);
Timur Iskhakov458ca362017-09-12 23:16:03 -0700273
274 CHECK(reversedOrder->find(this) == reversedOrder->end());
275 // Do not call insert and size in one statement to not rely on
276 // evaluation order.
277 size_t index = reversedOrder->size();
278 reversedOrder->insert({this, index});
279
Timur Iskhakov40731af2017-08-24 14:18:35 -0700280 return CheckAcyclicStatus(OK);
281}
282
Timur Iskhakov458ca362017-09-12 23:16:03 -0700283status_t Type::checkForwardReferenceRestrictions(const Reference<Type>& ref) const {
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700284 const Location& refLoc = ref.location();
285 const Type* refType = ref.shallowGet();
286
287 // Not NamedTypes are avaiable everywhere.
Timur Iskhakov78821ed2017-09-09 23:40:13 -0700288 // Only ArrayType and TemplatedType contain additional types in
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700289 // their reference (which is actually a part of type definition),
290 // so they are proceeded in this case.
291 //
292 // If we support named templated types one day, we will need to change
293 // this logic.
294 if (!refType->isNamedType()) {
Timur Iskhakov458ca362017-09-12 23:16:03 -0700295 for (const Reference<Type>* innerRef : refType->getReferences()) {
296 status_t err = checkForwardReferenceRestrictions(*innerRef);
297 if (err != OK) return err;
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700298 }
299 return OK;
300 }
301
302 const Location& typeLoc = static_cast<const NamedType*>(refType)->location();
303
304 // If referenced type is declared in another file or before reference,
305 // there is no forward reference here.
306 if (!Location::inSameFile(refLoc, typeLoc) ||
307 (!Location::intersect(refLoc, typeLoc) && typeLoc < refLoc)) {
308 return OK;
309 }
310
311 // Type must be declared somewhere in the current stack to make it
312 // available for forward referencing.
313 const Type* refTypeParent = refType->parent();
314 for (const Type* ancestor = this; ancestor != nullptr; ancestor = ancestor->parent()) {
315 if (ancestor == refTypeParent) return OK;
316 }
317
318 std::cerr << "ERROR: Forward reference of '" << refType->typeName() << "' at " << ref.location()
319 << " is not supported.\n"
320 << "C++ forward declaration doesn't support inner types.\n";
321
322 return UNKNOWN_ERROR;
323}
324
Andreas Huber737080b2016-08-02 15:38:04 -0700325const ScalarType *Type::resolveToScalarType() const {
Yi Kong56758da2018-07-24 16:21:37 -0700326 return nullptr;
Andreas Huber737080b2016-08-02 15:38:04 -0700327}
328
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700329bool Type::isValidEnumStorageType() const {
330 const ScalarType *scalarType = resolveToScalarType();
331
Yi Kong56758da2018-07-24 16:21:37 -0700332 if (scalarType == nullptr) {
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700333 return false;
334 }
335
336 return scalarType->isValidEnumStorageType();
337}
338
Steven Moreland9df52442016-12-12 08:51:14 -0800339bool Type::isElidableType() const {
340 return false;
341}
342
Yifan Hongc6752dc2016-12-20 14:00:14 -0800343bool Type::canCheckEquality() const {
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700344 std::unordered_set<const Type*> visited;
345 return canCheckEquality(&visited);
346}
347
348bool Type::canCheckEquality(std::unordered_set<const Type*>* visited) const {
349 // See isJavaCompatible for similar structure.
350 if (visited->find(this) != visited->end()) {
351 return true;
352 }
353 visited->insert(this);
354 return deepCanCheckEquality(visited);
355}
356
357bool Type::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
Yifan Hongc6752dc2016-12-20 14:00:14 -0800358 return false;
359}
360
Yifan Hong0e192c42018-10-23 15:32:19 -0700361Type::ParseStage Type::getParseStage() const {
362 return mParseStage;
363}
364
365void Type::setParseStage(ParseStage stage) {
366 CHECK(mParseStage < stage);
367 mParseStage = stage;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700368}
369
Timur Iskhakov63f39902017-08-29 15:47:29 -0700370Scope* Type::parent() {
371 return mParent;
372}
373
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700374const Scope* Type::parent() const {
375 return mParent;
376}
377
Neel Mehta3b414a82019-07-02 15:47:48 -0700378const std::string& Type::definedName() const {
379 return mDefinedName;
380}
381
Yifan Hong3b320f82016-11-01 15:15:54 -0700382std::string Type::getCppType(StorageMode, bool) const {
Steven Moreland47834482018-10-16 16:58:43 -0700383 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700384 return std::string();
385}
386
Yifan Hong3b320f82016-11-01 15:15:54 -0700387std::string Type::decorateCppName(
388 const std::string &name, StorageMode mode, bool specifyNamespaces) const {
389 return getCppType(mode, specifyNamespaces) + " " + name;
390}
391
Yifan Hong4ed13472016-11-02 10:44:11 -0700392std::string Type::getJavaType(bool /* forInitializer */) const {
Steven Moreland47834482018-10-16 16:58:43 -0700393 CHECK(!"Should not be here") << typeName();
Andreas Huber4c865b72016-09-14 15:26:27 -0700394 return std::string();
395}
396
Nirav Atre66842a92018-06-28 18:14:13 -0700397std::string Type::getJavaTypeClass() const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700398 return getJavaType();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700399}
400
Nirav Atre66842a92018-06-28 18:14:13 -0700401std::string Type::getJavaTypeCast(const std::string& objName) const {
402 return "(" + getJavaType() + ") " + objName;
403}
404
Andreas Huber2831d512016-08-15 09:33:47 -0700405std::string Type::getJavaSuffix() const {
Steven Moreland47834482018-10-16 16:58:43 -0700406 CHECK(!"Should not be here") << typeName();
Andreas Huber2831d512016-08-15 09:33:47 -0700407 return std::string();
408}
409
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700410std::string Type::getVtsType() const {
Steven Moreland47834482018-10-16 16:58:43 -0700411 CHECK(!"Should not be here") << typeName();
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700412 return std::string();
413}
414
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800415std::string Type::getVtsValueName() const {
Steven Moreland47834482018-10-16 16:58:43 -0700416 CHECK(!"Should not be here") << typeName();
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800417 return std::string();
418}
419
Andreas Huber881227d2016-08-02 14:20:21 -0700420void Type::emitReaderWriter(
421 Formatter &,
422 const std::string &,
423 const std::string &,
424 bool,
425 bool,
426 ErrorMode) const {
Steven Moreland47834482018-10-16 16:58:43 -0700427 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700428}
429
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800430void Type::emitDump(
431 Formatter &out,
432 const std::string &streamName,
433 const std::string &name) const {
Hridya Valsaraju9ab1e9e2017-03-10 07:52:23 -0800434 emitDumpWithMethod(out, streamName, "::android::hardware::toString", name);
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800435}
436
437void Type::emitDumpWithMethod(
438 Formatter &out,
439 const std::string &streamName,
440 const std::string &methodName,
441 const std::string &name) const {
442 out << streamName
443 << " += "
444 << methodName
445 << "("
446 << name
447 << ");\n";
448}
449
Yifan Honge45b5302017-02-22 10:49:07 -0800450void Type::emitJavaDump(
451 Formatter &out,
452 const std::string &streamName,
453 const std::string &name) const {
454 out << streamName << ".append(" << name << ");\n";
455}
456
Andreas Huber881227d2016-08-02 14:20:21 -0700457void Type::emitReaderWriterEmbedded(
458 Formatter &,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700459 size_t,
Andreas Huber881227d2016-08-02 14:20:21 -0700460 const std::string &,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700461 const std::string &,
Andreas Huber881227d2016-08-02 14:20:21 -0700462 bool,
463 const std::string &,
464 bool,
465 bool,
466 ErrorMode,
467 const std::string &,
468 const std::string &) const {
Steven Moreland47834482018-10-16 16:58:43 -0700469 CHECK(!"Should not be here") << typeName();
Andreas Huber881227d2016-08-02 14:20:21 -0700470}
471
Andreas Huber2831d512016-08-15 09:33:47 -0700472void Type::emitJavaReaderWriter(
473 Formatter &out,
474 const std::string &parcelObj,
475 const std::string &argName,
476 bool isReader) const {
477 emitJavaReaderWriterWithSuffix(
478 out,
479 parcelObj,
480 argName,
481 isReader,
482 getJavaSuffix(),
483 "" /* extra */);
484}
485
Andreas Huber85eabdb2016-08-25 11:24:49 -0700486void Type::emitJavaFieldInitializer(
487 Formatter &out,
488 const std::string &fieldName) const {
Yifan Hong4ed13472016-11-02 10:44:11 -0700489 out << getJavaType()
Andreas Huber85eabdb2016-08-25 11:24:49 -0700490 << " "
491 << fieldName
492 << ";\n";
493}
494
Nirav Atre66842a92018-06-28 18:14:13 -0700495void Type::emitJavaFieldDefaultInitialValue(Formatter &, const std::string &) const {}
496
Andreas Huber85eabdb2016-08-25 11:24:49 -0700497void Type::emitJavaFieldReaderWriter(
498 Formatter &,
Andreas Huber4c865b72016-09-14 15:26:27 -0700499 size_t,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700500 const std::string &,
501 const std::string &,
502 const std::string &,
Andreas Huber709b62d2016-09-19 11:21:18 -0700503 const std::string &,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700504 bool) const {
Steven Moreland47834482018-10-16 16:58:43 -0700505 CHECK(!"Should not be here") << typeName();
Andreas Huber85eabdb2016-08-25 11:24:49 -0700506}
507
Steven Moreland48cc6042019-04-30 11:28:56 -0700508void Type::handleError(Formatter &out, ErrorMode mode) {
Andreas Huber881227d2016-08-02 14:20:21 -0700509 switch (mode) {
Andreas Huber881227d2016-08-02 14:20:21 -0700510 case ErrorMode_Goto:
511 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700512 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700513 break;
514 }
515
516 case ErrorMode_Break:
517 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700518 out << "if (_hidl_err != ::android::OK) { break; }\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700519 break;
520 }
Andreas Huber737080b2016-08-02 15:38:04 -0700521
522 case ErrorMode_Return:
523 {
Iliyan Malchev549e2592016-08-10 08:59:12 -0700524 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
Andreas Huber737080b2016-08-02 15:38:04 -0700525 break;
526 }
Steven Moreland48cc6042019-04-30 11:28:56 -0700527
528 case ErrorMode_ReturnNothing:
529 {
530 out << "if (_hidl_err != ::android::OK) { return; }\n\n";
531 break;
532 }
533 default:
534 {
535 LOG(FATAL) << "Should not be here";
536 }
Andreas Huber881227d2016-08-02 14:20:21 -0700537 }
538}
539
Andreas Huber881227d2016-08-02 14:20:21 -0700540void Type::emitReaderWriterEmbeddedForTypeName(
541 Formatter &out,
542 const std::string &name,
543 bool nameIsPointer,
544 const std::string &parcelObj,
545 bool parcelObjIsPointer,
546 bool isReader,
547 ErrorMode mode,
548 const std::string &parentName,
549 const std::string &offsetText,
550 const std::string &typeName,
Yifan Hong244e82d2016-11-11 11:13:57 -0800551 const std::string &childName,
552 const std::string &funcNamespace) const {
553
554 const std::string parcelObjDeref =
Andreas Huber881227d2016-08-02 14:20:21 -0700555 parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
556
557 const std::string parcelObjPointer =
558 parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
559
Yifan Hong244e82d2016-11-11 11:13:57 -0800560 const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
Andreas Huber881227d2016-08-02 14:20:21 -0700561 const std::string namePointer = nameIsPointer ? name : ("&" + name);
562
Iliyan Malchev549e2592016-08-10 08:59:12 -0700563 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -0700564
Yifan Hong244e82d2016-11-11 11:13:57 -0800565 if (!funcNamespace.empty()) {
566 out << funcNamespace << "::";
567 }
568
569 out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
570
571 out.indent();
572 out.indent();
573
Andreas Huber881227d2016-08-02 14:20:21 -0700574 if (isReader) {
575 out << "const_cast<"
576 << typeName
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700577 << " &>("
578 << nameDerefed
Yifan Hong244e82d2016-11-11 11:13:57 -0800579 << "),\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700580 } else {
Yifan Hong244e82d2016-11-11 11:13:57 -0800581 out << nameDerefed
582 << ",\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700583 }
584
Andreas Huber881227d2016-08-02 14:20:21 -0700585 out << (isReader ? parcelObjDeref : parcelObjPointer)
586 << ",\n"
587 << parentName
588 << ",\n"
589 << offsetText;
590
591 if (!childName.empty()) {
592 out << ", &"
593 << childName;
594 }
595
596 out << ");\n\n";
597
598 out.unindent();
599 out.unindent();
600
601 handleError(out, mode);
602}
603
Neel Mehta3b414a82019-07-02 15:47:48 -0700604void Type::emitHidlDefinition(Formatter&) const {
605 CHECK(!"Should not be here.") << typeName();
606}
607
Steven Moreland368e4602018-02-16 14:21:49 -0800608void Type::emitTypeDeclarations(Formatter&) const {}
Andreas Huber881227d2016-08-02 14:20:21 -0700609
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700610void Type::emitTypeForwardDeclaration(Formatter&) const {}
611
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800612void Type::emitGlobalTypeDeclarations(Formatter&) const {}
613
Steven Moreland368e4602018-02-16 14:21:49 -0800614void Type::emitPackageTypeDeclarations(Formatter&) const {}
Andreas Hubere3f769a2016-10-10 10:54:44 -0700615
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700616void Type::emitPackageTypeHeaderDefinitions(Formatter&) const {}
617
Steven Moreland368e4602018-02-16 14:21:49 -0800618void Type::emitPackageHwDeclarations(Formatter&) const {}
Yifan Hong244e82d2016-11-11 11:13:57 -0800619
Steven Moreland368e4602018-02-16 14:21:49 -0800620void Type::emitTypeDefinitions(Formatter&, const std::string&) const {}
Andreas Huber881227d2016-08-02 14:20:21 -0700621
Steven Moreland368e4602018-02-16 14:21:49 -0800622void Type::emitJavaTypeDeclarations(Formatter&, bool) const {}
Andreas Huber2831d512016-08-15 09:33:47 -0700623
Andreas Huber881227d2016-08-02 14:20:21 -0700624bool Type::needsEmbeddedReadWrite() const {
625 return false;
626}
627
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700628bool Type::resultNeedsDeref() const {
Yifan Hongbf459bc2016-08-23 16:50:37 -0700629 return false;
630}
631
Yifan Hong3b320f82016-11-01 15:15:54 -0700632std::string Type::getCppStackType(bool specifyNamespaces) const {
633 return getCppType(StorageMode_Stack, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700634}
635
Yifan Hong3b320f82016-11-01 15:15:54 -0700636std::string Type::getCppResultType(bool specifyNamespaces) const {
637 return getCppType(StorageMode_Result, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700638}
639
Yifan Hong3b320f82016-11-01 15:15:54 -0700640std::string Type::getCppArgumentType(bool specifyNamespaces) const {
641 return getCppType(StorageMode_Argument, specifyNamespaces);
Andreas Huber881227d2016-08-02 14:20:21 -0700642}
643
Nirav Atreca7a5022018-06-29 20:43:49 -0700644std::string Type::getCppTypeCast(const std::string& objName, bool specifyNamespaces) const {
645 return "(" + getCppStackType(specifyNamespaces) + ") " + objName;
646}
647
Andreas Huber2831d512016-08-15 09:33:47 -0700648void Type::emitJavaReaderWriterWithSuffix(
649 Formatter &out,
650 const std::string &parcelObj,
651 const std::string &argName,
652 bool isReader,
653 const std::string &suffix,
654 const std::string &extra) const {
655 out << parcelObj
656 << "."
657 << (isReader ? "read" : "write")
658 << suffix
659 << "(";
660
661 if (isReader) {
662 out << extra;
663 } else {
664 out << (extra.empty() ? "" : (extra + ", "));
665 out << argName;
666 }
667
668 out << ");\n";
669}
670
Steven Moreland368e4602018-02-16 14:21:49 -0800671void Type::emitVtsTypeDeclarations(Formatter&) const {}
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700672
Steven Moreland368e4602018-02-16 14:21:49 -0800673void Type::emitVtsAttributeType(Formatter& out) const {
674 emitVtsTypeDeclarations(out);
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700675}
676
Andreas Huber70a59e12016-08-16 12:57:01 -0700677bool Type::isJavaCompatible() const {
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700678 std::unordered_set<const Type*> visited;
679 return isJavaCompatible(&visited);
680}
681
682bool Type::containsPointer() const {
683 std::unordered_set<const Type*> visited;
684 return containsPointer(&visited);
685}
686
687bool Type::isJavaCompatible(std::unordered_set<const Type*>* visited) const {
688 // We need to find al least one path from requested vertex
689 // to not java compatible.
690 // That means that if we have already visited some vertex,
691 // there is no need to determine whether it is java compatible
692 // (and we can assume that it is java compatible),
693 // as if not, the information about that would appear in the
694 // requested vertex through another path.
695 if (visited->find(this) != visited->end()) {
696 return true;
697 }
698 visited->insert(this);
699 return deepIsJavaCompatible(visited);
700}
701
702bool Type::containsPointer(std::unordered_set<const Type*>* visited) const {
703 // See isJavaCompatible for similar structure.
704 if (visited->find(this) != visited->end()) {
705 return false;
706 }
707 visited->insert(this);
708 return deepContainsPointer(visited);
709}
710
711bool Type::deepIsJavaCompatible(std::unordered_set<const Type*>* /* visited */) const {
Andreas Huber70a59e12016-08-16 12:57:01 -0700712 return true;
713}
714
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700715bool Type::deepContainsPointer(std::unordered_set<const Type*>* /* visited */) const {
716 return false;
717}
718
Andreas Huber60d3b222017-03-30 09:10:56 -0700719void Type::getAlignmentAndSize(
720 size_t * /* align */, size_t * /* size */) const {
Steven Moreland7ba51442019-04-23 15:31:31 -0700721 CHECK(!"Should not be here.") << typeName();
Andreas Huber60d3b222017-03-30 09:10:56 -0700722}
723
Andreas Huber019d21d2016-10-03 12:59:47 -0700724void Type::appendToExportedTypesVector(
725 std::vector<const Type *> * /* exportedTypes */) const {
726}
727
Steven Moreland368e4602018-02-16 14:21:49 -0800728void Type::emitExportedHeader(Formatter& /* out */, bool /* forJava */) const {}
Andreas Huber019d21d2016-10-03 12:59:47 -0700729
Timur Iskhakovff5e64a2017-09-11 14:56:18 -0700730bool Type::isNeverStrongReference() const {
731 return false;
732}
733
Yifan Hongbf459bc2016-08-23 16:50:37 -0700734////////////////////////////////////////
735
Neel Mehta3b414a82019-07-02 15:47:48 -0700736TemplatedType::TemplatedType(Scope* parent, const std::string& definedName)
737 : Type(parent, definedName) {}
Steven Moreland30bb6a82016-11-30 09:18:34 -0800738
Timur Iskhakov3f1d26e2017-08-30 15:35:53 -0700739std::string TemplatedType::typeName() const {
740 return templatedTypeName() + " of " + mElementType->typeName();
741}
742
Timur Iskhakov505316c2017-08-05 03:38:59 +0000743void TemplatedType::setElementType(const Reference<Type>& elementType) {
744 // can only be set once.
745 CHECK(mElementType.isEmptyReference());
746 CHECK(!elementType.isEmptyReference());
747
Yifan Hongbf459bc2016-08-23 16:50:37 -0700748 mElementType = elementType;
Neel Mehta3b414a82019-07-02 15:47:48 -0700749 mDefinedName = mDefinedName + "<" + mElementType.localName() + ">";
Yifan Hongbf459bc2016-08-23 16:50:37 -0700750}
751
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700752const Type* TemplatedType::getElementType() const {
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700753 return mElementType.get();
Yifan Hongabf73ee2016-12-05 18:47:00 -0800754}
755
756bool TemplatedType::isTemplatedType() const {
757 return true;
758}
759
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700760std::vector<const Reference<Type>*> TemplatedType::getReferences() const {
761 return {&mElementType};
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700762}
763
764status_t TemplatedType::validate() const {
Timur Iskhakovb3f8bcb2017-08-30 15:33:29 -0700765 if (!isCompatibleElementType(mElementType.get())) {
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700766 std::cerr << "ERROR: " << typeName() /* contains element type */
767 << " is not supported at " << mElementType.location() << "\n";
768 return UNKNOWN_ERROR;
769 }
770
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700771 return Type::validate();
772}
773
Steven Moreland368e4602018-02-16 14:21:49 -0800774void TemplatedType::emitVtsTypeDeclarations(Formatter& out) const {
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800775 out << "type: " << getVtsType() << "\n";
776 out << getVtsValueName() << ": {\n";
777 out.indent();
Steven Moreland368e4602018-02-16 14:21:49 -0800778 mElementType->emitVtsTypeDeclarations(out);
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800779 out.unindent();
780 out << "}\n";
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800781}
782
Steven Moreland368e4602018-02-16 14:21:49 -0800783void TemplatedType::emitVtsAttributeType(Formatter& out) const {
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800784 out << "type: " << getVtsType() << "\n";
785 out << getVtsValueName() << ": {\n";
786 out.indent();
Steven Moreland368e4602018-02-16 14:21:49 -0800787 mElementType->emitVtsAttributeType(out);
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800788 out.unindent();
789 out << "}\n";
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800790}
Timur Iskhakov505316c2017-08-05 03:38:59 +0000791
Andreas Huberc9410c72016-07-28 12:18:40 -0700792} // namespace android
793