MC/AsmParser: Move .section parsing to Darwin specific parser.
[oota-llvm.git] / lib / MC / MCParser / AsmParser.cpp
1 //===- AsmParser.cpp - Parser for Assembly Files --------------------------===//
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 // This class implements the parser for assembly files.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/MC/MCParser/AsmParser.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCSectionMachO.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Target/TargetAsmParser.h"
31 using namespace llvm;
32
33
34 namespace {
35
36 /// \brief Generic implementations of directive handling, etc. which is shared
37 /// (or the default, at least) for all assembler parser.
38 class GenericAsmParser : public MCAsmParserExtension {
39 public:
40   GenericAsmParser() {}
41
42   virtual void Initialize(MCAsmParser &Parser) {
43     // Call the base implementation.
44     this->MCAsmParserExtension::Initialize(Parser);
45
46     // Debugging directives.
47     Parser.AddDirectiveHandler(this, ".file", MCAsmParser::DirectiveHandler(
48                                  &GenericAsmParser::ParseDirectiveFile));
49     Parser.AddDirectiveHandler(this, ".line", MCAsmParser::DirectiveHandler(
50                                  &GenericAsmParser::ParseDirectiveLine));
51     Parser.AddDirectiveHandler(this, ".loc", MCAsmParser::DirectiveHandler(
52                                  &GenericAsmParser::ParseDirectiveLoc));
53   }
54
55   bool ParseDirectiveFile(StringRef, SMLoc DirectiveLoc); // ".file"
56   bool ParseDirectiveLine(StringRef, SMLoc DirectiveLoc); // ".line"
57   bool ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc); // ".loc"
58 };
59
60 /// \brief Implementation of directive handling which is shared across all
61 /// Darwin targets.
62 class DarwinAsmParser : public MCAsmParserExtension {
63   bool ParseSectionSwitch(const char *Segment, const char *Section,
64                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
65                           unsigned StubSize = 0);
66
67 public:
68   DarwinAsmParser() {}
69
70   virtual void Initialize(MCAsmParser &Parser) {
71     // Call the base implementation.
72     this->MCAsmParserExtension::Initialize(Parser);
73
74     Parser.AddDirectiveHandler(this, ".desc", MCAsmParser::DirectiveHandler(
75                                  &DarwinAsmParser::ParseDirectiveDesc));
76     Parser.AddDirectiveHandler(this, ".lsym", MCAsmParser::DirectiveHandler(
77                                  &DarwinAsmParser::ParseDirectiveLsym));
78     Parser.AddDirectiveHandler(this, ".subsections_via_symbols",
79                                MCAsmParser::DirectiveHandler(
80                         &DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols));
81     Parser.AddDirectiveHandler(this, ".dump", MCAsmParser::DirectiveHandler(
82                                  &DarwinAsmParser::ParseDirectiveDumpOrLoad));
83     Parser.AddDirectiveHandler(this, ".load", MCAsmParser::DirectiveHandler(
84                                  &DarwinAsmParser::ParseDirectiveDumpOrLoad));
85     Parser.AddDirectiveHandler(this, ".section", MCAsmParser::DirectiveHandler(
86                                  &DarwinAsmParser::ParseDirectiveSection));
87     Parser.AddDirectiveHandler(this, ".secure_log_unique",
88                                MCAsmParser::DirectiveHandler(
89                              &DarwinAsmParser::ParseDirectiveSecureLogUnique));
90     Parser.AddDirectiveHandler(this, ".secure_log_reset",
91                                MCAsmParser::DirectiveHandler(
92                              &DarwinAsmParser::ParseDirectiveSecureLogReset));
93     Parser.AddDirectiveHandler(this, ".tbss",
94                                MCAsmParser::DirectiveHandler(
95                                  &DarwinAsmParser::ParseDirectiveTBSS));
96     Parser.AddDirectiveHandler(this, ".zerofill",
97                                MCAsmParser::DirectiveHandler(
98                                  &DarwinAsmParser::ParseDirectiveZerofill));
99
100     // Special section directives.
101     Parser.AddDirectiveHandler(this, ".const",
102                                MCAsmParser::DirectiveHandler(
103                  &DarwinAsmParser::ParseSectionDirectiveConst));
104     Parser.AddDirectiveHandler(this, ".const_data",
105                                MCAsmParser::DirectiveHandler(
106                  &DarwinAsmParser::ParseSectionDirectiveConstData));
107     Parser.AddDirectiveHandler(this, ".constructor",
108                                MCAsmParser::DirectiveHandler(
109                  &DarwinAsmParser::ParseSectionDirectiveConstructor));
110     Parser.AddDirectiveHandler(this, ".cstring",
111                                MCAsmParser::DirectiveHandler(
112                  &DarwinAsmParser::ParseSectionDirectiveCString));
113     Parser.AddDirectiveHandler(this, ".data",
114                                MCAsmParser::DirectiveHandler(
115                  &DarwinAsmParser::ParseSectionDirectiveData));
116     Parser.AddDirectiveHandler(this, ".destructor",
117                                MCAsmParser::DirectiveHandler(
118                  &DarwinAsmParser::ParseSectionDirectiveDestructor));
119     Parser.AddDirectiveHandler(this, ".dyld",
120                                MCAsmParser::DirectiveHandler(
121                  &DarwinAsmParser::ParseSectionDirectiveDyld));
122     Parser.AddDirectiveHandler(this, ".fvmlib_init0",
123                                MCAsmParser::DirectiveHandler(
124                  &DarwinAsmParser::ParseSectionDirectiveFVMLibInit0));
125     Parser.AddDirectiveHandler(this, ".fvmlib_init1",
126                                MCAsmParser::DirectiveHandler(
127                  &DarwinAsmParser::ParseSectionDirectiveFVMLibInit1));
128     Parser.AddDirectiveHandler(this, ".lazy_symbol_pointer",
129                                MCAsmParser::DirectiveHandler(
130                  &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers));
131     Parser.AddDirectiveHandler(this, ".literal16",
132                                MCAsmParser::DirectiveHandler(
133                  &DarwinAsmParser::ParseSectionDirectiveLiteral16));
134     Parser.AddDirectiveHandler(this, ".literal4",
135                                MCAsmParser::DirectiveHandler(
136                  &DarwinAsmParser::ParseSectionDirectiveLiteral4));
137     Parser.AddDirectiveHandler(this, ".literal8",
138                                MCAsmParser::DirectiveHandler(
139                  &DarwinAsmParser::ParseSectionDirectiveLiteral8));
140     Parser.AddDirectiveHandler(this, ".mod_init_func",
141                                MCAsmParser::DirectiveHandler(
142                  &DarwinAsmParser::ParseSectionDirectiveModInitFunc));
143     Parser.AddDirectiveHandler(this, ".mod_term_func",
144                                MCAsmParser::DirectiveHandler(
145                  &DarwinAsmParser::ParseSectionDirectiveModTermFunc));
146     Parser.AddDirectiveHandler(this, ".non_lazy_symbol_pointer",
147                                MCAsmParser::DirectiveHandler(
148                  &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers));
149     Parser.AddDirectiveHandler(this, ".objc_cat_cls_meth",
150                                MCAsmParser::DirectiveHandler(
151                  &DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth));
152     Parser.AddDirectiveHandler(this, ".objc_cat_inst_meth",
153                                MCAsmParser::DirectiveHandler(
154                  &DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth));
155     Parser.AddDirectiveHandler(this, ".objc_category",
156                                MCAsmParser::DirectiveHandler(
157                  &DarwinAsmParser::ParseSectionDirectiveObjCCategory));
158     Parser.AddDirectiveHandler(this, ".objc_class",
159                                MCAsmParser::DirectiveHandler(
160                  &DarwinAsmParser::ParseSectionDirectiveObjCClass));
161     Parser.AddDirectiveHandler(this, ".objc_class_names",
162                                MCAsmParser::DirectiveHandler(
163                  &DarwinAsmParser::ParseSectionDirectiveObjCClassNames));
164     Parser.AddDirectiveHandler(this, ".objc_class_vars",
165                                MCAsmParser::DirectiveHandler(
166                  &DarwinAsmParser::ParseSectionDirectiveObjCClassVars));
167     Parser.AddDirectiveHandler(this, ".objc_cls_meth",
168                                MCAsmParser::DirectiveHandler(
169                  &DarwinAsmParser::ParseSectionDirectiveObjCClsMeth));
170     Parser.AddDirectiveHandler(this, ".objc_cls_refs",
171                                MCAsmParser::DirectiveHandler(
172                  &DarwinAsmParser::ParseSectionDirectiveObjCClsRefs));
173     Parser.AddDirectiveHandler(this, ".objc_inst_meth",
174                                MCAsmParser::DirectiveHandler(
175                  &DarwinAsmParser::ParseSectionDirectiveObjCInstMeth));
176     Parser.AddDirectiveHandler(this, ".objc_instance_vars",
177                                MCAsmParser::DirectiveHandler(
178                  &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars));
179     Parser.AddDirectiveHandler(this, ".objc_message_refs",
180                                MCAsmParser::DirectiveHandler(
181                  &DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs));
182     Parser.AddDirectiveHandler(this, ".objc_meta_class",
183                                MCAsmParser::DirectiveHandler(
184                  &DarwinAsmParser::ParseSectionDirectiveObjCMetaClass));
185     Parser.AddDirectiveHandler(this, ".objc_meth_var_names",
186                                MCAsmParser::DirectiveHandler(
187                  &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames));
188     Parser.AddDirectiveHandler(this, ".objc_meth_var_types",
189                                MCAsmParser::DirectiveHandler(
190                  &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes));
191     Parser.AddDirectiveHandler(this, ".objc_module_info",
192                                MCAsmParser::DirectiveHandler(
193                  &DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo));
194     Parser.AddDirectiveHandler(this, ".objc_protocol",
195                                MCAsmParser::DirectiveHandler(
196                  &DarwinAsmParser::ParseSectionDirectiveObjCProtocol));
197     Parser.AddDirectiveHandler(this, ".objc_selector_strs",
198                                MCAsmParser::DirectiveHandler(
199                  &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs));
200     Parser.AddDirectiveHandler(this, ".objc_string_object",
201                                MCAsmParser::DirectiveHandler(
202                  &DarwinAsmParser::ParseSectionDirectiveObjCStringObject));
203     Parser.AddDirectiveHandler(this, ".objc_symbols",
204                                MCAsmParser::DirectiveHandler(
205                  &DarwinAsmParser::ParseSectionDirectiveObjCSymbols));
206     Parser.AddDirectiveHandler(this, ".picsymbol_stub",
207                                MCAsmParser::DirectiveHandler(
208                  &DarwinAsmParser::ParseSectionDirectivePICSymbolStub));
209     Parser.AddDirectiveHandler(this, ".static_const",
210                                MCAsmParser::DirectiveHandler(
211                  &DarwinAsmParser::ParseSectionDirectiveStaticConst));
212     Parser.AddDirectiveHandler(this, ".static_data",
213                                MCAsmParser::DirectiveHandler(
214                  &DarwinAsmParser::ParseSectionDirectiveStaticData));
215     Parser.AddDirectiveHandler(this, ".symbol_stub",
216                                MCAsmParser::DirectiveHandler(
217                  &DarwinAsmParser::ParseSectionDirectiveSymbolStub));
218     Parser.AddDirectiveHandler(this, ".tdata",
219                                MCAsmParser::DirectiveHandler(
220                  &DarwinAsmParser::ParseSectionDirectiveTData));
221     Parser.AddDirectiveHandler(this, ".text",
222                                MCAsmParser::DirectiveHandler(
223                  &DarwinAsmParser::ParseSectionDirectiveText));
224     Parser.AddDirectiveHandler(this, ".thread_init_func",
225                                MCAsmParser::DirectiveHandler(
226                  &DarwinAsmParser::ParseSectionDirectiveThreadInitFunc));
227     Parser.AddDirectiveHandler(this, ".tlv",
228                                MCAsmParser::DirectiveHandler(
229                  &DarwinAsmParser::ParseSectionDirectiveTLV));
230   }
231
232   bool ParseDirectiveDesc(StringRef, SMLoc);
233   bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
234   bool ParseDirectiveLsym(StringRef, SMLoc);
235   bool ParseDirectiveSection();
236   bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
237   bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
238   bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
239   bool ParseDirectiveTBSS(StringRef, SMLoc);
240   bool ParseDirectiveZerofill(StringRef, SMLoc);
241
242   // Named Section Directive
243   bool ParseSectionDirectiveConst(StringRef, SMLoc) {
244     return ParseSectionSwitch("__TEXT", "__const");
245   }
246   bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
247     return ParseSectionSwitch("__TEXT", "__static_const");
248   }
249   bool ParseSectionDirectiveCString(StringRef, SMLoc) {
250     return ParseSectionSwitch("__TEXT","__cstring",
251                               MCSectionMachO::S_CSTRING_LITERALS);
252   }
253   bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
254     return ParseSectionSwitch("__TEXT", "__literal4",
255                               MCSectionMachO::S_4BYTE_LITERALS, 4);
256   }
257   bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
258     return ParseSectionSwitch("__TEXT", "__literal8",
259                               MCSectionMachO::S_8BYTE_LITERALS, 8);
260   }
261   bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
262     return ParseSectionSwitch("__TEXT","__literal16",
263                               MCSectionMachO::S_16BYTE_LITERALS, 16);
264   }
265   bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
266     return ParseSectionSwitch("__TEXT","__constructor");
267   }
268   bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
269     return ParseSectionSwitch("__TEXT","__destructor");
270   }
271   bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
272     return ParseSectionSwitch("__TEXT","__fvmlib_init0");
273   }
274   bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
275     return ParseSectionSwitch("__TEXT","__fvmlib_init1");
276   }
277   bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
278     return ParseSectionSwitch("__TEXT","__symbol_stub",
279                               MCSectionMachO::S_SYMBOL_STUBS |
280                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
281                               // FIXME: Different on PPC and ARM.
282                               0, 16);
283   }
284   bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
285     return ParseSectionSwitch("__TEXT","__picsymbol_stub",
286                               MCSectionMachO::S_SYMBOL_STUBS |
287                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
288   }
289   bool ParseSectionDirectiveData(StringRef, SMLoc) {
290     return ParseSectionSwitch("__DATA", "__data");
291   }
292   bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
293     return ParseSectionSwitch("__DATA", "__static_data");
294   }
295   bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
296     return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
297                               MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
298   }
299   bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
300     return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
301                               MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
302   }
303   bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
304     return ParseSectionSwitch("__DATA", "__dyld");
305   }
306   bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
307     return ParseSectionSwitch("__DATA", "__mod_init_func",
308                               MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
309   }
310   bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
311     return ParseSectionSwitch("__DATA", "__mod_term_func",
312                               MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
313   }
314   bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
315     return ParseSectionSwitch("__DATA", "__const");
316   }
317   bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
318     return ParseSectionSwitch("__OBJC", "__class",
319                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
320   }
321   bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
322     return ParseSectionSwitch("__OBJC", "__meta_class",
323                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
324   }
325   bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
326     return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
327                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
328   }
329   bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
330     return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
331                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
332   }
333   bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
334     return ParseSectionSwitch("__OBJC", "__protocol",
335                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
336   }
337   bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
338     return ParseSectionSwitch("__OBJC", "__string_object",
339                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
340   }
341   bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
342     return ParseSectionSwitch("__OBJC", "__cls_meth",
343                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
344   }
345   bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
346     return ParseSectionSwitch("__OBJC", "__inst_meth",
347                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
348   }
349   bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
350     return ParseSectionSwitch("__OBJC", "__cls_refs",
351                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
352                               MCSectionMachO::S_LITERAL_POINTERS, 4);
353   }
354   bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
355     return ParseSectionSwitch("__OBJC", "__message_refs",
356                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
357                               MCSectionMachO::S_LITERAL_POINTERS, 4);
358   }
359   bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
360     return ParseSectionSwitch("__OBJC", "__symbols",
361                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
362   }
363   bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
364     return ParseSectionSwitch("__OBJC", "__category",
365                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
366   }
367   bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
368     return ParseSectionSwitch("__OBJC", "__class_vars",
369                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
370   }
371   bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
372     return ParseSectionSwitch("__OBJC", "__instance_vars",
373                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
374   }
375   bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
376     return ParseSectionSwitch("__OBJC", "__module_info",
377                               MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
378   }
379   bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
380     return ParseSectionSwitch("__TEXT", "__cstring",
381                               MCSectionMachO::S_CSTRING_LITERALS);
382   }
383   bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
384     return ParseSectionSwitch("__TEXT", "__cstring",
385                               MCSectionMachO::S_CSTRING_LITERALS);
386   }
387   bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
388     return ParseSectionSwitch("__TEXT", "__cstring",
389                               MCSectionMachO::S_CSTRING_LITERALS);
390   }
391   bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
392     return ParseSectionSwitch("__OBJC", "__selector_strs",
393                               MCSectionMachO::S_CSTRING_LITERALS);
394   }
395   bool ParseSectionDirectiveTData(StringRef, SMLoc) {
396     return ParseSectionSwitch("__DATA", "__thread_data",
397                               MCSectionMachO::S_THREAD_LOCAL_REGULAR);
398   }
399   bool ParseSectionDirectiveText(StringRef, SMLoc) {
400     return ParseSectionSwitch("__TEXT", "__text",
401                               MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
402   }
403   bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
404     return ParseSectionSwitch("__DATA", "__thread_vars",
405                               MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
406   }
407   bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
408     return ParseSectionSwitch("__DATA", "__thread_init",
409                          MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
410   }
411
412 };
413
414 class ELFAsmParser : public MCAsmParserExtension {
415   bool ParseSectionSwitch(StringRef Section, unsigned Type,
416                           unsigned Flags, SectionKind Kind);
417
418 public:
419   ELFAsmParser() {}
420
421   virtual void Initialize(MCAsmParser &Parser) {
422     // Call the base implementation.
423     this->MCAsmParserExtension::Initialize(Parser);
424
425     Parser.AddDirectiveHandler(this, ".data", MCAsmParser::DirectiveHandler(
426                                  &ELFAsmParser::ParseSectionDirectiveData));
427     Parser.AddDirectiveHandler(this, ".text", MCAsmParser::DirectiveHandler(
428                                  &ELFAsmParser::ParseSectionDirectiveText));
429   }
430
431   bool ParseSectionDirectiveData(StringRef, SMLoc) {
432     return ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS,
433                               MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
434                               SectionKind::getDataRel());
435   }
436   bool ParseSectionDirectiveText(StringRef, SMLoc) {
437     return ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS,
438                               MCSectionELF::SHF_EXECINSTR |
439                               MCSectionELF::SHF_ALLOC, SectionKind::getText());
440   }
441 };
442
443 }
444
445 enum { DEFAULT_ADDRSPACE = 0 };
446
447 AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx,
448                      MCStreamer &_Out, const MCAsmInfo &_MAI)
449   : Lexer(_MAI), Ctx(_Ctx), Out(_Out), SrcMgr(_SM),
450     GenericParser(new GenericAsmParser), PlatformParser(0),
451     TargetParser(0), CurBuffer(0) {
452   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
453
454   // Initialize the generic parser.
455   GenericParser->Initialize(*this);
456
457   // Initialize the platform / file format parser.
458   //
459   // FIXME: This is a hack, we need to (majorly) cleanup how these objects are
460   // created.
461   if (_MAI.hasSubsectionsViaSymbols()) {
462     PlatformParser = new DarwinAsmParser;
463     PlatformParser->Initialize(*this);
464   } else {
465     PlatformParser = new ELFAsmParser;
466     PlatformParser->Initialize(*this);
467   }
468 }
469
470 AsmParser::~AsmParser() {
471   delete PlatformParser;
472   delete GenericParser;
473 }
474
475 void AsmParser::setTargetParser(TargetAsmParser &P) {
476   assert(!TargetParser && "Target parser is already initialized!");
477   TargetParser = &P;
478   TargetParser->Initialize(*this);
479 }
480
481 void AsmParser::Warning(SMLoc L, const Twine &Msg) {
482   PrintMessage(L, Msg.str(), "warning");
483 }
484
485 bool AsmParser::Error(SMLoc L, const Twine &Msg) {
486   PrintMessage(L, Msg.str(), "error");
487   return true;
488 }
489
490 void AsmParser::PrintMessage(SMLoc Loc, const std::string &Msg, 
491                              const char *Type) const {
492   SrcMgr.PrintMessage(Loc, Msg, Type);
493 }
494                   
495 bool AsmParser::EnterIncludeFile(const std::string &Filename) {
496   int NewBuf = SrcMgr.AddIncludeFile(Filename, Lexer.getLoc());
497   if (NewBuf == -1)
498     return true;
499   
500   CurBuffer = NewBuf;
501   
502   Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
503   
504   return false;
505 }
506                   
507 const AsmToken &AsmParser::Lex() {
508   const AsmToken *tok = &Lexer.Lex();
509   
510   if (tok->is(AsmToken::Eof)) {
511     // If this is the end of an included file, pop the parent file off the
512     // include stack.
513     SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer);
514     if (ParentIncludeLoc != SMLoc()) {
515       CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc);
516       Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer), 
517                       ParentIncludeLoc.getPointer());
518       tok = &Lexer.Lex();
519     }
520   }
521     
522   if (tok->is(AsmToken::Error))
523     PrintMessage(Lexer.getErrLoc(), Lexer.getErr(), "error");
524   
525   return *tok;
526 }
527
528 bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
529   // Create the initial section, if requested.
530   //
531   // FIXME: Target hook & command line option for initial section.
532   if (!NoInitialTextSection)
533     Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text",
534                                       MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
535                                       0, SectionKind::getText()));
536
537   // Prime the lexer.
538   Lex();
539   
540   bool HadError = false;
541   
542   AsmCond StartingCondState = TheCondState;
543
544   // While we have input, parse each statement.
545   while (Lexer.isNot(AsmToken::Eof)) {
546     if (!ParseStatement()) continue;
547   
548     // We had an error, remember it and recover by skipping to the next line.
549     HadError = true;
550     EatToEndOfStatement();
551   }
552
553   if (TheCondState.TheCond != StartingCondState.TheCond ||
554       TheCondState.Ignore != StartingCondState.Ignore)
555     return TokError("unmatched .ifs or .elses");
556   
557   // Finalize the output stream if there are no errors and if the client wants
558   // us to.
559   if (!HadError && !NoFinalize)  
560     Out.Finish();
561
562   return HadError;
563 }
564
565 /// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
566 void AsmParser::EatToEndOfStatement() {
567   while (Lexer.isNot(AsmToken::EndOfStatement) &&
568          Lexer.isNot(AsmToken::Eof))
569     Lex();
570   
571   // Eat EOL.
572   if (Lexer.is(AsmToken::EndOfStatement))
573     Lex();
574 }
575
576
577 /// ParseParenExpr - Parse a paren expression and return it.
578 /// NOTE: This assumes the leading '(' has already been consumed.
579 ///
580 /// parenexpr ::= expr)
581 ///
582 bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
583   if (ParseExpression(Res)) return true;
584   if (Lexer.isNot(AsmToken::RParen))
585     return TokError("expected ')' in parentheses expression");
586   EndLoc = Lexer.getLoc();
587   Lex();
588   return false;
589 }
590
591 /// ParsePrimaryExpr - Parse a primary expression and return it.
592 ///  primaryexpr ::= (parenexpr
593 ///  primaryexpr ::= symbol
594 ///  primaryexpr ::= number
595 ///  primaryexpr ::= '.'
596 ///  primaryexpr ::= ~,+,- primaryexpr
597 bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
598   switch (Lexer.getKind()) {
599   default:
600     return TokError("unknown token in expression");
601   case AsmToken::Exclaim:
602     Lex(); // Eat the operator.
603     if (ParsePrimaryExpr(Res, EndLoc))
604       return true;
605     Res = MCUnaryExpr::CreateLNot(Res, getContext());
606     return false;
607   case AsmToken::String:
608   case AsmToken::Identifier: {
609     // This is a symbol reference.
610     std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
611     MCSymbol *Sym = getContext().GetOrCreateSymbol(Split.first);
612
613     // Mark the symbol as used in an expression.
614     Sym->setUsedInExpr(true);
615
616     // Lookup the symbol variant if used.
617     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
618     if (Split.first.size() != getTok().getIdentifier().size())
619       Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
620
621     EndLoc = Lexer.getLoc();
622     Lex(); // Eat identifier.
623
624     // If this is an absolute variable reference, substitute it now to preserve
625     // semantics in the face of reassignment.
626     if (Sym->isVariable() && isa<MCConstantExpr>(Sym->getVariableValue())) {
627       if (Variant)
628         return Error(EndLoc, "unexpected modified on variable reference");
629
630       Res = Sym->getVariableValue();
631       return false;
632     }
633
634     // Otherwise create a symbol ref.
635     Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
636     return false;
637   }
638   case AsmToken::Integer: {
639     SMLoc Loc = getTok().getLoc();
640     int64_t IntVal = getTok().getIntVal();
641     Res = MCConstantExpr::Create(IntVal, getContext());
642     EndLoc = Lexer.getLoc();
643     Lex(); // Eat token.
644     // Look for 'b' or 'f' following an Integer as a directional label
645     if (Lexer.getKind() == AsmToken::Identifier) {
646       StringRef IDVal = getTok().getString();
647       if (IDVal == "f" || IDVal == "b"){
648         MCSymbol *Sym = Ctx.GetDirectionalLocalSymbol(IntVal,
649                                                       IDVal == "f" ? 1 : 0);
650         Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
651                                       getContext());
652         if(IDVal == "b" && Sym->isUndefined())
653           return Error(Loc, "invalid reference to undefined symbol");
654         EndLoc = Lexer.getLoc();
655         Lex(); // Eat identifier.
656       }
657     }
658     return false;
659   }
660   case AsmToken::Dot: {
661     // This is a '.' reference, which references the current PC.  Emit a
662     // temporary label to the streamer and refer to it.
663     MCSymbol *Sym = Ctx.CreateTempSymbol();
664     Out.EmitLabel(Sym);
665     Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
666     EndLoc = Lexer.getLoc();
667     Lex(); // Eat identifier.
668     return false;
669   }
670       
671   case AsmToken::LParen:
672     Lex(); // Eat the '('.
673     return ParseParenExpr(Res, EndLoc);
674   case AsmToken::Minus:
675     Lex(); // Eat the operator.
676     if (ParsePrimaryExpr(Res, EndLoc))
677       return true;
678     Res = MCUnaryExpr::CreateMinus(Res, getContext());
679     return false;
680   case AsmToken::Plus:
681     Lex(); // Eat the operator.
682     if (ParsePrimaryExpr(Res, EndLoc))
683       return true;
684     Res = MCUnaryExpr::CreatePlus(Res, getContext());
685     return false;
686   case AsmToken::Tilde:
687     Lex(); // Eat the operator.
688     if (ParsePrimaryExpr(Res, EndLoc))
689       return true;
690     Res = MCUnaryExpr::CreateNot(Res, getContext());
691     return false;
692   }
693 }
694
695 bool AsmParser::ParseExpression(const MCExpr *&Res) {
696   SMLoc EndLoc;
697   return ParseExpression(Res, EndLoc);
698 }
699
700 /// ParseExpression - Parse an expression and return it.
701 /// 
702 ///  expr ::= expr +,- expr          -> lowest.
703 ///  expr ::= expr |,^,&,! expr      -> middle.
704 ///  expr ::= expr *,/,%,<<,>> expr  -> highest.
705 ///  expr ::= primaryexpr
706 ///
707 bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
708   // Parse the expression.
709   Res = 0;
710   if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
711     return true;
712
713   // Try to constant fold it up front, if possible.
714   int64_t Value;
715   if (Res->EvaluateAsAbsolute(Value))
716     Res = MCConstantExpr::Create(Value, getContext());
717
718   return false;
719 }
720
721 bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
722   Res = 0;
723   return ParseParenExpr(Res, EndLoc) ||
724          ParseBinOpRHS(1, Res, EndLoc);
725 }
726
727 bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
728   const MCExpr *Expr;
729   
730   SMLoc StartLoc = Lexer.getLoc();
731   if (ParseExpression(Expr))
732     return true;
733
734   if (!Expr->EvaluateAsAbsolute(Res))
735     return Error(StartLoc, "expected absolute expression");
736
737   return false;
738 }
739
740 static unsigned getBinOpPrecedence(AsmToken::TokenKind K, 
741                                    MCBinaryExpr::Opcode &Kind) {
742   switch (K) {
743   default:
744     return 0;    // not a binop.
745
746     // Lowest Precedence: &&, ||
747   case AsmToken::AmpAmp:
748     Kind = MCBinaryExpr::LAnd;
749     return 1;
750   case AsmToken::PipePipe:
751     Kind = MCBinaryExpr::LOr;
752     return 1;
753
754     // Low Precedence: +, -, ==, !=, <>, <, <=, >, >=
755   case AsmToken::Plus:
756     Kind = MCBinaryExpr::Add;
757     return 2;
758   case AsmToken::Minus:
759     Kind = MCBinaryExpr::Sub;
760     return 2;
761   case AsmToken::EqualEqual:
762     Kind = MCBinaryExpr::EQ;
763     return 2;
764   case AsmToken::ExclaimEqual:
765   case AsmToken::LessGreater:
766     Kind = MCBinaryExpr::NE;
767     return 2;
768   case AsmToken::Less:
769     Kind = MCBinaryExpr::LT;
770     return 2;
771   case AsmToken::LessEqual:
772     Kind = MCBinaryExpr::LTE;
773     return 2;
774   case AsmToken::Greater:
775     Kind = MCBinaryExpr::GT;
776     return 2;
777   case AsmToken::GreaterEqual:
778     Kind = MCBinaryExpr::GTE;
779     return 2;
780
781     // Intermediate Precedence: |, &, ^
782     //
783     // FIXME: gas seems to support '!' as an infix operator?
784   case AsmToken::Pipe:
785     Kind = MCBinaryExpr::Or;
786     return 3;
787   case AsmToken::Caret:
788     Kind = MCBinaryExpr::Xor;
789     return 3;
790   case AsmToken::Amp:
791     Kind = MCBinaryExpr::And;
792     return 3;
793
794     // Highest Precedence: *, /, %, <<, >>
795   case AsmToken::Star:
796     Kind = MCBinaryExpr::Mul;
797     return 4;
798   case AsmToken::Slash:
799     Kind = MCBinaryExpr::Div;
800     return 4;
801   case AsmToken::Percent:
802     Kind = MCBinaryExpr::Mod;
803     return 4;
804   case AsmToken::LessLess:
805     Kind = MCBinaryExpr::Shl;
806     return 4;
807   case AsmToken::GreaterGreater:
808     Kind = MCBinaryExpr::Shr;
809     return 4;
810   }
811 }
812
813
814 /// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'.
815 /// Res contains the LHS of the expression on input.
816 bool AsmParser::ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res,
817                               SMLoc &EndLoc) {
818   while (1) {
819     MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add;
820     unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind);
821     
822     // If the next token is lower precedence than we are allowed to eat, return
823     // successfully with what we ate already.
824     if (TokPrec < Precedence)
825       return false;
826     
827     Lex();
828     
829     // Eat the next primary expression.
830     const MCExpr *RHS;
831     if (ParsePrimaryExpr(RHS, EndLoc)) return true;
832     
833     // If BinOp binds less tightly with RHS than the operator after RHS, let
834     // the pending operator take RHS as its LHS.
835     MCBinaryExpr::Opcode Dummy;
836     unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind(), Dummy);
837     if (TokPrec < NextTokPrec) {
838       if (ParseBinOpRHS(Precedence+1, RHS, EndLoc)) return true;
839     }
840
841     // Merge LHS and RHS according to operator.
842     Res = MCBinaryExpr::Create(Kind, Res, RHS, getContext());
843   }
844 }
845
846   
847   
848   
849 /// ParseStatement:
850 ///   ::= EndOfStatement
851 ///   ::= Label* Directive ...Operands... EndOfStatement
852 ///   ::= Label* Identifier OperandList* EndOfStatement
853 bool AsmParser::ParseStatement() {
854   if (Lexer.is(AsmToken::EndOfStatement)) {
855     Out.AddBlankLine();
856     Lex();
857     return false;
858   }
859
860   // Statements always start with an identifier.
861   AsmToken ID = getTok();
862   SMLoc IDLoc = ID.getLoc();
863   StringRef IDVal;
864   int64_t LocalLabelVal = -1;
865   // GUESS allow an integer followed by a ':' as a directional local label
866   if (Lexer.is(AsmToken::Integer)) {
867     LocalLabelVal = getTok().getIntVal();
868     if (LocalLabelVal < 0) {
869       if (!TheCondState.Ignore)
870         return TokError("unexpected token at start of statement");
871       IDVal = "";
872     }
873     else {
874       IDVal = getTok().getString();
875       Lex(); // Consume the integer token to be used as an identifier token.
876       if (Lexer.getKind() != AsmToken::Colon) {
877         if (!TheCondState.Ignore)
878           return TokError("unexpected token at start of statement");
879       }
880     }
881   }
882   else if (ParseIdentifier(IDVal)) {
883     if (!TheCondState.Ignore)
884       return TokError("unexpected token at start of statement");
885     IDVal = "";
886   }
887
888   // Handle conditional assembly here before checking for skipping.  We
889   // have to do this so that .endif isn't skipped in a ".if 0" block for
890   // example.
891   if (IDVal == ".if")
892     return ParseDirectiveIf(IDLoc);
893   if (IDVal == ".elseif")
894     return ParseDirectiveElseIf(IDLoc);
895   if (IDVal == ".else")
896     return ParseDirectiveElse(IDLoc);
897   if (IDVal == ".endif")
898     return ParseDirectiveEndIf(IDLoc);
899     
900   // If we are in a ".if 0" block, ignore this statement.
901   if (TheCondState.Ignore) {
902     EatToEndOfStatement();
903     return false;
904   }
905   
906   // FIXME: Recurse on local labels?
907
908   // See what kind of statement we have.
909   switch (Lexer.getKind()) {
910   case AsmToken::Colon: {
911     // identifier ':'   -> Label.
912     Lex();
913
914     // Diagnose attempt to use a variable as a label.
915     //
916     // FIXME: Diagnostics. Note the location of the definition as a label.
917     // FIXME: This doesn't diagnose assignment to a symbol which has been
918     // implicitly marked as external.
919     MCSymbol *Sym;
920     if (LocalLabelVal == -1)
921       Sym = getContext().GetOrCreateSymbol(IDVal);
922     else
923       Sym = Ctx.CreateDirectionalLocalSymbol(LocalLabelVal);
924     if (!Sym->isUndefined() || Sym->isVariable())
925       return Error(IDLoc, "invalid symbol redefinition");
926     
927     // Emit the label.
928     Out.EmitLabel(Sym);
929    
930     // Consume any end of statement token, if present, to avoid spurious
931     // AddBlankLine calls().
932     if (Lexer.is(AsmToken::EndOfStatement)) {
933       Lex();
934       if (Lexer.is(AsmToken::Eof))
935         return false;
936     }
937
938     return ParseStatement();
939   }
940
941   case AsmToken::Equal:
942     // identifier '=' ... -> assignment statement
943     Lex();
944
945     return ParseAssignment(IDVal);
946
947   default: // Normal instruction or directive.
948     break;
949   }
950   
951   // Otherwise, we have a normal instruction or directive.  
952   if (IDVal[0] == '.') {
953     // Assembler features
954     if (IDVal == ".set")
955       return ParseDirectiveSet();
956
957     // Data directives
958
959     if (IDVal == ".ascii")
960       return ParseDirectiveAscii(false);
961     if (IDVal == ".asciz")
962       return ParseDirectiveAscii(true);
963
964     if (IDVal == ".byte")
965       return ParseDirectiveValue(1);
966     if (IDVal == ".short")
967       return ParseDirectiveValue(2);
968     if (IDVal == ".long")
969       return ParseDirectiveValue(4);
970     if (IDVal == ".quad")
971       return ParseDirectiveValue(8);
972
973     // FIXME: Target hooks for IsPow2.
974     if (IDVal == ".align")
975       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
976     if (IDVal == ".align32")
977       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
978     if (IDVal == ".balign")
979       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
980     if (IDVal == ".balignw")
981       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
982     if (IDVal == ".balignl")
983       return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
984     if (IDVal == ".p2align")
985       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
986     if (IDVal == ".p2alignw")
987       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
988     if (IDVal == ".p2alignl")
989       return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
990
991     if (IDVal == ".org")
992       return ParseDirectiveOrg();
993
994     if (IDVal == ".fill")
995       return ParseDirectiveFill();
996     if (IDVal == ".space")
997       return ParseDirectiveSpace();
998
999     // Symbol attribute directives
1000
1001     if (IDVal == ".globl" || IDVal == ".global")
1002       return ParseDirectiveSymbolAttribute(MCSA_Global);
1003     if (IDVal == ".hidden")
1004       return ParseDirectiveSymbolAttribute(MCSA_Hidden);
1005     if (IDVal == ".indirect_symbol")
1006       return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
1007     if (IDVal == ".internal")
1008       return ParseDirectiveSymbolAttribute(MCSA_Internal);
1009     if (IDVal == ".lazy_reference")
1010       return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
1011     if (IDVal == ".no_dead_strip")
1012       return ParseDirectiveSymbolAttribute(MCSA_NoDeadStrip);
1013     if (IDVal == ".private_extern")
1014       return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern);
1015     if (IDVal == ".protected")
1016       return ParseDirectiveSymbolAttribute(MCSA_Protected);
1017     if (IDVal == ".reference")
1018       return ParseDirectiveSymbolAttribute(MCSA_Reference);
1019     if (IDVal == ".type")
1020       return ParseDirectiveELFType();
1021     if (IDVal == ".weak")
1022       return ParseDirectiveSymbolAttribute(MCSA_Weak);
1023     if (IDVal == ".weak_definition")
1024       return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition);
1025     if (IDVal == ".weak_reference")
1026       return ParseDirectiveSymbolAttribute(MCSA_WeakReference);
1027     if (IDVal == ".weak_def_can_be_hidden")
1028       return ParseDirectiveSymbolAttribute(MCSA_WeakDefAutoPrivate);
1029
1030     if (IDVal == ".comm")
1031       return ParseDirectiveComm(/*IsLocal=*/false);
1032     if (IDVal == ".lcomm")
1033       return ParseDirectiveComm(/*IsLocal=*/true);
1034
1035     if (IDVal == ".abort")
1036       return ParseDirectiveAbort();
1037     if (IDVal == ".include")
1038       return ParseDirectiveInclude();
1039
1040     // Look up the handler in the handler table.
1041     std::pair<MCAsmParserExtension*, DirectiveHandler> Handler =
1042       DirectiveMap.lookup(IDVal);
1043     if (Handler.first)
1044       return (Handler.first->*Handler.second)(IDVal, IDLoc);
1045
1046     // Target hook for parsing target specific directives.
1047     if (!getTargetParser().ParseDirective(ID))
1048       return false;
1049
1050     Warning(IDLoc, "ignoring directive for now");
1051     EatToEndOfStatement();
1052     return false;
1053   }
1054
1055   // Canonicalize the opcode to lower case.
1056   SmallString<128> Opcode;
1057   for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
1058     Opcode.push_back(tolower(IDVal[i]));
1059   
1060   SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
1061   bool HadError = getTargetParser().ParseInstruction(Opcode.str(), IDLoc,
1062                                                      ParsedOperands);
1063   if (!HadError && Lexer.isNot(AsmToken::EndOfStatement))
1064     HadError = TokError("unexpected token in argument list");
1065
1066   // If parsing succeeded, match the instruction.
1067   if (!HadError) {
1068     MCInst Inst;
1069     if (!getTargetParser().MatchInstruction(ParsedOperands, Inst)) {
1070       // Emit the instruction on success.
1071       Out.EmitInstruction(Inst);
1072     } else {
1073       // Otherwise emit a diagnostic about the match failure and set the error
1074       // flag.
1075       //
1076       // FIXME: We should give nicer diagnostics about the exact failure.
1077       Error(IDLoc, "unrecognized instruction");
1078       HadError = true;
1079     }
1080   }
1081
1082   // If there was no error, consume the end-of-statement token. Otherwise this
1083   // will be done by our caller.
1084   if (!HadError)
1085     Lex();
1086
1087   // Free any parsed operands.
1088   for (unsigned i = 0, e = ParsedOperands.size(); i != e; ++i)
1089     delete ParsedOperands[i];
1090
1091   return HadError;
1092 }
1093
1094 bool AsmParser::ParseAssignment(const StringRef &Name) {
1095   // FIXME: Use better location, we should use proper tokens.
1096   SMLoc EqualLoc = Lexer.getLoc();
1097
1098   const MCExpr *Value;
1099   if (ParseExpression(Value))
1100     return true;
1101   
1102   if (Lexer.isNot(AsmToken::EndOfStatement))
1103     return TokError("unexpected token in assignment");
1104
1105   // Eat the end of statement marker.
1106   Lex();
1107
1108   // Validate that the LHS is allowed to be a variable (either it has not been
1109   // used as a symbol, or it is an absolute symbol).
1110   MCSymbol *Sym = getContext().LookupSymbol(Name);
1111   if (Sym) {
1112     // Diagnose assignment to a label.
1113     //
1114     // FIXME: Diagnostics. Note the location of the definition as a label.
1115     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
1116     if (Sym->isUndefined() && !Sym->isUsedInExpr())
1117       ; // Allow redefinitions of undefined symbols only used in directives.
1118     else if (!Sym->isUndefined() && !Sym->isAbsolute())
1119       return Error(EqualLoc, "redefinition of '" + Name + "'");
1120     else if (!Sym->isVariable())
1121       return Error(EqualLoc, "invalid assignment to '" + Name + "'");
1122     else if (!isa<MCConstantExpr>(Sym->getVariableValue()))
1123       return Error(EqualLoc, "invalid reassignment of non-absolute variable '" +
1124                    Name + "'");
1125   } else
1126     Sym = getContext().GetOrCreateSymbol(Name);
1127
1128   // FIXME: Handle '.'.
1129
1130   Sym->setUsedInExpr(true);
1131
1132   // Do the assignment.
1133   Out.EmitAssignment(Sym, Value);
1134
1135   return false;
1136 }
1137
1138 /// ParseIdentifier:
1139 ///   ::= identifier
1140 ///   ::= string
1141 bool AsmParser::ParseIdentifier(StringRef &Res) {
1142   if (Lexer.isNot(AsmToken::Identifier) &&
1143       Lexer.isNot(AsmToken::String))
1144     return true;
1145
1146   Res = getTok().getIdentifier();
1147
1148   Lex(); // Consume the identifier token.
1149
1150   return false;
1151 }
1152
1153 /// ParseDirectiveSet:
1154 ///   ::= .set identifier ',' expression
1155 bool AsmParser::ParseDirectiveSet() {
1156   StringRef Name;
1157
1158   if (ParseIdentifier(Name))
1159     return TokError("expected identifier after '.set' directive");
1160   
1161   if (getLexer().isNot(AsmToken::Comma))
1162     return TokError("unexpected token in '.set'");
1163   Lex();
1164
1165   return ParseAssignment(Name);
1166 }
1167
1168 /// ParseDirectiveSection:
1169 ///   ::= .section identifier (',' identifier)*
1170 bool DarwinAsmParser::ParseDirectiveSection() {
1171   SMLoc Loc = getLexer().getLoc();
1172
1173   StringRef SectionName;
1174   if (getParser().ParseIdentifier(SectionName))
1175     return Error(Loc, "expected identifier after '.section' directive");
1176
1177   // Verify there is a following comma.
1178   if (!getLexer().is(AsmToken::Comma))
1179     return TokError("unexpected token in '.section' directive");
1180
1181   std::string SectionSpec = SectionName;
1182   SectionSpec += ",";
1183
1184   // Add all the tokens until the end of the line, ParseSectionSpecifier will
1185   // handle this.
1186   StringRef EOL = getLexer().LexUntilEndOfStatement();
1187   SectionSpec.append(EOL.begin(), EOL.end());
1188
1189   Lex();
1190   if (getLexer().isNot(AsmToken::EndOfStatement))
1191     return TokError("unexpected token in '.section' directive");
1192   Lex();
1193
1194
1195   StringRef Segment, Section;
1196   unsigned TAA, StubSize;
1197   std::string ErrorStr =
1198     MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
1199                                           TAA, StubSize);
1200
1201   if (!ErrorStr.empty())
1202     return Error(Loc, ErrorStr.c_str());
1203
1204   // FIXME: Arch specific.
1205   bool isText = Segment == "__TEXT";  // FIXME: Hack.
1206   getStreamer().SwitchSection(getContext().getMachOSection(
1207                                 Segment, Section, TAA, StubSize,
1208                                 isText ? SectionKind::getText()
1209                                 : SectionKind::getDataRel()));
1210   return false;
1211 }
1212
1213 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
1214                                          const char *Section,
1215                                          unsigned TAA, unsigned Align,
1216                                          unsigned StubSize) {
1217   if (getLexer().isNot(AsmToken::EndOfStatement))
1218     return TokError("unexpected token in section switching directive");
1219   Lex();
1220
1221   // FIXME: Arch specific.
1222   bool isText = StringRef(Segment) == "__TEXT";  // FIXME: Hack.
1223   getStreamer().SwitchSection(getContext().getMachOSection(
1224                                 Segment, Section, TAA, StubSize,
1225                                 isText ? SectionKind::getText()
1226                                        : SectionKind::getDataRel()));
1227
1228   // Set the implicit alignment, if any.
1229   //
1230   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
1231   // alignment on the section (e.g., if one manually inserts bytes into the
1232   // section, then just issueing the section switch directive will not realign
1233   // the section. However, this is arguably more reasonable behavior, and there
1234   // is no good reason for someone to intentionally emit incorrectly sized
1235   // values into the implicitly aligned sections.
1236   if (Align)
1237     getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
1238
1239   return false;
1240 }
1241
1242 bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
1243                                       unsigned Flags, SectionKind Kind) {
1244   if (getLexer().isNot(AsmToken::EndOfStatement))
1245     return TokError("unexpected token in section switching directive");
1246   Lex();
1247
1248   getStreamer().SwitchSection(getContext().getELFSection(
1249                                 Section, Type, Flags, Kind));
1250
1251   return false;
1252 }
1253
1254 bool AsmParser::ParseEscapedString(std::string &Data) {
1255   assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
1256
1257   Data = "";
1258   StringRef Str = getTok().getStringContents();
1259   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
1260     if (Str[i] != '\\') {
1261       Data += Str[i];
1262       continue;
1263     }
1264
1265     // Recognize escaped characters. Note that this escape semantics currently
1266     // loosely follows Darwin 'as'. Notably, it doesn't support hex escapes.
1267     ++i;
1268     if (i == e)
1269       return TokError("unexpected backslash at end of string");
1270
1271     // Recognize octal sequences.
1272     if ((unsigned) (Str[i] - '0') <= 7) {
1273       // Consume up to three octal characters.
1274       unsigned Value = Str[i] - '0';
1275
1276       if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1277         ++i;
1278         Value = Value * 8 + (Str[i] - '0');
1279
1280         if (i + 1 != e && ((unsigned) (Str[i + 1] - '0')) <= 7) {
1281           ++i;
1282           Value = Value * 8 + (Str[i] - '0');
1283         }
1284       }
1285
1286       if (Value > 255)
1287         return TokError("invalid octal escape sequence (out of range)");
1288
1289       Data += (unsigned char) Value;
1290       continue;
1291     }
1292
1293     // Otherwise recognize individual escapes.
1294     switch (Str[i]) {
1295     default:
1296       // Just reject invalid escape sequences for now.
1297       return TokError("invalid escape sequence (unrecognized character)");
1298
1299     case 'b': Data += '\b'; break;
1300     case 'f': Data += '\f'; break;
1301     case 'n': Data += '\n'; break;
1302     case 'r': Data += '\r'; break;
1303     case 't': Data += '\t'; break;
1304     case '"': Data += '"'; break;
1305     case '\\': Data += '\\'; break;
1306     }
1307   }
1308
1309   return false;
1310 }
1311
1312 /// ParseDirectiveAscii:
1313 ///   ::= ( .ascii | .asciz ) [ "string" ( , "string" )* ]
1314 bool AsmParser::ParseDirectiveAscii(bool ZeroTerminated) {
1315   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1316     for (;;) {
1317       if (getLexer().isNot(AsmToken::String))
1318         return TokError("expected string in '.ascii' or '.asciz' directive");
1319
1320       std::string Data;
1321       if (ParseEscapedString(Data))
1322         return true;
1323
1324       getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
1325       if (ZeroTerminated)
1326         getStreamer().EmitBytes(StringRef("\0", 1), DEFAULT_ADDRSPACE);
1327
1328       Lex();
1329
1330       if (getLexer().is(AsmToken::EndOfStatement))
1331         break;
1332
1333       if (getLexer().isNot(AsmToken::Comma))
1334         return TokError("unexpected token in '.ascii' or '.asciz' directive");
1335       Lex();
1336     }
1337   }
1338
1339   Lex();
1340   return false;
1341 }
1342
1343 /// ParseDirectiveValue
1344 ///  ::= (.byte | .short | ... ) [ expression (, expression)* ]
1345 bool AsmParser::ParseDirectiveValue(unsigned Size) {
1346   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1347     for (;;) {
1348       const MCExpr *Value;
1349       SMLoc ATTRIBUTE_UNUSED StartLoc = getLexer().getLoc();
1350       if (ParseExpression(Value))
1351         return true;
1352
1353       // Special case constant expressions to match code generator.
1354       if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value))
1355         getStreamer().EmitIntValue(MCE->getValue(), Size, DEFAULT_ADDRSPACE);
1356       else
1357         getStreamer().EmitValue(Value, Size, DEFAULT_ADDRSPACE);
1358
1359       if (getLexer().is(AsmToken::EndOfStatement))
1360         break;
1361       
1362       // FIXME: Improve diagnostic.
1363       if (getLexer().isNot(AsmToken::Comma))
1364         return TokError("unexpected token in directive");
1365       Lex();
1366     }
1367   }
1368
1369   Lex();
1370   return false;
1371 }
1372
1373 /// ParseDirectiveSpace
1374 ///  ::= .space expression [ , expression ]
1375 bool AsmParser::ParseDirectiveSpace() {
1376   int64_t NumBytes;
1377   if (ParseAbsoluteExpression(NumBytes))
1378     return true;
1379
1380   int64_t FillExpr = 0;
1381   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1382     if (getLexer().isNot(AsmToken::Comma))
1383       return TokError("unexpected token in '.space' directive");
1384     Lex();
1385     
1386     if (ParseAbsoluteExpression(FillExpr))
1387       return true;
1388
1389     if (getLexer().isNot(AsmToken::EndOfStatement))
1390       return TokError("unexpected token in '.space' directive");
1391   }
1392
1393   Lex();
1394
1395   if (NumBytes <= 0)
1396     return TokError("invalid number of bytes in '.space' directive");
1397
1398   // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
1399   getStreamer().EmitFill(NumBytes, FillExpr, DEFAULT_ADDRSPACE);
1400
1401   return false;
1402 }
1403
1404 /// ParseDirectiveFill
1405 ///  ::= .fill expression , expression , expression
1406 bool AsmParser::ParseDirectiveFill() {
1407   int64_t NumValues;
1408   if (ParseAbsoluteExpression(NumValues))
1409     return true;
1410
1411   if (getLexer().isNot(AsmToken::Comma))
1412     return TokError("unexpected token in '.fill' directive");
1413   Lex();
1414   
1415   int64_t FillSize;
1416   if (ParseAbsoluteExpression(FillSize))
1417     return true;
1418
1419   if (getLexer().isNot(AsmToken::Comma))
1420     return TokError("unexpected token in '.fill' directive");
1421   Lex();
1422   
1423   int64_t FillExpr;
1424   if (ParseAbsoluteExpression(FillExpr))
1425     return true;
1426
1427   if (getLexer().isNot(AsmToken::EndOfStatement))
1428     return TokError("unexpected token in '.fill' directive");
1429   
1430   Lex();
1431
1432   if (FillSize != 1 && FillSize != 2 && FillSize != 4 && FillSize != 8)
1433     return TokError("invalid '.fill' size, expected 1, 2, 4, or 8");
1434
1435   for (uint64_t i = 0, e = NumValues; i != e; ++i)
1436     getStreamer().EmitIntValue(FillExpr, FillSize, DEFAULT_ADDRSPACE);
1437
1438   return false;
1439 }
1440
1441 /// ParseDirectiveOrg
1442 ///  ::= .org expression [ , expression ]
1443 bool AsmParser::ParseDirectiveOrg() {
1444   const MCExpr *Offset;
1445   if (ParseExpression(Offset))
1446     return true;
1447
1448   // Parse optional fill expression.
1449   int64_t FillExpr = 0;
1450   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1451     if (getLexer().isNot(AsmToken::Comma))
1452       return TokError("unexpected token in '.org' directive");
1453     Lex();
1454     
1455     if (ParseAbsoluteExpression(FillExpr))
1456       return true;
1457
1458     if (getLexer().isNot(AsmToken::EndOfStatement))
1459       return TokError("unexpected token in '.org' directive");
1460   }
1461
1462   Lex();
1463
1464   // FIXME: Only limited forms of relocatable expressions are accepted here, it
1465   // has to be relative to the current section.
1466   getStreamer().EmitValueToOffset(Offset, FillExpr);
1467
1468   return false;
1469 }
1470
1471 /// ParseDirectiveAlign
1472 ///  ::= {.align, ...} expression [ , expression [ , expression ]]
1473 bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
1474   SMLoc AlignmentLoc = getLexer().getLoc();
1475   int64_t Alignment;
1476   if (ParseAbsoluteExpression(Alignment))
1477     return true;
1478
1479   SMLoc MaxBytesLoc;
1480   bool HasFillExpr = false;
1481   int64_t FillExpr = 0;
1482   int64_t MaxBytesToFill = 0;
1483   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1484     if (getLexer().isNot(AsmToken::Comma))
1485       return TokError("unexpected token in directive");
1486     Lex();
1487
1488     // The fill expression can be omitted while specifying a maximum number of
1489     // alignment bytes, e.g:
1490     //  .align 3,,4
1491     if (getLexer().isNot(AsmToken::Comma)) {
1492       HasFillExpr = true;
1493       if (ParseAbsoluteExpression(FillExpr))
1494         return true;
1495     }
1496
1497     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1498       if (getLexer().isNot(AsmToken::Comma))
1499         return TokError("unexpected token in directive");
1500       Lex();
1501
1502       MaxBytesLoc = getLexer().getLoc();
1503       if (ParseAbsoluteExpression(MaxBytesToFill))
1504         return true;
1505       
1506       if (getLexer().isNot(AsmToken::EndOfStatement))
1507         return TokError("unexpected token in directive");
1508     }
1509   }
1510
1511   Lex();
1512
1513   if (!HasFillExpr)
1514     FillExpr = 0;
1515
1516   // Compute alignment in bytes.
1517   if (IsPow2) {
1518     // FIXME: Diagnose overflow.
1519     if (Alignment >= 32) {
1520       Error(AlignmentLoc, "invalid alignment value");
1521       Alignment = 31;
1522     }
1523
1524     Alignment = 1ULL << Alignment;
1525   }
1526
1527   // Diagnose non-sensical max bytes to align.
1528   if (MaxBytesLoc.isValid()) {
1529     if (MaxBytesToFill < 1) {
1530       Error(MaxBytesLoc, "alignment directive can never be satisfied in this "
1531             "many bytes, ignoring maximum bytes expression");
1532       MaxBytesToFill = 0;
1533     }
1534
1535     if (MaxBytesToFill >= Alignment) {
1536       Warning(MaxBytesLoc, "maximum bytes expression exceeds alignment and "
1537               "has no effect");
1538       MaxBytesToFill = 0;
1539     }
1540   }
1541
1542   // Check whether we should use optimal code alignment for this .align
1543   // directive.
1544   //
1545   // FIXME: This should be using a target hook.
1546   bool UseCodeAlign = false;
1547   if (const MCSectionMachO *S = dyn_cast<MCSectionMachO>(
1548         getStreamer().getCurrentSection()))
1549       UseCodeAlign = S->hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
1550   if ((!HasFillExpr || Lexer.getMAI().getTextAlignFillValue() == FillExpr) &&
1551       ValueSize == 1 && UseCodeAlign) {
1552     getStreamer().EmitCodeAlignment(Alignment, MaxBytesToFill);
1553   } else {
1554     // FIXME: Target specific behavior about how the "extra" bytes are filled.
1555     getStreamer().EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
1556   }
1557
1558   return false;
1559 }
1560
1561 /// ParseDirectiveSymbolAttribute
1562 ///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
1563 bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
1564   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1565     for (;;) {
1566       StringRef Name;
1567
1568       if (ParseIdentifier(Name))
1569         return TokError("expected identifier in directive");
1570       
1571       MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1572
1573       getStreamer().EmitSymbolAttribute(Sym, Attr);
1574
1575       if (getLexer().is(AsmToken::EndOfStatement))
1576         break;
1577
1578       if (getLexer().isNot(AsmToken::Comma))
1579         return TokError("unexpected token in directive");
1580       Lex();
1581     }
1582   }
1583
1584   Lex();
1585   return false;  
1586 }
1587
1588 /// ParseDirectiveELFType
1589 ///  ::= .type identifier , @attribute
1590 bool AsmParser::ParseDirectiveELFType() {
1591   StringRef Name;
1592   if (ParseIdentifier(Name))
1593     return TokError("expected identifier in directive");
1594
1595   // Handle the identifier as the key symbol.
1596   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1597
1598   if (getLexer().isNot(AsmToken::Comma))
1599     return TokError("unexpected token in '.type' directive");
1600   Lex();
1601
1602   if (getLexer().isNot(AsmToken::At))
1603     return TokError("expected '@' before type");
1604   Lex();
1605
1606   StringRef Type;
1607   SMLoc TypeLoc;
1608
1609   TypeLoc = getLexer().getLoc();
1610   if (ParseIdentifier(Type))
1611     return TokError("expected symbol type in directive");
1612
1613   MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
1614     .Case("function", MCSA_ELF_TypeFunction)
1615     .Case("object", MCSA_ELF_TypeObject)
1616     .Case("tls_object", MCSA_ELF_TypeTLS)
1617     .Case("common", MCSA_ELF_TypeCommon)
1618     .Case("notype", MCSA_ELF_TypeNoType)
1619     .Default(MCSA_Invalid);
1620
1621   if (Attr == MCSA_Invalid)
1622     return Error(TypeLoc, "unsupported attribute in '.type' directive");
1623
1624   if (getLexer().isNot(AsmToken::EndOfStatement))
1625     return TokError("unexpected token in '.type' directive");
1626
1627   Lex();
1628
1629   getStreamer().EmitSymbolAttribute(Sym, Attr);
1630
1631   return false;
1632 }
1633
1634 /// ParseDirectiveDesc
1635 ///  ::= .desc identifier , expression
1636 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
1637   StringRef Name;
1638   if (getParser().ParseIdentifier(Name))
1639     return TokError("expected identifier in directive");
1640   
1641   // Handle the identifier as the key symbol.
1642   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1643
1644   if (getLexer().isNot(AsmToken::Comma))
1645     return TokError("unexpected token in '.desc' directive");
1646   Lex();
1647
1648   int64_t DescValue;
1649   if (getParser().ParseAbsoluteExpression(DescValue))
1650     return true;
1651
1652   if (getLexer().isNot(AsmToken::EndOfStatement))
1653     return TokError("unexpected token in '.desc' directive");
1654   
1655   Lex();
1656
1657   // Set the n_desc field of this Symbol to this DescValue
1658   getStreamer().EmitSymbolDesc(Sym, DescValue);
1659
1660   return false;
1661 }
1662
1663 /// ParseDirectiveComm
1664 ///  ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
1665 bool AsmParser::ParseDirectiveComm(bool IsLocal) {
1666   SMLoc IDLoc = getLexer().getLoc();
1667   StringRef Name;
1668   if (ParseIdentifier(Name))
1669     return TokError("expected identifier in directive");
1670   
1671   // Handle the identifier as the key symbol.
1672   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1673
1674   if (getLexer().isNot(AsmToken::Comma))
1675     return TokError("unexpected token in directive");
1676   Lex();
1677
1678   int64_t Size;
1679   SMLoc SizeLoc = getLexer().getLoc();
1680   if (ParseAbsoluteExpression(Size))
1681     return true;
1682
1683   int64_t Pow2Alignment = 0;
1684   SMLoc Pow2AlignmentLoc;
1685   if (getLexer().is(AsmToken::Comma)) {
1686     Lex();
1687     Pow2AlignmentLoc = getLexer().getLoc();
1688     if (ParseAbsoluteExpression(Pow2Alignment))
1689       return true;
1690     
1691     // If this target takes alignments in bytes (not log) validate and convert.
1692     if (Lexer.getMAI().getAlignmentIsInBytes()) {
1693       if (!isPowerOf2_64(Pow2Alignment))
1694         return Error(Pow2AlignmentLoc, "alignment must be a power of 2");
1695       Pow2Alignment = Log2_64(Pow2Alignment);
1696     }
1697   }
1698   
1699   if (getLexer().isNot(AsmToken::EndOfStatement))
1700     return TokError("unexpected token in '.comm' or '.lcomm' directive");
1701   
1702   Lex();
1703
1704   // NOTE: a size of zero for a .comm should create a undefined symbol
1705   // but a size of .lcomm creates a bss symbol of size zero.
1706   if (Size < 0)
1707     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
1708                  "be less than zero");
1709
1710   // NOTE: The alignment in the directive is a power of 2 value, the assembler
1711   // may internally end up wanting an alignment in bytes.
1712   // FIXME: Diagnose overflow.
1713   if (Pow2Alignment < 0)
1714     return Error(Pow2AlignmentLoc, "invalid '.comm' or '.lcomm' directive "
1715                  "alignment, can't be less than zero");
1716
1717   if (!Sym->isUndefined())
1718     return Error(IDLoc, "invalid symbol redefinition");
1719
1720   // '.lcomm' is equivalent to '.zerofill'.
1721   // Create the Symbol as a common or local common with Size and Pow2Alignment
1722   if (IsLocal) {
1723     getStreamer().EmitZerofill(Ctx.getMachOSection(
1724                                  "__DATA", "__bss", MCSectionMachO::S_ZEROFILL,
1725                                  0, SectionKind::getBSS()),
1726                                Sym, Size, 1 << Pow2Alignment);
1727     return false;
1728   }
1729
1730   getStreamer().EmitCommonSymbol(Sym, Size, 1 << Pow2Alignment);
1731   return false;
1732 }
1733
1734 /// ParseDirectiveZerofill
1735 ///  ::= .zerofill segname , sectname [, identifier , size_expression [
1736 ///      , align_expression ]]
1737 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
1738   StringRef Segment;
1739   if (getParser().ParseIdentifier(Segment))
1740     return TokError("expected segment name after '.zerofill' directive");
1741
1742   if (getLexer().isNot(AsmToken::Comma))
1743     return TokError("unexpected token in directive");
1744   Lex();
1745
1746   StringRef Section;
1747   if (getParser().ParseIdentifier(Section))
1748     return TokError("expected section name after comma in '.zerofill' "
1749                     "directive");
1750
1751   // If this is the end of the line all that was wanted was to create the
1752   // the section but with no symbol.
1753   if (getLexer().is(AsmToken::EndOfStatement)) {
1754     // Create the zerofill section but no symbol
1755     getStreamer().EmitZerofill(getContext().getMachOSection(
1756                                  Segment, Section, MCSectionMachO::S_ZEROFILL,
1757                                  0, SectionKind::getBSS()));
1758     return false;
1759   }
1760
1761   if (getLexer().isNot(AsmToken::Comma))
1762     return TokError("unexpected token in directive");
1763   Lex();
1764
1765   SMLoc IDLoc = getLexer().getLoc();
1766   StringRef IDStr;
1767   if (getParser().ParseIdentifier(IDStr))
1768     return TokError("expected identifier in directive");
1769   
1770   // handle the identifier as the key symbol.
1771   MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
1772
1773   if (getLexer().isNot(AsmToken::Comma))
1774     return TokError("unexpected token in directive");
1775   Lex();
1776
1777   int64_t Size;
1778   SMLoc SizeLoc = getLexer().getLoc();
1779   if (getParser().ParseAbsoluteExpression(Size))
1780     return true;
1781
1782   int64_t Pow2Alignment = 0;
1783   SMLoc Pow2AlignmentLoc;
1784   if (getLexer().is(AsmToken::Comma)) {
1785     Lex();
1786     Pow2AlignmentLoc = getLexer().getLoc();
1787     if (getParser().ParseAbsoluteExpression(Pow2Alignment))
1788       return true;
1789   }
1790   
1791   if (getLexer().isNot(AsmToken::EndOfStatement))
1792     return TokError("unexpected token in '.zerofill' directive");
1793   
1794   Lex();
1795
1796   if (Size < 0)
1797     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
1798                  "than zero");
1799
1800   // NOTE: The alignment in the directive is a power of 2 value, the assembler
1801   // may internally end up wanting an alignment in bytes.
1802   // FIXME: Diagnose overflow.
1803   if (Pow2Alignment < 0)
1804     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
1805                  "can't be less than zero");
1806
1807   if (!Sym->isUndefined())
1808     return Error(IDLoc, "invalid symbol redefinition");
1809
1810   // Create the zerofill Symbol with Size and Pow2Alignment
1811   //
1812   // FIXME: Arch specific.
1813   getStreamer().EmitZerofill(getContext().getMachOSection(
1814                                Segment, Section, MCSectionMachO::S_ZEROFILL,
1815                                0, SectionKind::getBSS()),
1816                              Sym, Size, 1 << Pow2Alignment);
1817
1818   return false;
1819 }
1820
1821 /// ParseDirectiveTBSS
1822 ///  ::= .tbss identifier, size, align
1823 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
1824   SMLoc IDLoc = getLexer().getLoc();
1825   StringRef Name;
1826   if (getParser().ParseIdentifier(Name))
1827     return TokError("expected identifier in directive");
1828     
1829   // Handle the identifier as the key symbol.
1830   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1831
1832   if (getLexer().isNot(AsmToken::Comma))
1833     return TokError("unexpected token in directive");
1834   Lex();
1835
1836   int64_t Size;
1837   SMLoc SizeLoc = getLexer().getLoc();
1838   if (getParser().ParseAbsoluteExpression(Size))
1839     return true;
1840
1841   int64_t Pow2Alignment = 0;
1842   SMLoc Pow2AlignmentLoc;
1843   if (getLexer().is(AsmToken::Comma)) {
1844     Lex();
1845     Pow2AlignmentLoc = getLexer().getLoc();
1846     if (getParser().ParseAbsoluteExpression(Pow2Alignment))
1847       return true;
1848   }
1849   
1850   if (getLexer().isNot(AsmToken::EndOfStatement))
1851     return TokError("unexpected token in '.tbss' directive");
1852   
1853   Lex();
1854
1855   if (Size < 0)
1856     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
1857                  "zero");
1858
1859   // FIXME: Diagnose overflow.
1860   if (Pow2Alignment < 0)
1861     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
1862                  "than zero");
1863
1864   if (!Sym->isUndefined())
1865     return Error(IDLoc, "invalid symbol redefinition");
1866   
1867   getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
1868                                  "__DATA", "__thread_bss",
1869                                  MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
1870                                  0, SectionKind::getThreadBSS()),
1871                                Sym, Size, 1 << Pow2Alignment);
1872   
1873   return false;
1874 }
1875
1876 /// ParseDirectiveSubsectionsViaSymbols
1877 ///  ::= .subsections_via_symbols
1878 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
1879   if (getLexer().isNot(AsmToken::EndOfStatement))
1880     return TokError("unexpected token in '.subsections_via_symbols' directive");
1881   
1882   Lex();
1883
1884   getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1885
1886   return false;
1887 }
1888
1889 /// ParseDirectiveAbort
1890 ///  ::= .abort [ "abort_string" ]
1891 bool AsmParser::ParseDirectiveAbort() {
1892   // FIXME: Use loc from directive.
1893   SMLoc Loc = getLexer().getLoc();
1894
1895   StringRef Str = "";
1896   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1897     if (getLexer().isNot(AsmToken::String))
1898       return TokError("expected string in '.abort' directive");
1899     
1900     Str = getTok().getString();
1901
1902     Lex();
1903   }
1904
1905   if (getLexer().isNot(AsmToken::EndOfStatement))
1906     return TokError("unexpected token in '.abort' directive");
1907   
1908   Lex();
1909
1910   // FIXME: Handle here.
1911   if (Str.empty())
1912     Error(Loc, ".abort detected. Assembly stopping.");
1913   else
1914     Error(Loc, ".abort '" + Str + "' detected. Assembly stopping.");
1915
1916   return false;
1917 }
1918
1919 /// ParseDirectiveLsym
1920 ///  ::= .lsym identifier , expression
1921 bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
1922   StringRef Name;
1923   if (getParser().ParseIdentifier(Name))
1924     return TokError("expected identifier in directive");
1925   
1926   // Handle the identifier as the key symbol.
1927   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
1928
1929   if (getLexer().isNot(AsmToken::Comma))
1930     return TokError("unexpected token in '.lsym' directive");
1931   Lex();
1932
1933   const MCExpr *Value;
1934   if (getParser().ParseExpression(Value))
1935     return true;
1936
1937   if (getLexer().isNot(AsmToken::EndOfStatement))
1938     return TokError("unexpected token in '.lsym' directive");
1939   
1940   Lex();
1941
1942   // We don't currently support this directive.
1943   //
1944   // FIXME: Diagnostic location!
1945   (void) Sym;
1946   return TokError("directive '.lsym' is unsupported");
1947 }
1948
1949 /// ParseDirectiveInclude
1950 ///  ::= .include "filename"
1951 bool AsmParser::ParseDirectiveInclude() {
1952   if (getLexer().isNot(AsmToken::String))
1953     return TokError("expected string in '.include' directive");
1954   
1955   std::string Filename = getTok().getString();
1956   SMLoc IncludeLoc = getLexer().getLoc();
1957   Lex();
1958
1959   if (getLexer().isNot(AsmToken::EndOfStatement))
1960     return TokError("unexpected token in '.include' directive");
1961   
1962   // Strip the quotes.
1963   Filename = Filename.substr(1, Filename.size()-2);
1964   
1965   // Attempt to switch the lexer to the included file before consuming the end
1966   // of statement to avoid losing it when we switch.
1967   if (EnterIncludeFile(Filename)) {
1968     PrintMessage(IncludeLoc,
1969                  "Could not find include file '" + Filename + "'",
1970                  "error");
1971     return true;
1972   }
1973
1974   return false;
1975 }
1976
1977 /// ParseDirectiveDumpOrLoad
1978 ///  ::= ( .dump | .load ) "filename"
1979 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
1980                                                SMLoc IDLoc) {
1981   bool IsDump = Directive == ".dump";
1982   if (getLexer().isNot(AsmToken::String))
1983     return TokError("expected string in '.dump' or '.load' directive");
1984   
1985   Lex();
1986
1987   if (getLexer().isNot(AsmToken::EndOfStatement))
1988     return TokError("unexpected token in '.dump' or '.load' directive");
1989   
1990   Lex();
1991
1992   // FIXME: If/when .dump and .load are implemented they will be done in the
1993   // the assembly parser and not have any need for an MCStreamer API.
1994   if (IsDump)
1995     Warning(IDLoc, "ignoring directive .dump for now");
1996   else
1997     Warning(IDLoc, "ignoring directive .load for now");
1998
1999   return false;
2000 }
2001
2002 /// ParseDirectiveSecureLogUnique
2003 ///  ::= .secure_log_unique "log message"
2004 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
2005   std::string LogMessage;
2006
2007   if (getLexer().isNot(AsmToken::String))
2008     LogMessage = "";
2009   else{
2010     LogMessage = getTok().getString();
2011     Lex();
2012   }
2013
2014   if (getLexer().isNot(AsmToken::EndOfStatement))
2015     return TokError("unexpected token in '.secure_log_unique' directive");
2016   
2017   if (getContext().getSecureLogUsed() != false)
2018     return Error(IDLoc, ".secure_log_unique specified multiple times");
2019
2020   char *SecureLogFile = getContext().getSecureLogFile();
2021   if (SecureLogFile == NULL)
2022     return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
2023                  "environment variable unset.");
2024
2025   raw_ostream *OS = getContext().getSecureLog();
2026   if (OS == NULL) {
2027     std::string Err;
2028     OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
2029     if (!Err.empty()) {
2030        delete OS;
2031        return Error(IDLoc, Twine("can't open secure log file: ") +
2032                     SecureLogFile + " (" + Err + ")");
2033     }
2034     getContext().setSecureLog(OS);
2035   }
2036
2037   int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
2038   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
2039       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
2040       << LogMessage + "\n";
2041
2042   getContext().setSecureLogUsed(true);
2043
2044   return false;
2045 }
2046
2047 /// ParseDirectiveSecureLogReset
2048 ///  ::= .secure_log_reset
2049 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
2050   if (getLexer().isNot(AsmToken::EndOfStatement))
2051     return TokError("unexpected token in '.secure_log_reset' directive");
2052   
2053   Lex();
2054
2055   getContext().setSecureLogUsed(false);
2056
2057   return false;
2058 }
2059
2060 /// ParseDirectiveIf
2061 /// ::= .if expression
2062 bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
2063   TheCondStack.push_back(TheCondState);
2064   TheCondState.TheCond = AsmCond::IfCond;
2065   if(TheCondState.Ignore) {
2066     EatToEndOfStatement();
2067   }
2068   else {
2069     int64_t ExprValue;
2070     if (ParseAbsoluteExpression(ExprValue))
2071       return true;
2072
2073     if (getLexer().isNot(AsmToken::EndOfStatement))
2074       return TokError("unexpected token in '.if' directive");
2075     
2076     Lex();
2077
2078     TheCondState.CondMet = ExprValue;
2079     TheCondState.Ignore = !TheCondState.CondMet;
2080   }
2081
2082   return false;
2083 }
2084
2085 /// ParseDirectiveElseIf
2086 /// ::= .elseif expression
2087 bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
2088   if (TheCondState.TheCond != AsmCond::IfCond &&
2089       TheCondState.TheCond != AsmCond::ElseIfCond)
2090       Error(DirectiveLoc, "Encountered a .elseif that doesn't follow a .if or "
2091                           " an .elseif");
2092   TheCondState.TheCond = AsmCond::ElseIfCond;
2093
2094   bool LastIgnoreState = false;
2095   if (!TheCondStack.empty())
2096       LastIgnoreState = TheCondStack.back().Ignore;
2097   if (LastIgnoreState || TheCondState.CondMet) {
2098     TheCondState.Ignore = true;
2099     EatToEndOfStatement();
2100   }
2101   else {
2102     int64_t ExprValue;
2103     if (ParseAbsoluteExpression(ExprValue))
2104       return true;
2105
2106     if (getLexer().isNot(AsmToken::EndOfStatement))
2107       return TokError("unexpected token in '.elseif' directive");
2108     
2109     Lex();
2110     TheCondState.CondMet = ExprValue;
2111     TheCondState.Ignore = !TheCondState.CondMet;
2112   }
2113
2114   return false;
2115 }
2116
2117 /// ParseDirectiveElse
2118 /// ::= .else
2119 bool AsmParser::ParseDirectiveElse(SMLoc DirectiveLoc) {
2120   if (getLexer().isNot(AsmToken::EndOfStatement))
2121     return TokError("unexpected token in '.else' directive");
2122   
2123   Lex();
2124
2125   if (TheCondState.TheCond != AsmCond::IfCond &&
2126       TheCondState.TheCond != AsmCond::ElseIfCond)
2127       Error(DirectiveLoc, "Encountered a .else that doesn't follow a .if or an "
2128                           ".elseif");
2129   TheCondState.TheCond = AsmCond::ElseCond;
2130   bool LastIgnoreState = false;
2131   if (!TheCondStack.empty())
2132     LastIgnoreState = TheCondStack.back().Ignore;
2133   if (LastIgnoreState || TheCondState.CondMet)
2134     TheCondState.Ignore = true;
2135   else
2136     TheCondState.Ignore = false;
2137
2138   return false;
2139 }
2140
2141 /// ParseDirectiveEndIf
2142 /// ::= .endif
2143 bool AsmParser::ParseDirectiveEndIf(SMLoc DirectiveLoc) {
2144   if (getLexer().isNot(AsmToken::EndOfStatement))
2145     return TokError("unexpected token in '.endif' directive");
2146   
2147   Lex();
2148
2149   if ((TheCondState.TheCond == AsmCond::NoCond) ||
2150       TheCondStack.empty())
2151     Error(DirectiveLoc, "Encountered a .endif that doesn't follow a .if or "
2152                         ".else");
2153   if (!TheCondStack.empty()) {
2154     TheCondState = TheCondStack.back();
2155     TheCondStack.pop_back();
2156   }
2157
2158   return false;
2159 }
2160
2161 /// ParseDirectiveFile
2162 /// ::= .file [number] string
2163 bool GenericAsmParser::ParseDirectiveFile(StringRef, SMLoc DirectiveLoc) {
2164   // FIXME: I'm not sure what this is.
2165   int64_t FileNumber = -1;
2166   if (getLexer().is(AsmToken::Integer)) {
2167     FileNumber = getTok().getIntVal();
2168     Lex();
2169
2170     if (FileNumber < 1)
2171       return TokError("file number less than one");
2172   }
2173
2174   if (getLexer().isNot(AsmToken::String))
2175     return TokError("unexpected token in '.file' directive");
2176
2177   StringRef Filename = getTok().getString();
2178   Filename = Filename.substr(1, Filename.size()-2);
2179   Lex();
2180
2181   if (getLexer().isNot(AsmToken::EndOfStatement))
2182     return TokError("unexpected token in '.file' directive");
2183
2184   if (FileNumber == -1)
2185     getStreamer().EmitFileDirective(Filename);
2186   else
2187     getStreamer().EmitDwarfFileDirective(FileNumber, Filename);
2188
2189   return false;
2190 }
2191
2192 /// ParseDirectiveLine
2193 /// ::= .line [number]
2194 bool GenericAsmParser::ParseDirectiveLine(StringRef, SMLoc DirectiveLoc) {
2195   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2196     if (getLexer().isNot(AsmToken::Integer))
2197       return TokError("unexpected token in '.line' directive");
2198
2199     int64_t LineNumber = getTok().getIntVal();
2200     (void) LineNumber;
2201     Lex();
2202
2203     // FIXME: Do something with the .line.
2204   }
2205
2206   if (getLexer().isNot(AsmToken::EndOfStatement))
2207     return TokError("unexpected token in '.line' directive");
2208
2209   return false;
2210 }
2211
2212
2213 /// ParseDirectiveLoc
2214 /// ::= .loc number [number [number]]
2215 bool GenericAsmParser::ParseDirectiveLoc(StringRef, SMLoc DirectiveLoc) {
2216   if (getLexer().isNot(AsmToken::Integer))
2217     return TokError("unexpected token in '.loc' directive");
2218
2219   // FIXME: What are these fields?
2220   int64_t FileNumber = getTok().getIntVal();
2221   (void) FileNumber;
2222   // FIXME: Validate file.
2223
2224   Lex();
2225   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2226     if (getLexer().isNot(AsmToken::Integer))
2227       return TokError("unexpected token in '.loc' directive");
2228
2229     int64_t Param2 = getTok().getIntVal();
2230     (void) Param2;
2231     Lex();
2232
2233     if (getLexer().isNot(AsmToken::EndOfStatement)) {
2234       if (getLexer().isNot(AsmToken::Integer))
2235         return TokError("unexpected token in '.loc' directive");
2236
2237       int64_t Param3 = getTok().getIntVal();
2238       (void) Param3;
2239       Lex();
2240
2241       // FIXME: Do something with the .loc.
2242     }
2243   }
2244
2245   if (getLexer().isNot(AsmToken::EndOfStatement))
2246     return TokError("unexpected token in '.file' directive");
2247
2248   return false;
2249 }
2250