| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef TYPE_H_ |
| |
| #define TYPE_H_ |
| |
| #include <android-base/macros.h> |
| #include <utils/Errors.h> |
| #include <set> |
| #include <string> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include "Reference.h" |
| |
| namespace android { |
| |
| // TODO(b/65200821): remove |
| // HACK because no no type can depend or see AST |
| extern std::string gCurrentCompileName; |
| |
| struct ConstantExpression; |
| struct Formatter; |
| struct FQName; |
| struct ScalarType; |
| struct Scope; |
| |
| struct Type { |
| Type(Scope* parent); |
| virtual ~Type(); |
| |
| virtual bool isArray() const; |
| virtual bool isBinder() const; |
| virtual bool isBitField() const; |
| virtual bool isCompoundType() const; |
| virtual bool isEnum() const; |
| virtual bool isHandle() const; |
| virtual bool isInterface() const; |
| virtual bool isNamedType() const; |
| virtual bool isMemory() const; |
| virtual bool isPointer() const; |
| virtual bool isScope() const; |
| virtual bool isScalar() const; |
| virtual bool isString() const; |
| virtual bool isTemplatedType() const; |
| virtual bool isTypeDef() const; |
| virtual bool isVector() const; |
| |
| // Resolves the type by unwrapping typedefs |
| Type* resolve(); |
| virtual const Type* resolve() const; |
| |
| // All types defined in this type. |
| std::vector<Type*> getDefinedTypes(); |
| virtual std::vector<const Type*> getDefinedTypes() const; |
| |
| // All types referenced in this type. |
| std::vector<Reference<Type>*> getReferences(); |
| virtual std::vector<const Reference<Type>*> getReferences() const; |
| |
| // All constant expressions referenced in this type. |
| std::vector<ConstantExpression*> getConstantExpressions(); |
| virtual std::vector<const ConstantExpression*> getConstantExpressions() const; |
| |
| // All types referenced in this type that must have completed |
| // definiton before being referenced. |
| std::vector<Reference<Type>*> getStrongReferences(); |
| virtual std::vector<const Reference<Type>*> getStrongReferences() const; |
| |
| // Proceeds recursive pass |
| // Makes sure to visit each node only once. |
| status_t recursivePass(const std::function<status_t(Type*)>& func, |
| std::unordered_set<const Type*>* visited); |
| status_t recursivePass(const std::function<status_t(const Type*)>& func, |
| std::unordered_set<const Type*>* visited) const; |
| |
| // Recursive tree pass that completes type declarations |
| // that depend on super types |
| virtual status_t resolveInheritance(); |
| |
| // Recursive tree pass that validates all type-related |
| // syntax restrictions |
| virtual status_t validate() const; |
| |
| // Recursive tree pass checkAcyclic return type. |
| // Stores cycle end for nice error messages. |
| struct CheckAcyclicStatus { |
| CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr); |
| |
| status_t status; |
| |
| // If a cycle is found, stores the end of cycle. |
| // While going back in recursion, this is used to stop printing the cycle. |
| const Type* cycleEnd; |
| }; |
| |
| // Recursive tree pass that ensures that type definitions and references |
| // are acyclic and builds reversed topological order of the types. |
| // If some cases allow using of incomplete types, these cases are to be |
| // declared in Type::getStrongReferences. |
| CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder, |
| std::unordered_set<const Type*>* stack) const; |
| |
| // Checks following C++ restriction on forward declaration: |
| // inner struct could be forward declared only inside its parent. |
| status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const; |
| |
| virtual const ScalarType *resolveToScalarType() const; |
| |
| virtual std::string typeName() const = 0; |
| |
| bool isValidEnumStorageType() const; |
| virtual bool isElidableType() const; |
| |
| virtual bool canCheckEquality() const; |
| bool canCheckEquality(std::unordered_set<const Type*>* visited) const; |
| virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const; |
| |
| // Marks that package proceeding is completed |
| // Post parse passes must be proceeded during owner package parsing |
| void setPostParseCompleted(); |
| |
| Scope* parent(); |
| const Scope* parent() const; |
| |
| enum StorageMode { |
| StorageMode_Stack, |
| StorageMode_Argument, |
| StorageMode_Result, |
| }; |
| |
| // specifyNamespaces: whether to specify namespaces for built-in types |
| virtual std::string getCppType( |
| StorageMode mode, |
| bool specifyNamespaces) const; |
| |
| std::string decorateCppName( |
| const std::string &name, |
| StorageMode mode, |
| bool specifyNamespaces) const; |
| |
| std::string getCppStackType(bool specifyNamespaces = true) const; |
| |
| std::string getCppResultType(bool specifyNamespaces = true) const; |
| |
| std::string getCppArgumentType(bool specifyNamespaces = true) const; |
| |
| // For an array type, dimensionality information will be accumulated at the |
| // end of the returned string. |
| // if forInitializer == true, actual dimensions are included, i.e. [3][5], |
| // otherwise (and by default), they are omitted, i.e. [][]. |
| virtual std::string getJavaType(bool forInitializer = false) const; |
| |
| virtual std::string getJavaWrapperType() const; |
| virtual std::string getJavaSuffix() const; |
| |
| virtual std::string getVtsType() const; |
| virtual std::string getVtsValueName() const; |
| |
| enum ErrorMode { |
| ErrorMode_Ignore, |
| ErrorMode_Goto, |
| ErrorMode_Break, |
| ErrorMode_Return, |
| }; |
| virtual void emitReaderWriter( |
| Formatter &out, |
| const std::string &name, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| bool isReader, |
| ErrorMode mode) const; |
| |
| virtual void emitReaderWriterEmbedded( |
| Formatter &out, |
| size_t depth, |
| const std::string &name, |
| const std::string &sanitizedName, |
| bool nameIsPointer, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| bool isReader, |
| ErrorMode mode, |
| const std::string &parentName, |
| const std::string &offsetText) const; |
| |
| virtual void emitResolveReferences( |
| Formatter &out, |
| const std::string &name, |
| bool nameIsPointer, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| bool isReader, |
| ErrorMode mode) const; |
| |
| virtual void emitResolveReferencesEmbedded( |
| Formatter &out, |
| size_t depth, |
| const std::string &name, |
| const std::string &sanitizedName, |
| bool nameIsPointer, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| bool isReader, |
| ErrorMode mode, |
| const std::string &parentName, |
| const std::string &offsetText) const; |
| |
| virtual void emitDump( |
| Formatter &out, |
| const std::string &streamName, |
| const std::string &name) const; |
| |
| virtual void emitJavaDump( |
| Formatter &out, |
| const std::string &streamName, |
| const std::string &name) const; |
| |
| virtual bool useParentInEmitResolveReferencesEmbedded() const; |
| |
| virtual bool useNameInEmitReaderWriterEmbedded(bool isReader) const; |
| |
| virtual void emitJavaReaderWriter( |
| Formatter &out, |
| const std::string &parcelObj, |
| const std::string &argName, |
| bool isReader) const; |
| |
| virtual void emitJavaFieldInitializer( |
| Formatter &out, |
| const std::string &fieldName) const; |
| |
| virtual void emitJavaFieldReaderWriter( |
| Formatter &out, |
| size_t depth, |
| const std::string &parcelName, |
| const std::string &blobName, |
| const std::string &fieldName, |
| const std::string &offset, |
| bool isReader) const; |
| |
| virtual void emitTypeDeclarations(Formatter& out) const; |
| |
| virtual void emitGlobalTypeDeclarations(Formatter& out) const; |
| |
| // Emit scope C++ forward declaration. |
| // There is no need to forward declare interfaces, as |
| // they are always declared in global scope in dedicated file. |
| virtual void emitTypeForwardDeclaration(Formatter& out) const; |
| |
| // Emit any declarations pertaining to this type that have to be |
| // at global scope, i.e. enum class operators. |
| // For android.hardware.foo@1.0::*, this will be in namespace |
| // android::hardware::foo::V1_0 |
| virtual void emitPackageTypeDeclarations(Formatter& out) const; |
| |
| // Emit any declarations pertaining to this type that have to be |
| // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel |
| // For android.hardware.foo@1.0::*, this will be in namespace |
| // android::hardware::foo::V1_0 |
| virtual void emitPackageHwDeclarations(Formatter& out) const; |
| |
| virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const; |
| |
| virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const; |
| |
| virtual bool needsEmbeddedReadWrite() const; |
| virtual bool resultNeedsDeref() const; |
| |
| bool needsResolveReferences() const; |
| bool needsResolveReferences(std::unordered_set<const Type*>* visited) const; |
| virtual bool deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const; |
| |
| // Generates type declaration for vts proto file. |
| // TODO (b/30844146): make it a pure virtual method. |
| virtual void emitVtsTypeDeclarations(Formatter& out) const; |
| // Generates type declaration as attribute of method (return value or method |
| // argument) or attribute of compound type for vts proto file. |
| virtual void emitVtsAttributeType(Formatter& out) const; |
| |
| // Returns true iff this type is supported through the Java backend. |
| bool isJavaCompatible() const; |
| bool isJavaCompatible(std::unordered_set<const Type*>* visited) const; |
| virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const; |
| // Returns true iff type contains pointer |
| // (excluding methods and inner types). |
| bool containsPointer() const; |
| bool containsPointer(std::unordered_set<const Type*>* visited) const; |
| virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const; |
| |
| virtual void getAlignmentAndSize(size_t *align, size_t *size) const; |
| |
| virtual void appendToExportedTypesVector( |
| std::vector<const Type *> *exportedTypes) const; |
| |
| virtual void emitExportedHeader(Formatter& out, bool forJava) const; |
| |
| virtual bool isNeverStrongReference() const; |
| |
| protected: |
| void handleError(Formatter &out, ErrorMode mode) const; |
| |
| void emitReaderWriterEmbeddedForTypeName( |
| Formatter &out, |
| const std::string &name, |
| bool nameIsPointer, |
| const std::string &parcelObj, |
| bool parcelObjIsPointer, |
| bool isReader, |
| ErrorMode mode, |
| const std::string &parentName, |
| const std::string &offsetText, |
| const std::string &typeName, |
| const std::string &childName, |
| const std::string &funcNamespace) const; |
| |
| void emitJavaReaderWriterWithSuffix( |
| Formatter &out, |
| const std::string &parcelObj, |
| const std::string &argName, |
| bool isReader, |
| const std::string &suffix, |
| const std::string &extra) const; |
| |
| void emitDumpWithMethod( |
| Formatter &out, |
| const std::string &streamName, |
| const std::string &methodName, |
| const std::string &name) const; |
| |
| private: |
| bool mIsPostParseCompleted = false; |
| Scope* const mParent; |
| |
| DISALLOW_COPY_AND_ASSIGN(Type); |
| }; |
| |
| /* Base type for VectorType and RefType. */ |
| struct TemplatedType : public Type { |
| void setElementType(const Reference<Type>& elementType); |
| const Type* getElementType() const; |
| |
| virtual std::string templatedTypeName() const = 0; |
| std::string typeName() const override; |
| |
| bool isTemplatedType() const override; |
| |
| virtual bool isCompatibleElementType(const Type* elementType) const = 0; |
| |
| std::vector<const Reference<Type>*> getReferences() const override; |
| |
| virtual status_t validate() const override; |
| |
| void emitVtsTypeDeclarations(Formatter& out) const override; |
| void emitVtsAttributeType(Formatter& out) const override; |
| |
| protected: |
| TemplatedType(Scope* parent); |
| Reference<Type> mElementType; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(TemplatedType); |
| }; |
| |
| } // namespace android |
| |
| #endif // TYPE_H_ |
| |