diff options
Diffstat (limited to 'tools/intergen/model/src/model/composite_type.cc')
-rw-r--r-- | tools/intergen/model/src/model/composite_type.cc | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/tools/intergen/model/src/model/composite_type.cc b/tools/intergen/model/src/model/composite_type.cc new file mode 100644 index 0000000000..57e89cce54 --- /dev/null +++ b/tools/intergen/model/src/model/composite_type.cc @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2014, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "model/composite_type.h" + +#include <cassert> +#include <iostream> +#include <utility> + +#include "model/constant.h" +#include "utils/safeformat.h" +#include "utils/common_types.h" + +using typesafe_format::strmfmt; + +namespace codegen { + +/* + * Array type + */ +Array::Array(const Type* type, const Range& range) + : type_(type), + range_(range) { +} + +Array::~Array() { +} + +const Type* Array::type() const { + return type_; +} + +const Array::Range& Array::range() const { + return range_; +} + +bool Array::operator <(const Array& that) const { + if (type_ != that.type_) { + return size_t(type_) < size_t(that.type_); + } + if (range_.min() == that.range_.min()) + return range_.min() < that.range_.min(); + return range_.max() < that.range_.max(); +} + +TypeCodeGenerator* Array::Apply(TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForArray(this); + return code_generator; +} + +const ConstantsCreator* Array::SupportsConstants() const { + return NULL; +} + +/* + * Map type + */ +Map::Map(const Type* type, const Range& range) + : type_(type), + range_(range) { +} + +Map::~Map() { +} + +const Type* Map::type() const { + return type_; +} + +const Map::Range& Map::range() const { + return range_; +} + +bool Map::operator <(const Map& that) const { + if (type_ != that.type_) { + return size_t(type_) < size_t(that.type_); + } + if (range_.min() == that.range_.min()) + return range_.min() < that.range_.min(); + return range_.max() < that.range_.max(); +} + +TypeCodeGenerator* Map::Apply(TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForMap(this); + return code_generator; +} + +const ConstantsCreator* Map::SupportsConstants() const { + return NULL; +} + +/* + * Enum type + */ + +// static +const char* Enum::kFunctionIdEnumName = "FunctionID"; + +Enum::Enum(const Interface* interface, + const std::string& name, + Scope scope, + InternalScope internal_scope, + const Description& description) + : interface_(interface), + name_(name), + scope_(scope), + internal_scope_(internal_scope), + description_(description), + last_constant_value_(-1) { + assert(interface); +} + +Enum::~Enum() { +} + +const Interface& Enum::interface() const { + return *interface_; +} + +const std::string& Enum::name() const { + return name_; +} + +const Enum::ConstantsList& Enum::constants() const { + return constants_; +} + +const Enum::ConstantsByName& Enum::constants_by_name() const { + return constants_by_name_; +} + +const Scope& Enum::scope() const { + return scope_; +} + +const InternalScope& Enum::internal_scope() const { + return internal_scope_; +} + +const Description& Enum::description() const { + return description_; +} + +TypeCodeGenerator* Enum::Apply(TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForEnum(this); + return code_generator; +} + +const ConstantsCreator* Enum::SupportsConstants() const { + return this; +} + +const codegen::Constant* Enum::ConstantFor(const std::string& literal) const { + ConstantsByName::const_iterator i = constants_by_name_.find(literal); + if (i != constants_by_name_.end()) + return i->second; + else { + return NULL; + } +} + +bool Enum::AddConstant(const std::string& name, Scope scope, + const std::string& internal_name, + const Description& description, + const std::string& design_description) { + if (ConstantFor(name) != NULL) { + strmfmt(std::cerr, "Constant {0} already defined in enum {1}\n", name, + name_); + return false; + } + constants_.push_back( + Constant(this, name, last_constant_value_ + 1, false, scope, internal_name, + description, design_description)); + constants_by_name_[name] = &constants_.back(); + ++last_constant_value_; + return true; +} + +bool Enum::AddConstant(const std::string& name, const int64_t value, + Scope scope, const std::string& internal_name, + const Description& description, + const std::string& design_description) { + if (ConstantFor(name) != NULL) { + strmfmt(std::cerr, "Constant {0} already defined in enum {1}\n", name, + name_); + return false; + } + constants_.push_back( + Constant(this, name, value, true, scope, internal_name, description, + design_description)); + constants_by_name_[name] = &constants_.back(); + last_constant_value_ = value; + return true; +} + + +/* + * Struct type + */ +Struct::Struct(const Interface* interface, + const std::string& name, + const Type* frankenmap, + Scope scope, + const Description& description) + : interface_(interface), + name_(name), + frankenmap_(frankenmap), + scope_(scope), + description_(description) { + assert(interface_); +} + +Struct::~Struct() { +} + +const std::string& Struct::Field::name() const { + return name_; +} + +bool Struct::Field::is_mandatory() const { + return mandatory_; +} + +const Description& Struct::description() const { + return description_; +} + +const Struct::FieldsList& Struct::fields() const { + return fields_; +} + +const Scope& Struct::scope() const { + return scope_; +} + +bool Struct::AddField(const Type* type, const std::string& name, bool mandatory, + Scope scope, const Constant* default_value, + const Description& description, Platform platform) { + fields_.push_back( + Field(type, name, mandatory, scope, default_value, description, platform)); + return true; +} + +TypeCodeGenerator* Struct::Apply(TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForStruct(this); + return code_generator; +} + +const ConstantsCreator* Struct::SupportsConstants() const { + return NULL; +} + +const Type* Struct::Field::type() const { + return type_; +} + +const Interface& Struct::interface() const { + return *interface_; +} + +const Type* Struct::frankenstruct() const { + return frankenmap_; +} + +const std::string& Struct::name() const { + return name_; +} + +const Constant* Struct::Field::default_value() const { + return default_value_; +} + +const Scope& Struct::Field::scope() const { + return scope_; +} + +const Description& Struct::Field::description() const { + return description_; +} + +Struct::Field::Field(const Type* type, const std::string& name, bool mandatory, + Scope scope, const Constant* default_value, + const Description& description, Platform platform) + : type_(type), + name_(name), + mandatory_(mandatory), + default_value_(default_value), + scope_(scope), + description_(description), + platform_(platform){ +} + +NullableType::NullableType(const Type* type) + : type_(type) { +} + +const Type* NullableType::type() const { + return type_; +} + +bool NullableType::operator<(const NullableType& that) const { + // Simple pointer comparison should be enough here + if (type_ != that.type_) { + return type_ < that.type_; + } +} + +TypeCodeGenerator* NullableType::Apply( + TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForNullable(this); + return code_generator; +} + +const ConstantsCreator* NullableType::SupportsConstants() const { + return type_->SupportsConstants(); +} + +Typedef::Typedef(const Interface* interface, + const std::string& name, + const Type* type, + const Description& description) + : interface_(interface), + name_(name), + type_(type), + description_(description) { + assert(interface_); +} + +const Description& Typedef::description() const { + return description_; +} + +const Interface& Typedef::interface() const { + return *interface_; +} + +const std::string& Typedef::name() const { + return name_; +} + +const Type* Typedef::type() const { + return type_; +} + +TypeCodeGenerator* Typedef::Apply(TypeCodeGenerator* code_generator) const { + code_generator->GenerateCodeForTypedef(this); + return code_generator; +} + +const ConstantsCreator* Typedef::SupportsConstants() const { + return NULL; +} + +} // namespace codegen |