diff --git a/compiler2/Type.cc b/compiler2/Type.cc index 9cd8d936ad329fd61f59dcc8d9bfaf545b96b059..0726ca4b34c631ff1e52f8fa543bcae9f66503ab 100644 --- a/compiler2/Type.cc +++ b/compiler2/Type.cc @@ -64,6 +64,7 @@ extern Ttcn::ExtensionAttributes * parse_extattributes( namespace Common { map<Type*, void> Type::RecursionTracker::types; + dynamic_array<Type*> Type::coding_attrib_check_stack; using Ttcn::MultiWithAttrib; using Ttcn::SingleWithAttrib; @@ -593,6 +594,7 @@ namespace Common { raw_checked = false; xer_checked = false; variants_checked = false; + coding_attribs_checked = false; raw_length_calculated = false; has_opentypes = false; opentype_outermost = false; diff --git a/compiler2/Type.hh b/compiler2/Type.hh index cd3ac9e58ee34bd4fc87d9360a480aa3e252f844..7f316ae402f3dc2398d7ad313eede8557c49dc3c 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -344,6 +344,8 @@ namespace Common { bool raw_checked; bool xer_checked; bool variants_checked; + bool coding_attribs_checked; + static dynamic_array<Type*> coding_attrib_check_stack; bool raw_length_calculated; bool has_opentypes; bool opentype_outermost; diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index f93130c376b33133b41c0cb2b133cb3dd7316d4e..c0502c2177dd68bb088e3549d9c672ba18cac1e5 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -229,9 +229,11 @@ void Type::chk() void Type::chk_coding_attribs() { - if (!legacy_codec_handling && !variants_checked) { + if (coding_attribs_checked || (!legacy_codec_handling && !variants_checked)) { return; } + coding_attribs_checked = true; + coding_attrib_check_stack.add(this); if (typetype == T_SEQ_T || typetype == T_SET_T || typetype == T_CHOICE_T) { // If this record/set/union type has no attributes but one of its fields does, // create an empty attribute structure. @@ -268,6 +270,7 @@ void Type::chk_coding_attribs() if (!legacy_codec_handling) { if (RecursionTracker::is_happening(this)) { + coding_attrib_check_stack.remove(coding_attrib_check_stack.size() - 1); return; } @@ -302,6 +305,7 @@ void Type::chk_coding_attribs() } } } + coding_attrib_check_stack.remove(coding_attrib_check_stack.size() - 1); } void Type::parse_attributes() @@ -2622,6 +2626,11 @@ void Type::chk_xer() { // XERSTUFF semantic check t1->chk(); if (!legacy_codec_handling && !t1->xer_checked) { xer_checked = false; + // the attribute-checking flags for the types currently running this + // check must all be reset, so this type can be checked again + for (size_t i = 0; i < coding_attrib_check_stack.size(); ++i) { + coding_attrib_check_stack[i]->coding_attribs_checked = false; + } return; } // Merge XER attributes from the referenced type.