To: J3 J3/26-124r3 From: Lorri Menard & JoR Subject: US11 - Specifications for intrinsics for source location Date: 2026-February-25 Reference: 23-193r1 I Introduction Paper 23-193r1 notes that users have requested a way to get the source name and source line in their programs, as well as the current procedure name. Uses for this would be for debugging, for logging purposes, etc. This request is being addressed in the preprocessor work via __FILE__ and __LINE__, however there are some uses for intrinsic routines for source name and line, as well as for current procedure name. II Use cases It is useful to be able to pass the name of the current module/procedure to diagnostic layers such as error handlers, progress reporters, etc. While a developer could readily produce such a string, that string will often become incorrect as code undergoes other refactoring. Further, experience shows that developers often use cut-and-paste when developing new procedures, ending up with wildly wrong names being passed to the diagnostic layer. A preprocessor directive in a TEMPLATE declaration will be resolved at compile-time of the TEMPLATE. However, instantiation of that template will happen in other files at other lines. For debugging or logging purposes the value of __FILE__ and/or __LINE__ might not be helpful. The current preprocessing standardization effort (25-142r2) does not anticipate adding preprocessor support for procedure name. This paper proposes adding three new intrinsic functions to the ISO_FORTRAN_ENV module to provide relevant information that could be useful for diagnosing problems at a later date. III Specifications SOURCE_FILE([CONTEXT]) Description. Processor-dependent string that describes the name of the source input to the translation phase of program execution. Class. Transformational function Argument. CONTEXT(optional) Shall be of type logical. It is an INTENT(IN) argument. Result Characteristics. The result is a system character scalar with processor-dependent length. Result Value. If CONTEXT is not present or has the value .FALSE. the processor shall return a processor-dependent value representing the name of the source input. If CONTEXT is present and has the value .TRUE. the result shall be a processor-dependent value representing a potentially more detailed name of the source input If no information is available the value is the empty string. Example. SOURCE_FILE() might have the value 'program.F90' and SOURCE_FILE(.true.) might have the value '/usr/src/program.F90'. SOURCE_LINE() Description. Returns the current source line Class. Transformational function Argument. None Result characteristics. Standard integer. Result value. A positive value representing the index of the invoking line within the Fortran program, computed in a processor-dependent manner. If the processor includes a preprocessor, it is recommended that SOURCE_LINE() return the same value reported by the preprocessor. PROCEDURE_NAME([CONTEXT]) Description. String that describes the name of the current procedure being executed. Class. Transformational function Argument. CONTEXT(optional) Shall be of type logical. It is an INTENT(IN) argument. Result characteristics. System character scalar with processor-dependent length Result value. If CONTEXT is not present or has the value .FALSE. the following information will be returned. If the invocation appears in the specifications section of a program unit that is not a subprogram, the value will be the name of the program unit (i.e. the given in the , the given in the , or the given in the ). If the program unit is an unnamed main program, it will return the string "MAIN PROGRAM". If the program unit is an unnamed block data, it will return the string "BLOCK DATA". Otherwise, if the invocation appears within a subprogram, the value will be the name of the subprogram. If CONTEXT is present and has the value .TRUE. a single string will be returned that gives full context of the procedure name in one of the following formats: module-name[/submodule-name]:[subprogram-name][.internal || =binding-name] subprogram-name[.internal || =binding-name] program-name[.internal] block-data-name With the exception of a binding-name, all values returned are in upper case. The binding-name appears if and only if the subprogram has BIND(C) with a NAME= specifier, and has the value of the NAME= specifier. Examples for PROCEDURE_NAME(context): Example 1: program main print*, procedure_name() ! 'MAIN' print*, procedure_name(.TRUE.)! 'MAIN' contains subroutine s() print*, procedure_name() ! 'S' print*, procedure_name(.TRUE.) ! 'MAIN.S' end subroutine s end program main Example 2: module A character(*), parameter :: mod_name = procedure_name() ! 'A' character(*), parameter :: full_mod_name = procedure_name(.TRUE.) ! 'A:' contains subroutine s() print*, procedure_name() ! 'S' print*, procedure_name(.TRUE.) ! 'A:S' contains subroutine inner() print*, procedure_name() ! 'INNER' print*, procedure_name(.TRUE.)! 'A:S.INNER' end subroutine inner end subroutine s subroutine s2() bind(C,name='qQ') print*, procedure_name() ! 'S2' print*, procedure_name(.TRUE.) ! 'A:S2=qQ' end subroutine s2 end module A Example 3: submodule (A) B character(*), parameter :: submod_name = procedure_name() ! 'B' character(*), parameter :: full = procedure_name(.TRUE.) ! 'A/B:' contains subroutine s() print*, procedure_name() ! 'S' print*, procedure_name(.TRUE.) ! 'A/B:S' contains subroutine inner() print*, procedure_name() ! 'INNER' print*, procedure_name(.TRUE.) ! 'A/B:S.INNER' end subroutine inner end subroutine s end submodule