00001
00002
00003
00004
00005
00006
00007
00008 #include "itl_generator.h"
00009 #include "be_extern.h"
00010 #include "global_extern.h"
00011
00012 #include "utl_identifier.h"
00013 #include "utl_labellist.h"
00014
00015 #include <ast_fixed.h>
00016
00017 using namespace AstTypeClassification;
00018
00019 std::ostream&
00020 operator<<(std::ostream& out,
00021 const itl_generator::Indent& i)
00022 {
00023 out << std::string(static_cast<size_t> (i.generator->level_ * 2), ' ');
00024 return out;
00025 }
00026
00027 std::ostream&
00028 operator<<(std::ostream& out,
00029 const itl_generator::Open& i)
00030 {
00031 i.generator->level_ += 1;
00032 return out;
00033 }
00034
00035 std::ostream&
00036 operator<<(std::ostream& out,
00037 const itl_generator::Close& i)
00038 {
00039 i.generator->level_ -= 1;
00040 return out;
00041 }
00042
00043 struct InlineType {
00044 AST_Type* type;
00045
00046 explicit InlineType(AST_Type* t)
00047 : type(t)
00048 { }
00049 };
00050
00051 std::ostream&
00052 operator<<(std::ostream& out,
00053 const InlineType& it)
00054 {
00055 AST_Typedef* td = AST_Typedef::narrow_from_decl(it.type);
00056 if (td) {
00057 be_global->itl_ << '"' << it.type->repoID() << '"';
00058 return out;
00059 }
00060
00061 Classification c = classify(it.type);
00062 if (c & CL_STRING) {
00063
00064 if (c & CL_WIDE) {
00065 be_global->itl_ << "{ \"kind\" : \"string\", \"note\" : { \"idl\" : { \"type\" : \"wstring\" } } }";
00066 }
00067 else {
00068 be_global->itl_ << "{ \"kind\" : \"string\" }";
00069 }
00070 }
00071 else if (c & CL_PRIMITIVE) {
00072 switch (AST_PredefinedType::narrow_from_decl(it.type)->pt()) {
00073 case AST_PredefinedType::PT_long:
00074 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 32 }";
00075 break;
00076 case AST_PredefinedType::PT_ulong:
00077 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 32, \"unsigned\" : true}";
00078 break;
00079 case AST_PredefinedType::PT_longlong:
00080 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 64 }";
00081 break;
00082 case AST_PredefinedType::PT_ulonglong:
00083 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 64, \"unsigned\" : true}";
00084 break;
00085 case AST_PredefinedType::PT_short:
00086 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 16 }";
00087 break;
00088 case AST_PredefinedType::PT_ushort:
00089 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 16, \"unsigned\" : true}";
00090 break;
00091 case AST_PredefinedType::PT_float:
00092 be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary32\" }";
00093 break;
00094 case AST_PredefinedType::PT_double:
00095 be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary64\" }";
00096 break;
00097 case AST_PredefinedType::PT_longdouble:
00098 be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary128\" }";
00099 break;
00100 case AST_PredefinedType::PT_char:
00101 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 8, \"note\" : { \"presentation\" : { \"type\" : \"char\" } } }";
00102 break;
00103 case AST_PredefinedType::PT_wchar:
00104 be_global->itl_ << "{ \"kind\" : \"int\", \"note\" : { \"presentation\" : { \"type\" : \"char\" }, \"idl\" : { \"type\" : \"wchar\" } } }";
00105 break;
00106 case AST_PredefinedType::PT_boolean:
00107 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 1, \"note\" : { \"presentation\" : { \"type\" : \"bool\" } } }";
00108 break;
00109 case AST_PredefinedType::PT_octet:
00110 be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 8, \"unsigned\" : true }";
00111 break;
00112 case AST_PredefinedType::PT_any:
00113 case AST_PredefinedType::PT_object:
00114 case AST_PredefinedType::PT_value:
00115 case AST_PredefinedType::PT_abstract:
00116 case AST_PredefinedType::PT_void:
00117 case AST_PredefinedType::PT_pseudo:
00118
00119 break;
00120 }
00121 }
00122 else {
00123 be_global->itl_ << '"' << it.type->repoID() << '"';
00124 }
00125
00126 return out;
00127 }
00128
00129 void itl_generator::gen_prologue()
00130 {
00131 be_global->itl_ << Indent(this) << "{\n"
00132 << Open(this)
00133 << Indent(this) << "\"types\" :\n"
00134 << Open(this)
00135 << Indent(this) << "[\n";
00136 }
00137
00138 void itl_generator::gen_epilogue()
00139 {
00140 be_global->itl_ << Indent(this) << "]\n"
00141 << Close(this)
00142 << Close(this)
00143 << Indent(this) << "}\n";
00144 }
00145
00146 void itl_generator::new_type()
00147 {
00148 if (count_ > 0)
00149 be_global->itl_ << Indent(this) << ",\n";
00150 ++count_;
00151 }
00152
00153 bool itl_generator::gen_enum(AST_Enum*, UTL_ScopedName* ,
00154 const std::vector<AST_EnumVal*>& contents, const char* repoid)
00155 {
00156 if (!be_global->generate_itl())
00157 return true;
00158
00159 new_type();
00160
00161 be_global->itl_ << Open(this)
00162 << Indent(this) << "{\n"
00163 << Open(this)
00164 << Indent(this) << "\"kind\" : \"alias\",\n"
00165 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00166 << Indent(this) << "\"type\" :\n"
00167 << Open(this)
00168 << Indent(this) << "{\n"
00169 << Open(this)
00170 << Indent(this) << "\"kind\" : \"int\",\n"
00171 << Indent(this) << "\"bits\" : 32,\n"
00172 << Indent(this) << "\"unsigned\" : true,\n"
00173 << Indent(this) << "\"constrained\" : true,\n"
00174 << Indent(this) << "\"values\" : {";
00175
00176 for (size_t i = 0; i < contents.size(); ++i) {
00177 if (i > 0)
00178 be_global->itl_ << ", ";
00179 be_global->itl_ << '"' << contents[i]->local_name()->get_string() << '"'
00180 << " : "
00181 << '"' << i << '"';
00182 }
00183
00184 be_global->itl_ << "}\n";
00185 be_global->itl_ << Close(this)
00186 << Indent(this) << "}\n"
00187 << Close(this);
00188
00189 be_global->itl_ << Close(this)
00190 << Indent(this) << "}\n"
00191 << Close(this);
00192
00193 return true;
00194 }
00195
00196 bool itl_generator::gen_typedef(AST_Typedef*, UTL_ScopedName* ,
00197 AST_Type* base,
00198 const char* repoid)
00199 {
00200 if (!be_global->generate_itl())
00201 return true;
00202
00203 new_type();
00204 switch (base->node_type()) {
00205 case AST_Decl::NT_sequence:
00206 {
00207 AST_Sequence *seq = AST_Sequence::narrow_from_decl(base);
00208 be_global->itl_ << Open(this)
00209 << Indent(this) << "{\n"
00210 << Open(this)
00211 << Indent(this) << "\"kind\" : \"alias\",\n"
00212 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00213 << Indent(this) << "\"type\" :\n"
00214 << Open(this)
00215 << Indent(this) << "{\n"
00216 << Open(this)
00217 << Indent(this) << "\"kind\" : \"sequence\",\n";
00218 if (!seq->unbounded()) {
00219 be_global->itl_ << Indent(this) << "\"capacity\" : " << seq->max_size()->ev()->u.ulval << ",\n";
00220 }
00221 be_global->itl_ << Indent(this) << "\"type\" : " << InlineType(seq->base_type()) << "\n"
00222 << Close(this)
00223 << Indent(this) << "}\n"
00224 << Close(this)
00225 << Close(this)
00226 << Indent(this) << "}\n"
00227 << Close(this);
00228 break;
00229 }
00230 case AST_Decl::NT_array:
00231 {
00232 AST_Array* arr = AST_Array::narrow_from_decl(base);
00233 be_global->itl_ << Open(this)
00234 << Indent(this) << "{\n"
00235 << Open(this)
00236 << Indent(this) << "\"kind\" : \"alias\",\n"
00237 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00238 << Indent(this) << "\"type\" :\n"
00239 << Open(this)
00240 << Indent(this) << "{\n"
00241 << Open(this)
00242 << Indent(this) << "\"kind\" : \"sequence\",\n"
00243 << Indent(this) << "\"type\" : " << InlineType(arr->base_type()) << ",\n"
00244 << Indent(this) << "\"size\" : [";
00245 ACE_CDR::ULong dims = arr->n_dims();
00246 for (size_t i = 0; i < dims; ++i) {
00247 if (i > 0)
00248 be_global->itl_ << ", ";
00249 be_global->itl_ << arr->dims()[i]->ev()->u.ulval;
00250 }
00251 be_global->itl_ << "]\n"
00252 << Close(this)
00253 << Indent(this) << "}\n"
00254 << Close(this)
00255 << Close(this)
00256 << Indent(this) << "}\n"
00257 << Close(this);
00258 break;
00259 }
00260 case AST_Decl::NT_fixed:
00261 {
00262 AST_Fixed* fixed = AST_Fixed::narrow_from_decl(base);
00263 unsigned digits = fixed->digits()->ev()->u.ulval;
00264 unsigned scale = fixed->scale()->ev()->u.ulval;
00265 be_global->itl_
00266 << Open(this) << Indent(this) << "{\n" << Open(this)
00267 << Indent(this) << "\"kind\" : \"alias\",\n"
00268 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00269 << Indent(this) << "\"type\" : { "
00270 << "\"kind\" : \"fixed\", "
00271 << "\"digits\" : " << digits << ", "
00272 << "\"scale\" : " << scale << ", "
00273 << "\"base\" : 10 }\n"
00274 << Close(this) << Indent(this) << "}\n" << Close(this);
00275 break;
00276 }
00277 default:
00278 {
00279 be_global->itl_ << Open(this)
00280 << Indent(this) << "{\n"
00281 << Open(this)
00282 << Indent(this) << "\"kind\" : \"alias\",\n"
00283 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00284 << Indent(this) << "\"type\" : " << InlineType(base) << "\n"
00285 << Close(this)
00286 << Indent(this) << "}\n"
00287 << Close(this);
00288
00289 return true;
00290 }
00291 }
00292 return true;
00293 }
00294
00295 bool itl_generator::gen_struct(AST_Structure*, UTL_ScopedName* name,
00296 const std::vector<AST_Field*>& fields,
00297 AST_Type::SIZE_TYPE, const char* repoid)
00298 {
00299 if (!be_global->generate_itl())
00300 return true;
00301
00302 new_type();
00303 be_global->itl_ << Open(this)
00304 << Indent(this) << "{\n"
00305 << Open(this)
00306 << Indent(this) << "\"kind\" : \"alias\",\n"
00307 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00308
00309
00310 << Indent(this) << "\"note\" : { \"is_dcps_data_type\" : "
00311 << (idl_global->is_dcps_type(name) ? "true" : "false")
00312 << " },\n"
00313
00314 << Indent(this) << "\"type\" :\n"
00315 << Open(this)
00316 << Indent(this) << "{\n"
00317 << Open(this)
00318 << Indent(this) << "\"kind\" : \"record\",\n"
00319 << Indent(this) << "\"fields\" :\n"
00320 << Open(this)
00321 << Indent(this) << "[\n";
00322
00323 bool comma_flag = false;
00324 for (std::vector<AST_Field*>::const_iterator pos = fields.begin(), limit = fields.end();
00325 pos != limit;
00326 ++pos) {
00327 AST_Field* field = *pos;
00328 if (comma_flag) {
00329 be_global->itl_ << Indent(this) << ",\n";
00330 }
00331 be_global->itl_ << Open(this)
00332 << Indent(this) << "{\n"
00333 << Open(this)
00334 << Indent(this) << "\"name\" : \"" << field->local_name()->get_string() << "\",\n"
00335 << Indent(this) << "\"type\" : " << InlineType(field->field_type()) << "\n"
00336 << Close(this)
00337 << Indent(this) << "}\n"
00338 << Close(this);
00339 comma_flag = true;
00340 }
00341
00342 be_global->itl_ << Indent(this) << "]\n"
00343 << Close(this)
00344 << Close(this)
00345 << Indent(this) << "}\n"
00346 << Close(this)
00347 << Close(this)
00348 << Indent(this) << "}\n"
00349 << Close(this);
00350
00351
00352 return true;
00353 }
00354
00355
00356 bool itl_generator::gen_union(AST_Union*, UTL_ScopedName* ,
00357 const std::vector<AST_UnionBranch*>& cases,
00358 AST_Type* _d,
00359 const char* repoid)
00360 {
00361 if (!be_global->generate_itl())
00362 return true;
00363
00364 new_type();
00365 be_global->itl_ << Open(this)
00366 << Indent(this) << "{\n"
00367 << Open(this)
00368 << Indent(this) << "\"kind\" : \"alias\",\n"
00369 << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00370 << Indent(this) << "\"type\" :\n"
00371 << Open(this)
00372 << Indent(this) << "{\n"
00373 << Open(this)
00374 << Indent(this) << "\"kind\" : \"union\",\n"
00375 << Indent(this) << "\"discriminator\" : " << InlineType(_d) << ",\n"
00376 << Indent(this) << "\"fields\" :\n"
00377 << Open(this)
00378 << Indent(this) << "[\n";
00379
00380 for (std::vector<AST_UnionBranch*>::const_iterator pos = cases.begin(), limit = cases.end();
00381 pos != limit;
00382 ++pos) {
00383 if (pos != cases.begin())
00384 be_global->itl_ << Indent(this) << ",\n";
00385
00386 AST_UnionBranch *branch = *pos;
00387
00388 be_global->itl_ << Open(this)
00389 << Indent(this) << "{\n"
00390 << Open(this)
00391 << Indent(this) << "\"name\" : \"" << branch->local_name()->get_string() << "\",\n"
00392 << Indent(this) << "\"type\" : " << InlineType(branch->field_type()) << ",\n"
00393
00394 << Indent(this) << "\"labels\" : [";
00395
00396
00397 unsigned long count = branch->label_list_length();
00398 for (unsigned long i = 0; i < count; i++)
00399 {
00400 if (i > 0)
00401 be_global->itl_ << ", ";
00402 AST_UnionLabel *label = branch->label(i);
00403 if (label->label_kind() == AST_UnionLabel::UL_default)
00404 {
00405 continue;
00406 }
00407 be_global->itl_ << "\"" << label->label_val()->n()->last_component()->get_string() << "\"";
00408 }
00409
00410 be_global->itl_ << "]\n"
00411 << Close(this)
00412 << Indent(this) << "}\n"
00413 << Close(this);
00414 }
00415
00416 be_global->itl_ << Indent(this) << "]\n"
00417 << Close(this)
00418 << Close(this)
00419 << Indent(this) << "}\n"
00420 << Close(this)
00421 << Close(this)
00422 << Indent(this) << "}\n"
00423 << Close(this);
00424
00425 return true;
00426 }