1329394Sdim//===- MCAsmMacro.h - Assembly Macros ---------------------------*- C++ -*-===//
2329394Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6329394Sdim//
7329394Sdim//===----------------------------------------------------------------------===//
8329394Sdim
9329394Sdim#ifndef LLVM_MC_MCASMMACRO_H
10329394Sdim#define LLVM_MC_MCASMMACRO_H
11329394Sdim
12341825Sdim#include "llvm/ADT/APInt.h"
13341825Sdim#include "llvm/ADT/StringRef.h"
14341825Sdim#include "llvm/Support/Debug.h"
15341825Sdim#include "llvm/Support/SMLoc.h"
16341825Sdim#include <vector>
17329394Sdim
18329394Sdimnamespace llvm {
19329394Sdim
20341825Sdim/// Target independent representation for an assembler token.
21341825Sdimclass AsmToken {
22341825Sdimpublic:
23341825Sdim  enum TokenKind {
24341825Sdim    // Markers
25341825Sdim    Eof, Error,
26341825Sdim
27341825Sdim    // String values.
28341825Sdim    Identifier,
29341825Sdim    String,
30341825Sdim
31341825Sdim    // Integer values.
32341825Sdim    Integer,
33341825Sdim    BigNum, // larger than 64 bits
34341825Sdim
35341825Sdim    // Real values.
36341825Sdim    Real,
37341825Sdim
38341825Sdim    // Comments
39341825Sdim    Comment,
40341825Sdim    HashDirective,
41341825Sdim    // No-value.
42341825Sdim    EndOfStatement,
43341825Sdim    Colon,
44341825Sdim    Space,
45341825Sdim    Plus, Minus, Tilde,
46341825Sdim    Slash,     // '/'
47341825Sdim    BackSlash, // '\'
48341825Sdim    LParen, RParen, LBrac, RBrac, LCurly, RCurly,
49341825Sdim    Star, Dot, Comma, Dollar, Equal, EqualEqual,
50341825Sdim
51341825Sdim    Pipe, PipePipe, Caret,
52341825Sdim    Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
53341825Sdim    Less, LessEqual, LessLess, LessGreater,
54344779Sdim    Greater, GreaterEqual, GreaterGreater, At, MinusGreater,
55341825Sdim
56341825Sdim    // MIPS unary expression operators such as %neg.
57341825Sdim    PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
58341825Sdim    PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
59341825Sdim    PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
60341825Sdim    PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
61341825Sdim    PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
62341825Sdim    PercentTprel_Lo
63341825Sdim  };
64341825Sdim
65341825Sdimprivate:
66341825Sdim  TokenKind Kind;
67341825Sdim
68341825Sdim  /// A reference to the entire token contents; this is always a pointer into
69341825Sdim  /// a memory buffer owned by the source manager.
70341825Sdim  StringRef Str;
71341825Sdim
72341825Sdim  APInt IntVal;
73341825Sdim
74341825Sdimpublic:
75341825Sdim  AsmToken() = default;
76341825Sdim  AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
77341825Sdim      : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
78341825Sdim  AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
79341825Sdim      : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
80341825Sdim
81341825Sdim  TokenKind getKind() const { return Kind; }
82341825Sdim  bool is(TokenKind K) const { return Kind == K; }
83341825Sdim  bool isNot(TokenKind K) const { return Kind != K; }
84341825Sdim
85341825Sdim  SMLoc getLoc() const;
86341825Sdim  SMLoc getEndLoc() const;
87341825Sdim  SMRange getLocRange() const;
88341825Sdim
89341825Sdim  /// Get the contents of a string token (without quotes).
90341825Sdim  StringRef getStringContents() const {
91341825Sdim    assert(Kind == String && "This token isn't a string!");
92341825Sdim    return Str.slice(1, Str.size() - 1);
93341825Sdim  }
94341825Sdim
95341825Sdim  /// Get the identifier string for the current token, which should be an
96341825Sdim  /// identifier or a string. This gets the portion of the string which should
97341825Sdim  /// be used as the identifier, e.g., it does not include the quotes on
98341825Sdim  /// strings.
99341825Sdim  StringRef getIdentifier() const {
100341825Sdim    if (Kind == Identifier)
101341825Sdim      return getString();
102341825Sdim    return getStringContents();
103341825Sdim  }
104341825Sdim
105341825Sdim  /// Get the string for the current token, this includes all characters (for
106341825Sdim  /// example, the quotes on strings) in the token.
107341825Sdim  ///
108341825Sdim  /// The returned StringRef points into the source manager's memory buffer, and
109341825Sdim  /// is safe to store across calls to Lex().
110341825Sdim  StringRef getString() const { return Str; }
111341825Sdim
112341825Sdim  // FIXME: Don't compute this in advance, it makes every token larger, and is
113341825Sdim  // also not generally what we want (it is nicer for recovery etc. to lex 123br
114341825Sdim  // as a single token, then diagnose as an invalid number).
115341825Sdim  int64_t getIntVal() const {
116341825Sdim    assert(Kind == Integer && "This token isn't an integer!");
117341825Sdim    return IntVal.getZExtValue();
118341825Sdim  }
119341825Sdim
120341825Sdim  APInt getAPIntVal() const {
121341825Sdim    assert((Kind == Integer || Kind == BigNum) &&
122341825Sdim           "This token isn't an integer!");
123341825Sdim    return IntVal;
124341825Sdim  }
125341825Sdim
126341825Sdim  void dump(raw_ostream &OS) const;
127341825Sdim};
128341825Sdim
129329394Sdimstruct MCAsmMacroParameter {
130329394Sdim  StringRef Name;
131329394Sdim  std::vector<AsmToken> Value;
132329394Sdim  bool Required = false;
133329394Sdim  bool Vararg = false;
134329394Sdim
135360784Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
136341825Sdim  void dump() const { dump(dbgs()); }
137360784Sdim  LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
138360784Sdim#endif
139329394Sdim};
140329394Sdim
141329394Sdimtypedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
142329394Sdimstruct MCAsmMacro {
143329394Sdim  StringRef Name;
144329394Sdim  StringRef Body;
145329394Sdim  MCAsmMacroParameters Parameters;
146329394Sdim
147329394Sdimpublic:
148329394Sdim  MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
149329394Sdim      : Name(N), Body(B), Parameters(std::move(P)) {}
150341825Sdim
151360784Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
152341825Sdim  void dump() const { dump(dbgs()); }
153360784Sdim  LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
154360784Sdim#endif
155329394Sdim};
156329983Sdim} // namespace llvm
157329394Sdim
158329394Sdim#endif
159