Coverage Report

Created: 2018-11-12 17:33

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCParser/MCAsmParser.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/MC/MCAsmParser.h - Abstract Asm Parser Interface ----*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
11
#define LLVM_MC_MCPARSER_MCASMPARSER_H
12
13
#include "llvm/ADT/None.h"
14
#include "llvm/ADT/STLExtras.h"
15
#include "llvm/ADT/SmallString.h"
16
#include "llvm/ADT/SmallVector.h"
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/ADT/Twine.h"
19
#include "llvm/MC/MCParser/MCAsmLexer.h"
20
#include "llvm/Support/SMLoc.h"
21
#include <cstdint>
22
#include <string>
23
#include <utility>
24
25
namespace llvm {
26
27
class MCAsmInfo;
28
class MCAsmParserExtension;
29
class MCContext;
30
class MCExpr;
31
class MCInstPrinter;
32
class MCInstrInfo;
33
class MCStreamer;
34
class MCTargetAsmParser;
35
class SourceMgr;
36
37
struct InlineAsmIdentifierInfo {
38
  enum IdKind {
39
    IK_Invalid,  // Initial state. Unexpected after a successful parsing.
40
    IK_Label,    // Function/Label reference.
41
    IK_EnumVal,  // Value of enumeration type.
42
    IK_Var       // Variable.
43
  };
44
  // Represents an Enum value
45
  struct EnumIdentifier {
46
    int64_t EnumVal;
47
  };
48
  // Represents a label/function reference
49
  struct LabelIdentifier {
50
    void *Decl;
51
  };
52
  // Represents a variable
53
  struct VariableIdentifier {
54
    void *Decl;
55
    bool IsGlobalLV;
56
    unsigned Length;
57
    unsigned Size;
58
    unsigned Type;
59
  };
60
  // An InlineAsm identifier can only be one of those
61
  union {
62
    EnumIdentifier Enum;
63
    LabelIdentifier Label;
64
    VariableIdentifier Var;
65
  };
66
1.03k
  bool isKind(IdKind kind) const { return Kind == kind; }
67
  // Initializers
68
17
  void setEnum(int64_t enumVal) {
69
17
    assert(isKind(IK_Invalid) && "should be initialized only once");
70
17
    Kind = IK_EnumVal;
71
17
    Enum.EnumVal = enumVal;
72
17
  }
73
13
  void setLabel(void *decl) {
74
13
    assert(isKind(IK_Invalid) && "should be initialized only once");
75
13
    Kind = IK_Label;
76
13
    Label.Decl = decl;
77
13
  }
78
165
  void setVar(void *decl, bool isGlobalLV, unsigned size, unsigned type) {
79
165
    assert(isKind(IK_Invalid) && "should be initialized only once");
80
165
    Kind = IK_Var;
81
165
    Var.Decl = decl;
82
165
    Var.IsGlobalLV = isGlobalLV;
83
165
    Var.Size = size;
84
165
    Var.Type = type;
85
165
    Var.Length = size / type;
86
165
  }
87
9.61k
  InlineAsmIdentifierInfo() : Kind(IK_Invalid) {}
88
89
private:
90
  // Discriminate using the current kind.
91
  IdKind Kind;
92
};
93
94
/// Generic Sema callback for assembly parser.
95
class MCAsmParserSemaCallback {
96
public:
97
  virtual ~MCAsmParserSemaCallback();
98
99
  virtual void LookupInlineAsmIdentifier(StringRef &LineBuf,
100
                                         InlineAsmIdentifierInfo &Info,
101
                                         bool IsUnevaluatedContext) = 0;
102
  virtual StringRef LookupInlineAsmLabel(StringRef Identifier, SourceMgr &SM,
103
                                         SMLoc Location, bool Create) = 0;
104
  virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
105
                                    unsigned &Offset) = 0;
106
};
107
108
/// Generic assembler parser interface, for use by target specific
109
/// assembly parsers.
110
class MCAsmParser {
111
public:
112
  using DirectiveHandler = bool (*)(MCAsmParserExtension*, StringRef, SMLoc);
113
  using ExtensionDirectiveHandler =
114
      std::pair<MCAsmParserExtension*, DirectiveHandler>;
115
116
  struct MCPendingError {
117
    SMLoc Loc;
118
    SmallString<64> Msg;
119
    SMRange Range;
120
  };
121
122
private:
123
  MCTargetAsmParser *TargetParser = nullptr;
124
125
protected: // Can only create subclasses.
126
  MCAsmParser();
127
128
  SmallVector<MCPendingError, 0> PendingErrors;
129
130
  /// Flag tracking whether any errors have been encountered.
131
  bool HadError = false;
132
133
  /// Enable print [latency:throughput] in output file.
134
  bool EnablePrintSchedInfo = false;
135
136
  bool ShowParsedOperands = false;
137
138
public:
139
  MCAsmParser(const MCAsmParser &) = delete;
140
  MCAsmParser &operator=(const MCAsmParser &) = delete;
141
  virtual ~MCAsmParser();
142
143
  virtual void addDirectiveHandler(StringRef Directive,
144
                                   ExtensionDirectiveHandler Handler) = 0;
145
146
  virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
147
148
  virtual SourceMgr &getSourceManager() = 0;
149
150
  virtual MCAsmLexer &getLexer() = 0;
151
40.9M
  const MCAsmLexer &getLexer() const {
152
40.9M
    return const_cast<MCAsmParser*>(this)->getLexer();
153
40.9M
  }
154
155
  virtual MCContext &getContext() = 0;
156
157
  /// Return the output streamer for the assembler.
158
  virtual MCStreamer &getStreamer() = 0;
159
160
3.50M
  MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
161
  void setTargetParser(MCTargetAsmParser &P);
162
163
0
  virtual unsigned getAssemblerDialect() { return 0;}
164
0
  virtual void setAssemblerDialect(unsigned i) { }
165
166
473k
  bool getShowParsedOperands() const { return ShowParsedOperands; }
167
  void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
168
169
9.93k
  void setEnablePrintSchedInfo(bool Value) { EnablePrintSchedInfo = Value; }
170
143k
  bool shouldPrintSchedInfo() const { return EnablePrintSchedInfo; }
171
172
  /// Run the parser on the input source buffer.
173
  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
174
175
  virtual void setParsingInlineAsm(bool V) = 0;
176
  virtual bool isParsingInlineAsm() = 0;
177
178
  /// Parse MS-style inline assembly.
179
  virtual bool parseMSInlineAsm(
180
      void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
181
      unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
182
      SmallVectorImpl<std::string> &Constraints,
183
      SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
184
      const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
185
186
  /// Emit a note at the location \p L, with the message \p Msg.
187
  virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
188
189
  /// Emit a warning at the location \p L, with the message \p Msg.
190
  ///
191
  /// \return The return value is true, if warnings are fatal.
192
  virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
193
194
  /// Return an error at the location \p L, with the message \p Msg. This
195
  /// may be modified before being emitted.
196
  ///
197
  /// \return The return value is always true, as an idiomatic convenience to
198
  /// clients.
199
  bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
200
201
  /// Emit an error at the location \p L, with the message \p Msg.
202
  ///
203
  /// \return The return value is always true, as an idiomatic convenience to
204
  /// clients.
205
  virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
206
207
1.98M
  bool hasPendingError() { return !PendingErrors.empty(); }
208
209
46.7k
  bool printPendingErrors() {
210
46.7k
    bool rv = !PendingErrors.empty();
211
46.7k
    for (auto Err : PendingErrors) {
212
45.6k
      printError(Err.Loc, Twine(Err.Msg), Err.Range);
213
45.6k
    }
214
46.7k
    PendingErrors.clear();
215
46.7k
    return rv;
216
46.7k
  }
217
218
3
  void clearPendingErrors() { PendingErrors.clear(); }
219
220
  bool addErrorSuffix(const Twine &Suffix);
221
222
  /// Get the next AsmToken in the stream, possibly handling file
223
  /// inclusion first.
224
  virtual const AsmToken &Lex() = 0;
225
226
  /// Get the current AsmToken from the stream.
227
  const AsmToken &getTok() const;
228
229
  /// Report an error at the current lexer location.
230
  bool TokError(const Twine &Msg, SMRange Range = None);
231
232
  bool parseTokenLoc(SMLoc &Loc);
233
  bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
234
  /// Attempt to parse and consume token, returning true on
235
  /// success.
236
  bool parseOptionalToken(AsmToken::TokenKind T);
237
238
  bool parseEOL(const Twine &ErrMsg);
239
240
  bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
241
242
  bool parseIntToken(int64_t &V, const Twine &ErrMsg);
243
244
  bool check(bool P, const Twine &Msg);
245
  bool check(bool P, SMLoc Loc, const Twine &Msg);
246
247
  /// Parse an identifier or string (as a quoted identifier) and set \p
248
  /// Res to the identifier contents.
249
  virtual bool parseIdentifier(StringRef &Res) = 0;
250
251
  /// Parse up to the end of statement and return the contents from the
252
  /// current token until the end of the statement; the current token on exit
253
  /// will be either the EndOfStatement or EOF.
254
  virtual StringRef parseStringToEndOfStatement() = 0;
255
256
  /// Parse the current token as a string which may include escaped
257
  /// characters and return the string contents.
258
  virtual bool parseEscapedString(std::string &Data) = 0;
259
260
  /// Skip to the end of the current statement, for error recovery.
261
  virtual void eatToEndOfStatement() = 0;
262
263
  /// Parse an arbitrary expression.
264
  ///
265
  /// \param Res - The value of the expression. The result is undefined
266
  /// on error.
267
  /// \return - False on success.
268
  virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
269
  bool parseExpression(const MCExpr *&Res);
270
271
  /// Parse a primary expression.
272
  ///
273
  /// \param Res - The value of the expression. The result is undefined
274
  /// on error.
275
  /// \return - False on success.
276
  virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
277
278
  /// Parse an arbitrary expression, assuming that an initial '(' has
279
  /// already been consumed.
280
  ///
281
  /// \param Res - The value of the expression. The result is undefined
282
  /// on error.
283
  /// \return - False on success.
284
  virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
285
286
  /// Parse an expression which must evaluate to an absolute value.
287
  ///
288
  /// \param Res - The value of the absolute expression. The result is undefined
289
  /// on error.
290
  /// \return - False on success.
291
  virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
292
293
  /// Ensure that we have a valid section set in the streamer. Otherwise,
294
  /// report an error and switch to .text.
295
  /// \return - False on success.
296
  virtual bool checkForValidSection() = 0;
297
298
  /// Parse an arbitrary expression of a specified parenthesis depth,
299
  /// assuming that the initial '(' characters have already been consumed.
300
  ///
301
  /// \param ParenDepth - Specifies how many trailing expressions outside the
302
  /// current parentheses we have to parse.
303
  /// \param Res - The value of the expression. The result is undefined
304
  /// on error.
305
  /// \return - False on success.
306
  virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
307
                                     SMLoc &EndLoc) = 0;
308
};
309
310
/// Create an MCAsmParser instance.
311
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
312
                               const MCAsmInfo &, unsigned CB = 0);
313
314
} // end namespace llvm
315
316
#endif // LLVM_MC_MCPARSER_MCASMPARSER_H