[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