From f82e47114ec2c33a68058f5154b944379cb95cbe Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Mon, 29 Apr 2024 17:29:58 -0400
Subject: [PATCH] improve symbol_exists()

---
 gcc/cobol/scan_ante.h | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index 54a9255da7a4..c2b734902c42 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -410,6 +410,8 @@ static int symbol_function_token( const char name[] ) {
   return e ? symbol_index(e) : 0;
 }
 
+bool in_procedure_division(void );
+
 static symbol_elem_t *
 symbol_exists( const char name[] ) {
   typedef std::map <std::string, size_t> name_cache_t;
@@ -418,17 +420,34 @@ symbol_exists( const char name[] ) {
   cbl_name_t lname;
   std::transform( name, name + strlen(name) + 1, lname, tolower );
   auto& cache = cachemap[PROGRAM];
+
+  if( in_procedure_division() && cache.empty() ) {
+    for( auto e = symbols_begin(PROGRAM) + 1;
+	 PROGRAM == e->program && e < symbols_end(); e++ ) {
+      if( e->type == SymFile ) {
+	cbl_file_t *f(cbl_file_of(e));
+	cbl_name_t lname;
+	std::transform( f->name, f->name + strlen(f->name) + 1, lname, tolower );
+	cache[lname] = symbol_index(e);
+	continue;
+      }
+      if( e->type == SymField ) {
+	auto f(cbl_field_of(e));
+	cbl_name_t lname;
+	std::transform( f->name, f->name + strlen(f->name) + 1, lname, tolower );
+	cache[lname] = symbol_index(e);
+      }
+    }
+    cache.erase("");
+  }
   auto p = cache.find(lname);
   
   if( p == cache.end() ) {
     symbol_elem_t * e = symbol_field( PROGRAM, 0, name );
-    if( !e ) return NULL;
-    cache[lname] = symbol_index(e);
     return e;
   }
 
-  size_t isym = p->second;
-  return symbol_at(cache[lname] = isym);
+  return symbol_at(p->second);
 }
 
 static int
-- 
GitLab