| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- // Filename: cppType.C
- // Created by: drose (19Oct99)
- //
- ////////////////////////////////////////////////////////////////////
- #include "cppType.h"
- #include "cppTypedef.h"
- CPPType::Types CPPType::_types;
- CPPType::PreferredNames CPPType::_preferred_names;
- bool CPPTypeCompare::
- operator () (CPPType *a, CPPType *b) const {
- return (*a) < (*b);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPType::
- CPPType(const CPPFile &file) :
- CPPDeclaration(file)
- {
- _declaration = (CPPTypeDeclaration *)NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::resolve_type
- // Access: Public, Virtual
- // Description: 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 *CPPType::
- resolve_type(CPPScope *, CPPScope *) {
- return this;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::is_tbd
- // Access: Public, Virtual
- // Description: 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 CPPType::
- is_tbd() const {
- return false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::has_typedef_name
- // Access: Public
- // Description: Returns true if the type has even been typedef'ed and
- // therefore has a simple name available to stand for
- // it. Extension types are all implicitly typedef'ed on
- // declaration.
- ////////////////////////////////////////////////////////////////////
- bool CPPType::
- has_typedef_name() const {
- return !_typedefs.empty();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_typedef_name
- // Access: Public
- // Description: Returns a string that can be used to name the type,
- // if has_typedef_name() returned true. This will be
- // the first typedef name applied to the type.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_typedef_name(CPPScope *scope) const {
- if (_typedefs.empty()) {
- return string();
- } else {
- return _typedefs.front()->get_local_name(scope);
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_simple_name
- // Access: Public, Virtual
- // Description: Returns a fundametal one-word name for the type.
- // This name will not include any scoping operators or
- // template parameters, so it may not be a compilable
- // reference to the type.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_simple_name() const {
- return get_local_name();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_local_name
- // Access: Public, Virtual
- // Description: Returns the compilable, correct name for this type
- // within the indicated scope. If the scope is NULL,
- // within the scope the type is declared in.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_local_name(CPPScope *scope) const {
- ostringstream ostrm;
- output(ostrm, 0, scope, false);
- return ostrm.str();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_fully_scoped_name
- // Access: Public, Virtual
- // Description: Returns the compilable, correct name for the type,
- // with completely explicit scoping.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_fully_scoped_name() const {
- return get_local_name();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_preferred_name
- // Access: Public, Virtual
- // Description: Returns the best name to use for the type from a
- // programmer's point of view. This will typically be a
- // typedef name if one is available, or the full C++
- // name if it is not. The typedef may or may not be
- // visible within the current scope, so this type name
- // may not be compilable.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_preferred_name() const {
- string preferred_name = get_preferred_name_for(this);
- if (!preferred_name.empty()) {
- return preferred_name;
- }
- return get_local_name();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::is_incomplete
- // Access: Public, Virtual
- // Description: Returns true if the type has not yet been fully
- // specified, false if it has.
- ////////////////////////////////////////////////////////////////////
- bool CPPType::
- is_incomplete() const {
- return false;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::is_equivalent
- // Access: Public, Virtual
- // Description: 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 CPPType::
- is_equivalent(const CPPType &other) const {
- if (get_subtype() != other.get_subtype()) {
- return false;
- }
- return is_equal(&other);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::output_instance
- // Access: Public, Virtual
- // Description: 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 CPPType::
- output_instance(ostream &out, const string &name, CPPScope *scope) const {
- output_instance(out, 0, scope, false, "", name);
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::output_instance
- // Access: Public, Virtual
- // Description: 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 CPPType::
- output_instance(ostream &out, int indent_level, CPPScope *scope,
- bool complete, const string &prename,
- const string &name) const {
- output(out, indent_level, scope, complete);
- out << " " << prename << name;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::as_type
- // Access: Public, Virtual
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPType::
- as_type() {
- return this;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::new_type
- // Access: Public, Static
- // Description: This should be called whenever a new CPPType object
- // is created. It will uniquify the type pointers by
- // checking to see if some equivalent CPPType object has
- // previously been created; if it has, it returns the
- // old object and deletes the new one. Otherwise, it
- // stores the new one and returns it.
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPType::
- new_type(CPPType *type) {
- pair<Types::iterator, bool> result = _types.insert(type);
- if (result.second) {
- // The insertion has taken place; thus, this is the first time
- // this type has been declared.
- assert(*result.first == type);
- return type;
- }
- // The insertion has not taken place; thus, there was previously
- // another equivalent type declared.
- if (*result.first != type) {
- // *** Something wrong here. Deleting this should always be safe;
- // however, it's not. Thus, someone failed to call new_type() on
- // a type pointer before saving it somewhere. Fix me soon. ****
- //delete type;
- }
- return *result.first;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::record_preferred_name_for
- // Access: Public, Static
- // Description: Records a global typedef name associated with the
- // indicated Type. This will be taken as the
- // "preferred" name for this class, should anyone ask.
- ////////////////////////////////////////////////////////////////////
- void CPPType::
- record_preferred_name_for(const CPPType *type, const string &name) {
- if (!name.empty()) {
- string tname = type->get_fully_scoped_name();
- if (!tname.empty()) {
- _preferred_names.insert(PreferredNames::value_type(tname, name));
- }
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPType::get_preferred_name_for
- // Access: Public, Static
- // Description: Returns the previously-stored "preferred" name
- // associated with the type, if any, or empty string if
- // no name is associated.
- ////////////////////////////////////////////////////////////////////
- string CPPType::
- get_preferred_name_for(const CPPType *type) {
- // We do a lookup based on the type's name, instead of its pointer,
- // so we can resolve different expansions of the same type.
- string tname = type->get_fully_scoped_name();
- if (!tname.empty()) {
- PreferredNames::const_iterator pi;
- pi = _preferred_names.find(tname);
- if (pi != _preferred_names.end()) {
- return (*pi).second;
- }
- }
- return string();
- }
|