OpenDDS  Snapshot(2023/04/07-19:43)
Public Member Functions | Private Attributes | List of all members
metaclass_generator Class Reference

#include <metaclass_generator.h>

Inheritance diagram for metaclass_generator:
Inheritance graph
[legend]
Collaboration diagram for metaclass_generator:
Collaboration graph
[legend]

Public Member Functions

 metaclass_generator ()
 
bool gen_enum (AST_Enum *node, UTL_ScopedName *name, const std::vector< AST_EnumVal *> &contents, const char *repoid)
 
bool gen_struct (AST_Structure *node, UTL_ScopedName *name, const std::vector< AST_Field *> &fields, AST_Type::SIZE_TYPE size, const char *repoid)
 
bool gen_typedef (AST_Typedef *node, UTL_ScopedName *name, AST_Type *type, const char *repoid)
 
bool gen_union (AST_Union *node, UTL_ScopedName *name, const std::vector< AST_UnionBranch *> &branches, AST_Type *type, const char *repoid)
 
- Public Member Functions inherited from dds_generator
virtual ~dds_generator ()=0
 
virtual bool do_included_files () const
 
virtual void gen_prologue ()
 
virtual void gen_epilogue ()
 
virtual bool gen_const (UTL_ScopedName *, bool, AST_Constant *)
 
virtual bool gen_struct_fwd (UTL_ScopedName *, AST_Type::SIZE_TYPE)
 
virtual bool gen_interf (AST_Interface *, UTL_ScopedName *, bool, const std::vector< AST_Interface *> &, const std::vector< AST_Interface *> &, const std::vector< AST_Attribute *> &, const std::vector< AST_Operation *> &, const char *)
 
virtual bool gen_interf_fwd (UTL_ScopedName *)
 
virtual bool gen_native (AST_Native *, UTL_ScopedName *, const char *)
 
virtual bool gen_union_fwd (AST_UnionFwd *, UTL_ScopedName *, AST_Type::SIZE_TYPE)
 

Private Attributes

bool first_struct_
 

Additional Inherited Members

- Static Public Member Functions inherited from dds_generator
static std::string get_tag_name (const std::string &base_name, bool nested_key_only=false)
 
static std::string get_xtag_name (UTL_ScopedName *name)
 
static bool cxx_escaped (const std::string &s)
 
static std::string valid_var_name (const std::string &str)
 
static std::string to_string (Identifier *id, EscapeContext ec=EscapeContext_Normal)
 
static std::string scoped_helper (UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
 
static std::string module_scope_helper (UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)
 

Detailed Description

Definition at line 13 of file metaclass_generator.h.

Constructor & Destructor Documentation

◆ metaclass_generator()

metaclass_generator::metaclass_generator ( )
inline

Definition at line 15 of file metaclass_generator.h.

References gen_enum(), gen_struct(), gen_typedef(), gen_union(), and name.

16  : first_struct_(true)
17  {}

Member Function Documentation

◆ gen_enum()

bool metaclass_generator::gen_enum ( AST_Enum *  node,
UTL_ScopedName *  name,
const std::vector< AST_EnumVal *> &  contents,
const char *  repoid 
)
virtual

Reimplemented from dds_generator.

Definition at line 46 of file metaclass_generator.cpp.

References be_global, ACE_String_Base< char >::c_str(), canonical_name(), AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_SCALAR, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::CL_UNION, AstTypeClassification::classify(), TopicKeys::count(), extensibilitykind_mutable, marshal_generator::gen_field_getValueFromSerialized(), NestedForLoops::index_, OpenDDS::XTypes::key_count(), name, AstTypeClassification::resolveActualType(), scoped(), dds_generator::scoped_helper(), and string_type().

Referenced by metaclass_generator().

48 {
49  NamespaceGuard ng;
50  std::string array_decl = "const char* gen_" + scoped_helper(name, "_") + "_names[]";
51  std::string size_decl = "const size_t gen_" + scoped_helper(name, "_") + "_names_size";
52  std::string decl_prefix = ((be_global->export_macro() == "") ? std::string("extern ") : (std::string(be_global->export_macro().c_str()) + " extern "));
53  be_global->header_ << decl_prefix << array_decl << ";\n";
54  be_global->header_ << decl_prefix << size_decl << ";\n";
55  be_global->impl_ << array_decl << " = {\n";
56  for (size_t i = 0; i < contents.size(); ++i) {
57  be_global->impl_ << " \"" << canonical_name(contents[i])
58  << ((i < contents.size() - 1) ? "\",\n" : "\"\n");
59  }
60  be_global->impl_ << "};\n";
61  be_global->impl_ << size_decl << " = " << contents.size() << ";\n";
62  return true;
63 }
const char * c_str(void) const
std::string canonical_name(UTL_ScopedName *sn)
const char *const name
Definition: debug.cpp:60
BE_GlobalData * be_global
Definition: be_global.cpp:43
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)

