Coverage Report

Created: 2018-07-19 03:59

/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.60k
  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
  unsigned ShowParsedOperands : 1;
126
127
protected: // Can only create subclasses.
128
  MCAsmParser();
129
130
  /// Flag tracking whether any errors have been encountered.
131
  bool HadError = false;
132
  /// Enable print [latency:throughput] in output file.
133
  bool EnablePrintSchedInfo = false;
134
135
  SmallVector<MCPendingError, 1> PendingErrors;
136
137
public:
138
  MCAsmParser(const MCAsmParser &) = delete;
139
  MCAsmParser &operator=(const MCAsmParser &) = delete;
140
  virtual ~MCAsmParser();
141
142
  virtual void addDirectiveHandler(StringRef Directive,
143
                                   ExtensionDirectiveHandler Handler) = 0;
144
145
  virtual void addAliasForDirective(StringRef Directive, StringRef Alias) = 0;
146
147
  virtual SourceMgr &getSourceManager() = 0;
148
149
  virtual MCAsmLexer &getLexer() = 0;
150
39.5M
  const MCAsmLexer &getLexer() const {
151
39.5M
    return const_cast<MCAsmParser*>(this)->getLexer();
152
39.5M
  }
153
154
  virtual MCContext &getContext() = 0;
155
156
  /// Return the output streamer for the assembler.
157
  virtual MCStreamer &getStreamer() = 0;
158
159
2.84M
  MCTargetAsmParser &getTargetParser() const { return *TargetParser; }
160
  void setTargetParser(MCTargetAsmParser &P);
161
162
0
  virtual unsigned getAssemblerDialect() { return 0;}
163
0
  virtual void setAssemblerDialect(unsigned i) { }
164
165
455k
  bool getShowParsedOperands() const { return ShowParsedOperands; }
166
0
  void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; }
167
168
9.47k
  void setEnablePrintSchedInfo(bool Value) { EnablePrintSchedInfo = Value; }
169
135k
  bool shouldPrintSchedInfo() { return EnablePrintSchedInfo; }
170
171
  /// Run the parser on the input source buffer.
172
  virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
173
174
  virtual void setParsingInlineAsm(bool V) = 0;
175
  virtual bool isParsingInlineAsm() = 0;
176
177
  /// Parse MS-style inline assembly.
178
  virtual bool parseMSInlineAsm(
179
      void *AsmLoc, std::string &AsmString, unsigned &NumOutputs,
180
      unsigned &NumInputs, SmallVectorImpl<std::pair<void *, bool>> &OpDecls,
181
      SmallVectorImpl<std::string> &Constraints,
182
      SmallVectorImpl<std::string> &Clobbers, const MCInstrInfo *MII,
183
      const MCInstPrinter *IP, MCAsmParserSemaCallback &SI) = 0;
184
185
  /// Emit a note at the location \p L, with the message \p Msg.
186
  virtual void Note(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
187
188
  /// Emit a warning at the location \p L, with the message \p Msg.
189
  ///
190
  /// \return The return value is true, if warnings are fatal.
191
  virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
192
193
  /// Return an error at the location \p L, with the message \p Msg. This
194
  /// may be modified before being emitted.
195
  ///
196
  /// \return The return value is always true, as an idiomatic convenience to
197
  /// clients.
198
  bool Error(SMLoc L, const Twine &Msg, SMRange Range = None);
199
200
  /// Emit an error at the location \p L, with the message \p Msg.
201
  ///
202
  /// \return The return value is always true, as an idiomatic convenience to
203
  /// clients.
204
  virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range = None) = 0;
205
206
1.96M
  bool hasPendingError() { return !PendingErrors.empty(); }
207
208
43.3k
  bool printPendingErrors() {
209
43.3k
    bool rv = !PendingErrors.empty();
210
43.3k
    for (auto Err : PendingErrors) {
211
42.2k
      printError(Err.Loc, Twine(Err.Msg), Err.Range);
212
42.2k
    }
213
43.3k
    PendingErrors.clear();
214
43.3k
    return rv;
215
43.3k
  }
