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