From f83b07774f133b20d74949bbc3bdf2f6147d7215 Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Sun, 28 Apr 2024 12:40:29 -0400
Subject: [PATCH] introduce new specials map

---
 gcc/cobol/symbols.cc | 11 +++++++++++
 gcc/cobol/symbols.h  | 21 +++++++++++++++++++++
 gcc/cobol/symfind.cc | 29 -----------------------------
 3 files changed, 32 insertions(+), 29 deletions(-)

diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc
index 7243e117f7b5..9f9f6445162a 100644
--- a/gcc/cobol/symbols.cc
+++ b/gcc/cobol/symbols.cc
@@ -79,6 +79,8 @@ static struct symbol_table_t {
 
   struct symbol_elem_t *elems;
 
+  std::map<elem_key_t, size_t> specials;
+  
   std::vector<symbol_pair_t> mappings;
 
   /*
@@ -698,6 +700,11 @@ symbol_function( size_t parent, const char name[] )
 struct symbol_elem_t *
 symbol_special( size_t program, const char name[] )
 {
+  elem_key_t key( program, name );
+  auto p = symbols.specials.find(key);
+  if( p == symbols.specials.end() ) return NULL;
+  return symbol_at(p->second);
+#if 0
   cbl_special_name_t special = { .id = special_name_t(-1) };
   assert(strlen(name) < sizeof special.name);
   strcpy(special.name, name);
@@ -709,6 +716,7 @@ symbol_special( size_t program, const char name[] )
                                                  &symbols.nelem, sizeof(key),
                                                  symbol_elem_cmp ) );
   return e;
+#endif
 }
 
 struct symbol_elem_t *
@@ -3665,6 +3673,9 @@ symbol_special_add( size_t program, struct cbl_special_name_t *special )
 	   e->elem.special.name);
   }
 
+  elem_key_t key(program, cbl_special_name_of(e)->name);
+  symbols.specials[key] = symbol_index(e);
+
   return e;
 }
 
diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h
index e6fe844e48e1..70a2378f5151 100644
--- a/gcc/cobol/symbols.h
+++ b/gcc/cobol/symbols.h
@@ -643,6 +643,27 @@ struct cbl_field_t {
   }
 };
 
+struct elem_key_t {
+  size_t program;
+  const char * name;
+  elem_key_t( size_t program, const cbl_name_t name  )
+    : program(program)
+    , name(name)
+  {}
+  bool operator<( const elem_key_t& that ) const {
+    if( program == that.program ) {
+      return  strcasecmp(name, that.name) < 0;
+    }
+    return program < that.program; 
+  }
+  bool operator==( const elem_key_t& that ) const {
+    if( program == that.program ) {
+      return strcasecmp(name, that.name) == 0;
+    }
+    return false;
+  }
+};
+
 struct field_key_t {
   size_t program;
   const char * name;
diff --git a/gcc/cobol/symfind.cc b/gcc/cobol/symfind.cc
index 535710cf3c91..c0e5f67ad6e4 100644
--- a/gcc/cobol/symfind.cc
+++ b/gcc/cobol/symfind.cc
@@ -383,15 +383,6 @@ name_has_names( const symbol_elem_t *e,
   return in_scope && name == names.rend();
 }
 
-//// remove if symbol_map2 works
-static bool
-is_typedef( const symbol_elem_t *elem ) {
-  if( elem->type == SymField ) {
-    return cbl_field_of(elem)->is_typedef();
-  }
-  return false;
-}
-
 size_t end_of_group( size_t igroup );
 
 static std::vector<size_t>
@@ -409,26 +400,6 @@ symbol_match2( size_t program,
     }
   }
 
-#if 0
-  auto e = symbols_begin(program);
-  if( is_program(*e) ) e++;
-
-  for( ; e != symbols_end(); e++ ) {
-    if( e->program != program ) break;
-    if( e->type != SymField ) continue;
-
-    if( is_typedef(e) ) {
-      auto isym = end_of_group( symbol_index(e) );
-      e = symbol_at(--isym);
-      continue;
-    }
-    
-    if( name_has_names( e, names, local ) ) {
-      fields.push_back( symbol_index(e) );
-    }
-  }
-#endif
-
   if( fields.empty() ){
     if( program > 0 ) { // try containing program
       program  = cbl_label_of(symbol_at(program))->parent;
-- 
GitLab