216
217
2
  void clearPendingErrors() { PendingErrors.clear(); }
218
219
  bool addErrorSuffix(const Twine &Suffix);
220
221
  /// Get the next AsmToken in the stream, possibly handling file
222
  /// inclusion first.
223
  virtual const AsmToken &Lex() = 0;
224
225
  /// Get the current AsmToken from the stream.
226
  const AsmToken &getTok() const;
227
228
  /// Report an error at the current lexer location.
229
  bool TokError(const Twine &Msg, SMRange Range = None);
230
231
  bool parseTokenLoc(SMLoc &Loc);
232
  bool parseToken(AsmToken::TokenKind T, const Twine &Msg = "unexpected token");
233
  /// Attempt to parse and consume token, returning true on
234
  /// success.
235
  bool parseOptionalToken(AsmToken::TokenKind T);
236
237
  bool parseEOL(const Twine &ErrMsg);
238
239
  bool parseMany(function_ref<bool()> parseOne, bool hasComma = true);
240
241
  bool parseIntToken(int64_t &V, const Twine &ErrMsg);
242
243
  bool check(bool P, const Twine &Msg);
244
  bool check(bool P, SMLoc Loc, const Twine &Msg);
245
246
  /// Parse an identifier or string (as a quoted identifier) and set \p
247
  /// Res to the identifier contents.
248
  virtual bool parseIdentifier(StringRef &Res) = 0;
249
250
  /// Parse up to the end of statement and return the contents from the
251
  /// current token until the end of the statement; the current token on exit
252
  /// will be either the EndOfStatement or EOF.
253
  virtual StringRef parseStringToEndOfStatement() = 0;
254
255
  /// Parse the current token as a string which may include escaped
256
  /// characters and return the string contents.
257
  virtual bool parseEscapedString(std::string &Data) = 0;
258
259
  /// Skip to the end of the current statement, for error recovery.
260
  virtual void eatToEndOfStatement() = 0;
261
262
  /// Parse an arbitrary expression.
263
  ///
264
  /// \param Res - The value of the expression. The result is undefined
265
  /// on error.
266
  /// \return - False on success.
267
  virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
268
  bool parseExpression(const MCExpr *&Res);
269
270
  /// Parse a primary expression.
271
  ///
272
  /// \param Res - The value of the expression. The result is undefined
273
  /// on error.
274
  /// \return - False on success.
275
  virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) = 0;
276
277
  /// Parse an arbitrary expression, assuming that an initial '(' has
278
  /// already been consumed.
279
  ///
280
  /// \param Res - The value of the expression. The result is undefined
281
  /// on error.
282
  /// \return - False on success.
283
  virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
284
285
  /// Parse an expression which must evaluate to an absolute value.
286
  ///
287
  /// \param Res - The value of the absolute expression. The result is undefined
288
  /// on error.
289
  /// \return - False on success.
290
  virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
291
292
  /// Ensure that we have a valid section set in the streamer. Otherwise,
293
  /// report an error and switch to .text.
294
  /// \return - False on success.
295
  virtual bool checkForValidSection() = 0;
296
297
  /// Parse an arbitrary expression of a specified parenthesis depth,
298
  /// assuming that the initial '(' characters have already been consumed.
299
  ///
300
  /// \param ParenDepth - Specifies how many trailing expressions outside the
301
  /// current parentheses we have to parse.
302
  /// \param Res - The value of the expression. The result is undefined
303
  /// on error.
304
  /// \return - False on success.
305
  virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res,
306
                                     SMLoc &EndLoc) = 0;
307
};
308
309
/// Create an MCAsmParser instance.
310
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
311
                               const MCAsmInfo &, unsigned CB = 0);
312
313
} // end namespace llvm
314
315
#endif // LLVM_MC_MCPARSER_MCASMPARSER_H