1 //===- MCAsmMacro.h - Assembly Macros ---------------------------*- 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 LLVM_MC_MCASMMACRO_H
10 #define LLVM_MC_MCASMMACRO_H
11 
12 #include "llvm/ADT/APInt.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/SMLoc.h"
16 #include <vector>
17 
18 namespace llvm {
19 
20 /// Target independent representation for an assembler token.
21 class AsmToken {
22 public:
23   enum TokenKind {
24     // Markers
25     Eof, Error,
26 
27     // String values.
28     Identifier,
29     String,
30 
31     // Integer values.
32     Integer,
33     BigNum, // larger than 64 bits
34 
35     // Real values.
36     Real,
37 
38     // Comments
39     Comment,
40     HashDirective,
41     // No-value.
42     EndOfStatement,
43     Colon,
44     Space,
45     Plus, Minus, Tilde,
46     Slash,     // '/'
47     BackSlash, // '\'
48     LParen, RParen, LBrac, RBrac, LCurly, RCurly,
49     Star, Dot, Comma, Dollar, Equal, EqualEqual,
50 
51     Pipe, PipePipe, Caret,
52     Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
53     Less, LessEqual, LessLess, LessGreater,
54     Greater, GreaterEqual, GreaterGreater, At, MinusGreater,
55 
56     // MIPS unary expression operators such as %neg.
57     PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
58     PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
59     PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
60     PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
61     PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
62     PercentTprel_Lo
63   };
64 
65 private:
66   TokenKind Kind;
67 
68   /// A reference to the entire token contents; this is always a pointer into
69   /// a memory buffer owned by the source manager.
70   StringRef Str;
71 
72   APInt IntVal;
73 
74 public:
75   AsmToken() = default;
AsmToken(TokenKind Kind,StringRef Str,APInt IntVal)76   AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
77       : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
78   AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
Kind(Kind)79       : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
80 
getKind()81   TokenKind getKind() const { return Kind; }
is(TokenKind K)82   bool is(TokenKind K) const { return Kind == K; }
isNot(TokenKind K)83   bool isNot(TokenKind K) const { return Kind != K; }
84 
85   SMLoc getLoc() const;
86   SMLoc getEndLoc() const;
87   SMRange getLocRange() const;
88 
89   /// Get the contents of a string token (without quotes).
getStringContents()90   StringRef getStringContents() const {
91     assert(Kind == String && "This token isn't a string!");
92     return Str.slice(1, Str.size() - 1);
93   }
94 
95   /// Get the identifier string for the current token, which should be an
96   /// identifier or a string. This gets the portion of the string which should
97   /// be used as the identifier, e.g., it does not include the quotes on
98   /// strings.
getIdentifier()99   StringRef getIdentifier() const {
100     if (Kind == Identifier)
101       return getString();
102     return getStringContents();
103   }
104 
105   /// Get the string for the current token, this includes all characters (for
106   /// example, the quotes on strings) in the token.
107   ///
108   /// The returned StringRef points into the source manager's memory buffer, and
109   /// is safe to store across calls to Lex().
getString()110   StringRef getString() const { return Str; }
111 
112   // FIXME: Don't compute this in advance, it makes every token larger, and is
113   // also not generally what we want (it is nicer for recovery etc. to lex 123br
114   // as a single token, then diagnose as an invalid number).
getIntVal()115   int64_t getIntVal() const {
116     assert(Kind == Integer && "This token isn't an integer!");
117     return IntVal.getZExtValue();
118   }
119 
getAPIntVal()120   APInt getAPIntVal() const {
121     assert((Kind == Integer || Kind == BigNum) &&
122            "This token isn't an integer!");
123     return IntVal;
124   }
125 
126   void dump(raw_ostream &OS) const;
127 };
128 
129 struct MCAsmMacroParameter {
130   StringRef Name;
131   std::vector<AsmToken> Value;
132   bool Required = false;
133   bool Vararg = false;
134 
135 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpMCAsmMacroParameter136   void dump() const { dump(dbgs()); }
137   LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
138 #endif
139 };
140 
141 typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
142 struct MCAsmMacro {
143   StringRef Name;
144   StringRef Body;
145   MCAsmMacroParameters Parameters;
146   std::vector<std::string> Locals;
147   bool IsFunction = false;
148 
149 public:
MCAsmMacroMCAsmMacro150   MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
151       : Name(N), Body(B), Parameters(std::move(P)) {}
MCAsmMacroMCAsmMacro152   MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P,
153              std::vector<std::string> L, bool F)
154       : Name(N), Body(B), Parameters(std::move(P)), Locals(std::move(L)),
155         IsFunction(F) {}
156 
157 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpMCAsmMacro158   void dump() const { dump(dbgs()); }
159   LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
160 #endif
161 };
162 } // namespace llvm
163 
164 #endif
165