| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /**
- * 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 cppReferenceType.cxx
- * @author drose
- * @date 1999-10-19
- */
- #include "cppReferenceType.h"
- #include "cppFile.h"
- #include "cppStructType.h"
- /**
- *
- */
- CPPReferenceType::
- CPPReferenceType(CPPType *pointing_at, ValueCategory vcat) :
- CPPType(CPPFile()),
- _pointing_at(pointing_at),
- _value_category(vcat)
- {
- }
- /**
- * Returns true if this declaration is an actual, factual declaration, or
- * false if some part of the declaration depends on a template parameter which
- * has not yet been instantiated.
- */
- bool CPPReferenceType::
- is_fully_specified() const {
- return CPPType::is_fully_specified() &&
- _pointing_at->is_fully_specified();
- }
- /**
- *
- */
- CPPDeclaration *CPPReferenceType::
- 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;
- }
- CPPReferenceType *rep = new CPPReferenceType(*this);
- rep->_pointing_at =
- _pointing_at->substitute_decl(subst, current_scope, global_scope)
- ->as_type();
- if (rep->_pointing_at == _pointing_at) {
- delete rep;
- rep = this;
- }
- rep = CPPType::new_type(rep)->as_reference_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 *CPPReferenceType::
- resolve_type(CPPScope *current_scope, CPPScope *global_scope) {
- CPPType *ptype = _pointing_at->resolve_type(current_scope, global_scope);
- if (ptype != _pointing_at) {
- CPPReferenceType *rep = new CPPReferenceType(*this);
- rep->_pointing_at = ptype;
- return CPPType::new_type(rep);
- }
- return this;
- }
- /**
- * 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 CPPReferenceType::
- is_tbd() const {
- return _pointing_at->is_tbd();
- }
- /**
- * Returns true if the type is considered a standard layout type.
- */
- bool CPPReferenceType::
- is_standard_layout() const {
- return false;
- }
- /**
- * Returns true if the type is considered a Plain Old Data (POD) type.
- */
- bool CPPReferenceType::
- is_trivial() const {
- return false;
- }
- /**
- * Returns true if the type can be constructed using the given argument.
- */
- bool CPPReferenceType::
- is_constructible(const CPPType *given_type) const {
- const CPPType *a;
- const CPPType *b;
- CPPReferenceType *ref_type = ((CPPType *)given_type)->as_reference_type();
- if (ref_type != nullptr) {
- if (ref_type->_value_category == VC_rvalue) {
- return is_constructible(ref_type->_pointing_at);
- }
- if (_value_category == VC_rvalue) {
- // Can never initialize an rvalue ref from an lvalue ref.
- return false;
- }
- if (!_pointing_at->is_const()) {
- // Cannot initialize a non-const reference using a const one.
- if (ref_type->_pointing_at->is_const()) {
- return false;
- }
- }
- a = _pointing_at->remove_cv();
- b = ref_type->_pointing_at->remove_cv();
- } else {
- // Initializing using an rvalue.
- if (!_pointing_at->is_const()) {
- // Cannot initialize a non-const reference using a const one.
- if (given_type->is_const()) {
- return false;
- }
- // Cannot initalise a non-const lvalue reference with an rvalue ref.
- if (_value_category == VC_lvalue) {
- return false;
- }
- }
- a = _pointing_at->remove_cv();
- b = ((CPPType *)given_type)->remove_cv();
- }
- if (a == b || *a == *b) {
- return true;
- }
- // Can initialize from derived class pointer.
- const CPPStructType *a_struct = a->as_struct_type();
- const CPPStructType *b_struct = b->as_struct_type();
- if (a_struct != nullptr && b_struct != nullptr) {
- return a_struct->is_base_of(b_struct);
- }
- return false;
- }
- /**
- * Returns true if the type is default-constructible.
- */
- bool CPPReferenceType::
- is_default_constructible() const {
- return false;
- }
- /**
- * Returns true if the type is copy-constructible.
- */
- bool CPPReferenceType::
- is_copy_constructible() const {
- return (_value_category == VC_lvalue);
- }
- /**
- * Returns true if the type is destructible.
- */
- bool CPPReferenceType::
- is_destructible() const {
- return false;
- }
- /**
- * 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 CPPReferenceType::
- is_equivalent(const CPPType &other) const {
- const CPPReferenceType *ot = ((CPPType *)&other)->as_reference_type();
- if (ot == nullptr) {
- return CPPType::is_equivalent(other);
- }
- return _pointing_at->is_equivalent(*ot->_pointing_at);
- }
- /**
- *
- */
- void CPPReferenceType::
- output(std::ostream &out, int indent_level, CPPScope *scope, bool complete) const {
- /*
- _pointing_at->output(out, indent_level, scope, complete);
- out << " &";
- */
- output_instance(out, indent_level, scope, complete, "", "");
- }
- /**
- * Formats a C++-looking line that defines an instance of the given type, with
- * the indicated name. In most cases this will be "type name", but some types
- * have special exceptions.
- */
- void CPPReferenceType::
- output_instance(std::ostream &out, int indent_level, CPPScope *scope,
- bool complete, const std::string &prename,
- const std::string &name) const {
- if (_value_category == VC_rvalue) {
- _pointing_at->output_instance(out, indent_level, scope, complete,
- "&&" + prename, name);
- } else {
- _pointing_at->output_instance(out, indent_level, scope, complete,
- "&" + prename, name);
- }
- }
- /**
- *
- */
- CPPDeclaration::SubType CPPReferenceType::
- get_subtype() const {
- return ST_reference;
- }
- /**
- *
- */
- CPPReferenceType *CPPReferenceType::
- as_reference_type() {
- return this;
- }
- /**
- * Called by CPPDeclaration() to determine whether this type is equivalent to
- * another type of the same type.
- */
- bool CPPReferenceType::
- is_equal(const CPPDeclaration *other) const {
- const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
- assert(ot != nullptr);
- return (_pointing_at == ot->_pointing_at) &&
- (_value_category == ot->_value_category);
- }
- /**
- * Called by CPPDeclaration() to determine whether this type should be ordered
- * before another type of the same type, in an arbitrary but fixed ordering.
- */
- bool CPPReferenceType::
- is_less(const CPPDeclaration *other) const {
- const CPPReferenceType *ot = ((CPPDeclaration *)other)->as_reference_type();
- assert(ot != nullptr);
- if (_value_category != ot->_value_category) {
- return (_value_category < ot->_value_category);
- }
- return _pointing_at < ot->_pointing_at;
- }
|