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