[Lldb-commits] [lldb] [lldb][Fortran] Added support for basic types in TypeSystemFortran (PR #223380)

Iasonas Karaprodromidis via lldb-commits lldb-commits at lists.llvm.org
Fri Sep 18 07:49:05 PDT 2026


https://github.com/Iasonaskrpr updated https://github.com/llvm/llvm-project/pull/223380

>From fd9e9e70f1ca01c9b6ba75c12486b72bbb36f3f6 Mon Sep 17 00:00:00 2001
From: Iasonaskrpr <iaskarapro at gmail.com>
Date: Mon, 14 Sep 2026 13:30:56 +0300
Subject: [PATCH 1/2] [lldb][Fortran] Added base type support to
 TypeSystemFortran and Tests for TypeSystemFortran

---
 .../Plugins/TypeSystem/Fortran/CMakeLists.txt |   1 +
 .../TypeSystem/Fortran/FortranTypes.cpp       |  16 ++
 .../Plugins/TypeSystem/Fortran/FortranTypes.h |  76 ++++++
 .../TypeSystem/Fortran/TypeSystemFortran.cpp  | 207 +++++++++++++++
 .../TypeSystem/Fortran/TypeSystemFortran.h    |  67 +++--
 lldb/unittests/Symbol/CMakeLists.txt          |   2 +
 .../Symbol/TestTypeSystemFortran.cpp          | 237 ++++++++++++++++++
 7 files changed, 571 insertions(+), 35 deletions(-)
 create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp
 create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h
 create mode 100644 lldb/unittests/Symbol/TestTypeSystemFortran.cpp

diff --git a/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt b/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt
index c78b70d48eb31..9fae49964fe0f 100644
--- a/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt
+++ b/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_lldb_library(lldbPluginTypeSystemFortran PLUGIN
   TypeSystemFortran.cpp
+  FortranTypes.cpp
 
   LINK_COMPONENTS
     Support
diff --git a/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp
new file mode 100644
index 0000000000000..e84684aab28f8
--- /dev/null
+++ b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp
@@ -0,0 +1,16 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "FortranTypes.h"
+
+using namespace lldb_private;
+using namespace lldb_private::plugin::fortran;
+
+char FortranType::ID;
+
+FortranType::~FortranType() = default;
diff --git a/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h
new file mode 100644
index 0000000000000..ecd14a3ca8b67
--- /dev/null
+++ b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the classes that describe the Fortran types.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_FORTRANTYPES_H
+#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_FORTRANTYPES_H
+
+#include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "lldb/Expression/DWARFExpressionList.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Utility/ConstString.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace lldb_private {
+namespace plugin {
+namespace fortran {
+
+/// A simplified internal representation of a Fortran type.
+class FortranType : public llvm::FoldingSetNode {
+  // LLVM RTTI support
+  static char ID;
+
+public:
+  // llvm casting support
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+
+  static bool classof(const FortranType *ft) { return ft->isA(&ID); }
+
+  enum TypeKind {
+    KIND_INTEGER,
+    KIND_LOGICAL,
+    KIND_REAL,
+    KIND_COMPLEX,
+    KIND_UNKNOWN
+  };
+
+  FortranType(int32_t kind, uint64_t bitsize, const ConstString &name)
+      : m_kind(kind), m_bitsize(bitsize), m_type_name(name) {}
+  virtual ~FortranType();
+  int GetKind() const { return m_kind; }
+  uint64_t GetBitSize() const { return m_bitsize; }
+  ConstString GetName() const { return m_type_name; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    Profile(ID, m_kind, m_bitsize);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, int32_t kind,
+                      uint64_t bitsize) {
+    ID.AddInteger(kind);
+    ID.AddInteger(bitsize);
+  }
+
+private:
+  int32_t m_kind;
+  uint64_t m_bitsize;
+  ConstString m_type_name;
+};
+
+} // namespace fortran
+} // namespace plugin
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_FORTRANTYPES_H
diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
index b96e1160b52c8..7cf55dad4325f 100644
--- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
+++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
@@ -7,7 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "TypeSystemFortran.h"
+#include "FortranTypes.h"
 
+#include "lldb/Core/DumpDataExtractor.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Target/Language.h"
@@ -17,6 +19,7 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace llvm;
 using namespace lldb_private::plugin::dwarf;
+using namespace lldb_private::plugin::fortran;
 
 LLDB_PLUGIN_DEFINE(TypeSystemFortran)
 
@@ -58,6 +61,210 @@ LanguageSet TypeSystemFortran::GetSupportedLanguagesForExpressions() {
   return GetSupportedLanguagesForTypes();
 }
 
+#ifndef NDEBUG
+bool TypeSystemFortran::Verify(lldb::opaque_compiler_type_t type) {
+  return !type || llvm::isa<FortranType>(static_cast<FortranType *>(type));
+}
+#endif
+
+bool TypeSystemFortran::IsFloatingPointType(opaque_compiler_type_t type) {
+  int kind = static_cast<FortranType *>(type)->GetKind();
+  if (kind == FortranType::KIND_REAL)
+    return true;
+  return false;
+}
+
+bool TypeSystemFortran::IsIntegerType(opaque_compiler_type_t type,
+                                      bool &is_signed) {
+  if (!type)
+    return false;
+  FortranType *fortran_type = static_cast<FortranType *>(type);
+  if (fortran_type->GetKind() == FortranType::KIND_INTEGER) {
+    is_signed = true;
+    return true;
+  }
+  return false;
+}
+
 bool TypeSystemFortran::SupportsLanguage(lldb::LanguageType language) {
   return Language::LanguageIsFortran(language);
 }
+
+/// Returns the type name upper-cased to follow Fortran's general style
+ConstString TypeSystemFortran::GetTypeName(opaque_compiler_type_t type,
+                                           bool BaseOnly) {
+  if (!type)
+    return ConstString();
+  FortranType *fortran_type = static_cast<FortranType *>(type);
+  switch (fortran_type->GetKind()) {
+  case FortranType::KIND_INTEGER:
+  case FortranType::KIND_LOGICAL:
+  case FortranType::KIND_REAL:
+  case FortranType::KIND_COMPLEX:
+    return fortran_type->GetName();
+  default:
+    return ConstString("Unsupported");
+  }
+}
+
+CompilerType TypeSystemFortran::CreateBaseType(uint32_t dwarf_encoding,
+                                               uint64_t bitsize,
+                                               ConstString name) {
+  int underlying_kind;
+  switch (dwarf_encoding) {
+  case dwarf::DW_ATE_boolean:
+    if (bitsize == 32)
+      name.SetCString("LOGICAL");
+    underlying_kind = FortranType::KIND_LOGICAL;
+    break;
+  case dwarf::DW_ATE_float:
+    if (bitsize == 32)
+      name.SetCString("REAL");
+    underlying_kind = FortranType::KIND_REAL;
+    break;
+  case dwarf::DW_ATE_signed:
+    if (bitsize == 32)
+      name.SetCString("INTEGER");
+    underlying_kind = FortranType::KIND_INTEGER;
+    break;
+  case dwarf::DW_ATE_complex_float:
+    if (bitsize == 64)
+      name.SetCString("COMPLEX");
+    underlying_kind = FortranType::KIND_COMPLEX;
+    break;
+  default:
+    return CompilerType();
+  }
+  return GetOrCreateFortranBaseType(underlying_kind, bitsize, name);
+}
+
+/// Returns the type assosciated with the kind and bitsize, or creates it
+/// if it is not in the map
+CompilerType TypeSystemFortran::GetOrCreateFortranBaseType(int kind,
+                                                           uint64_t bitsize,
+                                                           ConstString name) {
+  auto new_type_up = std::make_unique<FortranType>(kind, bitsize, name);
+  FortranType *fortran_type = m_basic_types.getOrInsert(new_type_up.get());
+  if (fortran_type == new_type_up.get())
+    m_types.push_back(std::move(new_type_up));
+  return CompilerType(weak_from_this(), (void *)fortran_type);
+}
+
+lldb::TypeClass
+TypeSystemFortran::GetTypeClass(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return lldb::eTypeClassInvalid;
+
+  return lldb::eTypeClassBuiltin;
+}
+
+CompilerType
+TypeSystemFortran::GetCanonicalType(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return CompilerType();
+  return CompilerType(weak_from_this(), type);
+}
+
+Expected<uint64_t>
+TypeSystemFortran::GetBitSize(opaque_compiler_type_t type,
+                              ExecutionContextScope *exe_scope) {
+  if (!type)
+    return 0;
+  FortranType *fortran_type = static_cast<FortranType *>(type);
+  return fortran_type->GetBitSize();
+}
+
+BasicType
+TypeSystemFortran::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
+  if (!type)
+    return eBasicTypeInvalid;
+  FortranType *fortran_type = static_cast<FortranType *>(type);
+  switch (fortran_type->GetKind()) {
+  case FortranType::KIND_INTEGER:
+    switch (fortran_type->GetBitSize()) {
+    case 8:
+      return eBasicTypeSignedChar;
+    case 16:
+      return eBasicTypeShort;
+    case 32:
+      return eBasicTypeInt;
+    case 64:
+      return eBasicTypeLongLong;
+    case 128:
+      return eBasicTypeInt128;
+    default:
+      return eBasicTypeInvalid;
+    }
+  case FortranType::KIND_LOGICAL:
+    return eBasicTypeBool;
+  case FortranType::KIND_COMPLEX:
+    switch (fortran_type->GetBitSize()) {
+    case 64:
+      return eBasicTypeFloatComplex;
+    case 128:
+      return eBasicTypeDoubleComplex;
+    case 256:
+      return eBasicTypeLongDoubleComplex;
+    default:
+      return eBasicTypeInvalid;
+    }
+  case FortranType::KIND_REAL:
+    switch (fortran_type->GetBitSize()) {
+    case 16:
+      return eBasicTypeHalf;
+    case 32:
+      return eBasicTypeFloat;
+    case 64:
+      return eBasicTypeDouble;
+    case 128:
+      return eBasicTypeFloat128;
+    default:
+      return eBasicTypeInvalid;
+    }
+  default:
+    return eBasicTypeInvalid;
+  }
+}
+
+CompilerType TypeSystemFortran::GetBasicTypeFromAST(BasicType basic_type) {
+  switch (basic_type) {
+  case eBasicTypeInt:
+    return GetOrCreateFortranBaseType(FortranType::KIND_INTEGER, 32,
+                                      ConstString("INTEGER"));
+  case eBasicTypeFloat:
+    return GetOrCreateFortranBaseType(FortranType::KIND_REAL, 32,
+                                      ConstString("REAL"));
+  case eBasicTypeDouble:
+    return GetOrCreateFortranBaseType(FortranType::KIND_REAL, 64,
+                                      ConstString("REAL(KIND=8)"));
+  case eBasicTypeBool:
+    return GetOrCreateFortranBaseType(FortranType::KIND_LOGICAL, 32,
+                                      ConstString("LOGICAL"));
+  case eBasicTypeFloatComplex:
+    return GetOrCreateFortranBaseType(FortranType::KIND_COMPLEX, 64,
+                                      ConstString("COMPLEX"));
+  case eBasicTypeDoubleComplex:
+    return GetOrCreateFortranBaseType(FortranType::KIND_COMPLEX, 128,
+                                      ConstString("COMPLEX(KIND=8)"));
+  case eBasicTypeLongDoubleComplex:
+    return GetOrCreateFortranBaseType(FortranType::KIND_COMPLEX, 256,
+                                      ConstString("COMPLEX(KIND=16)"));
+  default:
+    return CompilerType();
+  }
+}
+
+CompilerType
+TypeSystemFortran::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
+                                                       size_t bit_size) {
+  switch (encoding) {
+  case eEncodingSint:
+    return GetOrCreateFortranBaseType(FortranType::KIND_INTEGER, bit_size,
+                                      ConstString("INTEGER"));
+  case eEncodingIEEE754:
+    return GetOrCreateFortranBaseType(FortranType::KIND_REAL, bit_size,
+                                      ConstString("REAL"));
+  default:
+    return CompilerType();
+  }
+}
diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
index 1db819bdbbad0..31804398617d4 100644
--- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
+++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
@@ -9,7 +9,11 @@
 #ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H
 #define LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H
 
