Class: AdLint::Cc1::VariableTable
- Inherits:
-
Object
- Object
- AdLint::Cc1::VariableTable
- Defined in:
- lib/adlint/cc1/object.rb
Instance Method Summary collapse
- #all_named_variables ⇒ Object
- #begin_variables_value_versioning ⇒ Object
- #declare(dcl, br) ⇒ Object
- #define(dcl_or_def, br, init_val = nil) ⇒ Object
- #define_temporary(type, init_val) ⇒ Object
- #designators ⇒ Object
- #end_variables_value_versioning ⇒ Object
- #enter_scope ⇒ Object
- #enter_variables_value_versioning_group ⇒ Object
-
#initialize(mem_pool) ⇒ VariableTable
constructor
A new instance of VariableTable.
- #leave_scope ⇒ Object
- #leave_variables_value_versioning_group(raise_complement) ⇒ Object
- #lookup(name_str) ⇒ Object
- #storage_duration_of(dcl_or_def) ⇒ Object
- #thin_latest_variables_value_version!(with_rollback) ⇒ Object
Constructor Details
#initialize(mem_pool) ⇒ VariableTable
Returns a new instance of VariableTable.
662 663 664 665 666 667 |
# File 'lib/adlint/cc1/object.rb', line 662 def initialize(mem_pool) @memory_pool = mem_pool @named_variables = [{}] @temp_variables = [[]] @scope_stack = [GlobalScope.new] end |
Instance Method Details
#all_named_variables ⇒ Object
669 670 671 |
# File 'lib/adlint/cc1/object.rb', line 669 def all_named_variables @named_variables.map { |hash| hash.values }.flatten end |
#begin_variables_value_versioning ⇒ Object
764 765 766 767 768 |
# File 'lib/adlint/cc1/object.rb', line 764 def begin_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.begin_value_versioning } end end |
#declare(dcl, br) ⇒ Object
691 692 693 694 695 696 697 698 699 700 |
# File 'lib/adlint/cc1/object.rb', line 691 def declare(dcl, br) if var = lookup(dcl.identifier.value) var.declarations_and_definitions.push(dcl) return var end # NOTE: External variable may have undefined values. define_variable(dcl, br, dcl.type, allocate_memory(dcl), dcl.type.undefined_value) end |
#define(dcl_or_def, br, init_val = nil) ⇒ Object
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 |
# File 'lib/adlint/cc1/object.rb', line 702 def define(dcl_or_def, br, init_val = nil) if storage_duration_of(dcl_or_def) == :static && !dcl_or_def.type.const? # NOTE: Value of the inconstant static duration variable should be # arbitrary because execution of its accessors are out of order. # So, a value of the initializer should be ignored. init_val = dcl_or_def.type.arbitrary_value else init_val ||= dcl_or_def.type.undefined_value end if var = lookup(dcl_or_def.identifier.value) if var.scope == current_scope var.declarations_and_definitions.push(dcl_or_def) var.value.force_overwrite!(init_val.coerce_to(var.type)) if repr_elem = var.representative_element repr_elem.value.force_overwrite!(repr_elem.type.arbitrary_value) end return var end end # NOTE: Domain of the init-value will be restricted by type's min-max in # define_variable. define_variable(dcl_or_def, br, dcl_or_def.type, allocate_memory(dcl_or_def), init_val) end |
#define_temporary(type, init_val) ⇒ Object
729 730 731 732 733 734 735 |
# File 'lib/adlint/cc1/object.rb', line 729 def define_temporary(type, init_val) mem = @memory_pool.allocate_dynamic(type.aligned_byte_size) # NOTE: Domain of the init-value will be restricted by type's min-max in # define_variable. define_variable(nil, nil, type, mem, init_val) end |
#designators ⇒ Object
746 747 748 |
# File 'lib/adlint/cc1/object.rb', line 746 def designators @named_variables.map { |hash| hash.keys }.flatten.to_set end |
#end_variables_value_versioning ⇒ Object
770 771 772 773 774 |
# File 'lib/adlint/cc1/object.rb', line 770 def end_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.end_value_versioning } end end |
#enter_scope ⇒ Object
673 674 675 676 677 |
# File 'lib/adlint/cc1/object.rb', line 673 def enter_scope @named_variables.push({}) @temp_variables.push([]) @scope_stack.push(Scope.new(@scope_stack.size)) end |
#enter_variables_value_versioning_group ⇒ Object
750 751 752 753 754 |
# File 'lib/adlint/cc1/object.rb', line 750 def enter_variables_value_versioning_group @named_variables.each do |hash| hash.each_value { |var| var.enter_value_versioning_group } end end |
#leave_scope ⇒ Object
679 680 681 682 683 684 685 686 687 688 689 |
# File 'lib/adlint/cc1/object.rb', line 679 def leave_scope @named_variables.pop.each_value do |var| @memory_pool.free(var.binding.memory) end @temp_variables.pop.each do |var| @memory_pool.free(var.binding.memory) end @scope_stack.pop rollback_all_global_variables_value! if current_scope.global? end |
#leave_variables_value_versioning_group(raise_complement) ⇒ Object
756 757 758 759 760 761 762 |
# File 'lib/adlint/cc1/object.rb', line 756 def leave_variables_value_versioning_group(raise_complement) @named_variables.each do |hash| hash.each_value do |var| var.leave_value_versioning_group(raise_complement) end end end |
#lookup(name_str) ⇒ Object
737 738 739 740 741 742 743 744 |
# File 'lib/adlint/cc1/object.rb', line 737 def lookup(name_str) @named_variables.reverse_each do |hash| if var = hash[name_str] return var end end nil end |
#storage_duration_of(dcl_or_def) ⇒ Object
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 |
# File 'lib/adlint/cc1/object.rb', line 782 def storage_duration_of(dcl_or_def) # NOTE: The ISO C99 standard says; # # 6.2.2 Linkages of identifiers # # 1 An identifier declared in different scopes or in the same scope more # than once can be made to refer to the same object or function by a # process called linkage. There are three kinds of linkage: external, # internal, and none. # # 3 If the declaration of a file scope identifier for an object or a # function contains the storage-class specifier static, the identifier # has internal linkage. # # 4 For an identifier declared with the storage-class specifier extern in # a scope in which a prior declaration of that identifier is visible, # if the prior declaration specifies internal or external linkage, the # linkage of the identifier at the later declaration is the same as the # linkage specified at the prior declaration. If no prior declaration # is visible, or if the prior declaration specifies no linkage, then # the identifier has external linkage. # # 5 If the declaration of an identifier for a function has no # storage-class specifier, its linkage is determined exactly as if it # were declared with the storage-class specifier extern. If the # declaration of an identifier for an object has file scope and no # storage-class specifier, its linkage is external. # # 6 The following identifiers have no linkage: an identifier declared to # be anything other than an object or a function; an identifier # declared to be a function parameter; a block scope identifier for an # object declared without the storage-class specifier extern. # # 6.2.4 Storage durations of objects # # 1 An object has a storage duration that determines its lifetime. There # are three storage durations: static, automatic, and allocated. # Allocated storage is described in 7.20.3. # # 3 An object whose identifier is declared with external or internal # linkage, or with the storage-class specifier static has static # storage duration. Its lifetime is the entire execution of the program # and its stored value is initialized only once, prior to program # startup. # # 4 An object whose identifier is declared with no linkage and without # the storage-class specifier static has automatic storage duration. if sc_spec = dcl_or_def.storage_class_specifier and sc_spec.type == :EXTERN || sc_spec.type == :STATIC :static else current_scope.global? ? :static : :automatic end end |
#thin_latest_variables_value_version!(with_rollback) ⇒ Object
776 777 778 779 780 |
# File 'lib/adlint/cc1/object.rb', line 776 def thin_latest_variables_value_version!(with_rollback) @named_variables.each do |hash| hash.each_value { |var| var.thin_latest_value_version!(with_rollback) } end end |