@@ -85,6 +85,52 @@ def create_int_constant_ptr(value, builder, local_sym_tab, int_width=64):
8585 return ptr
8686
8787
88+ def get_struct_char_array_ptr (expr , builder , local_sym_tab , struct_sym_tab ):
89+ """Get pointer to first element of char array in struct field, or None."""
90+ if not (isinstance (expr , ast .Attribute ) and isinstance (expr .value , ast .Name )):
91+ return None
92+
93+ var_name = expr .value .id
94+ field_name = expr .attr
95+
96+ # Check if it's a valid struct field
97+ if not (
98+ local_sym_tab
99+ and var_name in local_sym_tab
100+ and struct_sym_tab
101+ and local_sym_tab [var_name ].metadata in struct_sym_tab
102+ ):
103+ return None
104+
105+ struct_type = local_sym_tab [var_name ].metadata
106+ struct_info = struct_sym_tab [struct_type ]
107+
108+ if field_name not in struct_info .fields :
109+ return None
110+
111+ field_type = struct_info .field_type (field_name )
112+
113+ # Check if it's a char array
114+ is_char_array = (
115+ isinstance (field_type , ir .ArrayType )
116+ and isinstance (field_type .element , ir .IntType )
117+ and field_type .element .width == 8
118+ )
119+
120+ if not is_char_array :
121+ return None
122+
123+ # Get field pointer and GEP to first element: [N x i8]* -> i8*
124+ struct_ptr = local_sym_tab [var_name ].var
125+ field_ptr = struct_info .gep (builder , struct_ptr , field_name )
126+
127+ return builder .gep (
128+ field_ptr ,
129+ [ir .Constant (ir .IntType (32 ), 0 ), ir .Constant (ir .IntType (32 ), 0 )],
130+ inbounds = True ,
131+ )
132+
133+
88134def get_or_create_ptr_from_arg (
89135 func ,
90136 module ,
@@ -97,13 +143,47 @@ def get_or_create_ptr_from_arg(
97143):
98144 """Extract or create pointer from the call arguments."""
99145
146+ logger .info (f"Getting pointer from arg: { ast .dump (arg )} " )
100147 if isinstance (arg , ast .Name ):
101148 # Stack space is already allocated
102149 ptr = get_var_ptr_from_name (arg .id , local_sym_tab )
103150 elif isinstance (arg , ast .Constant ) and isinstance (arg .value , int ):
104151 if expected_type and isinstance (expected_type , ir .IntType ):
105152 int_width = expected_type .width
106153 ptr = create_int_constant_ptr (arg .value , builder , local_sym_tab , int_width )
154+ elif isinstance (arg , ast .Attribute ):
155+ # A struct field
156+ struct_name = arg .value .id
157+ field_name = arg .attr
158+
159+ if not local_sym_tab or struct_name not in local_sym_tab :
160+ raise ValueError (f"Struct '{ struct_name } ' not found" )
161+
162+ struct_type = local_sym_tab [struct_name ].metadata
163+ if not struct_sym_tab or struct_type not in struct_sym_tab :
164+ raise ValueError (f"Struct type '{ struct_type } ' not found" )
165+
166+ struct_info = struct_sym_tab [struct_type ]
167+ if field_name not in struct_info .fields :
168+ raise ValueError (
169+ f"Field '{ field_name } ' not found in struct '{ struct_name } '"
170+ )
171+
172+ field_type = struct_info .field_type (field_name )
173+ struct_ptr = local_sym_tab [struct_name ].var
174+
175+ # Special handling for char arrays
176+ if (
177+ isinstance (field_type , ir .ArrayType )
178+ and isinstance (field_type .element , ir .IntType )
179+ and field_type .element .width == 8
180+ ):
181+ ptr = get_struct_char_array_ptr (arg , builder , local_sym_tab , struct_sym_tab )
182+ if not ptr :
183+ raise ValueError ("Failed to get char array pointer from struct field" )
184+ else :
185+ ptr = struct_info .gep (builder , struct_ptr , field_name )
186+
107187 else :
108188 # NOTE: For any integer expression reaching this branch, it is probably a struct field or a binop
109189 # Evaluate the expression and store the result in a temp variable
0 commit comments