+#include "FortranTypes.h"
+
 #include "lldb/Symbol/TypeSystem.h"
+
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/ErrorHandling.h"
 
 namespace lldb_private {
@@ -72,7 +76,7 @@ class TypeSystemFortran : public TypeSystem {
 #ifndef NDEBUG
   /// Verify the integrity of the type to catch CompilerTypes that mix
   /// and match invalid TypeSystem/Opaque type pairs.
-  bool Verify(lldb::opaque_compiler_type_t type) override { return false; };
+  bool Verify(lldb::opaque_compiler_type_t type) override;
 #endif
 
   bool IsArrayType(lldb::opaque_compiler_type_t type,
@@ -88,14 +92,12 @@ class TypeSystemFortran : public TypeSystem {
   bool IsCharType(lldb::opaque_compiler_type_t type) override { return false; }
 
   bool IsCompleteType(lldb::opaque_compiler_type_t type) override {
-    return false;
+    return true;
   }
 
-  bool IsDefined(lldb::opaque_compiler_type_t type) override { return false; }
+  bool IsDefined(lldb::opaque_compiler_type_t type) override { return true; }
 
-  bool IsFloatingPointType(lldb::opaque_compiler_type_t type) override {
-    return false;
-  }
+  bool IsFloatingPointType(lldb::opaque_compiler_type_t type) override;
 
   bool IsFunctionType(lldb::opaque_compiler_type_t type) override {
     return false;
@@ -129,9 +131,7 @@ class TypeSystemFortran : public TypeSystem {
   }
 
   bool IsIntegerType(lldb::opaque_compiler_type_t type,
-                     bool &is_signed) override {
-    return false;
-  };
+                     bool &is_signed) override;
 
   bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) override {
     return false;
@@ -148,9 +148,7 @@ class TypeSystemFortran : public TypeSystem {
     return false;
   }
 
-  bool IsScalarType(lldb::opaque_compiler_type_t type) override {
-    return false;
-  }
+  bool IsScalarType(lldb::opaque_compiler_type_t type) override { return true; }
 
   bool IsVoidType(lldb::opaque_compiler_type_t type) override { return false; }
 
@@ -166,7 +164,7 @@ class TypeSystemFortran : public TypeSystem {
   // Type Completion
 
   bool GetCompleteType(lldb::opaque_compiler_type_t type) override {
-    return false;
+    return true;
   }
 
   // AST related queries
@@ -194,12 +192,10 @@ class TypeSystemFortran : public TypeSystem {
   // Accessors
 
   ConstString GetTypeName(lldb::opaque_compiler_type_t type,
-                          bool BaseOnly) override {
-    return ConstString();
-  }
+                          bool BaseOnly) override;
 
   ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) override {
-    return ConstString();
+    return GetTypeName(type, false);
   }
 
   uint32_t
@@ -213,9 +209,13 @@ class TypeSystemFortran : public TypeSystem {
     return lldb::LanguageType::eLanguageTypeFortran90;
   }
 
-  lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override {
-    return lldb::TypeClass::eTypeClassInvalid;
-  }
+  lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;
+
+  CompilerType GetOrCreateFortranBaseType(int kind, uint64_t bitsize,
+                                          ConstString name);
+
+  CompilerType CreateBaseType(uint32_t dwarf_encoding, uint64_t bitsize,
+                              ConstString name);
 
   // Creating related types
 
@@ -224,9 +224,7 @@ class TypeSystemFortran : public TypeSystem {
     return CompilerType();
   }
 
-  CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override {
-    return CompilerType();
-  }
+  CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;
 
   CompilerType
   GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) override {
@@ -276,9 +274,7 @@ class TypeSystemFortran : public TypeSystem {
 
   llvm::Expected<uint64_t>
   GetBitSize(lldb::opaque_compiler_type_t type,
-             ExecutionContextScope *exe_scope) override {
-    return 0;
-  }
+             ExecutionContextScope *exe_scope) override;
 
   lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type) override {
     return lldb::eEncodingInvalid;
@@ -296,9 +292,7 @@ class TypeSystemFortran : public TypeSystem {
   }
 
   lldb::BasicType
-  GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override {
-    return lldb::eBasicTypeUnsignedInt;
-  }
+  GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;
 
   uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override {
     return 0;
@@ -426,14 +420,10 @@ class TypeSystemFortran : public TypeSystem {
     return 0;
   }
 
-  CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override {
-    return CompilerType();
-  }
+  CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;
 
   CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
-                                                   size_t bit_size) override {
-    return CompilerType();
-  }
+                                                   size_t bit_size) override;
 
   bool IsBeingDefined(lldb::opaque_compiler_type_t type) override {
     return false;
@@ -479,9 +469,16 @@ class TypeSystemFortran : public TypeSystem {
   }
 
 private:
+  mutable llvm::FoldingSet<plugin::fortran::FortranType> m_basic_types;
+  // We store all unique pointer types here so we can manage the lifecycle
+  // of the types
+  mutable llvm::SmallVector<std::unique_ptr<plugin::fortran::FortranType>>
+      m_types;
+
   TypeSystemFortran(const TypeSystemFortran &) = delete;
   const TypeSystemFortran &operator=(const TypeSystemFortran &) = delete;
 };
+
 } // namespace lldb_private
 
 #endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H
diff --git a/lldb/unittests/Symbol/CMakeLists.txt b/lldb/unittests/Symbol/CMakeLists.txt
index 0fdbc9d72445e..7475167d523a8 100644
--- a/lldb/unittests/Symbol/CMakeLists.txt
+++ b/lldb/unittests/Symbol/CMakeLists.txt
@@ -10,6 +10,7 @@ add_lldb_unittest(SymbolTests
   SymStoreTest.cpp
   TestTypeSystem.cpp
   TestTypeSystemClang.cpp
+  TestTypeSystemFortran.cpp
   TestClangASTImporter.cpp
   TestDWARFCallFrameInfo.cpp
   TestType.cpp
@@ -26,6 +27,7 @@ add_lldb_unittest(SymbolTests
     lldbPluginSymbolFileDWARF
     lldbPluginSymbolFileSymtab
     lldbPluginTypeSystemClang
+    lldbPluginTypeSystemFortran
     lldbPluginSymbolLocatorSymStore
     LLVMTestingSupport
   )
diff --git a/lldb/unittests/Symbol/TestTypeSystemFortran.cpp b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp
new file mode 100644
index 0000000000000..b3203a1a641ed
--- /dev/null
+++ b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp
@@ -0,0 +1,237 @@
+//===-- TestTypeSystemFortran.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/TypeSystem/Fortran/FortranTypes.h"
+#include "Plugins/TypeSystem/Fortran/TypeSystemFortran.h"
+#include "TestingSupport/SubsystemRAII.h"
+#include "lldb/Core/Declaration.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/lldb-enumerations.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::plugin::fortran;
+
+class TypeSystemFortranHolder {
+  std::shared_ptr<TypeSystemFortran> m_ast;
+
+public:
+  TypeSystemFortranHolder() : m_ast(std::make_shared<TypeSystemFortran>()) {}
+  TypeSystemFortran *GetAST() const { return m_ast.get(); }
+};
+
+class TestTypeSystemFortran : public testing::Test {
+public:
+  SubsystemRAII<FileSystem, HostInfo> subsystems;
+
+  void SetUp() override {
+    m_holder = std::make_unique<TypeSystemFortranHolder>();
+    m_ast = m_holder->GetAST();
+  }
+
+  void TearDown() override {
+    m_ast = nullptr;
+    m_holder.reset();
+  }
+
+protected:
+  TypeSystemFortran *m_ast = nullptr;
+  std::unique_ptr<TypeSystemFortranHolder> m_holder;
+};
+
+TEST_F(TestTypeSystemFortran, TestBaseTypes) {
+  CompilerType logical_type = m_ast->CreateBaseType(llvm::dwarf::DW_ATE_boolean,
+                                                    32, ConstString("Logical"));
+  EXPECT_TRUE(logical_type.IsValid());
+  auto bitsize_or_err = logical_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 32U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(logical_type.GetOpaqueQualType()),
+            eBasicTypeBool);
+
+  CompilerType int8_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 8, ConstString());
+  EXPECT_TRUE(int8_type.IsValid());
+  bitsize_or_err = int8_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 8U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(int8_type.GetOpaqueQualType()),
+            eBasicTypeSignedChar);
+
+  CompilerType int16_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 16, ConstString());
+  EXPECT_TRUE(int16_type.IsValid());
+  bitsize_or_err = int16_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 16U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(int16_type.GetOpaqueQualType()),
+            eBasicTypeShort);
+
+  CompilerType int32_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32, ConstString());
+  EXPECT_TRUE(int32_type.IsValid());
+  bitsize_or_err = int32_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 32U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(int32_type.GetOpaqueQualType()),
+            eBasicTypeInt);
+
+  CompilerType int64_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 64, ConstString());
+  EXPECT_TRUE(int64_type.IsValid());
+  bitsize_or_err = int64_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 64U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(int64_type.GetOpaqueQualType()),
+            eBasicTypeLongLong);
+
+  CompilerType int128_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 128, ConstString());
+  EXPECT_TRUE(int128_type.IsValid());
+  bitsize_or_err = int128_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 128U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(int128_type.GetOpaqueQualType()),
+            eBasicTypeInt128);
+
+  CompilerType real16_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 16, ConstString());
+  EXPECT_TRUE(real16_type.IsValid());
+  bitsize_or_err = real16_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 16U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(real16_type.GetOpaqueQualType()),
+            eBasicTypeHalf);
+
+  CompilerType real32_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 32, ConstString());
+  EXPECT_TRUE(real32_type.IsValid());
+  bitsize_or_err = real32_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 32U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(real32_type.GetOpaqueQualType()),
+            eBasicTypeFloat);
+
+  CompilerType real64_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 64, ConstString());
+  EXPECT_TRUE(real64_type.IsValid());
+  bitsize_or_err = real64_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 64U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(real64_type.GetOpaqueQualType()),
+            eBasicTypeDouble);
+
+  CompilerType real128_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 128, ConstString());
+  EXPECT_TRUE(real128_type.IsValid());
+  bitsize_or_err = real128_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 128U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(real128_type.GetOpaqueQualType()),
+            eBasicTypeFloat128);
+
+  CompilerType complex64_type = m_ast->CreateBaseType(
+      llvm::dwarf::DW_ATE_complex_float, 64, ConstString());
+  EXPECT_TRUE(complex64_type.IsValid());
+  bitsize_or_err = complex64_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 64U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(complex64_type.GetOpaqueQualType()),
+            eBasicTypeFloatComplex);
+
+  CompilerType complex128_type = m_ast->CreateBaseType(
+      llvm::dwarf::DW_ATE_complex_float, 128, ConstString());
+  EXPECT_TRUE(complex128_type.IsValid());
+  bitsize_or_err = complex128_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 128U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(complex128_type.GetOpaqueQualType()),
+            eBasicTypeDoubleComplex);
+
+  CompilerType complex256_type = m_ast->CreateBaseType(
+      llvm::dwarf::DW_ATE_complex_float, 256, ConstString());
+  EXPECT_TRUE(complex256_type.IsValid());
+  bitsize_or_err = complex256_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 256U);
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(complex256_type.GetOpaqueQualType()),
+            eBasicTypeLongDoubleComplex);
+
+  CompilerType invalid_int =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 42, ConstString());
+  EXPECT_EQ(m_ast->GetBasicTypeEnumeration(invalid_int.GetOpaqueQualType()),
+            eBasicTypeInvalid);
+}
+
+TEST_F(TestTypeSystemFortran, TestTypeClassifications) {
+  CompilerType logical_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_boolean, 32, ConstString());
+  CompilerType int_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32, ConstString());
+  CompilerType real_type =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 32, ConstString());
+  CompilerType complex_type = m_ast->CreateBaseType(
+      llvm::dwarf::DW_ATE_complex_float, 64, ConstString());
+
+  bool is_signed = false;
+
+  EXPECT_TRUE(int_type.IsIntegerType(is_signed));
+  EXPECT_TRUE(is_signed);
+  EXPECT_FALSE(logical_type.IsIntegerType(is_signed));
+  EXPECT_FALSE(real_type.IsIntegerType(is_signed));
+  EXPECT_FALSE(complex_type.IsIntegerType(is_signed));
+
+  EXPECT_TRUE(real_type.IsFloatingPointType());
+  EXPECT_FALSE(int_type.IsFloatingPointType());
+  EXPECT_FALSE(logical_type.IsFloatingPointType());
+  EXPECT_FALSE(complex_type.IsFloatingPointType());
+}
+
+TEST_F(TestTypeSystemFortran, TestTypeNameGeneration) {
+  CompilerType logical32 =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_boolean, 32, ConstString());
+  CompilerType int32 =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32, ConstString());
+  CompilerType real32 =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_float, 32, ConstString());
+  CompilerType complex64 = m_ast->CreateBaseType(
+      llvm::dwarf::DW_ATE_complex_float, 64, ConstString());
+
+  EXPECT_STREQ(logical32.GetTypeName().GetCString(), "LOGICAL");
+  EXPECT_STREQ(int32.GetTypeName().GetCString(), "INTEGER");
+  EXPECT_STREQ(real32.GetTypeName().GetCString(), "REAL");
+  EXPECT_STREQ(complex64.GetTypeName().GetCString(), "COMPLEX");
+}
+
+TEST_F(TestTypeSystemFortran, TestFoldingSetDeduplication) {
+  CompilerType int1 = m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32,
+                                            ConstString("INTEGER"));
+
+  CompilerType int2 = m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32,
+                                            ConstString("INTEGER"));
+
+  EXPECT_EQ(int1.GetOpaqueQualType(), int2.GetOpaqueQualType());
+}
+
+TEST_F(TestTypeSystemFortran, TestGetBasicTypeFromAST) {
+  CompilerType int_type = m_ast->GetBasicTypeFromAST(eBasicTypeInt);
+  EXPECT_TRUE(int_type.IsValid());
+  EXPECT_STREQ(int_type.GetTypeName().GetCString(), "INTEGER");
+
+  auto bitsize_or_err = int_type.GetBitSize(nullptr);
+  ASSERT_THAT_EXPECTED(bitsize_or_err, llvm::Succeeded());
+  EXPECT_EQ(*bitsize_or_err, 32U);
+
+  CompilerType complex_type =
+      m_ast->GetBasicTypeFromAST(eBasicTypeDoubleComplex);
+  EXPECT_TRUE(complex_type.IsValid());
+  EXPECT_STREQ(complex_type.GetTypeName().GetCString(), "COMPLEX(KIND=8)");
+}

