[llvm-branch-commits] [lldb] [lldb][Fortran] Added support for functions to DWARFASTParserFortran (PR #234312)

David Spickett via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Oct 26 03:02:43 PDT 2026


================
@@ -207,3 +207,269 @@ TEST_F(DWARFASTParserFortranTests, EnsureBaseTypeParsingWorks) {
   // Ensure all expected DIEs were iterated
   EXPECT_EQ(type_idx, expected_types.size());
 }
+
+TEST_F(DWARFASTParserFortranTests, EnsureFunctionParsingWorks) {
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+        - Code:            0x2
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+        - Code:            0x3
+          Tag:             DW_TAG_formal_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+        - Code:            0x4
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+  debug_info:
+    - Version:         4
+      Entries:
+        - AbbrCode:        0x1  # DW_TAG_compile_unit
+          Values:
+            - Value:           0x22  # DW_LANG_Fortran95
+        
+        - AbbrCode:        0x4  # DW_TAG_base_type
+          Values:
+            - CStr:            'integer'
+            - Value:           0x5   # DW_ATE_signed
+            - Value:           0x4   # 4 bytes
+
+        - AbbrCode:        0x2  # DW_TAG_subprogram
+          Values:
+            - CStr:            'multiply_and_add'
+            - Value:           0x0E  # Return type points to 0x0E (integer)
+        
+        # Child 1: Parameter 'a'
+        - AbbrCode:        0x3  # DW_TAG_formal_parameter
+          Values:
+            - CStr:            'a'
+            - Value:           0x0E  # Type points to 0x0E (integer)
+        
+        # Child 2: Parameter 'b'
+        - AbbrCode:        0x3  # DW_TAG_formal_parameter
+          Values:
+            - CStr:            'b'
+            - Value:           0x0E  # Type points to 0x0E (integer)
+            
+        - AbbrCode:        0x0  # End of subprogram children
+        - AbbrCode:        0x0  # End of compile_unit children
+)";
+
+  DWARFASTParserFortranYAMLTester tester(yamldata);
+  DWARFDIE cu_die = tester.GetCUDIE();
+  DWARFDIE subprogram_die;
+  SymbolContext sc;
+  bool is_new_type;
+  std::string expected_name = "INTEGER multiply_and_add(INTEGER a, INTEGER b)";
+  for (DWARFDIE child_die : cu_die.children()) {
+    if (child_die.Tag() == DW_TAG_subprogram) {
+      subprogram_die = child_die;
+      break;
+    }
+  }
+  EXPECT_TRUE(subprogram_die.IsValid());
+  lldb::TypeSP func_type_sp =
+      tester.GetParser().ParseTypeFromDWARF(sc, subprogram_die, &is_new_type);
+  EXPECT_TRUE(is_new_type);
+  EXPECT_TRUE(func_type_sp->IsValidType());
+  CompilerType function_type = func_type_sp->GetForwardCompilerType();
+  EXPECT_TRUE(function_type.IsFunctionType());
+  EXPECT_EQ(function_type.GetTypeName().GetString(), expected_name);
+  EXPECT_EQ(function_type.GetFunctionArgumentCount(), 2);
+  CompilerType arg_1 = function_type.GetFunctionArgumentAtIndex(0);
+  EXPECT_TRUE(arg_1.IsValid());
+  CompilerType arg_2 = function_type.GetFunctionArgumentAtIndex(1);
+  EXPECT_TRUE(arg_2.IsValid());
+  CompilerType return_type = function_type.GetFunctionReturnType();
+  EXPECT_TRUE(return_type.IsValid());
+  EXPECT_EQ(arg_1.GetBasicTypeEnumeration(), eBasicTypeInt);
+  EXPECT_EQ(arg_2.GetBasicTypeEnumeration(), eBasicTypeInt);
+  EXPECT_EQ(return_type.GetBasicTypeEnumeration(), eBasicTypeInt);
+}
+
+TEST_F(DWARFASTParserFortranTests,
+       EnsureFunctionParsingWithNoParametersOrArgumentsWorks) {
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+DWARF:
+  debug_abbrev:
+    - ID:              0
+      Table:
+        - Code:            0x1
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+        - Code:            0x2
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
+        - Code:            0x3
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+        - Code:            0x4
+          Tag:             DW_TAG_subprogram
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+        - Code:            0x5
+          Tag:             DW_TAG_formal_parameter
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_string
+            - Attribute:       DW_AT_type
+              Form:            DW_FORM_ref4
+  debug_info:
+    - Version:         4
+      Entries:
+        - AbbrCode:        0x1  # DW_TAG_compile_unit
+          Values:
+            - Value:           0x22  # DW_LANG_Fortran95
+        
+        - AbbrCode:        0x2  # DW_TAG_base_type
+          Values:
+            - CStr:            'integer'
+            - Value:           0x5   # DW_ATE_signed
+            - Value:           0x4   # 4 bytes
+        
+        - AbbrCode:        0x4  # DW_TAG_subprogram (No DW_AT_type)
+          Values:
+            - CStr:            'my_subroutine'
+        - AbbrCode:        0x5  # DW_TAG_formal_parameter
+          Values:
+            - CStr:            'a'
+            - Value:           0x0E
+        - AbbrCode:        0x5  # DW_TAG_formal_parameter
+          Values:
+            - CStr:            'b'
+            - Value:           0x0E
+        - AbbrCode:        0x0  # End of my_subroutine
+        
+        - AbbrCode:        0x3  # DW_TAG_subprogram (Has DW_AT_type)
+          Values:
+            - CStr:            'no_args_func'
+            - Value:           0x0E
+        - AbbrCode:        0x0  # End of no_args_func (0 parameters)
+        
+        - AbbrCode:        0x4  # DW_TAG_subprogram (No DW_AT_type)
+          Values:
+            - CStr:            'empty_sub'
+        - AbbrCode:        0x0  # End of empty_sub
+            
+        - AbbrCode:        0x0  # End of compile_unit
+)";
+
+  DWARFASTParserFortranYAMLTester tester(yamldata);
+  DWARFDIE cu_die = tester.GetCUDIE();
+  SymbolContext sc;
+
+  int subprograms_found = 0;
+
+  for (DWARFDIE child_die : cu_die.children()) {
+    if (child_die.Tag() != DW_TAG_subprogram)
+      continue;
+    subprograms_found++;
+
+    bool is_new_type;
+    lldb::TypeSP func_type_sp =
+        tester.GetParser().ParseTypeFromDWARF(sc, child_die, &is_new_type);
+
+    EXPECT_TRUE(is_new_type);
+    EXPECT_TRUE(func_type_sp->IsValidType());
+
+    CompilerType function_type = func_type_sp->GetForwardCompilerType();
+    EXPECT_TRUE(function_type.IsFunctionType());
+
+    llvm::StringRef name = child_die.GetName();
+
+    if (name == "my_subroutine") {
+      // Subroutine: No return type, 2 arguments
+      EXPECT_EQ(function_type.GetTypeName().GetString(),
+                "my_subroutine(INTEGER a, INTEGER b)");
+      EXPECT_EQ(function_type.GetFunctionArgumentCount(), 2);
+
+      CompilerType arg_1 = function_type.GetFunctionArgumentAtIndex(0);
+      CompilerType arg_2 = function_type.GetFunctionArgumentAtIndex(1);
+      EXPECT_TRUE(arg_1.IsValid());
+      EXPECT_TRUE(arg_2.IsValid());
+      EXPECT_EQ(arg_1.GetBasicTypeEnumeration(), eBasicTypeInt);
+      EXPECT_EQ(arg_2.GetBasicTypeEnumeration(), eBasicTypeInt);
+
+      CompilerType return_type = function_type.GetFunctionReturnType();
+      EXPECT_FALSE(
+          return_type
+              .IsValid()); // Subroutines shouldn't have a valid return type
+
+    } else if (name == "no_args_func") {
+      // Function: Has return type, 0 arguments
+      EXPECT_EQ(function_type.GetTypeName().GetString(),
+                "INTEGER no_args_func()");
+      EXPECT_EQ(function_type.GetFunctionArgumentCount(), 0);
+
+      CompilerType return_type = function_type.GetFunctionReturnType();
+      EXPECT_TRUE(return_type.IsValid());
+      EXPECT_EQ(return_type.GetBasicTypeEnumeration(), eBasicTypeInt);
+
+    } else if (name == "empty_sub") {
+      // Subroutine: No return type, 0 arguments
+      EXPECT_EQ(function_type.GetTypeName().GetString(), "empty_sub()");
----------------
DavidSpickett wrote:

Right, I always forget that. I've never used a language that made that distinction.

https://github.com/llvm/llvm-project/pull/234312


More information about the llvm-branch-commits mailing list