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