>From e4fbd2fb95f20514a893574f75d8a5bd0d8c37e3 Mon Sep 17 00:00:00 2001
From: Iasonaskrpr <iaskarapro at gmail.com>
Date: Fri, 18 Sep 2026 17:48:31 +0300
Subject: [PATCH 2/2] [lldb][Fortran] Added spacing after 1-line ifs, inlined
 type cases and added default name for all base types

---
 .../TypeSystem/Fortran/TypeSystemFortran.cpp  | 58 +++++++++++--------
 .../TypeSystem/Fortran/TypeSystemFortran.h    |  4 +-
 .../Symbol/TestTypeSystemFortran.cpp          |  3 +
 3 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
index 7cf55dad4325f..9b84f5e4c7043 100644
--- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
+++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp
@@ -68,9 +68,12 @@ bool TypeSystemFortran::Verify(lldb::opaque_compiler_type_t type) {
 #endif
 
 bool TypeSystemFortran::IsFloatingPointType(opaque_compiler_type_t type) {
-  int kind = static_cast<FortranType *>(type)->GetKind();
-  if (kind == FortranType::KIND_REAL)
+  if (!type)
+    return false;
+
+  if (static_cast<FortranType *>(type)->GetKind() == FortranType::KIND_REAL)
     return true;
+
   return false;
 }
 
@@ -78,8 +81,9 @@ bool TypeSystemFortran::IsIntegerType(opaque_compiler_type_t type,
                                       bool &is_signed) {
   if (!type)
     return false;
-  FortranType *fortran_type = static_cast<FortranType *>(type);
-  if (fortran_type->GetKind() == FortranType::KIND_INTEGER) {
+
+  if (static_cast<FortranType *>(type)->GetKind() ==
+      FortranType::KIND_INTEGER) {
     is_signed = true;
     return true;
   }
@@ -90,11 +94,12 @@ bool TypeSystemFortran::SupportsLanguage(lldb::LanguageType language) {
   return Language::LanguageIsFortran(language);
 }
 
-/// Returns the type name upper-cased to follow Fortran's general style
+/// Returns the type name upper-cased to follow Fortran's general style.
 ConstString TypeSystemFortran::GetTypeName(opaque_compiler_type_t type,
                                            bool BaseOnly) {
   if (!type)
     return ConstString();
+
   FortranType *fortran_type = static_cast<FortranType *>(type);
   switch (fortran_type->GetKind()) {
   case FortranType::KIND_INTEGER:
@@ -107,39 +112,43 @@ ConstString TypeSystemFortran::GetTypeName(opaque_compiler_type_t type,
   }
 }
 
-CompilerType TypeSystemFortran::CreateBaseType(uint32_t dwarf_encoding,
-                                               uint64_t bitsize,
-                                               ConstString name) {
-  int underlying_kind;
+CompilerType
+TypeSystemFortran::CreateBaseType(llvm::dwarf::TypeKind dwarf_encoding,
+                                  uint64_t bitsize, ConstString name) {
+  int underlying_kind = FortranType::KIND_UNKNOWN;
+  const char *default_name = nullptr;
+
   switch (dwarf_encoding) {
   case dwarf::DW_ATE_boolean:
-    if (bitsize == 32)
-      name.SetCString("LOGICAL");
     underlying_kind = FortranType::KIND_LOGICAL;
+    default_name = "LOGICAL";
     break;
   case dwarf::DW_ATE_float:
-    if (bitsize == 32)
-      name.SetCString("REAL");
     underlying_kind = FortranType::KIND_REAL;
+    default_name = "REAL";
     break;
   case dwarf::DW_ATE_signed:
-    if (bitsize == 32)
-      name.SetCString("INTEGER");
+  case dwarf::DW_ATE_signed_char:
     underlying_kind = FortranType::KIND_INTEGER;
+    default_name = "INTEGER";
     break;
   case dwarf::DW_ATE_complex_float:
-    if (bitsize == 64)
-      name.SetCString("COMPLEX");
     underlying_kind = FortranType::KIND_COMPLEX;
+    default_name = "COMPLEX";
     break;
   default:
     return CompilerType();
   }
+  /// DWARFASTParserFortran provides the names it gets from DWARF, but in case
+  /// it doesn't we fallback to the default name.
+  if (name.IsEmpty() && default_name)
+    name.SetCString(default_name);
+
   return GetOrCreateFortranBaseType(underlying_kind, bitsize, name);
 }
 
-/// Returns the type assosciated with the kind and bitsize, or creates it
-/// if it is not in the map
+/// Creates the type if it has not been created before, otherwise it gets it
+/// from the type map.
 CompilerType TypeSystemFortran::GetOrCreateFortranBaseType(int kind,
                                                            uint64_t bitsize,
                                                            ConstString name) {
@@ -152,16 +161,14 @@ CompilerType TypeSystemFortran::GetOrCreateFortranBaseType(int kind,
 
 lldb::TypeClass
 TypeSystemFortran::GetTypeClass(lldb::opaque_compiler_type_t type) {
-  if (!type)
-    return lldb::eTypeClassInvalid;
-
-  return lldb::eTypeClassBuiltin;
+  return type ? lldb::eTypeClassBuiltin : lldb::eTypeClassInvalid;
 }
 
 CompilerType
 TypeSystemFortran::GetCanonicalType(lldb::opaque_compiler_type_t type) {
   if (!type)
     return CompilerType();
+
   return CompilerType(weak_from_this(), type);
 }
 
@@ -170,14 +177,15 @@ TypeSystemFortran::GetBitSize(opaque_compiler_type_t type,
                               ExecutionContextScope *exe_scope) {
   if (!type)
     return 0;
-  FortranType *fortran_type = static_cast<FortranType *>(type);
-  return fortran_type->GetBitSize();
+
+  return static_cast<FortranType *>(type)->GetBitSize();
 }
 
 BasicType
 TypeSystemFortran::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
   if (!type)
     return eBasicTypeInvalid;
+
   FortranType *fortran_type = static_cast<FortranType *>(type);
   switch (fortran_type->GetKind()) {
   case FortranType::KIND_INTEGER:
diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
index 31804398617d4..46a4a4a74c584 100644
--- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
+++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h
@@ -214,8 +214,8 @@ class TypeSystemFortran : public TypeSystem {
   CompilerType GetOrCreateFortranBaseType(int kind, uint64_t bitsize,
                                           ConstString name);
 
-  CompilerType CreateBaseType(uint32_t dwarf_encoding, uint64_t bitsize,
-                              ConstString name);
+  CompilerType CreateBaseType(llvm::dwarf::TypeKind dwarf_encoding,
+                              uint64_t bitsize, ConstString name);
 
   // Creating related types
 
diff --git a/lldb/unittests/Symbol/TestTypeSystemFortran.cpp b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp
index b3203a1a641ed..d87ce39f75c78 100644
--- a/lldb/unittests/Symbol/TestTypeSystemFortran.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp
@@ -198,6 +198,8 @@ TEST_F(TestTypeSystemFortran, TestTypeClassifications) {
 TEST_F(TestTypeSystemFortran, TestTypeNameGeneration) {
   CompilerType logical32 =
       m_ast->CreateBaseType(llvm::dwarf::DW_ATE_boolean, 32, ConstString());
+  CompilerType logical64 =
+      m_ast->CreateBaseType(llvm::dwarf::DW_ATE_boolean, 64, ConstString());
   CompilerType int32 =
       m_ast->CreateBaseType(llvm::dwarf::DW_ATE_signed, 32, ConstString());
   CompilerType real32 =
@@ -206,6 +208,7 @@ TEST_F(TestTypeSystemFortran, TestTypeNameGeneration) {
       llvm::dwarf::DW_ATE_complex_float, 64, ConstString());
 
   EXPECT_STREQ(logical32.GetTypeName().GetCString(), "LOGICAL");
+  EXPECT_STREQ(logical64.GetTypeName().GetCString(), "LOGICAL");
   EXPECT_STREQ(int32.GetTypeName().GetCString(), "INTEGER");
   EXPECT_STREQ(real32.GetTypeName().GetCString(), "REAL");
   EXPECT_STREQ(complex64.GetTypeName().GetCString(), "COMPLEX");



More information about the lldb-commits mailing list