1 //===-- include/flang/Parser/source.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_PARSER_SOURCE_H_
10 #define FORTRAN_PARSER_SOURCE_H_
11 
12 // Source file content is lightly normalized when the file is read.
13 //  - Line ending markers are converted to single newline characters
14 //  - A newline character is added to the last line of the file if one is needed
15 //  - A Unicode byte order mark is recognized if present.
16 
17 #include "characters.h"
18 #include "llvm/Support/MemoryBuffer.h"
19 #include <cstddef>
20 #include <list>
21 #include <optional>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 namespace llvm {
27 class raw_ostream;
28 }
29 
30 namespace Fortran::parser {
31 
32 std::string DirectoryName(std::string path);
33 std::optional<std::string> LocateSourceFile(
34     std::string name, const std::list<std::string> &searchPath);
35 
36 class SourceFile;
37 
38 struct SourcePosition {
39   const SourceFile &file;
40   int line, column;
41 };
42 
43 class SourceFile {
44 public:
SourceFile(Encoding e)45   explicit SourceFile(Encoding e) : encoding_{e} {}
46   ~SourceFile();
path()47   std::string path() const { return path_; }
content()48   llvm::ArrayRef<char> content() const {
49     return buf_->getBuffer().slice(bom_end_, buf_end_ - bom_end_);
50   }
bytes()51   std::size_t bytes() const { return content().size(); }
lines()52   std::size_t lines() const { return lineStart_.size(); }
encoding()53   Encoding encoding() const { return encoding_; }
54 
55   bool Open(std::string path, llvm::raw_ostream &error);
56   bool ReadStandardInput(llvm::raw_ostream &error);
57   void Close();
58   SourcePosition FindOffsetLineAndColumn(std::size_t) const;
GetLineStartOffset(int lineNumber)59   std::size_t GetLineStartOffset(int lineNumber) const {
60     return lineStart_.at(lineNumber - 1);
61   }
62 
63 private:
64   void ReadFile();
65   void IdentifyPayload();
66   void RecordLineStarts();
67 
68   std::string path_;
69   std::unique_ptr<llvm::WritableMemoryBuffer> buf_;
70   std::vector<std::size_t> lineStart_;
71   std::size_t bom_end_{0};
72   std::size_t buf_end_;
73   Encoding encoding_;
74 };
75 } // namespace Fortran::parser
76 #endif // FORTRAN_PARSER_SOURCE_H_
77