| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_FIDL_FIDLC_INCLUDE_FIDL_CODED_TYPES_GENERATOR_H_ |
| #define TOOLS_FIDL_FIDLC_INCLUDE_FIDL_CODED_TYPES_GENERATOR_H_ |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "coded_ast.h" |
| #include "flat_ast.h" |
| |
| namespace fidl { |
| |
| class CodedTypesGenerator { |
| public: |
| explicit CodedTypesGenerator(const flat::Library* library) : library_(library) {} |
| |
| void CompileCodedTypes(const WireFormat wire_format); |
| |
| const flat::Library* library() const { return library_; } |
| const std::vector<std::unique_ptr<coded::Type>>& coded_types() const { return coded_types_; } |
| |
| const coded::Type* CodedTypeFor(flat::Name::Key name) const { |
| auto it = named_coded_types_.find(name); |
| return it != named_coded_types_.end() ? it->second.get() : nullptr; |
| } |
| |
| std::vector<const coded::Type*> AllCodedTypes() const; |
| |
| private: |
| // Returns a pointer owned by coded_types_. |
| const coded::Type* CompileType(const flat::Type* type, coded::CodingContext context, |
| const WireFormat wire_format); |
| void CompileFields(const flat::Decl* decl, const WireFormat wire_format); |
| void CompileDecl(const flat::Decl* decl, const WireFormat wire_format); |
| void CompileXRef(const coded::Type* type, const WireFormat wire_format); |
| |
| // Representation of the fields of a struct member after it has been flattened. |
| struct FlattenedStructMember { |
| FlattenedStructMember(const flat::StructMember& member, const WireFormat wire_format); |
| const flat::Type* type; |
| const SourceSpan name; |
| const uint32_t inline_size; |
| uint32_t offset; |
| uint32_t padding; |
| }; |
| |
| // Flatten a list of flat-AST struct members by recursively descending and expanding. |
| // e.g.: |
| // struct A { int8 x; }; |
| // struct B { A y; int8 z; }; |
| // becomes the equivalent of |
| // struct B { int8 x; int8 z; }; |
| std::vector<FlattenedStructMember> FlattenedStructMembers(const flat::Struct& input, |
| const WireFormat wire_format); |
| |
| const flat::Library* library_; |
| |
| template <typename FlatType, typename CodedType> |
| using TypeMap = std::map<const FlatType*, const CodedType*, flat::PtrCompare<const FlatType>>; |
| |
| template <typename T, typename P = const T*> |
| struct MaybeCodedTypeCompare { |
| bool operator()(const std::pair<bool, P>& lhs, const std::pair<bool, P>& rhs) const { |
| flat::PtrCompare<T> comparator; |
| bool a_less_b = comparator(lhs.second, rhs.second); |
| bool b_less_a = comparator(rhs.second, lhs.second); |
| if (!a_less_b && !b_less_a) { |
| // types are equivalent |
| return lhs.first < rhs.first; |
| } else { |
| return a_less_b; |
| } |
| } |
| }; |
| |
| // All flat::Types and flat::Names here are owned by library_, and |
| // all coded::Types by the named_coded_types_ map or the coded_types_ vector. |
| TypeMap<flat::PrimitiveType, coded::PrimitiveType> primitive_type_map_; |
| TypeMap<flat::HandleType, coded::HandleType> handle_type_map_; |
| TypeMap<flat::RequestHandleType, coded::RequestHandleType> request_type_map_; |
| TypeMap<flat::IdentifierType, coded::ProtocolHandleType> protocol_type_map_; |
| TypeMap<flat::ArrayType, coded::ArrayType> array_type_map_; |
| TypeMap<flat::VectorType, coded::VectorType> vector_type_map_; |
| TypeMap<flat::StringType, coded::StringType> string_type_map_; |
| TypeMap<flat::IdentifierType, coded::StructPointerType> struct_type_map_; |
| |
| std::map<flat::Name::Key, std::unique_ptr<coded::Type>> named_coded_types_; |
| std::vector<std::unique_ptr<coded::Type>> coded_types_; |
| }; |
| |
| } // namespace fidl |
| |
| #endif // TOOLS_FIDL_FIDLC_INCLUDE_FIDL_CODED_TYPES_GENERATOR_H_ |