1 //===-- lib/Semantics/mod-file.h --------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef FORTRAN_SEMANTICS_MOD_FILE_H_
10 #define FORTRAN_SEMANTICS_MOD_FILE_H_
11 
12 #include "flang/Semantics/attr.h"
13 #include "flang/Semantics/symbol.h"
14 #include "llvm/Support/raw_ostream.h"
15 #include <string>
16 
17 namespace Fortran::parser {
18 class CharBlock;
19 class Message;
20 class MessageFixedText;
21 } // namespace Fortran::parser
22 
23 namespace llvm {
24 class raw_ostream;
25 }
26 
27 namespace Fortran::semantics {
28 
29 using SourceName = parser::CharBlock;
30 class Symbol;
31 class Scope;
32 class SemanticsContext;
33 
34 class ModFileWriter {
35 public:
ModFileWriter(SemanticsContext & context)36   explicit ModFileWriter(SemanticsContext &context) : context_{context} {}
37   bool WriteAll();
38 
39 private:
40   SemanticsContext &context_;
41   // Buffer to use with raw_string_ostream
42   std::string usesBuf_;
43   std::string useExtraAttrsBuf_;
44   std::string declsBuf_;
45   std::string containsBuf_;
46   // Tracks nested DEC structures and fields of that type
47   UnorderedSymbolSet emittedDECStructures_, emittedDECFields_;
48 
49   llvm::raw_string_ostream uses_{usesBuf_};
50   llvm::raw_string_ostream useExtraAttrs_{
51       useExtraAttrsBuf_}; // attrs added to used entity
52   llvm::raw_string_ostream decls_{declsBuf_};
53   llvm::raw_string_ostream contains_{containsBuf_};
54 
55   void WriteAll(const Scope &);
56   void WriteOne(const Scope &);
57   void Write(const Symbol &);
58   std::string GetAsString(const Symbol &);
59   void PutSymbols(const Scope &);
60   // Returns true if a derived type with bindings and "contains" was emitted
61   bool PutComponents(const Symbol &);
62   void PutSymbol(llvm::raw_ostream &, const Symbol &);
63   void PutEntity(llvm::raw_ostream &, const Symbol &);
64   void PutEntity(
65       llvm::raw_ostream &, const Symbol &, std::function<void()>, Attrs);
66   void PutObjectEntity(llvm::raw_ostream &, const Symbol &);
67   void PutProcEntity(llvm::raw_ostream &, const Symbol &);
68   void PutDerivedType(const Symbol &, const Scope * = nullptr);
69   void PutDECStructure(const Symbol &, const Scope * = nullptr);
70   void PutTypeParam(llvm::raw_ostream &, const Symbol &);
71   void PutSubprogram(const Symbol &);
72   void PutGeneric(const Symbol &);
73   void PutUse(const Symbol &);
74   void PutUseExtraAttr(Attr, const Symbol &, const Symbol &);
75 };
76 
77 class ModFileReader {
78 public:
79   // directories specifies where to search for module files
ModFileReader(SemanticsContext & context)80   ModFileReader(SemanticsContext &context) : context_{context} {}
81   // Find and read the module file for a module or submodule.
82   // If ancestor is specified, look for a submodule of that module.
83   // Return the Scope for that module/submodule or nullptr on error.
84   Scope *Read(const SourceName &, std::optional<bool> isIntrinsic,
85       Scope *ancestor, bool silent = false);
86 
87 private:
88   SemanticsContext &context_;
89 
90   parser::Message &Say(const SourceName &, const std::string &,
91       parser::MessageFixedText &&, const std::string &);
92 };
93 
94 } // namespace Fortran::semantics
95 #endif
96