/* * 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 #include #include #include #include #include #include #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 getDefinedTypes(); virtual std::vector getDefinedTypes() const; // All types referenced in this type. std::vector*> getReferences(); virtual std::vector*> getReferences() const; // All constant expressions referenced in this type. std::vector getConstantExpressions(); virtual std::vector getConstantExpressions() const; // All types referenced in this type that must have completed // definiton before being referenced. std::vector*> getStrongReferences(); virtual std::vector*> getStrongReferences() const; // Proceeds recursive pass // Makes sure to visit each node only once. status_t recursivePass(const std::function& func, std::unordered_set* visited); status_t recursivePass(const std::function& func, std::unordered_set* 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* reversedOrder, std::unordered_set* stack) const; // Checks following C++ restriction on forward declaration: // inner struct could be forward declared only inside its parent. status_t checkForwardReferenceRestrictions(const Reference& 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* visited) const; virtual bool deepCanCheckEquality(std::unordered_set* 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* visited) const; virtual bool deepNeedsResolveReferences(std::unordered_set* 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* visited) const; virtual bool deepIsJavaCompatible(std::unordered_set* visited) const; // Returns true iff type contains pointer // (excluding methods and inner types). bool containsPointer() const; bool containsPointer(std::unordered_set* visited) const; virtual bool deepContainsPointer(std::unordered_set* visited) const; virtual void getAlignmentAndSize(size_t *align, size_t *size) const; virtual void appendToExportedTypesVector( std::vector *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& 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*> 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 mElementType; private: DISALLOW_COPY_AND_ASSIGN(TemplatedType); }; } // namespace android #endif // TYPE_H_