| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- // Filename: cppInstanceIdentifier.cxx
- // Created by: drose (21Oct99)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // 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."
- //
- ////////////////////////////////////////////////////////////////////
- #include "cppInstanceIdentifier.h"
- #include "cppPointerType.h"
- #include "cppReferenceType.h"
- #include "cppArrayType.h"
- #include "cppConstType.h"
- #include "cppFunctionType.h"
- #include "cppParameterList.h"
- #include "cppIdentifier.h"
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Modifier::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::Modifier::
- Modifier(CPPInstanceIdentifierType type) :
- _type(type)
- {
- _func_params = NULL;
- _func_flags = 0;
- _scoping = NULL;
- _expr = NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Modifier::named func_type constructor
- // Access: Public, Static
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
- func_type(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
- Modifier mod(IIT_func);
- mod._func_params = params;
- mod._func_flags = flags;
- mod._trailing_return_type = trailing_return_type;
- return mod;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Modifier::named array_type constructor
- // Access: Public, Static
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
- array_type(CPPExpression *expr) {
- Modifier mod(IIT_array);
- mod._expr = expr;
- return mod;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Modifier::named scoped_pointer_type
- // Access: Public, Static
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
- scoped_pointer_type(CPPIdentifier *scoping) {
- Modifier mod(IIT_scoped_pointer);
- mod._scoping = scoping;
- return mod;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Modifier::named initializer_type constructor
- // Access: Public, Static
- // Description: This is used only for instance declarations that turn
- // out to be have a parameter list for an initializer.
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::Modifier CPPInstanceIdentifier::Modifier::
- initializer_type(CPPParameterList *params) {
- Modifier mod(IIT_initializer);
- mod._func_params = params;
- return mod;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::Constructor
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPInstanceIdentifier::
- CPPInstanceIdentifier(CPPIdentifier *ident) :
- _ident(ident),
- _bit_width(-1) {
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::unroll_type
- // Access: Public
- // Description: Unrolls the list of type punctuation on either side
- // of the identifier to determine the actual type
- // represented by the identifier, given the indicated
- // starting type (that is, the type name written to the
- // left of the identifier).
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPInstanceIdentifier::
- unroll_type(CPPType *start_type) {
- CPPType *result = r_unroll_type(start_type, _modifiers.begin());
- return result;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_modifier
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_modifier(CPPInstanceIdentifierType type) {
- _modifiers.push_back(Modifier(type));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_func_modifier
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_func_modifier(CPPParameterList *params, int flags, CPPType *trailing_return_type) {
- // As a special hack, if we added a parameter list to an operator
- // function, check if the parameter list is empty. If it is, this
- // is really a unary operator, so set the unary_op flag. Operators
- // () and [] are never considered unary operators.
- if (_ident != NULL &&
- _ident->get_simple_name().substr(0, 9) == "operator ") {
- if (_ident->get_simple_name() != string("operator ()") &&
- _ident->get_simple_name() != string("operator []")) {
- if (params->_parameters.empty()) {
- flags |= CPPFunctionType::F_unary_op;
- }
- }
- flags |= CPPFunctionType::F_operator;
- }
- if (trailing_return_type != NULL) {
- // Remember whether trailing return type notation was used.
- flags |= CPPFunctionType::F_trailing_return_type;
- }
- _modifiers.push_back(Modifier::func_type(params, flags, trailing_return_type));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_scoped_pointer_modifier
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_scoped_pointer_modifier(CPPIdentifier *scoping) {
- _modifiers.push_back(Modifier::scoped_pointer_type(scoping));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_array_modifier
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_array_modifier(CPPExpression *expr) {
- // Special case for operator new[] and delete[]. We're not really
- // adding an array modifier to them, but appending [] to the
- // identifier. This is to work around a parser ambiguity.
- if (_ident != NULL && (_ident->get_simple_name() == "operator delete" ||
- _ident->get_simple_name() == "operator new")) {
- _ident->_names.back().append_name("[]");
- } else {
- _modifiers.push_back(Modifier::array_type(expr));
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_initializer_modifier
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_initializer_modifier(CPPParameterList *params) {
- _modifiers.push_back(Modifier::initializer_type(params));
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::add_trailing_return_type
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- void CPPInstanceIdentifier::
- add_trailing_return_type(CPPType *type) {
- // This is an awkward hack. Improve in the future.
- if (!_modifiers.empty()) {
- Modifier &mod = _modifiers.back();
- if (mod._type == IIT_func) {
- mod._trailing_return_type = type;
- mod._func_flags |= CPPFunctionType::F_trailing_return_type;
- return;
- }
- }
- cerr << "trailing return type can only be added to a function\n";
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::get_initializer
- // Access: Public
- // Description: Returns the initializer parameter list that was set
- // for this particular instance, e.g. if the instance
- // were:
- //
- // int foo(0);
- //
- // this would return the parameter list (0). Returns
- // NULL if the instance did not use a parameter list
- // initializer.
- ////////////////////////////////////////////////////////////////////
- CPPParameterList *CPPInstanceIdentifier::
- get_initializer() const {
- Modifiers::const_iterator mi;
- for (mi = _modifiers.begin(); mi != _modifiers.end(); ++mi) {
- const Modifier &mod = (*mi);
- if (mod._type == IIT_initializer) {
- return mod._func_params;
- }
- }
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::get_scope
- // Access: Public
- // Description:
- ////////////////////////////////////////////////////////////////////
- CPPScope *CPPInstanceIdentifier::
- get_scope(CPPScope *current_scope, CPPScope *global_scope,
- CPPPreprocessor *error_sink) const {
- if (_ident == NULL) {
- return current_scope;
- } else {
- return _ident->get_scope(current_scope, global_scope, error_sink);
- }
- }
- ////////////////////////////////////////////////////////////////////
- // Function: CPPInstanceIdentifier::r_unroll_type
- // Access: Private
- // Description: The recursive implementation of unroll_type().
- ////////////////////////////////////////////////////////////////////
- CPPType *CPPInstanceIdentifier::
- r_unroll_type(CPPType *start_type,
- CPPInstanceIdentifier::Modifiers::const_iterator mi) {
- assert(start_type != NULL);
- start_type = CPPType::new_type(start_type);
- if (mi == _modifiers.end()) {
- return start_type;
- }
- const Modifier &mod = (*mi);
- ++mi;
- CPPType *result = NULL;
- switch (mod._type) {
- case IIT_pointer:
- result = new CPPPointerType(r_unroll_type(start_type, mi));
- break;
- case IIT_reference:
- result = new CPPReferenceType(r_unroll_type(start_type, mi),
- CPPReferenceType::VC_lvalue);
- break;
- case IIT_rvalue_reference:
- result = new CPPReferenceType(r_unroll_type(start_type, mi),
- CPPReferenceType::VC_rvalue);
- break;
- case IIT_scoped_pointer:
- {
- CPPType *type = r_unroll_type(start_type, mi);
- CPPFunctionType *ftype = type->as_function_type();
- if (ftype != NULL) {
- ftype = new CPPFunctionType(*ftype);
- ftype->_class_owner = mod._scoping;
- ftype->_flags |= CPPFunctionType::F_method_pointer;
- type = ftype;
- }
- result = new CPPPointerType(type);
- }
- break;
- case IIT_array:
- result = new CPPArrayType(r_unroll_type(start_type, mi),
- mod._expr);
- break;
- case IIT_const:
- result = new CPPConstType(r_unroll_type(start_type, mi));
- break;
- case IIT_volatile:
- // Just pass it through for now.
- result = r_unroll_type(start_type, mi);
- break;
- case IIT_paren:
- result = r_unroll_type(start_type, mi);
- break;
- case IIT_func:
- {
- CPPType *return_type = r_unroll_type(start_type, mi);
- if (mod._trailing_return_type != (CPPType *)NULL) {
- CPPSimpleType *simple_type = return_type->as_simple_type();
- if (simple_type != NULL && simple_type->_type == CPPSimpleType::T_auto) {
- return_type = mod._trailing_return_type;
- } else {
- cerr << "function with trailing return type needs auto\n";
- }
- }
- result = new CPPFunctionType(return_type, mod._func_params,
- mod._func_flags);
- }
- break;
- case IIT_initializer:
- // In this case, we have parsed an instance declaration with a set
- // of initializers as a parameter list. We lose the initializers
- // at this point, but the instance will put it back again.
- result = start_type;
- break;
- default:
- cerr << "Internal error--invalid CPPInstanceIdentifier\n";
- abort();
- }
- return CPPType::new_type(result);
- }
|