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 <string>
21 #include <utility>
22 #include <vector>
23 
24 namespace llvm {
25 class raw_ostream;
26 }
27 
28 namespace Fortran::parser {
29 
30 std::string DirectoryName(std::string path);
31 std::string LocateSourceFile(
32     std::string name, const std::vector<std::string> &searchPath);
33 
34 class SourceFile;
35 
36 struct SourcePosition {
37   const SourceFile &file;
38   int line, column;
39 };
40 
41 class SourceFile {
42 public:
SourceFile(Encoding e)43   explicit SourceFile(Encoding e) : encoding_{e} {}
44   ~SourceFile();
path()45   std::string path() const { return path_; }
content()46   llvm::ArrayRef<char> content() const {
47     return buf_->getBuffer().slice(bom_end_, buf_end_ - bom_end_);
48   }
bytes()49   std::size_t bytes() const { return content().size(); }
lines()50   std::size_t lines() const { return lineStart_.size(); }
encoding()51   Encoding encoding() const { return encoding_; }
52 
53   bool Open(std::string path, llvm::raw_ostream &error);
54   bool ReadStandardInput(llvm::raw_ostream &error);
55   void Close();
56   SourcePosition FindOffsetLineAndColumn(std::size_t) const;
GetLineStartOffset(int lineNumber)57   std::size_t GetLineStartOffset(int lineNumber) const {
58     return lineStart_.at(lineNumber - 1);
59   }
60 
61 private:
62   void ReadFile();
63   void IdentifyPayload();
64   void RecordLineStarts();
65 
66   std::string path_;
67   std::unique_ptr<llvm::WritableMemoryBuffer> buf_;
68   std::vector<std::size_t> lineStart_;
69   std::size_t bom_end_{0};
70   std::size_t buf_end_;
71   Encoding encoding_;
72 };
73 } // namespace Fortran::parser
74 #endif // FORTRAN_PARSER_SOURCE_H_
75