| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file cppExtensionType.cxx
- * @author drose
- * @date 1999-10-21
- */
- #include "cppExtensionType.h"
- #include "cppTypedefType.h"
- #include "cppIdentifier.h"
- #include "cppParser.h"
- #include <map>
- /**
- *
- */
- CPPExtensionType::
- CPPExtensionType(CPPExtensionType::Type type,
- CPPIdentifier *ident, CPPScope *current_scope,
- const CPPFile &file) :
- CPPType(file),
- _type(type), _ident(ident),
- _alignment(nullptr)
- {
- if (_ident != nullptr) {
- _ident->_native_scope = current_scope;
- }
- }
- /**
- *
- */
- std::string CPPExtensionType::
- get_simple_name() const {
- if (_ident == nullptr) {
- return "";
- }
- return _ident->get_simple_name();
- }
- /**
- *
- */
- std::string CPPExtensionType::
- get_local_name(CPPScope *scope) const {
- if (_ident == nullptr) {
- return "";
- }
- return _ident->get_local_name(scope);
- }
- /**
- *
- */
- std::string CPPExtensionType::
- get_fully_scoped_name() const {
- if (_ident == nullptr) {
- return "";
- }
- return _ident->get_fully_scoped_name();
- }
- /**
- * Returns true if the type has not yet been fully specified, false if it has.
- */
- bool CPPExtensionType::
- is_incomplete() const {
- return true;
- }
- /**
- * Returns true if the type, or any nested type within the type, is a
- * CPPTBDType and thus isn't fully determined right now. In this case,
- * calling resolve_type() may or may not resolve the type.
- */
- bool CPPExtensionType::
- is_tbd() const {
- if (_ident != nullptr) {
- return _ident->is_tbd();
- }
- return false;
- }
- /**
- * Returns true if the type is considered a standard layout type.
- */
- bool CPPExtensionType::
- is_standard_layout() const {
- return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
- }
- /**
- * Returns true if the type is considered a Plain Old Data (POD) type.
- */
- bool CPPExtensionType::
- is_trivial() const {
- return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
- }
- /**
- * Returns true if the type can be constructed using the given argument.
- */
- bool CPPExtensionType::
- is_constructible(const CPPType *given_type) const {
- if (_type == T_enum || _type == T_enum_class || _type == T_enum_struct) {
- const CPPExtensionType *other = ((CPPType *)given_type)->remove_reference()->remove_const()->as_extension_type();
- return other != nullptr && is_equal(other);
- }
- return false;
- }
- /**
- * Returns true if the type is default-constructible.
- */
- bool CPPExtensionType::
- is_default_constructible() const {
- return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
- }
- /**
- * Returns true if the type is copy-constructible.
- */
- bool CPPExtensionType::
- is_copy_constructible() const {
- return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
- }
- /**
- * Returns true if the type is copy-assignable.
- */
- bool CPPExtensionType::
- is_copy_assignable() const {
- return (_type == T_enum || _type == T_enum_class || _type == T_enum_struct);
- }
- /**
- *
- */
- CPPDeclaration *CPPExtensionType::
- substitute_decl(CPPDeclaration::SubstDecl &subst,
- CPPScope *current_scope, CPPScope *global_scope) {
- SubstDecl::const_iterator si = subst.find(this);
- if (si != subst.end()) {
- return (*si).second;
- }
- CPPExtensionType *rep = new CPPExtensionType(*this);
- if (_ident != nullptr) {
- rep->_ident =
- _ident->substitute_decl(subst, current_scope, global_scope);
- }
- if (rep->_ident == _ident) {
- delete rep;
- rep = this;
- }
- rep = CPPType::new_type(rep)->as_extension_type();
- subst.insert(SubstDecl::value_type(this, rep));
- return rep;
- }
- /**
- * If this CPPType object is a forward reference or other nonspecified
- * reference to a type that might now be known a real type, returns the real
- * type. Otherwise returns the type itself.
- */
- CPPType *CPPExtensionType::
- resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
- if (_ident == nullptr) {
- // We can't resolve anonymous types. But that's OK, since they can't be
- // forward declared anyway.
- return this;
- }
- // Maybe it has been defined by now.
- CPPType *type = _ident->find_type(current_scope, global_scope);
- if (type != nullptr) {
- return type;
- }
- return this;
- }
- /**
- * This is a little more forgiving than is_equal(): it returns true if the
- * types appear to be referring to the same thing, even if they may have
- * different pointers or somewhat different definitions. It's useful for
- * parameter matching, etc.
- */
- bool CPPExtensionType::
- is_equivalent(const CPPType &other) const {
- const CPPExtensionType *ot = ((CPPType *)&other)->as_extension_type();
- if (ot == nullptr) {
- return CPPType::is_equivalent(other);
- }
- // We consider two different extension types to be equivalent if they have
- // the same name.
- return *_ident == *ot->_ident;
- }
- /**
- *
- */
- void CPPExtensionType::
- output(std::ostream &out, int, CPPScope *scope, bool complete) const {
- if (_ident != nullptr) {
- // If we have a name, use it.
- if (complete || cppparser_output_class_keyword) {
- out << _type << " ";
- }
- out << _ident->get_local_name(scope);
- } else if (!_typedefs.empty()) {
- // If we have a typedef name, use it.
- out << _typedefs.front()->get_local_name(scope);
- } else {
- out << "(**unknown forward-reference type**)";
- }
- }
- /**
- *
- */
- CPPDeclaration::SubType CPPExtensionType::
- get_subtype() const {
- return ST_extension;
- }
- /**
- *
- */
- CPPExtensionType *CPPExtensionType::
- as_extension_type() {
- return this;
- }
- std::ostream &
- operator << (std::ostream &out, CPPExtensionType::Type type) {
- switch (type) {
- case CPPExtensionType::T_enum:
- return out << "enum";
- case CPPExtensionType::T_class:
- return out << "class";
- case CPPExtensionType::T_struct:
- return out << "struct";
- case CPPExtensionType::T_union:
- return out << "union";
- case CPPExtensionType::T_enum_class:
- return out << "enum class";
- case CPPExtensionType::T_enum_struct:
- return out << "enum struct";
- default:
- return out << "***invalid extension type***";
- }
- }
|