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 ; |
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 { |
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 PutUserReduction(llvm::raw_ostream &, const Symbol &); |
84 | void PutSubprogram(const Symbol &); |
85 | void PutGeneric(const Symbol &); |
86 | void PutUse(const Symbol &); |
87 | void (Attr, const Symbol &, const Symbol &); |
88 | llvm::raw_ostream &PutAttrs(llvm::raw_ostream &, Attrs, |
89 | const std::string * = nullptr, bool = false, std::string before = ","s , |
90 | std::string after = ""s ) const; |
91 | void PutDirective(llvm::raw_ostream &, const Symbol &); |
92 | }; |
93 | |
94 | class ModFileReader { |
95 | public: |
96 | ModFileReader(SemanticsContext &context) : context_{context} {} |
97 | // Find and read the module file for a module or submodule. |
98 | // If ancestor is specified, look for a submodule of that module. |
99 | // Return the Scope for that module/submodule or nullptr on error. |
100 | Scope *Read(SourceName, std::optional<bool> isIntrinsic, Scope *ancestor, |
101 | bool silent); |
102 | |
103 | private: |
104 | SemanticsContext &context_; |
105 | |
106 | parser::Message &Say(const char *verb, SourceName, const std::string &, |
107 | parser::MessageFixedText &&, const std::string &); |
108 | }; |
109 | |
110 | } // namespace Fortran::semantics |
111 | #endif |
112 | |