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