diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y index 00380de3543ffbc4c194ec65d0a3e263b68e2223..b8968e0abda9da86d179dbb4d3447fa7ca6eef09 100644 --- a/gcc/cobol/parse.y +++ b/gcc/cobol/parse.y @@ -3299,6 +3299,7 @@ data_clause: any_length { $$ = any_length_e; } | same_clause { $$ = same_clause_e; } | sign_clause { $$ = sign_clause_e; } | synched_clause { $$ = synched_clause_e; } + | type_clause { $$ = type_clause_e; } | typedef_clause { $$ = typedef_clause_e; } | usage_clause { $$ = usage_clause_e; } | value_clause { $$ = value_clause_e; @@ -3842,6 +3843,20 @@ sign_separate: %empty { $$ = false; } | SEPARATE { $$ = true; } ; +/* + * "The effect of the TYPE clause is as though the data description identified + * by type-name- 1 had been coded in place of the TYPE clause, excluding the + * level-number, name, alignment, and the GLOBAL, SELECT WHEN, and TYPEDEF + * clauses specified for type-name-1;" + */ +type_clause: is TYPE strong + { + cbl_field_t *field = current_field(); + field->attr |= typedef_e; + yywarn("warning: TYPEDEF not implemented"); + } + ; + typedef_clause: is TYPEDEF strong { cbl_field_t *field = current_field(); diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 2d59541a4ab3d70b1a37b00308601a15dbda27e1..83c1b31337d918e24f299c314a0d5aa67365b05e 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -200,7 +200,8 @@ enum data_clause_t { based_clause_e = 0x0800, same_clause_e = 0x1000, volatile_clause_e = 0x2000, - typedef_clause_e = 0x4000, + type_clause_e = 0x4000, + typedef_clause_e = 0x8000, }; static inline bool diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index f88cfade06d7b40ac15808121b1980b0f49f87c8..8b4587c62f1ec3081688e531965d8c1ee7fd3d5d 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -3106,10 +3106,15 @@ temporaries_t::acquire( cbl_field_type_t type ) { } void -temporaries_t::unacquire( cbl_field_t * field ) { - auto& fields = used[field->type]; - fields.erase(field); - freed[field->type].insert(field); +symbol_temporaries_free() { + for( auto& elem : temporaries.used ) { + const cbl_field_type_t& type(elem.first); + temporaries_t::fieldset_t& used(elem.second); + auto freed = std::inserter(temporaries.freed[type], + temporaries.freed[type].begin()); + std::copy( used.begin(), used.end(), freed ); + used.clear(); + } } cbl_field_t * diff --git a/gcc/cobol/symbols.h b/gcc/cobol/symbols.h index 999511c216771f9c76e14f62a6a9d0c6d1561d45..d435898e1be1a8d631a0bf96ba1fb47a2375b6bd 100644 --- a/gcc/cobol/symbols.h +++ b/gcc/cobol/symbols.h @@ -1191,7 +1191,10 @@ cbl_field_t * new_temporary( enum cbl_field_type_t type ); cbl_field_t * new_literal( uint32_t len, const char initial[], enum cbl_field_attr_t attr = none_e ); +void symbol_temporaries_free(); + class temporaries_t { + friend void symbol_temporaries_free(); struct literal_an { bool is_quoted; std::string value; @@ -1217,9 +1220,9 @@ class temporaries_t { public: cbl_field_t *literal( const char value[], uint32_t len, cbl_field_attr_t attr = none_e ); cbl_field_t *acquire( cbl_field_type_t type ); - void unacquire( cbl_field_t * field ); }; + static inline bool is_table( const cbl_field_t *field ) { return field && field->occurs.ntimes() > 0; }