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