◆ gen_struct()

bool metaclass_generator::gen_struct ( AST_Structure *  node,
UTL_ScopedName *  name,
const std::vector< AST_Field *> &  fields,
AST_Type::SIZE_TYPE  size,
const char *  repoid 
)
virtual

Implements dds_generator.

Definition at line 468 of file metaclass_generator.cpp.

References Function::addArg(), FieldInfo::arr_, array_element_count(), FieldInfo::as_act_, be_global, AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_PRIMITIVE, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::classify(), Function::endArgs(), marshal_generator::generate_dheader_code(), dds_generator::get_tag_name(), FieldInfo::is_new(), FieldInfo::length_, FieldInfo::ptr_, AstTypeClassification::resolveActualType(), scoped(), dds_generator::scoped_helper(), FieldInfo::seq_, and to_cxx_type().

Referenced by metaclass_generator().

470 {
471  const std::string clazz = scoped(name);
472  ContentSubscriptionGuard csg;
473  NamespaceGuard ng;
474  be_global->add_include("dds/DCPS/PoolAllocator.h",
475  BE_GlobalData::STREAM_CPP);
476 
477  if (!generate_metaclass(node, name, fields, first_struct_, clazz)) {
478  return false;
479  }
480 
481  FieldInfo::EleLenSet anonymous_seq_generated;
482  for (size_t i = 0; i < fields.size(); ++i) {
483  if (fields[i]->field_type()->anonymous()) {
484  FieldInfo af(*fields[i]);
485  if (af.arr_ || (af.seq_ && af.is_new(anonymous_seq_generated))) {
486  Function f("gen_skip_over", "bool");
487  f.addArg("ser", "Serializer&");
488  f.addArg("", af.ptr_);
489  f.endArgs();
490 
491  AST_Type* elem;
492  if (af.seq_ != 0) {
493  elem = af.seq_->base_type();
494  } else {
495  elem = af.arr_->base_type();
496  }
497  be_global->impl_ <<
498  " const Encoding& encoding = ser.encoding();\n"
499  " ACE_UNUSED_ARG(encoding);\n";
500  Classification elem_cls = classify(elem);
501  const bool primitive = elem_cls & CL_PRIMITIVE;
503  " if (!ser.read_delimiter(total_size)) {\n"
504  " return false;\n"
505  " }\n", !primitive, true);
506 
507  std::string len;
508  if (af.arr_) {
509  std::ostringstream strstream;
510  strstream << array_element_count(af.arr_);
511  len = strstream.str();
512  } else { // Sequence
513  be_global->impl_ <<
514  " ACE_CDR::ULong length;\n"
515  " if (!(ser >> length)) return false;\n";
516  len = "length";
517  }
518  const std::string cxx_elem = scoped(elem->name());
519  AST_Type* elem_orig = elem;
520  elem = resolveActualType(elem);
521  elem_cls = classify(elem);
522 
523  if ((elem_cls & (CL_PRIMITIVE | CL_ENUM))) {
524  // fixed-length sequence/array element -> skip all elements at once
525  size_t sz = 0;
526  to_cxx_type(af.as_act_, sz);
527  be_global->impl_ <<
528  " return ser.skip(" << af.length_ << ", " << sz << ");\n";
529  } else {
530  be_global->impl_ <<
531  " for (ACE_CDR::ULong i = 0; i < " << len << "; ++i) {\n";
532  if (elem_cls & CL_STRING) {
533  be_global->impl_ <<
534  " ACE_CDR::ULong strlength;\n"
535  " if (!(ser >> strlength)) return false;\n"
536  " if (!ser.skip(strlength)) return false;\n";
537  } else if (elem_cls & (CL_ARRAY | CL_SEQUENCE | CL_STRUCTURE)) {
538  std::string pre, post;
539  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
540  if (!use_cxx11 && (elem_cls & CL_ARRAY)) {
541  post = "_forany";
542  } else if (use_cxx11 && (elem_cls & (CL_ARRAY | CL_SEQUENCE))) {
543  pre = "IDL::DistinctType<";
544  post = ", " + dds_generator::get_tag_name(dds_generator::scoped_helper(elem_orig->name(), "_")) + ">";
545  }
546  be_global->impl_ <<
547  " if (!gen_skip_over(ser, static_cast<" << pre << cxx_elem << post
548  << "*>(0))) return false;\n";
549  }
550  be_global->impl_ <<
551  " }\n";
552  be_global->impl_ <<
553  " return true;\n";
554  }
555 
556  }
557  }
558  }
559 
560  {
561  Function f("gen_skip_over", "bool");
562  f.addArg("ser", "Serializer&");
563  f.addArg("", clazz + "*");
564  f.endArgs();
565  be_global->impl_ <<
566  " MetaStructImpl<" << clazz << ">().getValue(ser, \"\");\n"
567  " return true;\n";
568  }
569  return true;
570 }
const Classification CL_ARRAY
static std::string get_tag_name(const std::string &base_name, bool nested_key_only=false)
const Classification CL_STRUCTURE
AST_Type * resolveActualType(AST_Type *element)
const Classification CL_PRIMITIVE
Classification classify(AST_Type *type)
const Classification CL_STRING
const Classification CL_ENUM
const Classification CL_SEQUENCE
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
ACE_CDR::ULong array_element_count(AST_Array *arr)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
std::set< EleLen > EleLenSet
Definition: field_info.h:31
std::string to_cxx_type(AST_Type *type, std::size_t &size)
const char *const name
Definition: debug.cpp:60
BE_GlobalData * be_global
Definition: be_global.cpp:43
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)

