xref: /freebsd/contrib/llvm-project/lld/ELF/ScriptLexer.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- ScriptLexer.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 LLD_ELF_SCRIPT_LEXER_H
10 #define LLD_ELF_SCRIPT_LEXER_H
11 
12 #include "lld/Common/LLVM.h"
13 #include "llvm/ADT/DenseSet.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Support/MemoryBufferRef.h"
17 #include <vector>
18 
19 namespace lld::elf {
20 struct Ctx;
21 
22 class ScriptLexer {
23 protected:
24   struct Buffer {
25     // The remaining content to parse and the filename.
26     StringRef s, filename;
27     const char *begin = nullptr;
28     size_t lineNumber = 1;
29     // True if the script is opened as an absolute path under the --sysroot
30     // directory.
31     bool isUnderSysroot = false;
32 
33     Buffer() = default;
34     Buffer(Ctx &ctx, MemoryBufferRef mb);
35   };
36   Ctx &ctx;
37   // The current buffer and parent buffers due to INCLUDE.
38   Buffer curBuf;
39   SmallVector<Buffer, 0> buffers;
40 
41   // Used to detect INCLUDE() cycles.
42   llvm::DenseSet<StringRef> activeFilenames;
43 
44   enum class State {
45     Script,
46     Expr,
47   };
48 
49   struct Token {
50     StringRef str;
51     explicit operator bool() const { return !str.empty(); }
StringRefToken52     operator StringRef() const { return str; }
53   };
54 
55   // The token before the last next().
56   StringRef prevTok;
57   // Rules for what is a token are different when we are in an expression.
58   // curTok holds the cached return value of peek() and is invalid when the
59   // expression state changes.
60   StringRef curTok;
61   size_t prevTokLine = 1;
62   // The lex state when curTok is cached.
63   State curTokState = State::Script;
64   State lexState = State::Script;
65   bool eof = false;
66 
67 public:
68   explicit ScriptLexer(Ctx &ctx, MemoryBufferRef mb);
69 
70   void setError(const Twine &msg);
71   void lex();
72   StringRef skipSpace(StringRef s);
73   bool atEOF();
74   StringRef next();
75   StringRef peek();
76   void skip();
77   bool consume(StringRef tok);
78   void expect(StringRef expect);
79   Token till(StringRef tok);
80   std::string getCurrentLocation();
81   MemoryBufferRef getCurrentMB();
82 
83   std::vector<MemoryBufferRef> mbs;
84 
85 private:
86   StringRef getLine();
87   size_t getColumnNumber();
88 };
89 
90 } // namespace lld::elf
91 
92 #endif
93