summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/COFFAsmParser.cpp
diff options
context:
space:
mode:
authorMichael J. Spencer <bigcheesegs@gmail.com>2010-10-09 11:01:07 +0000
committerMichael J. Spencer <bigcheesegs@gmail.com>2010-10-09 11:01:07 +0000
commit7d4900416af3813aa9473e6ec2f0497ad5d208dd (patch)
tree39faaed2d6c112d2a959c959ed95ddd6fb5506e6 /lib/MC/MCParser/COFFAsmParser.cpp
parentc0c8df3cea0dde2069edd10313a958508f99ec85 (diff)
downloadllvm-7d4900416af3813aa9473e6ec2f0497ad5d208dd.tar.gz
llvm-7d4900416af3813aa9473e6ec2f0497ad5d208dd.tar.bz2
llvm-7d4900416af3813aa9473e6ec2f0497ad5d208dd.tar.xz
MC-COFF: Add COFFAsmParser. Completes PR8343.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116150 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/COFFAsmParser.cpp')
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
new file mode 100644
index 0000000000..5ecab03b00
--- /dev/null
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -0,0 +1,144 @@
+//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCParser/MCAsmParserExtension.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/COFF.h"
+using namespace llvm;
+
+namespace {
+
+class COFFAsmParser : public MCAsmParserExtension {
+ template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
+ void AddDirectiveHandler(StringRef Directive) {
+ getParser().AddDirectiveHandler(this, Directive,
+ HandleDirective<COFFAsmParser, Handler>);
+ }
+
+ bool ParseSectionSwitch(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind);
+
+ virtual void Initialize(MCAsmParser &Parser) {
+ // Call the base implementation.
+ MCAsmParserExtension::Initialize(Parser);
+
+ AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
+ AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
+ AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
+ AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
+ AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
+ AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ }
+
+ bool ParseSectionDirectiveText(StringRef, SMLoc) {
+ return ParseSectionSwitch(".text",
+ COFF::IMAGE_SCN_CNT_CODE
+ | COFF::IMAGE_SCN_MEM_EXECUTE
+ | COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getText());
+ }
+ bool ParseSectionDirectiveData(StringRef, SMLoc) {
+ return ParseSectionSwitch(".data",
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ
+ | COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
+ }
+ bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
+ return ParseSectionSwitch(".bss",
+ COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ
+ | COFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getBSS());
+ }
+
+ bool ParseDirectiveDef(StringRef, SMLoc);
+ bool ParseDirectiveScl(StringRef, SMLoc);
+ bool ParseDirectiveType(StringRef, SMLoc);
+ bool ParseDirectiveEndef(StringRef, SMLoc);
+
+public:
+ COFFAsmParser() {}
+};
+
+} // end annonomous namespace.
+
+bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
+ unsigned Characteristics,
+ SectionKind Kind) {
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in section switching directive");
+ Lex();
+
+ getStreamer().SwitchSection(getContext().getCOFFSection(
+ Section, Characteristics, Kind));
+
+ return false;
+}
+
+bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
+ StringRef SymbolName;
+
+ if (getParser().ParseIdentifier(SymbolName))
+ return TokError("expected identifier in directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
+
+ getStreamer().BeginCOFFSymbolDef(Sym);
+
+ Lex();
+ return false;
+}
+
+bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
+ int64_t SymbolStorageClass;
+ if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ Lex();
+ getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
+ return false;
+}
+
+bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
+ int64_t Type;
+ if (getParser().ParseAbsoluteExpression(Type))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ Lex();
+ getStreamer().EmitCOFFSymbolType(Type);
+ return false;
+}
+
+bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
+ Lex();
+ getStreamer().EndCOFFSymbolDef();
+ return false;
+}
+
+namespace llvm {
+
+MCAsmParserExtension *createCOFFAsmParser() {
+ return new COFFAsmParser;
+}
+
+}