◆ gen_typedef()

bool metaclass_generator::gen_typedef ( AST_Typedef *  node,
UTL_ScopedName *  name,
AST_Type *  type,
const char *  repoid 
)
virtual

Implements dds_generator.

Definition at line 573 of file metaclass_generator.cpp.

References Function::addArg(), array_element_count(), be_global, AstTypeClassification::CL_ARRAY, AstTypeClassification::CL_ENUM, AstTypeClassification::CL_PRIMITIVE, AstTypeClassification::CL_SEQUENCE, AstTypeClassification::CL_STRING, AstTypeClassification::CL_STRUCTURE, AstTypeClassification::classify(), Function::endArgs(), marshal_generator::generate_dheader_code(), dds_generator::get_tag_name(), AstTypeClassification::resolveActualType(), scoped(), and to_cxx_type().

Referenced by metaclass_generator().

575 {
576  AST_Array* arr = dynamic_cast<AST_Array*>(type);
577  AST_Sequence* seq = 0;
578  if (!arr && !(seq = dynamic_cast<AST_Sequence*>(type))) {
579  return true;
580  }
581  const bool use_cxx11 = be_global->language_mapping() == BE_GlobalData::LANGMAP_CXX11;
582 
583  const std::string clazz = scoped(name);
584  ContentSubscriptionGuard csg;
585  NamespaceGuard ng;
586  Function f("gen_skip_over", "bool");
587  f.addArg("ser", "Serializer&");
588  if (use_cxx11) {
589  f.addArg("", "IDL::DistinctType<" + clazz + ", " + dds_generator::get_tag_name(clazz) +">*");
590  } else {
591  f.addArg("", clazz + (arr ? "_forany*" : "*"));
592  }
593  f.endArgs();
594 
595  AST_Type* elem;
596  if (seq != 0) {
597  elem = seq->base_type();
598  } else {
599  elem = arr->base_type();
600  }
601  be_global->impl_ <<
602  " const Encoding& encoding = ser.encoding();\n"
603  " ACE_UNUSED_ARG(encoding);\n";
604  Classification elem_cls = classify(elem);
605  const bool primitive = elem_cls & CL_PRIMITIVE;
607  " if (!ser.read_delimiter(total_size)) {\n"
608  " return false;\n"
609  " }\n", !primitive, true);
610 
611  std::string len;
612 
613  if (arr) {
614  std::ostringstream strstream;
615  strstream << array_element_count(arr);
616  len = strstream.str();
617  } else { // Sequence
618  be_global->impl_ <<
619  " ACE_CDR::ULong length;\n"
620  " if (!(ser >> length)) return false;\n";
621  len = "length";
622  }
623 
624  const std::string cxx_elem = scoped(elem->name());
625  AST_Type* elem_orig = elem;
626  elem = resolveActualType(elem);
627  elem_cls = classify(elem);
628 
629  if ((elem_cls & (CL_PRIMITIVE | CL_ENUM))) {
630  // fixed-length sequence/array element -> skip all elements at once
631  size_t sz = 0;
632  to_cxx_type(elem, sz);
633  be_global->impl_ <<
634  " return ser.skip(" << len << ", " << sz << ");\n";
635  } else {
636  be_global->impl_ <<
637  " for (ACE_CDR::ULong i = 0; i < " << len << "; ++i) {\n";
638  if (elem_cls & CL_STRING) {
639  be_global->impl_ <<
640  " ACE_CDR::ULong strlength;\n"
641  " if (!(ser >> strlength)) return false;\n"
642  " if (!ser.skip(strlength)) return false;\n";
643  } else if (elem_cls & (CL_ARRAY | CL_SEQUENCE | CL_STRUCTURE)) {
644  std::string pre, post;
645  if (!use_cxx11 && (elem_cls & CL_ARRAY)) {
646  post = "_forany";
647  } else if (use_cxx11 && (elem_cls & (CL_ARRAY | CL_SEQUENCE))) {
648  pre = "IDL::DistinctType<";
649  post = ", " + dds_generator::get_tag_name(scoped_helper(elem_orig->name(), "::")) + ">";
650  }
651  be_global->impl_ <<
652  " if (!gen_skip_over(ser, static_cast<" << pre << cxx_elem << post
653  << "*>(0))) return false;\n";
654  }
655  be_global->impl_ <<
656  " }\n";
657  be_global->impl_ <<
658  " return true;\n";
659  }
660 
661  return true;
662 }
const Classification CL_ARRAY
static std::string get_tag_name(const std::string &base_name, bool nested_key_only=false)
const Classification CL_STRUCTURE
AST_Type * resolveActualType(AST_Type *element)
const Classification CL_PRIMITIVE
Classification classify(AST_Type *type)
const Classification CL_STRING
const Classification CL_ENUM
const Classification CL_SEQUENCE
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
ACE_CDR::ULong array_element_count(AST_Array *arr)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
std::string to_cxx_type(AST_Type *type, std::size_t &size)
const char *const name
Definition: debug.cpp:60
BE_GlobalData * be_global
Definition: be_global.cpp:43
static std::string scoped_helper(UTL_ScopedName *sn, const char *sep, EscapeContext cxt=EscapeContext_Normal)

