xref: /llvm-project/flang/lib/Semantics/mod-file.h (revision 9629f2c4ca6a514abe27f537c1cb4af35ef0aa10)
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:
36   explicit ModFileWriter(SemanticsContext &context) : context_{context} {}
37   bool WriteAll();
38   void WriteClosure(llvm::raw_ostream &, const Symbol &,
39       UnorderedSymbolSet &nonIntrinsicModulesWritten);
40   ModFileWriter &set_hermeticModuleFileOutput(bool yes = true) {
41     hermeticModuleFileOutput_ = yes;
42     return *this;
43   }
44 
45 private:
46   SemanticsContext &context_;
47   // Buffers to use with raw_string_ostream
48   std::string needsBuf_;
49   std::string usesBuf_;
50   std::string useExtraAttrsBuf_;
51   std::string declsBuf_;
52   std::string containsBuf_;
53   // Tracks nested DEC structures and fields of that type
54   UnorderedSymbolSet emittedDECStructures_, emittedDECFields_;
55   UnorderedSymbolSet usedNonIntrinsicModules_;
56 
57   llvm::raw_string_ostream needs_{needsBuf_};
58   llvm::raw_string_ostream uses_{usesBuf_};
59   llvm::raw_string_ostream useExtraAttrs_{
60       useExtraAttrsBuf_}; // attrs added to used entity
61   llvm::raw_string_ostream decls_{declsBuf_};
62   llvm::raw_string_ostream contains_{containsBuf_};
63   bool isSubmodule_{false};
64   bool hermeticModuleFileOutput_{false};
65 
66   void WriteAll(const Scope &);
67   void WriteOne(const Scope &);
68   void Write(const Symbol &);
69   std::string GetAsString(const Symbol &);
70   void PrepareRenamings(const Scope &);
71   void PutSymbols(const Scope &, UnorderedSymbolSet *hermetic);
72   // Returns true if a derived type with bindings and "contains" was emitted
73   bool PutComponents(const Symbol &);
74   void PutSymbol(llvm::raw_ostream &, const Symbol &);
75   void PutEntity(llvm::raw_ostream &, const Symbol &);
76   void PutEntity(
77       llvm::raw_ostream &, const Symbol &, std::function<void()>, Attrs);
78   void PutObjectEntity(llvm::raw_ostream &, const Symbol &);
79   void PutProcEntity(llvm::raw_ostream &, const Symbol &);
80   void PutDerivedType(const Symbol &, const Scope * = nullptr);
81   void PutDECStructure(const Symbol &, const Scope * = nullptr);
82   void PutTypeParam(llvm::raw_ostream &, const Symbol &);
83   void PutSubprogram(const Symbol &);
84   void PutGeneric(const Symbol &);
85   void PutUse(const Symbol &);
86   void PutUseExtraAttr(Attr, const Symbol &, const Symbol &);
87   llvm::raw_ostream &PutAttrs(llvm::raw_ostream &, Attrs,
88       const std::string * = nullptr, bool = false, std::string before = ","s,
89       std::string after = ""s) const;
90   void PutDirective(llvm::raw_ostream &, const Symbol &);
91 };
92 
93 class ModFileReader {
94 public:
95   ModFileReader(SemanticsContext &context) : context_{context} {}
96   // Find and read the module file for a module or submodule.
97   // If ancestor is specified, look for a submodule of that module.
98   // Return the Scope for that module/submodule or nullptr on error.
99   Scope *Read(SourceName, std::optional<bool> isIntrinsic, Scope *ancestor,
100       bool silent);
101 
102 private:
103   SemanticsContext &context_;
104 
105   parser::Message &Say(const char *verb, SourceName, const std::string &,
106       parser::MessageFixedText &&, const std::string &);
107 };
108 
109 } // namespace Fortran::semantics
110 #endif
111