https://github.com/Iasonaskrpr created https://github.com/llvm/llvm-project/pull/218269
Depends on #218024 (first 18 commits are from #218024; the last 3 commits belong to this PR). This PR adds support for Base Types (INTEGER, LOGICAL, COMPLEX, REAL). Changes: - Adds methods to create types through the FortranType class. - Manages type lifetimes using a SmallVector. - Prevents duplicates using a FoldingSet. - Allows retrieving information about the size, name, and kind of base type. Testing is done through TestTypeSystemFortran, which will have all tests relating to the Type System. Part of the Add Fortran support to LLDB GSoC 2026 project. >From c94bc02707b56671dfe25e76eb4ca634cf6d2132 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Mon, 6 Jul 2026 18:06:32 +0300 Subject: [PATCH 01/21] [lldb][Fortran] Added CMAKE variable guard for Fortran support in LLDB --- lldb/cmake/modules/FindFlang.cmake | 17 +++++++++++++++++ lldb/cmake/modules/LLDBConfig.cmake | 1 + 2 files changed, 18 insertions(+) create mode 100644 lldb/cmake/modules/FindFlang.cmake diff --git a/lldb/cmake/modules/FindFlang.cmake b/lldb/cmake/modules/FindFlang.cmake new file mode 100644 index 0000000000000..f71d42c5fb586 --- /dev/null +++ b/lldb/cmake/modules/FindFlang.cmake @@ -0,0 +1,17 @@ +# FindFlang.cmake + +include(FindPackageHandleStandardArgs) + +# If Flang and lldb are in-tree then the libraries will already be available, otherwise look for specific directories +if(TARGET flangFrontEnd) + set(Flang_FOUND TRUE) +else() + find_package(Flang QUIET CONFIG HINTS ${Flang_DIR} ${LLVM_DIR}/../flang) +endif() + +find_package_handle_standard_args(Flang + FOUND_VAR + Flang_FOUND + REQUIRED_VARS + Flang_FOUND +) \ No newline at end of file diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index e086aaf5d3632..82ad8b19ebb79 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -64,6 +64,7 @@ add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" L add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND) add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION ${LLDB_LIBXML2_VERSION}) add_optional_dependency(LLDB_ENABLE_TREESITTER "Enable Tree-sitter syntax highlighting" TreeSitter TREESITTER_FOUND) +add_optional_dependency(LLDB_ENABLE_FORTRAN "Enable Fortran support in lldb" Flang Flang_FOUND) option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) >From 569e29d532ebf858728e4b79cfb93fd827f4dc16 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Mon, 6 Jul 2026 22:14:20 +0300 Subject: [PATCH 02/21] [lldb] Removed support for out-of-tree flang builds --- lldb/cmake/modules/FindFlang.cmake | 17 ----------------- lldb/cmake/modules/LLDBConfig.cmake | 9 ++++++++- 2 files changed, 8 insertions(+), 18 deletions(-) delete mode 100644 lldb/cmake/modules/FindFlang.cmake diff --git a/lldb/cmake/modules/FindFlang.cmake b/lldb/cmake/modules/FindFlang.cmake deleted file mode 100644 index f71d42c5fb586..0000000000000 --- a/lldb/cmake/modules/FindFlang.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# FindFlang.cmake - -include(FindPackageHandleStandardArgs) - -# If Flang and lldb are in-tree then the libraries will already be available, otherwise look for specific directories -if(TARGET flangFrontEnd) - set(Flang_FOUND TRUE) -else() - find_package(Flang QUIET CONFIG HINTS ${Flang_DIR} ${LLVM_DIR}/../flang) -endif() - -find_package_handle_standard_args(Flang - FOUND_VAR - Flang_FOUND - REQUIRED_VARS - Flang_FOUND -) \ No newline at end of file diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 82ad8b19ebb79..ffb01342531dc 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -56,6 +56,14 @@ set(LLDB_LIBXML2_VERSION "2.8" CACHE STRING static builds of libxml 2. Use at your own risk.") mark_as_advanced(LLDB_LIBXML2_VERSION) +set(LLDB_DEFAULT_ENABLE_FORTRAN OFF) + +if("flang" IN_LIST LLVM_ENABLE_PROJECTS) + set(LLDB_DEFAULT_ENABLE_FORTRAN ON) +endif() + +option(LLDB_ENABLE_FORTRAN "Enable Fortran support in LLDB" ${LLDB_DEFAULT_ENABLE_FORTRAN}) + add_optional_dependency(LLDB_ENABLE_SWIG "Enable SWIG to generate LLDB bindings" SWIG SWIG_FOUND VERSION 4) add_optional_dependency(LLDB_ENABLE_LIBEDIT "Enable editline support in LLDB" LibEdit LibEdit_FOUND) add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" CursesAndPanel CURSESANDPANEL_FOUND) @@ -64,7 +72,6 @@ add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" L add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND) add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION ${LLDB_LIBXML2_VERSION}) add_optional_dependency(LLDB_ENABLE_TREESITTER "Enable Tree-sitter syntax highlighting" TreeSitter TREESITTER_FOUND) -add_optional_dependency(LLDB_ENABLE_FORTRAN "Enable Fortran support in lldb" Flang Flang_FOUND) option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) >From 50fbbc56e37fca4514dd863b415c2a796cb5d32c Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Mon, 6 Jul 2026 22:39:47 +0300 Subject: [PATCH 03/21] Added error message --- lldb/cmake/modules/LLDBConfig.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index ffb01342531dc..23809b5c94f84 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -64,6 +64,15 @@ endif() option(LLDB_ENABLE_FORTRAN "Enable Fortran support in LLDB" ${LLDB_DEFAULT_ENABLE_FORTRAN}) +# Fail early if the user forced Fortran ON but we don't have in-tree Flang +if(LLDB_ENABLE_FORTRAN AND NOT "flang" IN_LIST LLVM_ENABLE_PROJECTS) + message(FATAL_ERROR + "Fortran support in LLDB requires an in-tree Flang build. " + "Please add 'flang' to LLVM_ENABLE_PROJECTS or disable Fortran " + "support by passing -DLLDB_ENABLE_FORTRAN=OFF." + ) +endif() + add_optional_dependency(LLDB_ENABLE_SWIG "Enable SWIG to generate LLDB bindings" SWIG SWIG_FOUND VERSION 4) add_optional_dependency(LLDB_ENABLE_LIBEDIT "Enable editline support in LLDB" LibEdit LibEdit_FOUND) add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" CursesAndPanel CURSESANDPANEL_FOUND) >From 9e620ae8a0e251001fdaf1fd4cfe82a318590d21 Mon Sep 17 00:00:00 2001 From: Iasonas Karaprodromidis <[email protected]> Date: Wed, 8 Jul 2026 15:53:34 +0300 Subject: [PATCH 04/21] Fix punctuation in comment Co-authored-by: Jonas Devlieghere <[email protected]> --- lldb/cmake/modules/LLDBConfig.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 23809b5c94f84..3f2e50cc7ab45 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -64,7 +64,7 @@ endif() option(LLDB_ENABLE_FORTRAN "Enable Fortran support in LLDB" ${LLDB_DEFAULT_ENABLE_FORTRAN}) -# Fail early if the user forced Fortran ON but we don't have in-tree Flang +# Fail early if the user forced Fortran ON but we don't have in-tree Flang. if(LLDB_ENABLE_FORTRAN AND NOT "flang" IN_LIST LLVM_ENABLE_PROJECTS) message(FATAL_ERROR "Fortran support in LLDB requires an in-tree Flang build. " >From 87d8be3cbb63f5ec4ede01ba7baa8e03d4067864 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 17 Jul 2026 18:42:38 +0300 Subject: [PATCH 05/21] [lldb] Removed error if flang is not in enabled projects but support was requested --- lldb/cmake/modules/LLDBConfig.cmake | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 3f2e50cc7ab45..ffb01342531dc 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -64,15 +64,6 @@ endif() option(LLDB_ENABLE_FORTRAN "Enable Fortran support in LLDB" ${LLDB_DEFAULT_ENABLE_FORTRAN}) -# Fail early if the user forced Fortran ON but we don't have in-tree Flang. -if(LLDB_ENABLE_FORTRAN AND NOT "flang" IN_LIST LLVM_ENABLE_PROJECTS) - message(FATAL_ERROR - "Fortran support in LLDB requires an in-tree Flang build. " - "Please add 'flang' to LLVM_ENABLE_PROJECTS or disable Fortran " - "support by passing -DLLDB_ENABLE_FORTRAN=OFF." - ) -endif() - add_optional_dependency(LLDB_ENABLE_SWIG "Enable SWIG to generate LLDB bindings" SWIG SWIG_FOUND VERSION 4) add_optional_dependency(LLDB_ENABLE_LIBEDIT "Enable editline support in LLDB" LibEdit LibEdit_FOUND) add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" CursesAndPanel CURSESANDPANEL_FOUND) >From 2e1c0f845194c820f1483a5c1493c80a2c4d5914 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 21:38:19 +0300 Subject: [PATCH 06/21] [lldb] Added message printing if fortran is enabled --- lldb/cmake/modules/LLDBConfig.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index ffb01342531dc..809ed2c7eed29 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -64,6 +64,12 @@ endif() option(LLDB_ENABLE_FORTRAN "Enable Fortran support in LLDB" ${LLDB_DEFAULT_ENABLE_FORTRAN}) +if(LLDB_ENABLE_FORTRAN) + message(STATUS "Fortran support in LLDB enabled.") +else() + message(STATUS "Fortran support in LLDB disabled.") +endif() + add_optional_dependency(LLDB_ENABLE_SWIG "Enable SWIG to generate LLDB bindings" SWIG SWIG_FOUND VERSION 4) add_optional_dependency(LLDB_ENABLE_LIBEDIT "Enable editline support in LLDB" LibEdit LibEdit_FOUND) add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" CursesAndPanel CURSESANDPANEL_FOUND) >From ace964d6d4bd9a14a94b034337d41a02a3169ea9 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Mon, 6 Jul 2026 19:41:37 +0300 Subject: [PATCH 07/21] [lldb] Allow for Fortran API tests to use F_SOURCES in Makefile --- .../Python/lldbsuite/test/builders/builder.py | 10 ++++-- lldb/packages/Python/lldbsuite/test/dotest.py | 17 ++++++++++ .../Python/lldbsuite/test/dotest_args.py | 9 +++++ .../Python/lldbsuite/test/make/Makefile.rules | 33 ++++++++++++++++++- lldb/test/API/CMakeLists.txt | 14 ++++++++ lldb/test/API/lit.cfg.py | 3 ++ lldb/test/API/lit.site.cfg.py.in | 2 ++ 7 files changed, 85 insertions(+), 3 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index 93ce4cc732bd3..3aa4a7ea2c96a 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -203,12 +203,18 @@ def getToolchainUtil(util_name): if lldbplatformutil.platformIsDarwin(): utils.extend(["AR=%slibtool" % os.getenv("CROSS_COMPILE", "")]) - return [ + build_cmd = [ "CC=%s" % cc, "CC_TYPE=%s" % cc_type, "CXX=%s" % cxx, - ] + utils + ] + + fc = configuration.fortran_compiler + if fc: + build_cmd.append("FC=%s" % fc) + return build_cmd + utils + def getSDKRootSpec(self): """ Helper function to return the key-value string to specify the SDK root diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index b1145f8f96078..c3bf11efccf03 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -267,6 +267,23 @@ def parseOptionsAndInitTestdirs(): configuration.compiler = candidate break + if args.fortran_compiler: + configuration.fortran_compiler = os.path.abspath(args.fortran_compiler) + if not is_exe(configuration.fortran_compiler): + configuration.fortran_compiler = which(args.fortran_compiler) + if not is_exe(configuration.fortran_compiler): + logging.error( + '"%s" is not a valid Fortran compiler executable; aborting...', args.fortran_compiler + ) + sys.exit(-1) + else: + # If no Fortran compiler was explicitly specified, search for local fallbacks. + candidateFortranCompilers = ["flang-new", "flang", "gfortran"] + for candidate in candidateFortranCompilers: + if which(candidate): + configuration.fortran_compiler = candidate + break + if args.make: configuration.make_path = args.make diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py index 13b3d85628dc2..c06ebd60ebcf0 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest_args.py +++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py @@ -48,6 +48,15 @@ def create_parser(): """Specify the compiler(s) used to build the inferior executables. The compiler path can be an executable basename or a full path to a compiler executable. This option can be specified multiple times.""" ), ) + group.add_argument( + '--fortran-compiler', + metavar="fortran_compiler", + dest='fortran_compiler', + default="", + help=textwrap.dedent( + """The fortran compiler used to build the test programs.""" + ), + ) group.add_argument( "--sysroot", metavar="sysroot", diff --git a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules index 51729959fdf62..86e92f6ac6427 100644 --- a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules +++ b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules @@ -255,14 +255,17 @@ endif DEBUG_INFO_FLAG ?= -g CFLAGS ?= $(DEBUG_INFO_FLAG) -O0 +FFLAGS ?= $(DEBUG_INFO_FLAG) -O0 # Some tests require no debug information. When lldb-dotest specifies a DWARF version, # it adds `-gdwarf-{version}` to the CFLAGS environment variable which causes those tests # to fail. Strip any existing debug flags from CFLAGS and force -g0 to prevent this. ifeq "$(MAKE_NO_DEBUG_INFO)" "YES" CFLAGS := $(filter-out -g%,$(CFLAGS)) -g0 + FFLAGS := $(filter-out -g%,$(FFLAGS)) -g0 endif CFLAGS += $(SYSROOT_FLAGS) +FFLAGS += $(SYSROOT_FLAGS) ifeq "$(OS)" "Darwin" CFLAGS += $(FRAMEWORK_INCLUDES) @@ -270,18 +273,22 @@ endif CFLAGS += -I$(LLDB_BASE_DIR)/include -I$(LLDB_OBJ_ROOT)/include CFLAGS += -I$(SRCDIR) -I$(THIS_FILE_DIR) +FFLAGS += -I$(LLDB_BASE_DIR)/include -I$(LLDB_OBJ_ROOT)/include +FFLAGS += -I$(SRCDIR) -I$(THIS_FILE_DIR) ifndef NO_TEST_COMMON_H CFLAGS += -include $(THIS_FILE_DIR)/test_common.h endif CFLAGS += $(NO_LIMIT_DEBUG_INFO_FLAGS) $(ARCH_CFLAGS) +FFLAGS += $(ARCH_CFLAGS) # Use this one if you want to build one part of the result without debug information: CFLAGS_NO_DEBUG = -O0 $(FRAMEWORK_INCLUDES) $(ARCH_CFLAGS) $(CFLAGS_EXTRAS) $(SYSROOT_FLAGS) ifeq "$(MAKE_DWO)" "YES" CFLAGS += -gsplit-dwarf + FFLAGS += -gsplit-dwarf endif ifeq "$(MAKE_DEBUG_NAMES)" "YES" @@ -324,10 +331,17 @@ ifeq ($(CC_TYPE), clang) endif CFLAGS += $(CFLAGS_EXTRAS) +FFLAGS += $(FFLAGS_EXTRAS) CXXFLAGS += -std=c++11 $(CFLAGS) $(ARCH_CXXFLAGS) # Copy common options to the linker flags (dwarf, arch. & etc). # Note: we get some 'garbage' options for linker here (such as -I, --isystem & etc). -LDFLAGS += $(CFLAGS) +ifneq "$(strip $(F_SOURCES))" "" + # We are building Fortran. Use FFLAGS flags. + LDFLAGS += $(FFLAGS) +else + # We are building C/C++. Use CFLAGS. + LDFLAGS += $(CFLAGS) +endif LDFLAGS += $(LD_EXTRAS) $(ARCH_LDFLAGS) ifeq (,$(filter $(OS), Windows_NT Android Darwin Wasm)) ifneq (,$(filter YES,$(ENABLE_THREADS))) @@ -540,6 +554,20 @@ ifeq ($(CC_TYPE), clang) CXXFLAGS += --driver-mode=g++ endif +#---------------------------------------------------------------------- +# Check if we have any Fortran source files +#---------------------------------------------------------------------- +ifneq "$(strip $(F_SOURCES))" "" + ifeq "$(FC)" "" + $(error "No Fortran compiler found for fortran tests") + endif + OBJECTS +=$(strip $(F_SOURCES:.f90=.o)) + # Override the linker with the Fortran compiler, LDC is not needed + # currently so it is set to any + override LD := $(FC) + override LDC := any +endif + ifneq "$(CXX)" "" # Specify the driver mode parameter if we use clang as the linker. ifeq ($(LDC), clang) @@ -673,6 +701,9 @@ endif %.o: %.mm %.d $(CXX) $(CXXFLAGS) -MT $@ -MD -MP -MF $*.d -c -o $@ $< +%.o: %.f90 + $(FC) $(FFLAGS) -c -o $@ $< + #---------------------------------------------------------------------- # Automatic variables based on items already entered. Below we create # an object's lists from the list of sources by replacing all entries diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index bff3bac438d6b..ad093dd6e3ccb 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -88,6 +88,20 @@ else() set(LLDB_DEFAULT_TEST_COMPILER "") endif() +if(LLDB_ENABLE_FORTRAN) + # Prefer the in-tree built target if available. + if(TARGET flang) + set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "${LLVM_TOOLS_BINARY_DIR}/flang${CMAKE_EXECUTABLE_SUFFIX}") + # Fall back to the out-of-tree installation prefix if configured via find_package. + elif(FLANG_INSTALL_PREFIX) + set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "${FLANG_INSTALL_PREFIX}/bin/flang${CMAKE_EXECUTABLE_SUFFIX}") + else() + set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "") + endif() + + set(LLDB_TEST_FORTRAN_COMPILER "${LLDB_DEFAULT_TEST_FORTRAN_COMPILER}" CACHE PATH "Fortran Compiler to use for building LLDB test inferiors") +endif() + set(LLDB_TEST_EXECUTABLE "${LLDB_DEFAULT_TEST_EXECUTABLE}" CACHE PATH "lldb executable used for testing") set(LLDB_TEST_COMPILER "${LLDB_DEFAULT_TEST_COMPILER}" CACHE PATH "C Compiler to use for building LLDB test inferiors") set(LLDB_TEST_DSYMUTIL "${LLDB_DEFAULT_TEST_DSYMUTIL}" CACHE PATH "dsymutil used for generating dSYM bundles") diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 7d6b43f07287d..3d27aa6f7d3bc 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -297,6 +297,9 @@ def delete_module_cache(path): if is_configured("test_compiler"): dotest_cmd += ["--compiler", config.test_compiler] +if is_configured("fortran_test_compiler"): + dotest_cmd += ["--fortran-compiler", config.fortran_test_compiler] + if is_configured("dsymutil"): dotest_cmd += ["--dsymutil", config.dsymutil] diff --git a/lldb/test/API/lit.site.cfg.py.in b/lldb/test/API/lit.site.cfg.py.in index 44c62414f8bdd..c655f9b1dfd96 100644 --- a/lldb/test/API/lit.site.cfg.py.in +++ b/lldb/test/API/lit.site.cfg.py.in @@ -24,6 +24,7 @@ config.python_root_dir = "@Python3_ROOT_DIR@" config.lua_executable = "@LUA_EXECUTABLE@" config.lldb_lua_cpath = "@LLDB_LUA_CPATH@" config.lua_test_entry = "TestLuaAPI.py" +config.lldb_enable_fortran = "@LLDB_ENABLE_FORTRAN@" config.dotest_common_args_str = lit_config.substitute("@LLDB_TEST_COMMON_ARGS@") config.dotest_user_args_str = lit_config.substitute("@LLDB_TEST_USER_ARGS@") config.lldb_platform_url = lit_config.substitute("@LLDB_TEST_PLATFORM_URL@") @@ -36,6 +37,7 @@ config.enabled_plugins = [] config.lldb_executable = lit_config.substitute('@LLDB_TEST_EXECUTABLE@') config.test_triple = '@LLDB_TEST_TRIPLE@' config.test_compiler = lit_config.substitute('@LLDB_TEST_COMPILER@') +config.fortran_test_compiler = lit_config.substitute('@LLDB_TEST_FORTRAN_COMPILER@') config.dsymutil = lit_config.substitute('@LLDB_TEST_DSYMUTIL@') config.make = lit_config.substitute('@LLDB_TEST_MAKE@') config.has_libcxx = @LLDB_HAS_LIBCXX@ >From 1d3053c2a7781573f38a9315cc17fe70ea3aebd3 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Mon, 6 Jul 2026 20:20:47 +0300 Subject: [PATCH 08/21] [lldb] Removed broken elseif statement in CMake --- lldb/test/API/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/lldb/test/API/CMakeLists.txt b/lldb/test/API/CMakeLists.txt index ad093dd6e3ccb..540a1280ad04a 100644 --- a/lldb/test/API/CMakeLists.txt +++ b/lldb/test/API/CMakeLists.txt @@ -92,9 +92,6 @@ if(LLDB_ENABLE_FORTRAN) # Prefer the in-tree built target if available. if(TARGET flang) set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "${LLVM_TOOLS_BINARY_DIR}/flang${CMAKE_EXECUTABLE_SUFFIX}") - # Fall back to the out-of-tree installation prefix if configured via find_package. - elif(FLANG_INSTALL_PREFIX) - set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "${FLANG_INSTALL_PREFIX}/bin/flang${CMAKE_EXECUTABLE_SUFFIX}") else() set(LLDB_DEFAULT_TEST_FORTRAN_COMPILER "") endif() >From 416ae1fbac31bcb781feb5a6b46a8ed348534429 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Wed, 8 Jul 2026 22:34:02 +0300 Subject: [PATCH 09/21] [lldb] Fixed formatting --- lldb/packages/Python/lldbsuite/test/builders/builder.py | 4 ++-- lldb/packages/Python/lldbsuite/test/dotest.py | 3 ++- lldb/packages/Python/lldbsuite/test/dotest_args.py | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/builders/builder.py b/lldb/packages/Python/lldbsuite/test/builders/builder.py index 3aa4a7ea2c96a..c53de950028e8 100644 --- a/lldb/packages/Python/lldbsuite/test/builders/builder.py +++ b/lldb/packages/Python/lldbsuite/test/builders/builder.py @@ -211,10 +211,10 @@ def getToolchainUtil(util_name): fc = configuration.fortran_compiler if fc: - build_cmd.append("FC=%s" % fc) + build_cmd.append("FC=%s" % fc) return build_cmd + utils - + def getSDKRootSpec(self): """ Helper function to return the key-value string to specify the SDK root diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index c3bf11efccf03..9c415ec5889b3 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -273,7 +273,8 @@ def parseOptionsAndInitTestdirs(): configuration.fortran_compiler = which(args.fortran_compiler) if not is_exe(configuration.fortran_compiler): logging.error( - '"%s" is not a valid Fortran compiler executable; aborting...', args.fortran_compiler + '"%s" is not a valid Fortran compiler executable; aborting...', + args.fortran_compiler, ) sys.exit(-1) else: diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py index c06ebd60ebcf0..49bd9fefc40c2 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest_args.py +++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py @@ -49,14 +49,14 @@ def create_parser(): ), ) group.add_argument( - '--fortran-compiler', + "--fortran-compiler", metavar="fortran_compiler", - dest='fortran_compiler', + dest="fortran_compiler", default="", help=textwrap.dedent( """The fortran compiler used to build the test programs.""" ), - ) + ) group.add_argument( "--sysroot", metavar="sysroot", >From db7e9806d1da9bcbddc5d92c4007d3a81ea7e244 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Wed, 8 Jul 2026 23:12:13 +0300 Subject: [PATCH 10/21] [lldb] Added fortran_compiler to configuration --- lldb/packages/Python/lldbsuite/test/configuration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py b/lldb/packages/Python/lldbsuite/test/configuration.py index 7f9616be9a482..db2cec5e405b9 100644 --- a/lldb/packages/Python/lldbsuite/test/configuration.py +++ b/lldb/packages/Python/lldbsuite/test/configuration.py @@ -43,6 +43,7 @@ # command line. arch = None compiler = None +fortran_compiler = None dsymutil = None sdkroot = None make_path = None >From c390be0bb969a7144ba1c44a24bc2326942a25ff Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 10 Jul 2026 22:33:34 +0300 Subject: [PATCH 11/21] [lldb] Addressed code quality comments --- lldb/packages/Python/lldbsuite/test/dotest_args.py | 2 +- lldb/packages/Python/lldbsuite/test/make/Makefile.rules | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/dotest_args.py b/lldb/packages/Python/lldbsuite/test/dotest_args.py index 49bd9fefc40c2..8791ddc377c65 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest_args.py +++ b/lldb/packages/Python/lldbsuite/test/dotest_args.py @@ -54,7 +54,7 @@ def create_parser(): dest="fortran_compiler", default="", help=textwrap.dedent( - """The fortran compiler used to build the test programs.""" + """The Fortran compiler used to build the test programs.""" ), ) group.add_argument( diff --git a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules index 86e92f6ac6427..22eeeb24a59c1 100644 --- a/lldb/packages/Python/lldbsuite/test/make/Makefile.rules +++ b/lldb/packages/Python/lldbsuite/test/make/Makefile.rules @@ -261,8 +261,8 @@ FFLAGS ?= $(DEBUG_INFO_FLAG) -O0 # it adds `-gdwarf-{version}` to the CFLAGS environment variable which causes those tests # to fail. Strip any existing debug flags from CFLAGS and force -g0 to prevent this. ifeq "$(MAKE_NO_DEBUG_INFO)" "YES" - CFLAGS := $(filter-out -g%,$(CFLAGS)) -g0 - FFLAGS := $(filter-out -g%,$(FFLAGS)) -g0 + CFLAGS := $(filter-out -g%,$(CFLAGS)) -g0 + FFLAGS := $(filter-out -g%,$(FFLAGS)) -g0 endif CFLAGS += $(SYSROOT_FLAGS) FFLAGS += $(SYSROOT_FLAGS) @@ -558,12 +558,12 @@ endif # Check if we have any Fortran source files #---------------------------------------------------------------------- ifneq "$(strip $(F_SOURCES))" "" - ifeq "$(FC)" "" + ifeq "$(FC)" "" $(error "No Fortran compiler found for fortran tests") endif OBJECTS +=$(strip $(F_SOURCES:.f90=.o)) # Override the linker with the Fortran compiler, LDC is not needed - # currently so it is set to any + # currently so it is set to any. override LD := $(FC) override LDC := any endif >From cc2b09e625323229fd5d3cfc190925455bdf61a4 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 22:19:03 +0300 Subject: [PATCH 12/21] [lldb] Added LanguageIsFortran helper to language class --- lldb/include/lldb/Target/Language.h | 2 ++ lldb/source/Target/Language.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h index bd3faf89658c9..5c7bdfcc628ce 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -443,6 +443,8 @@ class Language : public PluginInterface { /// Equivalent to \c LanguageIsC||LanguageIsObjC||LanguageIsCPlusPlus. static bool LanguageIsCFamily(lldb::LanguageType language); + static bool LanguageIsFortran(lldb::LanguageType language); + static bool LanguageIsPascal(lldb::LanguageType language); // return the primary language, so if LanguageIsC(l), return eLanguageTypeC, diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp index 077c403f4ea58..a4d6031b4b27d 100644 --- a/lldb/source/Target/Language.cpp +++ b/lldb/source/Target/Language.cpp @@ -396,6 +396,20 @@ bool Language::LanguageIsCFamily(LanguageType language) { } } +bool Language::LanguageIsFortran(LanguageType language) { + switch (language) { + case eLanguageTypeFortran77: + case eLanguageTypeFortran90: + case eLanguageTypeFortran95: + case eLanguageTypeFortran03: + case eLanguageTypeFortran08: + case eLanguageTypeFortran18: + return true; + default: + return false; + } +} + bool Language::LanguageIsPascal(LanguageType language) { switch (language) { case eLanguageTypePascal83: >From 9ae401cb1e563069eef0b4094a5d9c2a31817bfa Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 22:19:33 +0300 Subject: [PATCH 13/21] [lldb][Fortran] Added Fortran language PLugin --- lldb/source/Plugins/Language/CMakeLists.txt | 3 + .../Plugins/Language/Fortran/CMakeLists.txt | 12 ++++ .../Language/Fortran/FortranLanguage.cpp | 62 +++++++++++++++++++ .../Language/Fortran/FortranLanguage.h | 58 +++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 lldb/source/Plugins/Language/Fortran/CMakeLists.txt create mode 100644 lldb/source/Plugins/Language/Fortran/FortranLanguage.cpp create mode 100644 lldb/source/Plugins/Language/Fortran/FortranLanguage.h diff --git a/lldb/source/Plugins/Language/CMakeLists.txt b/lldb/source/Plugins/Language/CMakeLists.txt index 6367ab916c8fb..2dd89b5207a57 100644 --- a/lldb/source/Plugins/Language/CMakeLists.txt +++ b/lldb/source/Plugins/Language/CMakeLists.txt @@ -7,3 +7,6 @@ set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES add_subdirectory(CPlusPlus) add_subdirectory(ObjC) add_subdirectory(ObjCPlusPlus) +if(LLDB_ENABLE_FORTRAN) + add_subdirectory(Fortran) +endif() \ No newline at end of file diff --git a/lldb/source/Plugins/Language/Fortran/CMakeLists.txt b/lldb/source/Plugins/Language/Fortran/CMakeLists.txt new file mode 100644 index 0000000000000..7c5faa87aeaba --- /dev/null +++ b/lldb/source/Plugins/Language/Fortran/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_library(lldbPluginFortranLanguage PLUGIN + FortranLanguage.cpp + + LINK_LIBS + lldbCore + lldbDataFormatters + lldbExpression + lldbHost + lldbSymbol + lldbTarget + lldbUtility +) \ No newline at end of file diff --git a/lldb/source/Plugins/Language/Fortran/FortranLanguage.cpp b/lldb/source/Plugins/Language/Fortran/FortranLanguage.cpp new file mode 100644 index 0000000000000..073c963d4492d --- /dev/null +++ b/lldb/source/Plugins/Language/Fortran/FortranLanguage.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 implements the Fortran language Plugin. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringRef.h" + +#include "FortranLanguage.h" + +#include "lldb/Core/PluginManager.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::formatters; + +LLDB_PLUGIN_DEFINE(FortranLanguage) + +void FortranLanguage::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), "Fortran Language", + CreateInstance); +} + +void FortranLanguage::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +StringRef FortranLanguage::GetPluginNameStatic() { + static llvm::StringRef g_name("fortran"); + return g_name; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +StringRef FortranLanguage::GetPluginName() { return GetPluginNameStatic(); } + +uint32_t FortranLanguage::GetPluginVersion() { return 1; } + +Language *FortranLanguage::CreateInstance(LanguageType language) { + if (Language::LanguageIsFortran(language)) { + return new FortranLanguage(); + } + return nullptr; +} + +bool FortranLanguage::IsSourceFile(StringRef file_path) const { + const auto suffixes = {".f90", ".f", ".f95", ".f03", ".f08", ".f18"}; + for (auto suffix : suffixes) { + if (file_path.ends_with_insensitive(suffix)) + return true; + } + return false; +} \ No newline at end of file diff --git a/lldb/source/Plugins/Language/Fortran/FortranLanguage.h b/lldb/source/Plugins/Language/Fortran/FortranLanguage.h new file mode 100644 index 0000000000000..2bd616f347b78 --- /dev/null +++ b/lldb/source/Plugins/Language/Fortran/FortranLanguage.h @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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 Fortran language Plugin. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_FORTRAN_FORTRANLANGUAGE_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_FORTRAN_FORTRANLANGUAGE_H +#include "lldb/Target/Language.h" + +#include "llvm/ADT/StringRef.h" + +#include "lldb/Target/Language.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class FortranLanguage : public Language { +public: + FortranLanguage() = default; + + ~FortranLanguage() override = default; + + lldb::LanguageType GetLanguageType() const override { + return lldb::eLanguageTypeFortran90; + } + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static lldb_private::Language *CreateInstance(lldb::LanguageType language); + + static llvm::StringRef GetPluginNameStatic(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + llvm::StringRef GetPluginName() override; + + uint32_t GetPluginVersion(); + + bool IsSourceFile(llvm::StringRef file_path) const override; +}; + +}; // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_FORTRAN_FORTRANLANGUAGE_H \ No newline at end of file >From 1f67c2943dff7ba7f29f1237bdc7526e5b4d62dd Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 22:20:03 +0300 Subject: [PATCH 14/21] [lldb][Fortran] Added Fortran language plugin tests --- lldb/unittests/Language/CMakeLists.txt | 3 ++ .../unittests/Language/Fortran/CMakeLists.txt | 6 +++ .../Language/Fortran/FortranLanguageTest.cpp | 41 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 lldb/unittests/Language/Fortran/CMakeLists.txt create mode 100644 lldb/unittests/Language/Fortran/FortranLanguageTest.cpp diff --git a/lldb/unittests/Language/CMakeLists.txt b/lldb/unittests/Language/CMakeLists.txt index a0bdc62af98c6..db43874757bc3 100644 --- a/lldb/unittests/Language/CMakeLists.txt +++ b/lldb/unittests/Language/CMakeLists.txt @@ -1,3 +1,6 @@ add_subdirectory(CPlusPlus) add_subdirectory(CLanguages) add_subdirectory(ObjC) +if(LLDB_ENABLE_FORTRAN) + add_subdirectory(Fortran) +endif() \ No newline at end of file diff --git a/lldb/unittests/Language/Fortran/CMakeLists.txt b/lldb/unittests/Language/Fortran/CMakeLists.txt new file mode 100644 index 0000000000000..661b12ebf8950 --- /dev/null +++ b/lldb/unittests/Language/Fortran/CMakeLists.txt @@ -0,0 +1,6 @@ +add_lldb_unittest(LanguageFortranLanguageTests + FortranLanguageTest.cpp + + LINK_LIBS + lldbPluginFortranLanguage +) diff --git a/lldb/unittests/Language/Fortran/FortranLanguageTest.cpp b/lldb/unittests/Language/Fortran/FortranLanguageTest.cpp new file mode 100644 index 0000000000000..5b81544539785 --- /dev/null +++ b/lldb/unittests/Language/Fortran/FortranLanguageTest.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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 tests the Fortran Plugin features. +/// +//===----------------------------------------------------------------------===// + +#include "Plugins/Language/Fortran/FortranLanguage.h" +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/lldb-enumerations.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using namespace lldb_private; + +/// Returns the name of the LLDB plugin for the given language or an empty +/// string if there is no fitting plugin. +static llvm::StringRef GetPluginName(lldb::LanguageType language) { + Language *language_plugin = Language::FindPlugin(language); + if (language_plugin) + return language_plugin->GetPluginName(); + return ""; +} + +TEST(FortranLanguage, LookupFortranLanguageByLanguageType) { + SubsystemRAII<FortranLanguage> langs; + + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran77), "fortran"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran90), "fortran"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran95), "fortran"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran03), "fortran"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran08), "fortran"); + EXPECT_EQ(GetPluginName(lldb::eLanguageTypeFortran18), "fortran"); +} >From 309b530037b57649bf47487ed7bf10513dab627a Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 22:44:49 +0300 Subject: [PATCH 15/21] [lldb][Fortran] Add TypeSystemFortran class --- lldb/source/Plugins/TypeSystem/CMakeLists.txt | 4 + .../Plugins/TypeSystem/Fortran/CMakeLists.txt | 12 + .../TypeSystem/Fortran/TypeSystemFortran.cpp | 81 +++ .../TypeSystem/Fortran/TypeSystemFortran.h | 492 ++++++++++++++++++ 4 files changed, 589 insertions(+) create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h diff --git a/lldb/source/Plugins/TypeSystem/CMakeLists.txt b/lldb/source/Plugins/TypeSystem/CMakeLists.txt index 47e32ff176d8c..7342c5a8af639 100644 --- a/lldb/source/Plugins/TypeSystem/CMakeLists.txt +++ b/lldb/source/Plugins/TypeSystem/CMakeLists.txt @@ -3,3 +3,7 @@ set_property(DIRECTORY PROPERTY LLDB_PLUGIN_KIND TypeSystem) set_property(DIRECTORY PROPERTY LLDB_TOLERATED_PLUGIN_DEPENDENCIES SymbolFile) add_subdirectory(Clang) + +if(LLDB_ENABLE_FORTRAN) + add_subdirectory(Fortran) +endif() \ No newline at end of file diff --git a/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt b/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt new file mode 100644 index 0000000000000..c78b70d48eb31 --- /dev/null +++ b/lldb/source/Plugins/TypeSystem/Fortran/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_library(lldbPluginTypeSystemFortran PLUGIN + TypeSystemFortran.cpp + + LINK_COMPONENTS + Support + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbUtility + lldbPluginSymbolFileDWARF +) diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp new file mode 100644 index 0000000000000..ab70415881564 --- /dev/null +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// 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 implements the Fortran type system. +/// +//===----------------------------------------------------------------------===// +#include "TypeSystemFortran.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; +using namespace lldb_private::plugin::dwarf; + +LLDB_PLUGIN_DEFINE(TypeSystemFortran) + +/// Used to determine if TypeSystem supports the language passed in +/// CreateInstance +static bool IsLanguageSupported(lldb::LanguageType language) { + if (language == lldb::LanguageType::eLanguageTypeFortran77 || + language == lldb::LanguageType::eLanguageTypeFortran90 || + language == lldb::LanguageType::eLanguageTypeFortran95 || + language == lldb::LanguageType::eLanguageTypeFortran03 || + language == lldb::LanguageType::eLanguageTypeFortran08 || + language == lldb::LanguageType::eLanguageTypeFortran18) + return true; + + return false; +} + +char TypeSystemFortran::ID; + +TypeSystemFortran::~TypeSystemFortran() = default; +TypeSystemFortran::TypeSystemFortran() = default; + +void TypeSystemFortran::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "fortran AST context plug-in", CreateInstance, + GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions()); +} + +void TypeSystemFortran::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb::TypeSystemSP +TypeSystemFortran::CreateInstance(lldb::LanguageType language, Module *module, + Target *target) { + if (IsLanguageSupported(language)) { + return std::make_shared<TypeSystemFortran>(); + } + return TypeSystemSP(); +} + +LanguageSet TypeSystemFortran::GetSupportedLanguagesForTypes() { + LanguageSet languages; + languages.Insert(eLanguageTypeFortran77); + languages.Insert(eLanguageTypeFortran90); + languages.Insert(eLanguageTypeFortran95); + languages.Insert(eLanguageTypeFortran03); + languages.Insert(eLanguageTypeFortran08); + languages.Insert(eLanguageTypeFortran18); + return languages; +} + +LanguageSet TypeSystemFortran::GetSupportedLanguagesForExpressions() { + return GetSupportedLanguagesForTypes(); +} + +bool TypeSystemFortran::SupportsLanguage(lldb::LanguageType language) { + return IsLanguageSupported(language); +} \ No newline at end of file diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h new file mode 100644 index 0000000000000..002501acac718 --- /dev/null +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h @@ -0,0 +1,492 @@ +//===----------------------------------------------------------------------===// +// +// 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 contains the definition of the Fortran Type System. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H +#define LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H + +#include "lldb/Symbol/TypeSystem.h" +#include "llvm/Support/ErrorHandling.h" + +namespace lldb_private { + +class TypeSystemFortran : public TypeSystem { + // LLVM RTTI support + static char ID; + +public: + // llvm casting support + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const TypeSystem *ts) { return ts->isA(&ID); } + + TypeSystemFortran(); + + ~TypeSystemFortran(); + + static void Initialize(); + + static void Terminate(); + + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, + Module *module, Target *target); + + static LanguageSet GetSupportedLanguagesForTypes(); + + static LanguageSet GetSupportedLanguagesForExpressions(); + + // CompilerDecl functions + ConstString DeclGetName(void *opaque_decl) override { return ConstString(); } + + CompilerType GetTypeForDecl(void *opaque_decl) override { + return CompilerType(); + } + + // CompilerDeclContext functions + + ConstString DeclContextGetName(void *opaque_decl_ctx) override { + return ConstString(); + } + + ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override { + return ConstString(); + } + + bool DeclContextIsClassMethod(void *opaque_decl_ctx) override { + return false; + } + + bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, + void *other_opaque_decl_ctx) override { + return false; + } + + lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override { + return lldb::LanguageType::eLanguageTypeUnknown; + } + +// Tests +#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; }; +#endif + + bool IsArrayType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override { + return false; + }; + + bool IsAggregateType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsCharType(lldb::opaque_compiler_type_t type) override { return false; } + + bool IsCompleteType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsDefined(lldb::opaque_compiler_type_t type) override { return false; } + + bool IsFloatingPointType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsFunctionType(lldb::opaque_compiler_type_t type) override { + return false; + } + + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override { + return 0; + } + + CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, + const size_t index) override { + return CompilerType(); + } + + bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsMemberDataPointerType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, + CompilerType *function_pointer_type_ptr) override { + return false; + } + + bool IsIntegerType(lldb::opaque_compiler_type_t type, + bool &is_signed) override { + return false; + }; + + bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, + CompilerType *target_type, // Can pass NULL + bool check_cplusplus, bool check_objc) override { + return false; + } + + bool IsPointerType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override { + return false; + } + + bool IsScalarType(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsVoidType(lldb::opaque_compiler_type_t type) override { return false; } + + bool CanPassInRegisters(const CompilerType &type) override { return false; } + + // TypeSystems can support more than one language + bool SupportsLanguage(lldb::LanguageType language) override; + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + static llvm::StringRef GetPluginNameStatic() { return "fortran"; } + + // Type Completion + + bool GetCompleteType(lldb::opaque_compiler_type_t type) override { + return false; + } + + // AST related queries + + uint32_t GetPointerByteSize() override { return 0; } + + CompilerType GetPointerDiffType(bool is_signed) override { + return CompilerType(); + } + + unsigned GetPtrAuthKey(lldb::opaque_compiler_type_t type) override { + return 0; + } + + unsigned GetPtrAuthDiscriminator(lldb::opaque_compiler_type_t type) override { + return 0; + } + + bool GetPtrAuthAddressDiversity(lldb::opaque_compiler_type_t type) override { + return false; + } + + // Accessors + + ConstString GetTypeName(lldb::opaque_compiler_type_t type, + bool BaseOnly) override { + return ConstString(); + } + + ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) override { + return ConstString(); + } + + uint32_t + GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type) override { + return 0; + } + + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override { + return lldb::LanguageType::eLanguageTypeFortran90; + } + + lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override { + return lldb::TypeClass::eTypeClassInvalid; + } + + // Creating related types + + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override { + return CompilerType(); + } + + CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + CompilerType + GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + // Returns -1 if this isn't a function of if the function doesn't have a + // prototype Returns a value >= 0 if there is a prototype. + int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override { + return -1; + } + + CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override { + return CompilerType(); + } + + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override { + return 0; + } + + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, + size_t idx) override { + return TypeMemberFunctionImpl(); + } + + CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + // Exploring the type + + const llvm::fltSemantics & + GetFloatTypeSemantics(size_t byte_size, lldb::Format format) override { + return llvm::APFloatBase::Bogus(); + } + + llvm::Expected<uint64_t> + GetBitSize(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override { + return 0; + } + + lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type) override { + return lldb::eEncodingInvalid; + } + + lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override { + return lldb::eFormatDefault; + } + + llvm::Expected<uint32_t> + GetNumChildren(lldb::opaque_compiler_type_t type, + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) override { + return 0; + } + + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override { + return lldb::eBasicTypeUnsignedInt; + } + + uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override { + return 0; + } + + CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, + std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, + bool *is_bitfield_ptr) override { + return CompilerType(); + } + + uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } + + uint32_t + GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override { + return 0; + } + + CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } + + CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, + size_t idx, + uint32_t *bit_offset_ptr) override { + return CompilerType(); + } + + llvm::Expected<CompilerType> + GetDereferencedType(lldb::opaque_compiler_type_t type, + ExecutionContext *exe_ctx, std::string &deref_name, + uint32_t &deref_byte_size, int32_t &deref_byte_offset, + ValueObject *valobj, uint64_t &language_flags) override { + return CompilerType(); + } + + llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex( + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, + bool ignore_array_bounds, std::string &child_name, + uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, + ValueObject *valobj, uint64_t &language_flags) override { + return CompilerType(); + } + + // Lookup a child given a name. This function will match base class names and + // member member names in "clang_type" only, not descendants. + llvm::Expected<uint32_t> + GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, + llvm::StringRef name, + bool omit_empty_base_classes) override { + return 0; + } + + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, + llvm::StringRef name, + bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override { + return 0; + } + +#ifndef NDEBUG + /// Convenience LLVM-style dump method for use in the debugger only. + LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override { + } +#endif + + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream &s, + lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, + uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, + ExecutionContextScope *exe_scope) override { + return false; + } + + /// Dump the type to stdout. + void DumpTypeDescription( + lldb::opaque_compiler_type_t type, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override {} + + /// Print a description of the type to a stream. The exact implementation + /// varies, but the expectation is that eDescriptionLevelFull returns a + /// source-like representation of the type, whereas eDescriptionLevelVerbose + /// does a dump of the underlying AST if applicable. + void DumpTypeDescription( + lldb::opaque_compiler_type_t type, Stream &s, + lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override {} + + /// Dump a textual representation of the internal TypeSystem state to the + /// given stream. + /// + /// This should not modify the state of the TypeSystem if possible. + /// + /// \param[out] output Stream to dup the AST into. + /// \param[in] filter If empty, dump whole AST. If non-empty, will only + /// dump decls whose names contain \c filter. + /// \param[in] show_color If true, prints the AST color-highlighted. + void Dump(llvm::raw_ostream &output, llvm::StringRef filter, + bool show_color) override {} + + /// This is used by swift. + bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override { + return false; + } + + // TODO: Determine if these methods should move to TypeSystemClang. + + bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type) override { + return false; + } + + unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override { + return 0; + } + + std::optional<size_t> + GetTypeBitAlign(lldb::opaque_compiler_type_t type, + ExecutionContextScope *exe_scope) override { + return 0; + } + + CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override { + return CompilerType(); + } + + CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, + size_t bit_size) override { + return CompilerType(); + } + + bool IsBeingDefined(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsConst(lldb::opaque_compiler_type_t type) override { return false; } + + uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, + CompilerType *base_type_ptr) override { + return 0; + } + + bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override { + return false; + } + + bool IsTypedefType(lldb::opaque_compiler_type_t type) override { + return false; + } + + // If the current object represents a typedef type, get the underlying type + CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + bool IsVectorType(lldb::opaque_compiler_type_t type, + CompilerType *element_type, uint64_t *size) override { + return false; + } + + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override { + return CompilerType(); + } + + bool IsReferenceType(lldb::opaque_compiler_type_t type, + CompilerType *pointee_type, bool *is_rvalue) override { + return false; + } + +private: + TypeSystemFortran(const TypeSystemFortran &) = delete; + const TypeSystemFortran &operator=(const TypeSystemFortran &) = delete; +}; +} // namespace lldb_private +#endif // LLDB_SOURCE_PLUGINS_TYPESYSTEM_FORTRAN_TYPESYSTEMFORTRAN_H >From b1f62d123dbd90fe81528ba4cacca24b7d704b56 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 22:45:35 +0300 Subject: [PATCH 16/21] [lldb][Fortran] Add TypeSystemFortran to lldb-forward.h --- lldb/include/lldb/lldb-forward.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 67888f7d32ed1..9c6a11dd6d9b3 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -282,6 +282,7 @@ class TypeSummaryImpl; class TypeSummaryOptions; class TypeSystem; class TypeSystemClang; +class TypeSystemFortran; class UUID; class UnixSignals; class Unwind; >From 25d3d348918167606fc9d95523817dd9163fc0d5 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 23:12:18 +0300 Subject: [PATCH 17/21] [lldb][Fortran] Added DWARFASTParser for Fortran --- .../Plugins/SymbolFile/DWARF/CMakeLists.txt | 15 ++++ .../Plugins/SymbolFile/DWARF/DWARFASTParser.h | 2 +- .../DWARF/DWARFASTParserFortran.cpp | 43 ++++++++++ .../SymbolFile/DWARF/DWARFASTParserFortran.h | 80 +++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.cpp create mode 100644 lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.h diff --git a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt index 3f7cf023ac21c..dcaf1c2df2b19 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -10,6 +10,13 @@ lldb_tablegen(SymbolFileDWARFProperties.json -dump-json SOURCE SymbolFileDWARFProperties.td TARGET LLDBPluginSymbolFileDWARFPropertiesJsonGen) +set(LLVM_OPTIONAL_SOURCES DWARFASTParserFortran.cpp) + +set(FORTRAN_DWARF_SOURCES "") +if(LLDB_ENABLE_FORTRAN) + set(FORTRAN_DWARF_SOURCES DWARFASTParserFortran.cpp) +endif() + add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN AppleDWARFIndex.cpp DebugNamesDWARFIndex.cpp @@ -41,6 +48,7 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN SymbolFileDWARFDebugMap.cpp SymbolFileWasm.cpp UniqueDWARFASTType.cpp + ${FORTRAN_DWARF_SOURCES} LINK_COMPONENTS DebugInfoDWARF @@ -66,3 +74,10 @@ add_lldb_library(lldbPluginSymbolFileDWARF PLUGIN add_dependencies(lldbPluginSymbolFileDWARF LLDBPluginSymbolFileDWARFPropertiesGen LLDBPluginSymbolFileDWARFPropertiesEnumGen) + +if(LLDB_ENABLE_FORTRAN) + target_link_libraries(lldbPluginSymbolFileDWARF PRIVATE + lldbPluginFortranLanguage + lldbPluginTypeSystemFortran + ) +endif() diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 80f7becc1b24b..8f32874d788af 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -29,7 +29,7 @@ class SymbolFileDWARF; class DWARFASTParser { public: - enum class Kind { DWARFASTParserClang }; + enum class Kind { DWARFASTParserClang, DWARFASTParserFortran }; DWARFASTParser(Kind kind) : m_kind(kind) {} virtual ~DWARFASTParser() = default; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.cpp new file mode 100644 index 0000000000000..1179e0e004600 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 implements the DWARF AST Parser for the Fortran language. +/// +//===----------------------------------------------------------------------===// + +#include "DWARFASTParserFortran.h" + +using namespace lldb; +using namespace lldb_private; + +DWARFASTParserFortran::DWARFASTParserFortran( + lldb_private::TypeSystemFortran &m_ast) + : lldb_private::plugin::dwarf::DWARFASTParser(Kind::DWARFASTParserFortran), + m_ast(m_ast) {} + +DWARFASTParserFortran::~DWARFASTParserFortran() {} + +lldb::TypeSP DWARFASTParserFortran::ParseTypeFromDWARF( + const lldb_private::SymbolContext &sc, + const lldb_private::plugin::dwarf::DWARFDIE &die, bool *type_is_new_ptr) { + return lldb::TypeSP(); +} + +lldb_private::Function *DWARFASTParserFortran::ParseFunctionFromDWARF( + lldb_private::CompileUnit &comp_unit, + const lldb_private::plugin::dwarf::DWARFDIE &die, + lldb_private::AddressRanges ranges) { + return nullptr; +} + +bool DWARFASTParserFortran::CompleteTypeFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die, lldb_private::Type *type, + const lldb_private::CompilerType &compiler_type) { + return false; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.h new file mode 100644 index 0000000000000..b0410be2ba89e --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserFortran.h @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// 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 DWARF AST Parser for the Fortran language. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERFORTRAN_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERFORTRAN_H + +#include "DWARFASTParser.h" +#include "Plugins/SymbolFile/DWARF/DWARFDIE.h" +#include "Plugins/TypeSystem/Fortran/TypeSystemFortran.h" + +namespace lldb_private { +class CompileUnit; +class ExecutionContext; +} // namespace lldb_private + +class DWARFASTParserFortran + : public lldb_private::plugin::dwarf::DWARFASTParser { +public: + DWARFASTParserFortran(lldb_private::TypeSystemFortran &m_ast); + + ~DWARFASTParserFortran() override; + + lldb::TypeSP + ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, + const lldb_private::plugin::dwarf::DWARFDIE &die, + bool *type_is_new_ptr) override; + + lldb_private::Function * + ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, + const lldb_private::plugin::dwarf::DWARFDIE &die, + lldb_private::AddressRanges ranges) override; + + bool CompleteTypeFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die, + lldb_private::Type *type, + const lldb_private::CompilerType &compiler_type) override; + + lldb_private::ConstString ConstructDemangledNameFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die) override { + return lldb_private::ConstString(); + } + + lldb_private::CompilerDecl GetDeclForUIDFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die) override { + return lldb_private::CompilerDecl(); + } + + lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die) override { + return lldb_private::CompilerDeclContext(); + } + + lldb_private::CompilerDeclContext GetDeclContextContainingUIDFromDWARF( + const lldb_private::plugin::dwarf::DWARFDIE &die) override { + return lldb_private::CompilerDeclContext(); + } + + void EnsureAllDIEsInDeclContextHaveBeenParsed( + lldb_private::CompilerDeclContext decl_context) override {} + + std::string GetDIEClassTemplateParams( + lldb_private::plugin::dwarf::DWARFDIE die) override { + return {}; + } + +private: + lldb_private::TypeSystemFortran &m_ast; +}; + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERFORTRAN_H >From ab47ff44bdf8ef7f74aaf57b4f189c32b89da57e Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Fri, 21 Aug 2026 23:21:18 +0300 Subject: [PATCH 18/21] [lldb][Fortran] Add function to return DWARFASTParserFortran from TypeSystemFortran --- .../Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp | 8 ++++++++ .../source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp index ab70415881564..2fe29a81c7520 100644 --- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp @@ -16,6 +16,8 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Target/Target.h" +#include "Plugins/SymbolFile/DWARF/DWARFASTParserFortran.h" + using namespace lldb; using namespace lldb_private; using namespace llvm; @@ -52,6 +54,12 @@ void TypeSystemFortran::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } +plugin::dwarf::DWARFASTParser *TypeSystemFortran::GetDWARFParser() { + if (!m_dwarf_ast_parser_up) + m_dwarf_ast_parser_up = std::make_unique<DWARFASTParserFortran>(*this); + return m_dwarf_ast_parser_up.get(); +} + lldb::TypeSystemSP TypeSystemFortran::CreateInstance(lldb::LanguageType language, Module *module, Target *target) { diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h index 002501acac718..e15582c2ce67b 100644 --- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h @@ -36,6 +36,8 @@ class TypeSystemFortran : public TypeSystem { static void Terminate(); + plugin::dwarf::DWARFASTParser *GetDWARFParser() override; + static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module, Target *target); @@ -485,6 +487,8 @@ class TypeSystemFortran : public TypeSystem { } private: + std::unique_ptr<plugin::dwarf::DWARFASTParser> m_dwarf_ast_parser_up; + TypeSystemFortran(const TypeSystemFortran &) = delete; const TypeSystemFortran &operator=(const TypeSystemFortran &) = delete; }; >From 077c3775a6615f9660107b36015d6401212584f8 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Sat, 22 Aug 2026 15:43:08 +0300 Subject: [PATCH 19/21] [lldb][Fortran] Added FortranType class, the internal representation of fortran types --- .../Plugins/TypeSystem/Fortran/CMakeLists.txt | 1 + .../TypeSystem/Fortran/FortranTypes.cpp | 21 +++++ .../Plugins/TypeSystem/Fortran/FortranTypes.h | 76 +++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp create mode 100644 lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h 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..d02ecea419680 --- /dev/null +++ b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 implements the classes that describe the Fortran types. +/// +//===----------------------------------------------------------------------===// + +#include "FortranTypes.h" + +using namespace lldb_private; +using namespace lldb_private::plugin::fortran; + +char FortranType::ID; + +FortranType::~FortranType() = default; \ No newline at end of file diff --git a/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h b/lldb/source/Plugins/TypeSystem/Fortran/FortranTypes.h new file mode 100644 index 0000000000000..3a88f0c1aedd1 --- /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 \ No newline at end of file >From b312a468a80d431bf19884580c0613f551c58009 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Sat, 22 Aug 2026 18:50:13 +0300 Subject: [PATCH 20/21] [lldb][Fortran] Added Base type support to TypeSystemFortran --- .../TypeSystem/Fortran/TypeSystemFortran.cpp | 161 ++++++++++++++++++ .../TypeSystem/Fortran/TypeSystemFortran.h | 72 ++++---- 2 files changed, 196 insertions(+), 37 deletions(-) diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp index 2fe29a81c7520..a335f1bfacf82 100644 --- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.cpp @@ -11,7 +11,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/Target.h" @@ -22,6 +24,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) @@ -84,6 +87,164 @@ 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 IsLanguageSupported(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::CreateType(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 GetOrCreateFortranType(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::GetOrCreateFortranType(int kind, + uint64_t bitsize, + ConstString name) { + llvm::FoldingSetNodeID id; + FortranType::Profile(id, kind, bitsize); + void *insert_pos = nullptr; + FortranType *fortran_type = m_basic_types.FindNodeOrInsertPos(id, insert_pos); + if (fortran_type) + return CompilerType(weak_from_this(), (void *)fortran_type); + auto new_type_up = std::make_unique<FortranType>(kind, bitsize, name); + fortran_type = new_type_up.get(); + + m_types.push_back(std::move(new_type_up)); + m_basic_types.InsertNode(fortran_type, insert_pos); + 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(); +} + +CompilerType TypeSystemFortran::GetBasicTypeFromAST(BasicType basic_type) { + switch (basic_type) { + case eBasicTypeInt: + return GetOrCreateFortranType(FortranType::KIND_INTEGER, 32, + ConstString("INTEGER")); + case eBasicTypeFloat: + return GetOrCreateFortranType(FortranType::KIND_REAL, 32, + ConstString("REAL")); + case eBasicTypeDouble: + return GetOrCreateFortranType(FortranType::KIND_REAL, 64, + ConstString("REAL(KIND=8)")); + case eBasicTypeBool: + return GetOrCreateFortranType(FortranType::KIND_LOGICAL, 32, + ConstString("LOGICAL")); + case eBasicTypeFloatComplex: + return GetOrCreateFortranType(FortranType::KIND_COMPLEX, 64, + ConstString("COMPLEX")); + case eBasicTypeDoubleComplex: + return GetOrCreateFortranType(FortranType::KIND_COMPLEX, 128, + ConstString("COMPLEX(KIND=8)")); + case eBasicTypeLongDoubleComplex: + return GetOrCreateFortranType(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 GetOrCreateFortranType(FortranType::KIND_INTEGER, bit_size, + ConstString("INTEGER")); + case eEncodingIEEE754: + return GetOrCreateFortranType(FortranType::KIND_REAL, bit_size, + ConstString("REAL")); + default: + return CompilerType(); + } } \ No newline at end of file diff --git a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h index e15582c2ce67b..365df7a90f32d 100644 --- a/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h +++ b/lldb/source/Plugins/TypeSystem/Fortran/TypeSystemFortran.h @@ -14,7 +14,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 { @@ -79,7 +83,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, @@ -95,14 +99,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; @@ -136,9 +138,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; @@ -155,9 +155,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; } @@ -173,7 +171,7 @@ class TypeSystemFortran : public TypeSystem { // Type Completion bool GetCompleteType(lldb::opaque_compiler_type_t type) override { - return false; + return true; } // AST related queries @@ -199,18 +197,15 @@ 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 - GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type) override { - return 0; + uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type, + CompilerType *pointee_or_element_compiler_type) override { + return 0; } lldb::LanguageType @@ -218,24 +213,26 @@ 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; // Creating related types + CompilerType GetOrCreateFortranType(int kind, uint64_t bitsize, + ConstString name); + + CompilerType CreateType(uint32_t dwarf_encoding, uint64_t bitsize, + ConstString name); + CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override { 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 { - return CompilerType(); + return CompilerType(weak_from_this(), type); } // Returns -1 if this isn't a function of if the function doesn't have a @@ -281,9 +278,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; @@ -434,14 +429,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; @@ -487,7 +478,14 @@ 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; std::unique_ptr<plugin::dwarf::DWARFASTParser> m_dwarf_ast_parser_up; + /// Store byte order of the system so variables can be printed correctly + lldb::ByteOrder m_byte_order; TypeSystemFortran(const TypeSystemFortran &) = delete; const TypeSystemFortran &operator=(const TypeSystemFortran &) = delete; >From bb3ad8e02b0054306c10dd36fa8170d73e5f9711 Mon Sep 17 00:00:00 2001 From: Iasonaskrpr <[email protected]> Date: Sat, 22 Aug 2026 18:50:34 +0300 Subject: [PATCH 21/21] [lldb][Fortran] Added TypeSystemFortran tests --- lldb/unittests/Symbol/CMakeLists.txt | 1 + .../Symbol/TestTypeSystemFortran.cpp | 206 ++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 lldb/unittests/Symbol/TestTypeSystemFortran.cpp diff --git a/lldb/unittests/Symbol/CMakeLists.txt b/lldb/unittests/Symbol/CMakeLists.txt index f9794369a89f4..47dbf66dfa409 100644 --- a/lldb/unittests/Symbol/CMakeLists.txt +++ b/lldb/unittests/Symbol/CMakeLists.txt @@ -9,6 +9,7 @@ add_lldb_unittest(SymbolTests SymStoreTest.cpp TestTypeSystem.cpp TestTypeSystemClang.cpp + TestTypeSystemFortran.cpp TestClangASTImporter.cpp TestDWARFCallFrameInfo.cpp TestType.cpp diff --git a/lldb/unittests/Symbol/TestTypeSystemFortran.cpp b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp new file mode 100644 index 0000000000000..916424bdfe941 --- /dev/null +++ b/lldb/unittests/Symbol/TestTypeSystemFortran.cpp @@ -0,0 +1,206 @@ +//===-- 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->CreateType(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); + + CompilerType int8_type = + m_ast->CreateType(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); + + CompilerType int16_type = + m_ast->CreateType(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); + + CompilerType int32_type = + m_ast->CreateType(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); + + CompilerType int64_type = + m_ast->CreateType(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); + + CompilerType int128_type = + m_ast->CreateType(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); + + CompilerType real16_type = + m_ast->CreateType(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); + + CompilerType real32_type = + m_ast->CreateType(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); + + CompilerType real64_type = + m_ast->CreateType(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); + + CompilerType real128_type = + m_ast->CreateType(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); + + CompilerType complex64_type = + m_ast->CreateType(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); + + CompilerType complex128_type = + m_ast->CreateType(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); + + CompilerType complex256_type = + m_ast->CreateType(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); +} + +TEST_F(TestTypeSystemFortran, TestTypeClassifications) { + CompilerType logical_type = + m_ast->CreateType(llvm::dwarf::DW_ATE_boolean, 32, ConstString()); + CompilerType int_type = + m_ast->CreateType(llvm::dwarf::DW_ATE_signed, 32, ConstString()); + CompilerType real_type = + m_ast->CreateType(llvm::dwarf::DW_ATE_float, 32, ConstString()); + CompilerType complex_type = + m_ast->CreateType(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->CreateType(llvm::dwarf::DW_ATE_boolean, 32, ConstString()); + CompilerType int32 = + m_ast->CreateType(llvm::dwarf::DW_ATE_signed, 32, ConstString()); + CompilerType real32 = + m_ast->CreateType(llvm::dwarf::DW_ATE_float, 32, ConstString()); + CompilerType complex64 = + m_ast->CreateType(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->CreateType(llvm::dwarf::DW_ATE_signed, 32, ConstString("INTEGER")); + + CompilerType int2 = + m_ast->CreateType(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)"); +} \ No newline at end of file _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
