summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCParser
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCParser')
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp8
-rw-r--r--llvm/lib/MC/MCParser/CMakeLists.txt1
-rw-r--r--llvm/lib/MC/MCParser/WasmAsmParser.cpp145
3 files changed, 149 insertions, 5 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 3f7b507791e..7299ed29e4b 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -675,6 +675,7 @@ namespace llvm {
extern MCAsmParserExtension *createDarwinAsmParser();
extern MCAsmParserExtension *createELFAsmParser();
extern MCAsmParserExtension *createCOFFAsmParser();
+extern MCAsmParserExtension *createWasmAsmParser();
} // end namespace llvm
@@ -705,10 +706,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
PlatformParser.reset(createELFAsmParser());
break;
case MCObjectFileInfo::IsWasm:
- // TODO: WASM will need its own MCAsmParserExtension implementation, but
- // for now we can re-use the ELF one, since the directives can be the
- // same for now.
- PlatformParser.reset(createELFAsmParser());
+ PlatformParser.reset(createWasmAsmParser());
break;
}
@@ -3921,7 +3919,7 @@ bool AsmParser::parseDirectiveCFIStartProc() {
parseToken(AsmToken::EndOfStatement))
return addErrorSuffix(" in '.cfi_startproc' directive");
}
-
+
// TODO(kristina): Deal with a corner case of incorrect diagnostic context
// being produced if this directive is emitted as part of preprocessor macro
// expansion which can *ONLY* happen if Clang's cc1as is the API consumer.
diff --git a/llvm/lib/MC/MCParser/CMakeLists.txt b/llvm/lib/MC/MCParser/CMakeLists.txt
index 99fdd016799..0c54e8e9019 100644
--- a/llvm/lib/MC/MCParser/CMakeLists.txt
+++ b/llvm/lib/MC/MCParser/CMakeLists.txt
@@ -8,6 +8,7 @@ add_llvm_library(LLVMMCParser
MCAsmParser.cpp
MCAsmParserExtension.cpp
MCTargetAsmParser.cpp
+ WasmAsmParser.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/MC/MCParser
diff --git a/llvm/lib/MC/MCParser/WasmAsmParser.cpp b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
new file mode 100644
index 00000000000..93bb0cb3c72
--- /dev/null
+++ b/llvm/lib/MC/MCParser/WasmAsmParser.cpp
@@ -0,0 +1,145 @@
+//===- WasmAsmParser.cpp - Wasm Assembly Parser -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+// --
+//
+// Note, this is for wasm, the binary format (analogous to ELF), not wasm,
+// the instruction set (analogous to x86), for which parsing code lives in
+// WebAssemblyAsmParser.
+//
+// This file contains processing for generic directives implemented using
+// MCTargetStreamer, the ones that depend on WebAssemblyTargetStreamer are in
+// WebAssemblyAsmParser.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BinaryFormat/Wasm.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/Support/MachineValueType.h"
+
+using namespace llvm;
+
+namespace {
+
+class WasmAsmParser : public MCAsmParserExtension {
+ MCAsmParser *Parser;
+ MCAsmLexer *Lexer;
+
+ template<bool (WasmAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<WasmAsmParser, HandlerMethod>);
+
+ getParser().addDirectiveHandler(Directive, Handler);
+ }
+
+public:
+ WasmAsmParser() : Parser(nullptr), Lexer(nullptr) {
+ BracketExpressionsSupported = true;
+ }
+
+ void Initialize(MCAsmParser &P) override {
+ Parser = &P;
+ Lexer = &Parser->getLexer();
+ // Call the base implementation.
+ this->MCAsmParserExtension::Initialize(*Parser);
+
+ addDirectiveHandler<&WasmAsmParser::parseSectionDirectiveText>(".text");
+ addDirectiveHandler<&WasmAsmParser::parseSectionDirective>(".section");
+ addDirectiveHandler<&WasmAsmParser::parseDirectiveSize>(".size");
+ addDirectiveHandler<&WasmAsmParser::parseDirectiveType>(".type");
+ }
+
+ bool Error(const StringRef &msg, const AsmToken &tok) {
+ return Parser->Error(tok.getLoc(), msg + tok.getString());
+ }
+
+ bool IsNext(AsmToken::TokenKind Kind) {
+ auto ok = Lexer->is(Kind);
+ if (ok) Lex();
+ return ok;
+ }
+
+ bool Expect(AsmToken::TokenKind Kind, const char *KindName) {
+ if (!IsNext(Kind))
+ return Error(std::string("Expected ") + KindName + ", instead got: ",
+ Lexer->getTok());
+ return false;
+ }
+
+ bool parseSectionDirectiveText(StringRef, SMLoc) {
+ // FIXME: .text currently no-op.
+ return false;
+ }
+
+ bool parseSectionDirective(StringRef, SMLoc) {
+ // FIXME: .section currently no-op.
+ while (Lexer->isNot(AsmToken::EndOfStatement)) Parser->Lex();
+ return false;
+ }
+
+ // TODO: This function is almost the same as ELFAsmParser::ParseDirectiveSize
+ // so maybe could be shared somehow.
+ bool parseDirectiveSize(StringRef, SMLoc) {
+ StringRef Name;
+ if (Parser->parseIdentifier(Name))
+ return TokError("expected identifier in directive");
+ auto Sym = getContext().getOrCreateSymbol(Name);
+ if (Lexer->isNot(AsmToken::Comma))
+ return TokError("unexpected token in directive");
+ Lex();
+ const MCExpr *Expr;
+ if (Parser->parseExpression(Expr))
+ return true;
+ if (Lexer->isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+ Lex();
+ // MCWasmStreamer implements this.
+ getStreamer().emitELFSize(Sym, Expr);
+ return false;
+ }
+
+ bool parseDirectiveType(StringRef, SMLoc) {
+ // This could be the start of a function, check if followed by
+ // "label,@function"
+ if (!Lexer->is(AsmToken::Identifier))
+ return Error("Expected label after .type directive, got: ",
+ Lexer->getTok());
+ auto WasmSym = cast<MCSymbolWasm>(
+ getStreamer().getContext().getOrCreateSymbol(
+ Lexer->getTok().getString()));
+ Lex();
+ if (!(IsNext(AsmToken::Comma) && IsNext(AsmToken::At) &&
+ Lexer->is(AsmToken::Identifier)))
+ return Error("Expected label,@type declaration, got: ", Lexer->getTok());
+ auto TypeName = Lexer->getTok().getString();
+ if (TypeName == "function")
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
+ else if (TypeName == "global")
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ else
+ return Error("Unknown WASM symbol type: ", Lexer->getTok());
+ Lex();
+ return Expect(AsmToken::EndOfStatement, "EOL");
+ }
+};
+
+} // end anonymous namespace
+
+namespace llvm {
+
+MCAsmParserExtension *createWasmAsmParser() {
+ return new WasmAsmParser;
+}
+
+} // end namespace llvm
OpenPOWER on IntegriCloud