00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cppExtensionType.h"
00021 #include "cppTypedef.h"
00022 #include "cppIdentifier.h"
00023 #include "cppParser.h"
00024 #include "indent.h"
00025
00026
00027
00028
00029
00030
00031 CPPExtensionType::
00032 CPPExtensionType(CPPExtensionType::Type type,
00033 CPPIdentifier *ident, CPPScope *current_scope,
00034 const CPPFile &file) :
00035 CPPType(file),
00036 _type(type), _ident(ident)
00037 {
00038 if (_ident != NULL) {
00039 _ident->_native_scope = current_scope;
00040 }
00041 }
00042
00043
00044
00045
00046
00047
00048 string CPPExtensionType::
00049 get_simple_name() const {
00050 if (_ident == NULL) {
00051 return "";
00052 }
00053 return _ident->get_simple_name();
00054 }
00055
00056
00057
00058
00059
00060
00061 string CPPExtensionType::
00062 get_local_name(CPPScope *scope) const {
00063 if (_ident == NULL) {
00064 return "";
00065 }
00066 return _ident->get_local_name(scope);
00067 }
00068
00069
00070
00071
00072
00073
00074 string CPPExtensionType::
00075 get_fully_scoped_name() const {
00076 if (_ident == NULL) {
00077 return "";
00078 }
00079 return _ident->get_fully_scoped_name();
00080 }
00081
00082
00083
00084
00085
00086
00087
00088 bool CPPExtensionType::
00089 is_incomplete() const {
00090 return true;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 bool CPPExtensionType::
00102 is_tbd() const {
00103 if (_ident != (CPPIdentifier *)NULL) {
00104 return _ident->is_tbd();
00105 }
00106 return false;
00107 }
00108
00109
00110
00111
00112
00113
00114 CPPDeclaration *CPPExtensionType::
00115 substitute_decl(CPPDeclaration::SubstDecl &subst,
00116 CPPScope *current_scope, CPPScope *global_scope) {
00117 SubstDecl::const_iterator si = subst.find(this);
00118 if (si != subst.end()) {
00119 return (*si).second;
00120 }
00121
00122 CPPExtensionType *rep = new CPPExtensionType(*this);
00123 if (_ident != NULL) {
00124 rep->_ident =
00125 _ident->substitute_decl(subst, current_scope, global_scope);
00126 }
00127
00128 if (rep->_ident == _ident) {
00129 delete rep;
00130 rep = this;
00131 }
00132 rep = CPPType::new_type(rep)->as_extension_type();
00133 subst.insert(SubstDecl::value_type(this, rep));
00134 return rep;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 bool CPPExtensionType::
00148 is_equivalent(const CPPType &other) const {
00149 const CPPExtensionType *ot = ((CPPType *)&other)->as_extension_type();
00150 if (ot == (CPPExtensionType *)NULL) {
00151 return CPPType::is_equivalent(other);
00152 }
00153
00154
00155
00156
00157 return *_ident == *ot->_ident;
00158 }
00159
00160
00161
00162
00163
00164
00165 void CPPExtensionType::
00166 output(ostream &out, int, CPPScope *scope, bool) const {
00167 if (_ident != NULL) {
00168
00169 if (cppparser_output_class_keyword) {
00170 out << _type << " ";
00171 }
00172 out << _ident->get_local_name(scope);
00173
00174 } else if (!_typedefs.empty()) {
00175
00176 out << _typedefs.front()->get_local_name(scope);
00177
00178 } else {
00179 out << "(**unknown forward-reference type**)";
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188 CPPDeclaration::SubType CPPExtensionType::
00189 get_subtype() const {
00190 return ST_extension;
00191 }
00192
00193
00194
00195
00196
00197
00198 CPPExtensionType *CPPExtensionType::
00199 as_extension_type() {
00200 return this;
00201 }
00202
00203 ostream &
00204 operator << (ostream &out, CPPExtensionType::Type type) {
00205 switch (type) {
00206 case CPPExtensionType::T_enum:
00207 return out << "enum";
00208
00209 case CPPExtensionType::T_class:
00210 return out << "class";
00211
00212 case CPPExtensionType::T_struct:
00213 return out << "struct";
00214
00215 case CPPExtensionType::T_union:
00216 return out << "union";
00217
00218 default:
00219 return out << "***invalid extension type***";
00220 }
00221 }