blob: 5ecab03b00f0c42975137850265849e1e356e47c [file] [log] [blame]
Michael J. Spencer7d490042010-10-09 11:01:07 +00001//===- COFFAsmParser.cpp - COFF 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#include "llvm/MC/MCParser/MCAsmParserExtension.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/MC/MCAsmInfo.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCParser/MCAsmLexer.h"
15#include "llvm/MC/MCSectionCOFF.h"
16#include "llvm/MC/MCStreamer.h"
17#include "llvm/Support/COFF.h"
18using namespace llvm;
19
20namespace {
21
22class COFFAsmParser : public MCAsmParserExtension {
23 template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
24 void AddDirectiveHandler(StringRef Directive) {
25 getParser().AddDirectiveHandler(this, Directive,
26 HandleDirective<COFFAsmParser, Handler>);
27 }
28
29 bool ParseSectionSwitch(StringRef Section,
30 unsigned Characteristics,
31 SectionKind Kind);
32
33 virtual void Initialize(MCAsmParser &Parser) {
34 // Call the base implementation.
35 MCAsmParserExtension::Initialize(Parser);
36
37 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
38 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
39 AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
40 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
41 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
42 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
43 AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
44 }
45
46 bool ParseSectionDirectiveText(StringRef, SMLoc) {
47 return ParseSectionSwitch(".text",
48 COFF::IMAGE_SCN_CNT_CODE
49 | COFF::IMAGE_SCN_MEM_EXECUTE
50 | COFF::IMAGE_SCN_MEM_READ,
51 SectionKind::getText());
52 }
53 bool ParseSectionDirectiveData(StringRef, SMLoc) {
54 return ParseSectionSwitch(".data",
55 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
56 | COFF::IMAGE_SCN_MEM_READ
57 | COFF::IMAGE_SCN_MEM_WRITE,
58 SectionKind::getDataRel());
59 }
60 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
61 return ParseSectionSwitch(".bss",
62 COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA
63 | COFF::IMAGE_SCN_MEM_READ
64 | COFF::IMAGE_SCN_MEM_WRITE,
65 SectionKind::getBSS());
66 }
67
68 bool ParseDirectiveDef(StringRef, SMLoc);
69 bool ParseDirectiveScl(StringRef, SMLoc);
70 bool ParseDirectiveType(StringRef, SMLoc);
71 bool ParseDirectiveEndef(StringRef, SMLoc);
72
73public:
74 COFFAsmParser() {}
75};
76
77} // end annonomous namespace.
78
79bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
80 unsigned Characteristics,
81 SectionKind Kind) {
82 if (getLexer().isNot(AsmToken::EndOfStatement))
83 return TokError("unexpected token in section switching directive");
84 Lex();
85
86 getStreamer().SwitchSection(getContext().getCOFFSection(
87 Section, Characteristics, Kind));
88
89 return false;
90}
91
92bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
93 StringRef SymbolName;
94
95 if (getParser().ParseIdentifier(SymbolName))
96 return TokError("expected identifier in directive");
97
98 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
99
100 getStreamer().BeginCOFFSymbolDef(Sym);
101
102 Lex();
103 return false;
104}
105
106bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
107 int64_t SymbolStorageClass;
108 if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
109 return true;
110
111 if (getLexer().isNot(AsmToken::EndOfStatement))
112 return TokError("unexpected token in directive");
113
114 Lex();
115 getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
116 return false;
117}
118
119bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
120 int64_t Type;
121 if (getParser().ParseAbsoluteExpression(Type))
122 return true;
123
124 if (getLexer().isNot(AsmToken::EndOfStatement))
125 return TokError("unexpected token in directive");
126
127 Lex();
128 getStreamer().EmitCOFFSymbolType(Type);
129 return false;
130}
131
132bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
133 Lex();
134 getStreamer().EndCOFFSymbolDef();
135 return false;
136}
137
138namespace llvm {
139
140MCAsmParserExtension *createCOFFAsmParser() {
141 return new COFFAsmParser;
142}
143
144}