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.
671 672 673 674 675 676 |
# File 'lib/adlint/cc1/object.rb', line 671 def initialize(mem_pool) @memory_pool = mem_pool @named_variables = [{}] @temp_variables = [[]] @scope_stack = [GlobalScope.new] end |
Instance Method Details
#all_named_variables ⇒ Object
678 679 680 |
# File 'lib/adlint/cc1/object.rb', line 678 def all_named_variables @named_variables.map { |hash| hash.values }.flatten end |
#begin_variables_value_versioning ⇒ Object
773 774 775 776 777 |
# File 'lib/adlint/cc1/object.rb', line 773 def begin_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.begin_value_versioning } end end |
#declare(dcl, br) ⇒ Object
700 701 702 703 704 705 706 707 708 709 |
# File 'lib/adlint/cc1/object.rb', line 700 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
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 |
# File 'lib/adlint/cc1/object.rb', line 711 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
738 739 740 741 742 743 744 |
# File 'lib/adlint/cc1/object.rb', line 738 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
755 756 757 |
# File 'lib/adlint/cc1/object.rb', line 755 def designators @named_variables.map { |hash| hash.keys }.flatten.to_set end |
#end_variables_value_versioning ⇒ Object
779 780 781 782 783 |
# File 'lib/adlint/cc1/object.rb', line 779 def end_variables_value_versioning @named_variables.each do |hash| hash.each_value { |var| var.end_value_versioning } end end |
#enter_scope ⇒ Object
682 683 684 685 686 |
# File 'lib/adlint/cc1/object.rb', line 682 def enter_scope @named_variables.push({}) @temp_variables.push([]) @scope_stack.push(Scope.new(@scope_stack.size)) end |
#enter_variables_value_versioning_group ⇒ Object
759 760 761 762 763 |
# File 'lib/adlint/cc1/object.rb', line 759 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
688 689 690 691 692 693 694 695 696 697 698 |
# File 'lib/adlint/cc1/object.rb', line 688 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
765 766 767 768 769 770 771 |
# File 'lib/adlint/cc1/object.rb', line 765 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
746 747 748 749 750 751 752 753 |
# File 'lib/adlint/cc1/object.rb', line 746 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
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 837 838 839 840 841 842 843 844 845 |
# File 'lib/adlint/cc1/object.rb', line 791 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
785 786 787 788 789 |
# File 'lib/adlint/cc1/object.rb', line 785 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 |