From d2f16dfb4f6b70648cae2649371975ee675c0dfd Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Thu, 8 Mar 2018 13:35:01 +0100
Subject: [PATCH] Improved performance of checking coding attributes (bug
 532066)

Change-Id: I4068064d3f81521238023b85119aac78648999ef
Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
---
 compiler2/Type.cc     |  2 ++
 compiler2/Type.hh     |  2 ++
 compiler2/Type_chk.cc | 11 ++++++++++-
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/compiler2/Type.cc b/compiler2/Type.cc
index 9cd8d936a..0726ca4b3 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 cd3ac9e58..7f316ae40 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 f93130c37..c0502c217 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.
-- 
GitLab