Type.h revision 8e61c5af41226b0e1e88aa439c1360836f71795b
1/*
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
17#ifndef TYPE_H_
18
19#define TYPE_H_
20
21#include <android-base/macros.h>
22#include <utils/Errors.h>
23#include <set>
24#include <string>
25#include <unordered_map>
26#include <unordered_set>
27#include <vector>
28
29#include "Reference.h"
30
31namespace android {
32
33// TODO(b/65200821): remove
34// HACK because no no type can depend or see AST
35extern std::string gCurrentCompileName;
36
37struct ConstantExpression;
38struct Formatter;
39struct FQName;
40struct ScalarType;
41struct Scope;
42
43struct Type {
44    Type(Scope* parent);
45    virtual ~Type();
46
47    virtual bool isArray() const;
48    virtual bool isBinder() const;
49    virtual bool isBitField() const;
50    virtual bool isCompoundType() const;
51    virtual bool isEnum() const;
52    virtual bool isHandle() const;
53    virtual bool isInterface() const;
54    virtual bool isNamedType() const;
55    virtual bool isMemory() const;
56    virtual bool isPointer() const;
57    virtual bool isScope() const;
58    virtual bool isScalar() const;
59    virtual bool isString() const;
60    virtual bool isTemplatedType() const;
61    virtual bool isTypeDef() const;
62    virtual bool isVector() const;
63
64    // Resolves the type by unwrapping typedefs
65    Type* resolve();
66    virtual const Type* resolve() const;
67
68    // All types defined in this type.
69    std::vector<Type*> getDefinedTypes();
70    virtual std::vector<const Type*> getDefinedTypes() const;
71
72    // All types referenced in this type.
73    std::vector<Reference<Type>*> getReferences();
74    virtual std::vector<const Reference<Type>*> getReferences() const;
75
76    // All constant expressions referenced in this type.
77    std::vector<ConstantExpression*> getConstantExpressions();
78    virtual std::vector<const ConstantExpression*> getConstantExpressions() const;
79
80    // All types referenced in this type that must have completed
81    // definiton before being referenced.
82    std::vector<Reference<Type>*> getStrongReferences();
83    virtual std::vector<const Reference<Type>*> getStrongReferences() const;
84
85    // Proceeds recursive pass
86    // Makes sure to visit each node only once.
87    status_t recursivePass(const std::function<status_t(Type*)>& func,
88                           std::unordered_set<const Type*>* visited);
89    status_t recursivePass(const std::function<status_t(const Type*)>& func,
90                           std::unordered_set<const Type*>* visited) const;
91
92    // Recursive tree pass that completes type declarations
93    // that depend on super types
94    virtual status_t resolveInheritance();
95
96    // Recursive tree pass that validates all type-related
97    // syntax restrictions
98    virtual status_t validate() const;
99
100    // Recursive tree pass checkAcyclic return type.
101    // Stores cycle end for nice error messages.
102    struct CheckAcyclicStatus {
103        CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr);
104
105        status_t status;
106
107        // If a cycle is found, stores the end of cycle.
108        // While going back in recursion, this is used to stop printing the cycle.
109        const Type* cycleEnd;
110    };
111
112    // Recursive tree pass that ensures that type definitions and references
113    // are acyclic and builds reversed topological order of the types.
114    // If some cases allow using of incomplete types, these cases are to be
115    // declared in Type::getStrongReferences.
116    CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder,
117                                        std::unordered_set<const Type*>* stack) const;
118
119    // Checks following C++ restriction on forward declaration:
120    // inner struct could be forward declared only inside its parent.
121    status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const;
122
123    virtual const ScalarType *resolveToScalarType() const;
124
125    virtual std::string typeName() const = 0;
126
127    bool isValidEnumStorageType() const;
128    virtual bool isElidableType() const;
129
130    virtual bool canCheckEquality() const;
131    bool canCheckEquality(std::unordered_set<const Type*>* visited) const;
132    virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const;
133
134    // Marks that package proceeding is completed
135    // Post parse passes must be proceeded during owner package parsing
136    void setPostParseCompleted();
137
138    Scope* parent();
139    const Scope* parent() const;
140
141    enum StorageMode {
142        StorageMode_Stack,
143        StorageMode_Argument,
144        StorageMode_Result,
145    };
146
147    // specifyNamespaces: whether to specify namespaces for built-in types
148    virtual std::string getCppType(
149            StorageMode mode,
150            bool specifyNamespaces) const;
151
152    std::string decorateCppName(
153            const std::string &name,
154            StorageMode mode,
155            bool specifyNamespaces) const;
156
157    std::string getCppStackType(bool specifyNamespaces = true) const;
158
159    std::string getCppResultType(bool specifyNamespaces = true) const;
160
161    std::string getCppArgumentType(bool specifyNamespaces = true) const;
162
163    // For an array type, dimensionality information will be accumulated at the
164    // end of the returned string.
165    // if forInitializer == true, actual dimensions are included, i.e. [3][5],
166    // otherwise (and by default), they are omitted, i.e. [][].
167    virtual std::string getJavaType(bool forInitializer = false) const;
168
169    virtual std::string getJavaWrapperType() const;
170    virtual std::string getJavaSuffix() const;
171
172    virtual std::string getVtsType() const;
173    virtual std::string getVtsValueName() const;
174
175    enum ErrorMode {
176        ErrorMode_Ignore,
177        ErrorMode_Goto,
178        ErrorMode_Break,
179        ErrorMode_Return,
180    };
181    virtual void emitReaderWriter(
182            Formatter &out,
183            const std::string &name,
184            const std::string &parcelObj,
185            bool parcelObjIsPointer,
186            bool isReader,
187            ErrorMode mode) const;
188
189    virtual void emitReaderWriterEmbedded(
190            Formatter &out,
191            size_t depth,
192            const std::string &name,
193            const std::string &sanitizedName,
194            bool nameIsPointer,
195            const std::string &parcelObj,
196            bool parcelObjIsPointer,
197            bool isReader,
198            ErrorMode mode,
199            const std::string &parentName,
200            const std::string &offsetText) const;
201
202    virtual void emitResolveReferences(
203            Formatter &out,
204            const std::string &name,
205            bool nameIsPointer,
206            const std::string &parcelObj,
207            bool parcelObjIsPointer,
208            bool isReader,
209            ErrorMode mode) const;
210
211    virtual void emitResolveReferencesEmbedded(
212            Formatter &out,
213            size_t depth,
214            const std::string &name,
215            const std::string &sanitizedName,
216            bool nameIsPointer,
217            const std::string &parcelObj,
218            bool parcelObjIsPointer,
219            bool isReader,
220            ErrorMode mode,
221            const std::string &parentName,
222            const std::string &offsetText) const;
223
224    virtual void emitDump(
225            Formatter &out,
226            const std::string &streamName,
227            const std::string &name) const;
228
229    virtual void emitJavaDump(
230            Formatter &out,
231            const std::string &streamName,
232            const std::string &name) const;
233
234    virtual bool useParentInEmitResolveReferencesEmbedded() const;
235
236    virtual bool useNameInEmitReaderWriterEmbedded(bool isReader) const;
237
238    virtual void emitJavaReaderWriter(
239            Formatter &out,
240            const std::string &parcelObj,
241            const std::string &argName,
242            bool isReader) const;
243
244    virtual void emitJavaFieldInitializer(
245            Formatter &out,
246            const std::string &fieldName) const;
247
248    virtual void emitJavaFieldReaderWriter(
249            Formatter &out,
250            size_t depth,
251            const std::string &parcelName,
252            const std::string &blobName,
253            const std::string &fieldName,
254            const std::string &offset,
255            bool isReader) const;
256
257    virtual status_t emitTypeDeclarations(Formatter &out) const;
258
259    virtual void emitGlobalTypeDeclarations(Formatter& out) const;
260
261    // Emit scope C++ forward declaration.
262    // There is no need to forward declare interfaces, as
263    // they are always declared in global scope in dedicated file.
264    virtual void emitTypeForwardDeclaration(Formatter& out) const;
265
266    // Emit any declarations pertaining to this type that have to be
267    // at global scope, i.e. enum class operators.
268    // For android.hardware.foo@1.0::*, this will be in namespace
269    // android::hardware::foo::V1_0
270    virtual status_t emitPackageTypeDeclarations(Formatter& out) const;
271
272    // Emit any declarations pertaining to this type that have to be
273    // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel
274    // For android.hardware.foo@1.0::*, this will be in namespace
275    // android::hardware::foo::V1_0
276    virtual status_t emitPackageHwDeclarations(Formatter& out) const;
277
278    virtual status_t emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
279
280    virtual status_t emitJavaTypeDeclarations(
281            Formatter &out, bool atTopLevel) const;
282
283    virtual bool needsEmbeddedReadWrite() const;
284    virtual bool resultNeedsDeref() const;
285
286    bool needsResolveReferences() const;
287    bool needsResolveReferences(std::unordered_set<const Type*>* visited) const;
288    virtual bool deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const;
289
290    // Generates type declaration for vts proto file.
291    // TODO (b/30844146): make it a pure virtual method.
292    virtual status_t emitVtsTypeDeclarations(Formatter &out) const;
293    // Generates type declaration as attribute of method (return value or method
294    // argument) or attribute of compound type for vts proto file.
295    virtual status_t emitVtsAttributeType(Formatter &out) const;
296
297    // Returns true iff this type is supported through the Java backend.
298    bool isJavaCompatible() const;
299    bool isJavaCompatible(std::unordered_set<const Type*>* visited) const;
300    virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const;
301    // Returns true iff type contains pointer
302    // (excluding methods and inner types).
303    bool containsPointer() const;
304    bool containsPointer(std::unordered_set<const Type*>* visited) const;
305    virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const;
306
307    virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
308
309    virtual void appendToExportedTypesVector(
310            std::vector<const Type *> *exportedTypes) const;
311
312    virtual status_t emitExportedHeader(Formatter &out, bool forJava) const;
313
314    virtual bool isNeverStrongReference() const;
315
316   protected:
317    void handleError(Formatter &out, ErrorMode mode) const;
318
319    void emitReaderWriterEmbeddedForTypeName(
320            Formatter &out,
321            const std::string &name,
322            bool nameIsPointer,
323            const std::string &parcelObj,
324            bool parcelObjIsPointer,
325            bool isReader,
326            ErrorMode mode,
327            const std::string &parentName,
328            const std::string &offsetText,
329            const std::string &typeName,
330            const std::string &childName,
331            const std::string &funcNamespace) const;
332
333    void emitJavaReaderWriterWithSuffix(
334            Formatter &out,
335            const std::string &parcelObj,
336            const std::string &argName,
337            bool isReader,
338            const std::string &suffix,
339            const std::string &extra) const;
340
341    void emitDumpWithMethod(
342            Formatter &out,
343            const std::string &streamName,
344            const std::string &methodName,
345            const std::string &name) const;
346
347   private:
348    bool mIsPostParseCompleted = false;
349    Scope* const mParent;
350
351    DISALLOW_COPY_AND_ASSIGN(Type);
352};
353
354/* Base type for VectorType and RefType. */
355struct TemplatedType : public Type {
356    void setElementType(const Reference<Type>& elementType);
357    const Type* getElementType() const;
358
359    virtual std::string templatedTypeName() const = 0;
360    std::string typeName() const override;
361
362    bool isTemplatedType() const override;
363
364    virtual bool isCompatibleElementType(const Type* elementType) const = 0;
365
366    std::vector<const Reference<Type>*> getReferences() const override;
367
368    virtual status_t validate() const override;
369
370    status_t emitVtsTypeDeclarations(Formatter& out) const override;
371    status_t emitVtsAttributeType(Formatter& out) const override;
372
373   protected:
374    TemplatedType(Scope* parent);
375    Reference<Type> mElementType;
376
377   private:
378    DISALLOW_COPY_AND_ASSIGN(TemplatedType);
379};
380
381}  // namespace android
382
383#endif  // TYPE_H_
384
385