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