LLVM  8.0.1
WasmAsmParser.cpp
Go to the documentation of this file.
1 //===- WasmAsmParser.cpp - Wasm Assembly Parser -----------------------------===//
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 // Note, this is for wasm, the binary format (analogous to ELF), not wasm,
11 // the instruction set (analogous to x86), for which parsing code lives in
12 // WebAssemblyAsmParser.
13 //
14 // This file contains processing for generic directives implemented using
15 // MCTargetStreamer, the ones that depend on WebAssemblyTargetStreamer are in
16 // WebAssemblyAsmParser.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 #include "llvm/BinaryFormat/Wasm.h"
21 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCSymbolWasm.h"
29 
30 using namespace llvm;
31 
32 namespace {
33 
34 class WasmAsmParser : public MCAsmParserExtension {
35  MCAsmParser *Parser;
36  MCAsmLexer *Lexer;
37 
38  template<bool (WasmAsmParser::*HandlerMethod)(StringRef, SMLoc)>
39  void addDirectiveHandler(StringRef Directive) {
40  MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
41  this, HandleDirective<WasmAsmParser, HandlerMethod>);
42 
43  getParser().addDirectiveHandler(Directive, Handler);
44  }
45 
46 public:
47  WasmAsmParser() : Parser(nullptr), Lexer(nullptr) {
48  BracketExpressionsSupported = true;
49  }
50 
51  void Initialize(MCAsmParser &P) override {
52  Parser = &P;
53  Lexer = &Parser->getLexer();
54  // Call the base implementation.
55  this->MCAsmParserExtension::Initialize(*Parser);
56 
57  addDirectiveHandler<&WasmAsmParser::parseSectionDirectiveText>(".text");
58  addDirectiveHandler<&WasmAsmParser::parseSectionDirective>(".section");
59  addDirectiveHandler<&WasmAsmParser::parseDirectiveSize>(".size");
60  addDirectiveHandler<&WasmAsmParser::parseDirectiveType>(".type");
61  }
62 
63  bool Error(const StringRef &msg, const AsmToken &tok) {
64  return Parser->Error(tok.getLoc(), msg + tok.getString());
65  }
66 
67  bool IsNext(AsmToken::TokenKind Kind) {
68  auto ok = Lexer->is(Kind);
69  if (ok) Lex();
70  return ok;
71  }
72 
73  bool Expect(AsmToken::TokenKind Kind, const char *KindName) {
74  if (!IsNext(Kind))
75  return Error(std::string("Expected ") + KindName + ", instead got: ",
76  Lexer->getTok());
77  return false;
78  }
79 
80  bool parseSectionDirectiveText(StringRef, SMLoc) {
81  // FIXME: .text currently no-op.
82  return false;
83  }
84 
85  bool parseSectionDirective(StringRef, SMLoc) {
86  // FIXME: .section currently no-op.
87  while (Lexer->isNot(AsmToken::EndOfStatement)) Parser->Lex();
88  return false;
89  }
90 
91  // TODO: This function is almost the same as ELFAsmParser::ParseDirectiveSize
92  // so maybe could be shared somehow.
93  bool parseDirectiveSize(StringRef, SMLoc) {
95  if (Parser->parseIdentifier(Name))
96  return TokError("expected identifier in directive");
97  auto Sym = getContext().getOrCreateSymbol(Name);
98  if (Lexer->isNot(AsmToken::Comma))
99  return TokError("unexpected token in directive");
100  Lex();
101  const MCExpr *Expr;
102  if (Parser->parseExpression(Expr))
103  return true;
104  if (Lexer->isNot(AsmToken::EndOfStatement))
105  return TokError("unexpected token in directive");
106  Lex();
107  // MCWasmStreamer implements this.
108  getStreamer().emitELFSize(Sym, Expr);
109  return false;
110  }
111 
112  bool parseDirectiveType(StringRef, SMLoc) {
113  // This could be the start of a function, check if followed by
114  // "label,@function"
115  if (!Lexer->is(AsmToken::Identifier))
116  return Error("Expected label after .type directive, got: ",
117  Lexer->getTok());
118  auto WasmSym = cast<MCSymbolWasm>(
119  getStreamer().getContext().getOrCreateSymbol(
120  Lexer->getTok().getString()));
121  Lex();
122  if (!(IsNext(AsmToken::Comma) && IsNext(AsmToken::At) &&
123  Lexer->is(AsmToken::Identifier)))
124  return Error("Expected label,@type declaration, got: ", Lexer->getTok());
125  auto TypeName = Lexer->getTok().getString();
126  if (TypeName == "function")
127  WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
128  else if (TypeName == "global")
129  WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
130  else
131  return Error("Unknown WASM symbol type: ", Lexer->getTok());
132  Lex();
133  return Expect(AsmToken::EndOfStatement, "EOL");
134  }
135 };
136 
137 } // end anonymous namespace
138 
139 namespace llvm {
140 
142  return new WasmAsmParser;
143 }
144 
145 } // end namespace llvm
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition: MCAsmLexer.h:101
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:111
This class represents lattice values for constants.
Definition: AllocatorList.h:24
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:136
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParserExtension * createWasmAsmParser()
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:40
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
#define P(N)
virtual MCAsmLexer & getLexer()=0
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
Definition: MCAsmParser.cpp:88
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:139
const unsigned Kind
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:114
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents...
Represents a location in source code.
Definition: SMLoc.h:24