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