diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index c6fc305f4a44e97c0136b9641a52cac3742a0aae..2936d8bfd0ea80a1af5c15e1c7cc5b2064982019 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -2962,8 +2962,8 @@ new_temporary( enum cbl_field_type_t type ) { return parser_symbol_add2(field); } -cbl_field_t * -new_literal( const char initial[], enum cbl_field_attr_t attr ) { +static cbl_field_t * +new_literal_impl( const char initial[], enum cbl_field_attr_t attr ) { static char empty[2] = "\0"; cbl_field_t *field = NULL; if( !(attr & quoted_e) ) @@ -2989,6 +2989,28 @@ new_literal( const char initial[], enum cbl_field_attr_t attr ) { return parser_symbol_add2(field); } +static temporaries_t temporaries; + +cbl_field_t * +temporaries_t::literal( const char value[], cbl_field_attr_t attr ) { + auto p = literals.find(value); + if( p != literals.end() ) { + cbl_field_t *field = p->second; + if( false && attr != none_e && field->attr != attr ) { + warnx("temporaries_t::%s:%d: '%s' logic: using prior attr %08lx, not %08lx", + __func__, __LINE__, + field->data.initial, field->attr, attr); + } + return field; + } + return literals[value] = new_literal_impl(value, attr); +} + +cbl_field_t * +new_literal( const char initial[], enum cbl_field_attr_t attr ) { + return temporaries.literal(initial, attr); +} + cbl_field_t * new_alphanumeric( size_t capacity ) { cbl_field_t * field = new_temporary_impl(FldAlphanumeric); diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 463a0ecf161a109d84725eda9415716fccaf388d..c5f60e0561bc59c408ecc4e485e41aa8300d9f19 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -1183,6 +1183,14 @@ cbl_field_t * new_temporary( enum cbl_field_type_t type ); cbl_field_t * new_literal( const char initial[], enum cbl_field_attr_t attr = none_e ); +class temporaries_t { + std::map<std::string, cbl_field_t *> literals; + typedef std::set<cbl_field_t *> fieldset_t; + std::map<cbl_field_type_t, fieldset_t> used, freed; +public: + cbl_field_t *literal( const char value[], cbl_field_attr_t attr = none_e ); +}; + static inline bool is_table( const cbl_field_t *field ) { return field && field->occurs.ntimes() > 0; }