◆ gen_union()

bool metaclass_generator::gen_union ( AST_Union *  node,
UTL_ScopedName *  name,
const std::vector< AST_UnionBranch *> &  branches,
AST_Type *  type,
const char *  repoid 
)
virtual

Implements dds_generator.

Definition at line 706 of file metaclass_generator.cpp.

References Function::addArg(), be_global, Function::endArgs(), extensibilitykind_final, extensibilitykind_mutable, func(), marshal_generator::generate_dheader_code(), generateSwitchForUnion(), getWrapper(), scoped(), and WD_INPUT.

Referenced by metaclass_generator().

709 {
710  const std::string clazz = scoped(name);
711  ContentSubscriptionGuard csg;
712  NamespaceGuard ng;
713 
714  std::vector<AST_Field*> dummy_field_list;
715  if (!generate_metaclass(node, name, dummy_field_list, first_struct_, clazz)) {
716  return false;
717  }
718 
719  {
720  Function f("gen_skip_over", "bool");
721  f.addArg("ser", "Serializer&");
722  f.addArg("", clazz + "*");
723  f.endArgs();
724 
725  const ExtensibilityKind exten = be_global->extensibility(node);
726  const bool not_final = exten != extensibilitykind_final;
727  const bool is_mutable = exten == extensibilitykind_mutable;
728  be_global->impl_ <<
729  " const Encoding& encoding = ser.encoding();\n"
730  " ACE_UNUSED_ARG(encoding);\n"
731  " const bool is_mutable = " << is_mutable <<";\n"
732  " unsigned member_id;\n"
733  " size_t field_size;\n"
734  " bool must_understand = false;\n";
736  " if (!ser.read_delimiter(total_size)) {\n"
737  " return false;\n"
738  " }\n", not_final);
739  if (is_mutable) {
740  be_global->impl_ <<
741  " if (!ser.read_parameter_id(member_id, field_size, must_understand)) {\n"
742  " return false;\n"
743  " }\n";
744  }
745  be_global->impl_ <<
746  " " << scoped(discriminator->name()) << " disc;\n"
747  " if (!(ser >> " << getWrapper("disc", discriminator, WD_INPUT) << ")) {\n"
748  " return false;\n"
749  " }\n";
750  if (generateSwitchForUnion(node, "disc", func, branches, discriminator, "", "", "",
751  false, true, false)) {
752  be_global->impl_ <<
753  " return true;\n";
754  }
755  }
756  return true;
757 }
std::string getWrapper(const std::string &name, AST_Type *type, WrapDirection wd)
ExtensibilityKind
Definition: annotations.h:278
static std::string func(const std::string &, AST_Decl *, const std::string &, AST_Type *br_type, const std::string &, bool, Intro &, const std::string &)
std::string scoped(UTL_ScopedName *sn, EscapeContext ec=EscapeContext_Normal)
static void generate_dheader_code(const std::string &code, bool dheader_required, bool is_ser_func=true)
const char *const name
Definition: debug.cpp:60
bool generateSwitchForUnion(AST_Union *u, const char *switchExpr, CommonFn commonFn, const std::vector< AST_UnionBranch *> &branches, AST_Type *discriminator, const char *statementPrefix, const char *namePrefix="", const char *uni="", bool forceDisableDefault=false, bool parens=true, bool breaks=true, CommonFn commonFn2=0)
returns true if a default: branch was generated (no default: label in IDL)
BE_GlobalData * be_global
Definition: be_global.cpp:43

Member Data Documentation

◆ first_struct_

bool metaclass_generator::first_struct_
private

Definition at line 33 of file metaclass_generator.h.


The documentation for this class was generated from the following files: