private components in module files

Andrew Benson abenson@carnegiescience.edu
Mon Oct 28 23:50:00 GMT 2019


On Thursday, October 24, 2019 11:26:27 AM PDT Janne Blomqvist wrote:
> On Wed, Oct 23, 2019 at 7:07 PM Andrew Benson
> 
> <abenson@carnegiescience.edu> wrote:
> > Hi all,
> > 
> > I've been slowly trying to educate myself about the structure of gfortran
> > module files, in the hope that I can eventually work on making some
> > improvements (I'm particularly interested in anything that would reduce
> > the
> > file size or speed up parsing).
> 
> AFAICS the big improvements, thought absolutely not low-hanging fruit
> (which is why it hasn't been done), is
> 
> 1) Not including transitive dependencies in .mod files. Implying that
> .mod files would need to have the equivalent of USE statements, so
> that the module parser knows it might need to parse other modules to
> resolve all symbols.
> 
> 2) Caching parsed module files. This is likely necessary to get (1) to
> work decently.
> 
> AFAIK the NAG Fortran compiler does something like this.
> 
> See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40958#c13
> 
> Also see previous discussion in
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25708

I spent an hour or two today working to understand how caching of parsed 
module files might be implemented. Following the ideas in:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25708#c5

I was able to implement a linked list of namespaces for modules, and then add 
symbols to a symtree within that namespace as the module is parsed and, if the 
same module is parsed again, return that cached symbol. (This is a very 
crude implementation so far - I'm mostly just trying things to improve my 
understanding - I expect I'll end up re-writing this multiple times as I learn 
from my mistakes....) 

This seems to work in some simple cases, but I have a few questions:

I'm considering a simple case such as this:

module a

  type aa
     integer :: ab
  end type aa
  
end module a

module b

contains

  subroutine b1()
    use a
    type(aa) :: ba
  end subroutine b1

  subroutine b2()
    use a
    type(aa) :: ba
  end subroutine b2

end module b

program test
  use b
  call b1()
end program test


I had initially attempted to return a pointer to the symbol for type(aa) in 
the module namespace on the second use of the module. If I do this though then 
the second "type(aa) :: ba" triggers an error:

tmp.F90:20:12:

   20 |     type(aa) :: ba
      |            1
Error: Cannot change attributes of USE-associated symbol aa at (1)

This occurs in gfc_match_decl_type_spec() in decl.c at the line:

  if (dt_sym->attr.flavor != FL_DERIVED && dt_sym->attr.flavor != FL_STRUCT
      && !gfc_add_flavor (&dt_sym->attr, FL_DERIVED, sym->name, NULL))
    return MATCH_ERROR;

Therefore I've instead opted to return a copy of the symbol for type(aa) from 
the module namespace, which avoids this problem. It's not clear to me if this 
is the best solution though, or if there is a way to return just a pointer to 
the symbol and avoid this "change attributes" error?


A second question: To add each symbol to the module namespace I need to give 
it a unique name. I've tried to construct such a name by concatenating the 
"proc_name" of the symbol's namespace with the "true_name" associated with the 
symbol. This works in most cases, but fails for symbols such as the "src" and 
"dst" symbols that get created - there can be many of these and they all share 
the same "proc_name" (the module itself). So, I'm not sure on how best to 
generate a unique name. (Each of these "src" and "dst" symbols belong to a 
unique namespace within the load_needed() function - I could similarly put 
them in unique namespaces within the module namespace. But then I'd need some 
way to assign a unique name to each of those namespaces, so this wouldn't 
resolve the problem.)

I can post the patch for my modifications if it's useful (although I should 
probably clean it up first to make it more comprehensible).

Thanks,
Andrew

-- 

* Andrew Benson: http://users.obs.carnegiescience.edu/abenson/contact.html

* Galacticus: https://github.com/galacticusorg/galacticus



More information about the Fortran mailing list