blob: 6426de4107da064bf7d22c41e1dea3a57506fda3 [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#ifndef TYPE_H_
18
19#define TYPE_H_
20
21#include <android-base/macros.h>
Andreas Huber881227d2016-08-02 14:20:21 -070022#include <utils/Errors.h>
Steven Moreland979e0992016-09-07 09:18:08 -070023#include <set>
Timur Iskhakovcec46c42017-08-09 00:22:02 -070024#include <string>
Timur Iskhakov458ca362017-09-12 23:16:03 -070025#include <unordered_map>
Timur Iskhakov33431e62017-08-21 17:31:23 -070026#include <unordered_set>
Timur Iskhakovcec46c42017-08-09 00:22:02 -070027#include <vector>
Andreas Huberc9410c72016-07-28 12:18:40 -070028
Steven Moreland073269e2018-05-17 15:45:26 -070029#include "DocComment.h"
Timur Iskhakov505316c2017-08-05 03:38:59 +000030#include "Reference.h"
31
Andreas Huberc9410c72016-07-28 12:18:40 -070032namespace android {
33
Steven Morelandbf714212017-10-27 18:29:01 -070034// TODO(b/65200821): remove
35// HACK because no no type can depend or see AST
36extern std::string gCurrentCompileName;
37
Timur Iskhakov891a8662017-08-25 21:53:48 -070038struct ConstantExpression;
Andreas Huberc9410c72016-07-28 12:18:40 -070039struct Formatter;
Steven Moreland979e0992016-09-07 09:18:08 -070040struct FQName;
Timur Iskhakov891a8662017-08-25 21:53:48 -070041struct ScalarType;
Timur Iskhakov63f39902017-08-29 15:47:29 -070042struct Scope;
Andreas Huberc9410c72016-07-28 12:18:40 -070043
Steven Moreland073269e2018-05-17 15:45:26 -070044struct Type : DocCommentable {
Timur Iskhakov63f39902017-08-29 15:47:29 -070045 Type(Scope* parent);
Andreas Huberc9410c72016-07-28 12:18:40 -070046 virtual ~Type();
47
Andreas Huber709b62d2016-09-19 11:21:18 -070048 virtual bool isArray() const;
Martijn Coenen99e6beb2016-12-01 15:48:42 +010049 virtual bool isBinder() const;
Yifan Hongabf73ee2016-12-05 18:47:00 -080050 virtual bool isBitField() const;
Martijn Coenen99e6beb2016-12-01 15:48:42 +010051 virtual bool isCompoundType() const;
52 virtual bool isEnum() const;
Yifan Hongabf73ee2016-12-05 18:47:00 -080053 virtual bool isHandle() const;
Martijn Coenen99e6beb2016-12-01 15:48:42 +010054 virtual bool isInterface() const;
55 virtual bool isNamedType() const;
Steven Moreland397b5e12017-06-08 14:02:26 -070056 virtual bool isMemory() const;
Martijn Coenen99e6beb2016-12-01 15:48:42 +010057 virtual bool isPointer() const;
58 virtual bool isScope() const;
Yifan Hongabf73ee2016-12-05 18:47:00 -080059 virtual bool isScalar() const;
60 virtual bool isString() const;
61 virtual bool isTemplatedType() const;
Martijn Coenen99e6beb2016-12-01 15:48:42 +010062 virtual bool isTypeDef() const;
Andreas Huber709b62d2016-09-19 11:21:18 -070063 virtual bool isVector() const;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070064
Timur Iskhakovdbaed332017-08-31 16:33:41 -070065 // Resolves the type by unwrapping typedefs
66 Type* resolve();
67 virtual const Type* resolve() const;
68
Timur Iskhakov33431e62017-08-21 17:31:23 -070069 // All types defined in this type.
Timur Iskhakovb58f4182017-08-29 15:19:24 -070070 std::vector<Type*> getDefinedTypes();
71 virtual std::vector<const Type*> getDefinedTypes() const;
Timur Iskhakov33431e62017-08-21 17:31:23 -070072
73 // All types referenced in this type.
Timur Iskhakovb58f4182017-08-29 15:19:24 -070074 std::vector<Reference<Type>*> getReferences();
75 virtual std::vector<const Reference<Type>*> getReferences() const;
Timur Iskhakov33431e62017-08-21 17:31:23 -070076
Timur Iskhakov891a8662017-08-25 21:53:48 -070077 // All constant expressions referenced in this type.
Timur Iskhakovb58f4182017-08-29 15:19:24 -070078 std::vector<ConstantExpression*> getConstantExpressions();
79 virtual std::vector<const ConstantExpression*> getConstantExpressions() const;
Timur Iskhakov891a8662017-08-25 21:53:48 -070080
Timur Iskhakov40731af2017-08-24 14:18:35 -070081 // All types referenced in this type that must have completed
82 // definiton before being referenced.
Timur Iskhakovb58f4182017-08-29 15:19:24 -070083 std::vector<Reference<Type>*> getStrongReferences();
84 virtual std::vector<const Reference<Type>*> getStrongReferences() const;
Timur Iskhakov40731af2017-08-24 14:18:35 -070085
Timur Iskhakov33431e62017-08-21 17:31:23 -070086 // Proceeds recursive pass
87 // Makes sure to visit each node only once.
88 status_t recursivePass(const std::function<status_t(Type*)>& func,
89 std::unordered_set<const Type*>* visited);
90 status_t recursivePass(const std::function<status_t(const Type*)>& func,
91 std::unordered_set<const Type*>* visited) const;
92
Timur Iskhakovcec46c42017-08-09 00:22:02 -070093 // Recursive tree pass that completes type declarations
94 // that depend on super types
95 virtual status_t resolveInheritance();
96
Timur Iskhakovcec46c42017-08-09 00:22:02 -070097 // Recursive tree pass that validates all type-related
98 // syntax restrictions
99 virtual status_t validate() const;
100
Timur Iskhakov40731af2017-08-24 14:18:35 -0700101 // Recursive tree pass checkAcyclic return type.
102 // Stores cycle end for nice error messages.
103 struct CheckAcyclicStatus {
104 CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr);
105
106 status_t status;
107
108 // If a cycle is found, stores the end of cycle.
109 // While going back in recursion, this is used to stop printing the cycle.
110 const Type* cycleEnd;
111 };
112
113 // Recursive tree pass that ensures that type definitions and references
Timur Iskhakov458ca362017-09-12 23:16:03 -0700114 // are acyclic and builds reversed topological order of the types.
Timur Iskhakov40731af2017-08-24 14:18:35 -0700115 // If some cases allow using of incomplete types, these cases are to be
116 // declared in Type::getStrongReferences.
Timur Iskhakov458ca362017-09-12 23:16:03 -0700117 CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder,
118 std::unordered_set<const Type*>* stack) const;
Timur Iskhakov40731af2017-08-24 14:18:35 -0700119
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700120 // Checks following C++ restriction on forward declaration:
121 // inner struct could be forward declared only inside its parent.
Timur Iskhakov458ca362017-09-12 23:16:03 -0700122 status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const;
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700123
Andreas Huber737080b2016-08-02 15:38:04 -0700124 virtual const ScalarType *resolveToScalarType() const;
Andreas Huberc9410c72016-07-28 12:18:40 -0700125
Steven Moreland0ecc7b82017-07-19 12:59:23 -0700126 virtual std::string typeName() const = 0;
Steven Moreland30bb6a82016-11-30 09:18:34 -0800127
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700128 bool isValidEnumStorageType() const;
Steven Moreland9df52442016-12-12 08:51:14 -0800129 virtual bool isElidableType() const;
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700130
Yifan Hongc6752dc2016-12-20 14:00:14 -0800131 virtual bool canCheckEquality() const;
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700132 bool canCheckEquality(std::unordered_set<const Type*>* visited) const;
133 virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700134
Timur Iskhakov35930c42017-08-28 18:49:54 -0700135 // Marks that package proceeding is completed
136 // Post parse passes must be proceeded during owner package parsing
137 void setPostParseCompleted();
138
Timur Iskhakov63f39902017-08-29 15:47:29 -0700139 Scope* parent();
Timur Iskhakov041fdfe2017-09-06 15:56:01 -0700140 const Scope* parent() const;
Timur Iskhakov63f39902017-08-29 15:47:29 -0700141
Andreas Huber881227d2016-08-02 14:20:21 -0700142 enum StorageMode {
143 StorageMode_Stack,
144 StorageMode_Argument,
Martijn Coenenac587892016-11-17 15:14:19 +0100145 StorageMode_Result,
Andreas Huber881227d2016-08-02 14:20:21 -0700146 };
Yifan Hong3b320f82016-11-01 15:15:54 -0700147
Steven Morelande30ee9b2017-05-09 13:31:01 -0700148 // specifyNamespaces: whether to specify namespaces for built-in types
Andreas Huber881227d2016-08-02 14:20:21 -0700149 virtual std::string getCppType(
Steven Moreland979e0992016-09-07 09:18:08 -0700150 StorageMode mode,
Yifan Hong3b320f82016-11-01 15:15:54 -0700151 bool specifyNamespaces) const;
152
153 std::string decorateCppName(
154 const std::string &name,
155 StorageMode mode,
Steven Moreland979e0992016-09-07 09:18:08 -0700156 bool specifyNamespaces) const;
157
Yifan Hong3b320f82016-11-01 15:15:54 -0700158 std::string getCppStackType(bool specifyNamespaces = true) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700159
Yifan Hong3b320f82016-11-01 15:15:54 -0700160 std::string getCppResultType(bool specifyNamespaces = true) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700161
Yifan Hong3b320f82016-11-01 15:15:54 -0700162 std::string getCppArgumentType(bool specifyNamespaces = true) const;
Andreas Huber4c865b72016-09-14 15:26:27 -0700163
Nirav Atreca7a5022018-06-29 20:43:49 -0700164 std::string getCppTypeCast(const std::string& objName,
165 bool specifyNamespaces = true) const;
166
Yifan Hong4ed13472016-11-02 10:44:11 -0700167 // For an array type, dimensionality information will be accumulated at the
168 // end of the returned string.
Andreas Huber4c865b72016-09-14 15:26:27 -0700169 // if forInitializer == true, actual dimensions are included, i.e. [3][5],
170 // otherwise (and by default), they are omitted, i.e. [][].
Yifan Hong4ed13472016-11-02 10:44:11 -0700171 virtual std::string getJavaType(bool forInitializer = false) const;
Andreas Huber4c865b72016-09-14 15:26:27 -0700172
Nirav Atre66842a92018-06-28 18:14:13 -0700173 // Identical to getJavaType() for most types, except: primitives, in which
174 // case the wrapper type is returned, and generics (such as ArrayList<?>),
175 // where the type specialization is omitted to facilitate use of
176 // instanceof or class.isInstance().
177 virtual std::string getJavaTypeClass() const;
178
179 virtual std::string getJavaTypeCast(const std::string& objName) const;
Andreas Huber2831d512016-08-15 09:33:47 -0700180 virtual std::string getJavaSuffix() const;
181
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700182 virtual std::string getVtsType() const;
Zhuoyao Zhange9667842017-01-19 12:35:32 -0800183 virtual std::string getVtsValueName() const;
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700184
Andreas Huber881227d2016-08-02 14:20:21 -0700185 enum ErrorMode {
186 ErrorMode_Ignore,
187 ErrorMode_Goto,
188 ErrorMode_Break,
Andreas Huber737080b2016-08-02 15:38:04 -0700189 ErrorMode_Return,
Andreas Huber881227d2016-08-02 14:20:21 -0700190 };
191 virtual void emitReaderWriter(
192 Formatter &out,
193 const std::string &name,
194 const std::string &parcelObj,
195 bool parcelObjIsPointer,
196 bool isReader,
197 ErrorMode mode) const;
198
199 virtual void emitReaderWriterEmbedded(
200 Formatter &out,
Andreas Huberf9d49f12016-09-12 14:58:36 -0700201 size_t depth,
Andreas Huber881227d2016-08-02 14:20:21 -0700202 const std::string &name,
Yifan Hongbe2a3732016-10-05 13:33:41 -0700203 const std::string &sanitizedName,
Andreas Huber881227d2016-08-02 14:20:21 -0700204 bool nameIsPointer,
205 const std::string &parcelObj,
206 bool parcelObjIsPointer,
207 bool isReader,
208 ErrorMode mode,
209 const std::string &parentName,
210 const std::string &offsetText) const;
211
Yifan Hongbf459bc2016-08-23 16:50:37 -0700212 virtual void emitResolveReferences(
213 Formatter &out,
214 const std::string &name,
215 bool nameIsPointer,
216 const std::string &parcelObj,
217 bool parcelObjIsPointer,
218 bool isReader,
219 ErrorMode mode) const;
220
221 virtual void emitResolveReferencesEmbedded(
222 Formatter &out,
223 size_t depth,
224 const std::string &name,
225 const std::string &sanitizedName,
226 bool nameIsPointer,
227 const std::string &parcelObj,
228 bool parcelObjIsPointer,
229 bool isReader,
230 ErrorMode mode,
231 const std::string &parentName,
232 const std::string &offsetText) const;
233
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800234 virtual void emitDump(
235 Formatter &out,
236 const std::string &streamName,
237 const std::string &name) const;
238
Yifan Honge45b5302017-02-22 10:49:07 -0800239 virtual void emitJavaDump(
240 Formatter &out,
241 const std::string &streamName,
242 const std::string &name) const;
243
Yifan Hong00f47172016-09-30 14:40:45 -0700244 virtual bool useParentInEmitResolveReferencesEmbedded() const;
245
Yifan Hong244e82d2016-11-11 11:13:57 -0800246 virtual bool useNameInEmitReaderWriterEmbedded(bool isReader) const;
247
Andreas Huber2831d512016-08-15 09:33:47 -0700248 virtual void emitJavaReaderWriter(
249 Formatter &out,
250 const std::string &parcelObj,
251 const std::string &argName,
252 bool isReader) const;
253
Andreas Huber85eabdb2016-08-25 11:24:49 -0700254 virtual void emitJavaFieldInitializer(
255 Formatter &out,
256 const std::string &fieldName) const;
257
Nirav Atre66842a92018-06-28 18:14:13 -0700258 virtual void emitJavaFieldDefaultInitialValue(
259 Formatter &out,
260 const std::string &declaredFieldName) const;
261
Andreas Huber85eabdb2016-08-25 11:24:49 -0700262 virtual void emitJavaFieldReaderWriter(
263 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700264 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700265 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700266 const std::string &blobName,
267 const std::string &fieldName,
268 const std::string &offset,
269 bool isReader) const;
270
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800271 virtual void emitTypeDeclarations(Formatter& out) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700272
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800273 virtual void emitGlobalTypeDeclarations(Formatter& out) const;
274
Timur Iskhakovfd3f2502017-09-05 16:25:02 -0700275 // Emit scope C++ forward declaration.
276 // There is no need to forward declare interfaces, as
277 // they are always declared in global scope in dedicated file.
278 virtual void emitTypeForwardDeclaration(Formatter& out) const;
279
Andreas Hubere3f769a2016-10-10 10:54:44 -0700280 // Emit any declarations pertaining to this type that have to be
281 // at global scope, i.e. enum class operators.
Steven Moreland4b8f7a12017-11-17 15:39:54 -0800282 // For android.hardware.foo@1.0::*, this will be in namespace
283 // android::hardware::foo::V1_0
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800284 virtual void emitPackageTypeDeclarations(Formatter& out) const;
Andreas Hubere3f769a2016-10-10 10:54:44 -0700285
Yifan Hong244e82d2016-11-11 11:13:57 -0800286 // Emit any declarations pertaining to this type that have to be
287 // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel
Steven Moreland4b8f7a12017-11-17 15:39:54 -0800288 // For android.hardware.foo@1.0::*, this will be in namespace
289 // android::hardware::foo::V1_0
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800290 virtual void emitPackageHwDeclarations(Formatter& out) const;
Yifan Hong244e82d2016-11-11 11:13:57 -0800291
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800292 virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700293
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800294 virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const;
Andreas Huber2831d512016-08-15 09:33:47 -0700295
Andreas Huber881227d2016-08-02 14:20:21 -0700296 virtual bool needsEmbeddedReadWrite() const;
297 virtual bool resultNeedsDeref() const;
298
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700299 bool needsResolveReferences() const;
300 bool needsResolveReferences(std::unordered_set<const Type*>* visited) const;
301 virtual bool deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const;
302
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700303 // Generates type declaration for vts proto file.
304 // TODO (b/30844146): make it a pure virtual method.
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800305 virtual void emitVtsTypeDeclarations(Formatter& out) const;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700306 // Generates type declaration as attribute of method (return value or method
307 // argument) or attribute of compound type for vts proto file.
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800308 virtual void emitVtsAttributeType(Formatter& out) const;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700309
Andreas Huber70a59e12016-08-16 12:57:01 -0700310 // Returns true iff this type is supported through the Java backend.
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700311 bool isJavaCompatible() const;
312 bool isJavaCompatible(std::unordered_set<const Type*>* visited) const;
313 virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const;
314 // Returns true iff type contains pointer
315 // (excluding methods and inner types).
316 bool containsPointer() const;
317 bool containsPointer(std::unordered_set<const Type*>* visited) const;
318 virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const;
319
Andreas Huber85eabdb2016-08-25 11:24:49 -0700320 virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
321
Andreas Huber019d21d2016-10-03 12:59:47 -0700322 virtual void appendToExportedTypesVector(
323 std::vector<const Type *> *exportedTypes) const;
324
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800325 virtual void emitExportedHeader(Formatter& out, bool forJava) const;
Andreas Huber019d21d2016-10-03 12:59:47 -0700326
Timur Iskhakovff5e64a2017-09-11 14:56:18 -0700327 virtual bool isNeverStrongReference() const;
328
329 protected:
Andreas Huber881227d2016-08-02 14:20:21 -0700330 void handleError(Formatter &out, ErrorMode mode) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700331
332 void emitReaderWriterEmbeddedForTypeName(
333 Formatter &out,
334 const std::string &name,
335 bool nameIsPointer,
336 const std::string &parcelObj,
337 bool parcelObjIsPointer,
338 bool isReader,
339 ErrorMode mode,
340 const std::string &parentName,
341 const std::string &offsetText,
342 const std::string &typeName,
Yifan Hong244e82d2016-11-11 11:13:57 -0800343 const std::string &childName,
344 const std::string &funcNamespace) const;
Andreas Huber881227d2016-08-02 14:20:21 -0700345
Andreas Huber2831d512016-08-15 09:33:47 -0700346 void emitJavaReaderWriterWithSuffix(
347 Formatter &out,
348 const std::string &parcelObj,
349 const std::string &argName,
350 bool isReader,
351 const std::string &suffix,
352 const std::string &extra) const;
353
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800354 void emitDumpWithMethod(
355 Formatter &out,
356 const std::string &streamName,
357 const std::string &methodName,
358 const std::string &name) const;
359
Timur Iskhakov35930c42017-08-28 18:49:54 -0700360 private:
361 bool mIsPostParseCompleted = false;
Timur Iskhakov63f39902017-08-29 15:47:29 -0700362 Scope* const mParent;
Timur Iskhakov35930c42017-08-28 18:49:54 -0700363
Andreas Huberc9410c72016-07-28 12:18:40 -0700364 DISALLOW_COPY_AND_ASSIGN(Type);
365};
366
Yifan Hongbf459bc2016-08-23 16:50:37 -0700367/* Base type for VectorType and RefType. */
368struct TemplatedType : public Type {
Timur Iskhakov505316c2017-08-05 03:38:59 +0000369 void setElementType(const Reference<Type>& elementType);
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700370 const Type* getElementType() const;
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700371
Timur Iskhakov3f1d26e2017-08-30 15:35:53 -0700372 virtual std::string templatedTypeName() const = 0;
373 std::string typeName() const override;
374
Timur Iskhakov33431e62017-08-21 17:31:23 -0700375 bool isTemplatedType() const override;
376
Timur Iskhakov24e605b2017-08-30 14:02:55 -0700377 virtual bool isCompatibleElementType(const Type* elementType) const = 0;
Timur Iskhakov33431e62017-08-21 17:31:23 -0700378
Timur Iskhakovb58f4182017-08-29 15:19:24 -0700379 std::vector<const Reference<Type>*> getReferences() const override;
Timur Iskhakov33431e62017-08-21 17:31:23 -0700380
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700381 virtual status_t validate() const override;
382
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800383 void emitVtsTypeDeclarations(Formatter& out) const override;
384 void emitVtsAttributeType(Formatter& out) const override;
Timur Iskhakov33431e62017-08-21 17:31:23 -0700385
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700386 protected:
Timur Iskhakov63f39902017-08-29 15:47:29 -0700387 TemplatedType(Scope* parent);
Timur Iskhakov505316c2017-08-05 03:38:59 +0000388 Reference<Type> mElementType;
389
390 private:
Yifan Hongbf459bc2016-08-23 16:50:37 -0700391 DISALLOW_COPY_AND_ASSIGN(TemplatedType);
392};
393
Andreas Huberc9410c72016-07-28 12:18:40 -0700394} // namespace android
395
396#endif // TYPE_H_
397