@@ -184,3 +184,83 @@ def create_global_var_debug_info(
184184 "DIGlobalVariableExpression" ,
185185 {"var" : global_var , "expr" : self .module .add_debug_info ("DIExpression" , {})},
186186 )
187+
188+ def get_int64_type (self ):
189+ return self .get_basic_type ("long" , 64 , dc .DW_ATE_signed )
190+
191+ def create_subroutine_type (self , return_type , param_types ):
192+ """
193+ Create a DISubroutineType given return type and list of parameter types.
194+ Equivalent to: !DISubroutineType(types: !{ret, args...})
195+ """
196+ type_array = [return_type ]
197+ if isinstance (param_types , (list , tuple )):
198+ type_array .extend (param_types )
199+ else :
200+ type_array .append (param_types )
201+ return self .module .add_debug_info ("DISubroutineType" , {"types" : type_array })
202+
203+ def create_local_variable_debug_info (
204+ self , name : str , arg : int , var_type : Any
205+ ) -> Any :
206+ """
207+ Create debug info for a local variable (DILocalVariable) without scope.
208+ Example:
209+ !DILocalVariable(name: "ctx", arg: 1, file: !3, line: 20, type: !7)
210+ """
211+ return self .module .add_debug_info (
212+ "DILocalVariable" ,
213+ {
214+ "name" : name ,
215+ "arg" : arg ,
216+ "file" : self .module ._file_metadata ,
217+ "type" : var_type ,
218+ },
219+ )
220+
221+ def add_scope_to_local_variable (self , local_variable_debug_info , scope_value ):
222+ """
223+ Add scope information to an existing local variable debug info object.
224+ """
225+ # TODO: this is a workaround a flaw in the debug info generation. Fix this if possible in the future.
226+ # We should not be touching llvmlite's internals like this.
227+ if hasattr (local_variable_debug_info , "operands" ):
228+ # LLVM metadata operands is a tuple, so we need to rebuild it
229+ existing_operands = local_variable_debug_info .operands
230+
231+ # Convert tuple to list, add scope, convert back to tuple
232+ operands_list = list (existing_operands )
233+ operands_list .append (("scope" , scope_value ))
234+
235+ # Reassign the new tuple
236+ local_variable_debug_info .operands = tuple (operands_list )
237+
238+ def create_subprogram (
239+ self , name : str , subroutine_type : Any , retained_nodes : List [Any ]
240+ ) -> Any :
241+ """
242+ Create a DISubprogram for a function.
243+
244+ Args:
245+ name: Function name
246+ subroutine_type: DISubroutineType for the function signature
247+ retained_nodes: List of DILocalVariable nodes for function parameters/variables
248+
249+ Returns:
250+ DISubprogram metadata
251+ """
252+ return self .module .add_debug_info (
253+ "DISubprogram" ,
254+ {
255+ "name" : name ,
256+ "scope" : self .module ._file_metadata ,
257+ "file" : self .module ._file_metadata ,
258+ "type" : subroutine_type ,
259+ # TODO: the following flags do not exist at the moment in our dwarf constants file. We need to add them.
260+ # "flags": dc.DW_FLAG_Prototyped | dc.DW_FLAG_AllCallsDescribed,
261+ # "spFlags": dc.DW_SPFLAG_Definition | dc.DW_SPFLAG_Optimized,
262+ "unit" : self .module ._debug_compile_unit ,
263+ "retainedNodes" : retained_nodes ,
264+ },
265+ is_distinct = True ,
266+ )
0 commit comments